OpenCores
URL https://opencores.org/ocsvn/openrisc/openrisc/trunk

Subversion Repositories openrisc

[/] [openrisc/] [trunk/] [rtos/] [ecos-2.0/] [packages/] [hal/] [arm/] [ebsa285/] [v2_0/] [src/] [ebsa285_misc.c] - Blame information for rev 594

Go to most recent revision | Details | Compare with Previous | View Log

Line No. Rev Author Line
1 27 unneback
//==========================================================================
2
//
3
//      ebsa285_misc.c
4
//
5
//      HAL misc board support code for StrongARM EBSA285-1
6
//
7
//==========================================================================
8
//####ECOSGPLCOPYRIGHTBEGIN####
9
// -------------------------------------------
10
// This file is part of eCos, the Embedded Configurable Operating System.
11
// Copyright (C) 1998, 1999, 2000, 2001, 2002 Red Hat, Inc.
12
//
13
// eCos is free software; you can redistribute it and/or modify it under
14
// the terms of the GNU General Public License as published by the Free
15
// Software Foundation; either version 2 or (at your option) any later version.
16
//
17
// eCos is distributed in the hope that it will be useful, but WITHOUT ANY
18
// WARRANTY; without even the implied warranty of MERCHANTABILITY or
19
// FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
20
// for more details.
21
//
22
// You should have received a copy of the GNU General Public License along
23
// with eCos; if not, write to the Free Software Foundation, Inc.,
24
// 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
25
//
26
// As a special exception, if other files instantiate templates or use macros
27
// or inline functions from this file, or you compile this file and link it
28
// with other works to produce a work based on this file, this file does not
29
// by itself cause the resulting work to be covered by the GNU General Public
30
// License. However the source code for this file must still be made available
31
// in accordance with section (3) of the GNU General Public License.
32
//
33
// This exception does not invalidate any other reasons why a work based on
34
// this file might be covered by the GNU General Public License.
35
//
36
// Alternative licenses for eCos may be arranged by contacting Red Hat, Inc.
37
// at http://sources.redhat.com/ecos/ecos-license/
38
// -------------------------------------------
39
//####ECOSGPLCOPYRIGHTEND####
40
//==========================================================================
41
//#####DESCRIPTIONBEGIN####
42
//
43
// Author(s):    gthomas
44
// Contributors: gthomas
45
// Date:         1999-02-20
46
// Purpose:      HAL board support
47
// Description:  Implementations of HAL board interfaces
48
//
49
//####DESCRIPTIONEND####
50
//
51
//========================================================================*/
52
 
53
#include <pkgconf/hal.h>
54
#include <pkgconf/system.h>
55
#include CYGBLD_HAL_PLATFORM_H
56
#include CYGHWR_MEMORY_LAYOUT_H
57
 
58
#include <cyg/infra/cyg_type.h>         // base types
59
#include <cyg/infra/cyg_trac.h>         // tracing macros
60
#include <cyg/infra/cyg_ass.h>          // assertion macros
61
 
62
#include <cyg/hal/hal_io.h>             // IO macros
63
#include <cyg/hal/hal_if.h>             // calling interface API
64
#include <cyg/hal/hal_arch.h>           // Register state info
65
#include <cyg/hal/hal_diag.h>
66
#include <cyg/hal/hal_intr.h>           // Interrupt names
67
#include <cyg/hal/hal_cache.h>
68
#include <cyg/hal/hal_ebsa285.h>        // Hardware definitions
69
 
70
#include <cyg/infra/diag.h>             // diag_printf
71
 
72
#include <string.h> // memset
73
 
74
/*
75
 * Toggle LED for debugging purposes.
76
 */
77
/*
78
 * EBSA-285 Soft I/O Register
79
 */
80
#define EBSA_285_SOFT_IO_REGISTER           ((cyg_uint32 *)0x40012000)
81
 
82
/*
83
 * EBSA-285 Soft I/O Register Bit Field definitions
84
 */
85
#define EBSA_285_SOFT_IO_TOGGLE             0x80
86
#define EBSA_285_SOFT_IO_RED_LED            0x04
87
#define EBSA_285_SOFT_IO_GREEN_LED          0x02
88
#define EBSA_285_SOFT_IO_AMBER_LED          0x01
89
#define EBSA_285_SOFT_IO_J9_9_10_MASK       0x40
90
#define EBSA_285_SOFT_IO_J9_11_12_MASK      0x20
91
#define EBSA_285_SOFT_IO_J9_13_14_MASK      0x10
92
#define EBSA_285_SOFT_IO_SWITCH_L_MASK      0x0F
93
 
94
static void
95
hal_bsp_mmu_init(int sdram_size);
96
 
97
// Some initialization has already been done before we get here.
98
//
99
// Set up the interrupt environment.
100
// Set up the MMU so that we can use caches.
101
// Enable caches.
102
// - All done!
103
 
104
 
105
void hal_hardware_init(void)
106
{
107
    // Disable all interrupt sources:
108
    *SA110_IRQCONT_IRQENABLECLEAR = 0xffffffff;
109
    *SA110_IRQCONT_FIQENABLECLEAR = 0xffffffff; // including FIQ
110
    // Disable the timers
111
    *SA110_TIMER1_CONTROL = 0;
112
    *SA110_TIMER2_CONTROL = 0;
113
    *SA110_TIMER3_CONTROL = 0;
114
    *SA110_TIMER4_CONTROL = 0;
115
 
116
    *SA110_TIMER1_CLEAR = 0;            // Clear any pending interrupt
117
    *SA110_TIMER2_CLEAR = 0;            // (Data: don't care)
118
    *SA110_TIMER3_CLEAR = 0;
119
    *SA110_TIMER4_CLEAR = 0;
120
 
121
    // Let the timer run at a default rate (for delays)
122
    hal_clock_initialize(CYGNUM_HAL_RTC_PERIOD);
123
 
124
    // Set up MMU so that we can use caches
125
    hal_bsp_mmu_init( hal_dram_size );
126
 
127
    // Enable caches
128
    HAL_DCACHE_ENABLE();
129
    HAL_ICACHE_ENABLE();
130
 
131
    // Set up eCos/ROM interfaces
132
    hal_if_init();
133
}
134
 
135
// -------------------------------------------------------------------------
136
// MMU initialization:
137
 
138
static void
139
hal_bsp_mmu_init(int sdram_size)
140
{
141
    unsigned long ttb_base = ((unsigned long)0x4000); // could be external
142
    unsigned long i;
143
 
144
    *EBSA_285_SOFT_IO_REGISTER = ~EBSA_285_SOFT_IO_RED_LED; // Red LED on
145
 
146
 
147
// For if we assign the ttb base dynamically:
148
//    if ((ttb_base & ARM_TRANSLATION_TABLE_MASK) != ttb_base) {
149
//        // we cannot do this:
150
//        while ( 1 ) {
151
//            *EBSA_285_SOFT_IO_REGISTER = 0; // All LEDs on
152
//            for ( i = 100000; i > 0 ; i++ ) ;
153
//            *EBSA_285_SOFT_IO_REGISTER = 7; // All LEDs off
154
//            for ( i = 100000; i > 0 ; i++ ) ;
155
//#ifdef CYG_HAL_STARTUP_RAM
156
//            return; // Do not bother looping forever...
157
//#endif
158
//        }
159
//    }
160
 
161
    /*
162
     * Set the TTB register
163
     */
164
    asm volatile ("mcr  p15,0,%0,c2,c0,0"
165
                  :
166
                  : "r"(ttb_base)
167
                /*:*/
168
        );
169
    /*
170
     * Set the Domain Access Control Register
171
     */
172
    i = ARM_ACCESS_TYPE_MANAGER(0)    |
173
        ARM_ACCESS_TYPE_NO_ACCESS(1)  |
174
        ARM_ACCESS_TYPE_NO_ACCESS(2)  |
175
        ARM_ACCESS_TYPE_NO_ACCESS(3)  |
176
        ARM_ACCESS_TYPE_NO_ACCESS(4)  |
177
        ARM_ACCESS_TYPE_NO_ACCESS(5)  |
178
        ARM_ACCESS_TYPE_NO_ACCESS(6)  |
179
        ARM_ACCESS_TYPE_NO_ACCESS(7)  |
180
        ARM_ACCESS_TYPE_NO_ACCESS(8)  |
181
        ARM_ACCESS_TYPE_NO_ACCESS(9)  |
182
        ARM_ACCESS_TYPE_NO_ACCESS(10) |
183
        ARM_ACCESS_TYPE_NO_ACCESS(11) |
184
        ARM_ACCESS_TYPE_NO_ACCESS(12) |
185
        ARM_ACCESS_TYPE_NO_ACCESS(13) |
186
        ARM_ACCESS_TYPE_NO_ACCESS(14) |
187
        ARM_ACCESS_TYPE_NO_ACCESS(15);
188
 
189
    asm volatile ("mcr  p15,0,%0,c3,c0,0"
190
                  :
191
                  : "r"(i)
192
                /*:*/
193
        );
194
 
195
    /*
196
     * First clear all TT entries - ie Set them to Faulting
197
     */
198
    memset((void *)ttb_base, 0, ARM_FIRST_LEVEL_PAGE_TABLE_SIZE);
199
 
200
    /*
201
     * We only do direct mapping for the EBSA board. That is, all
202
     * virt_addr == phys_addr.
203
     */
204
 
205
    /*
206
     * Actual Base = 0x000(00000)
207
     * Virtual Base = 0x000(00000)
208
     * Size = Max SDRAM
209
     * SDRAM
210
     */
211
    for (i = 0x000; i < (sdram_size >> 20); i++) {
212
        ARM_MMU_SECTION(ttb_base, i, i,
213
                        ARM_CACHEABLE, ARM_BUFFERABLE,
214
                        ARM_ACCESS_PERM_RW_RW);
215
    }
216
 
217
#ifdef CYGPKG_IO_PCI
218
    /*
219
     * Actual Base = CYGHWR_HAL_ARM_EBSA285_PCI_MEM_MAP_BASE
220
     * Virtual Base = CYGHWR_HAL_ARM_EBSA285_PCI_MEM_MAP_BASE
221
     * Size = CYGHWR_HAL_ARM_EBSA285_PCI_MEM_MAP_SIZE
222
     * Memory accessible from PCI space. Overrides part of the above mapping.
223
     */
224
    for (i = CYGHWR_HAL_ARM_EBSA285_PCI_MEM_MAP_BASE >> 20;
225
         i < ((CYGHWR_HAL_ARM_EBSA285_PCI_MEM_MAP_BASE+CYGHWR_HAL_ARM_EBSA285_PCI_MEM_MAP_SIZE) >> 20);
226
         i++) {
227
        ARM_MMU_SECTION(ttb_base, i, i,
228
                        ARM_UNCACHEABLE, ARM_UNBUFFERABLE,
229
                        ARM_ACCESS_PERM_RW_RW);
230
    }
231
#endif
232
 
233
    /*
234
     * Actual Base = 0x400(00000)
235
     * Virtual Base = 0x400(00000)
236
     * Size = 1M
237
     * 21285 Registers
238
     *
239
     * Actual Base = 0x400(10000)
240
     * Virtual Base = 0x400(10000)
241
     * Size = 1M
242
     * Soft I/O port and XBus IO
243
     */
244
    ARM_MMU_SECTION(ttb_base, 0x400, 0x400,
245
                    ARM_UNCACHEABLE, ARM_UNBUFFERABLE,
246
                    ARM_ACCESS_PERM_RW_RW);
247
 
248
    /*
249
     * Actual Base = 0x410(00000) - 0x413(FFFFF)
250
     * Virtual Base = 0x410(00000) - 0x413(FFFFF)
251
     * Size = 4M
252
     * FLASH ROM
253
     */
254
    for (i = 0x410; i <= 0x413; i++) {
255
        ARM_MMU_SECTION(ttb_base, i, i,
256
                        ARM_CACHEABLE, ARM_UNBUFFERABLE,
257
                        ARM_ACCESS_PERM_RW_RW);
258
    }
259
 
260
    /*
261
     * Actual Base = 0x420(00000)
262
     * Virtual Base = 0x420(00000)
263
     * Size = 1M
264
     * 21285 CSR Space
265
     */
266
    ARM_MMU_SECTION(ttb_base, 0x420, 0x420,
267
                    ARM_UNCACHEABLE, ARM_UNBUFFERABLE,
268
                    ARM_ACCESS_PERM_RW_RW);
269
 
270
    /*
271
     * Actual Base = 0x500(00000)-0x50F(FFFFF)
272
     * Virtual Base = 0x500(00000)-0x50F(FFFFF)
273
     * Size = 16M
274
     * Zeros (Cache Clean) Bank
275
     */
276
    for (i = 0x500; i <= 0x50F; i++) {
277
        ARM_MMU_SECTION(ttb_base, i, i,
278
                        ARM_CACHEABLE, ARM_BUFFERABLE,
279
                        ARM_ACCESS_PERM_RW_RW);
280
    }
281
 
282
    /*
283
     * Actual Base = 0x780(00000)-0x78F(FFFFF)
284
     * Virtual Base = 0x780(00000)-0x78F(FFFFF)
285
     * Size = 16M
286
     * Outbound Write Flush
287
     */
288
    for (i = 0x780; i <= 0x78F; i++) {
289
        ARM_MMU_SECTION(ttb_base, i, i,
290
                        ARM_UNCACHEABLE, ARM_UNBUFFERABLE,
291
                        ARM_ACCESS_PERM_RW_RW);
292
    }
293
 
294
    /*
295
     * Actual Base = 0x790(00000)-0x7C0(FFFFF)
296
     * Virtual Base = 0x790(00000)-0x7C0(FFFFF)
297
     * Size = 65M
298
     * PCI IACK/Config/IO Space
299
     */
300
    for (i = 0x790; i <= 0x7C0; i++) {
301
        ARM_MMU_SECTION(ttb_base, i, i,
302
                        ARM_UNCACHEABLE, ARM_UNBUFFERABLE,
303
                        ARM_ACCESS_PERM_RW_RW);
304
    }
305
 
306
    /*
307
     * Actual Base = 0x800(00000) - 0xFFF(FFFFF)
308
     * Virtual Base = 0x800(00000) - 0xFFF(FFFFF)
309
     * Size = 2G
310
     * PCI Memory Space
311
     */
312
    for (i = 0x800; i <= 0xFFF; i++) {
313
        ARM_MMU_SECTION(ttb_base, i, i,
314
                        ARM_UNCACHEABLE, ARM_BUFFERABLE,
315
                        ARM_ACCESS_PERM_RW_RW);
316
    }
317
 
318
    *EBSA_285_SOFT_IO_REGISTER = ~EBSA_285_SOFT_IO_AMBER_LED; // AmberLED on
319
 
320
}
321
 
322
/*------------------------------------------------------------------------*/
323
 
324
//
325
// Memory layout
326
//
327
 
328
externC cyg_uint8 *
329
hal_arm_mem_real_region_top( cyg_uint8 *regionend )
330
{
331
    CYG_ASSERT( hal_dram_size > 0, "Didn't detect DRAM size!" );
332
    CYG_ASSERT( hal_dram_size <=  256<<20,
333
                "More than 256MB reported - that can't be right" );
334
 
335
    // is it the "normal" end of the DRAM region? If so, it should be
336
    // replaced by the real size
337
    if ( regionend ==
338
         ((cyg_uint8 *)CYGMEM_REGION_ram + CYGMEM_REGION_ram_SIZE) ) {
339
        regionend = (cyg_uint8 *)CYGMEM_REGION_ram + hal_dram_size;
340
    }
341
    return regionend;
342
} // hal_arm_mem_real_region_top()
343
 
344
 
345
 
346
// -------------------------------------------------------------------------
347
static cyg_uint32 _period;
348
 
349
void hal_clock_initialize(cyg_uint32 period)
350
{
351
    _period = period;
352
 
353
    *SA110_TIMER3_CONTROL = 0;          // Disable while we are setting up
354
 
355
    *SA110_TIMER3_LOAD = period;        // Reload value
356
 
357
    *SA110_TIMER3_CLEAR = 0;            // Clear any pending interrupt
358
                                        // (Data: don't care)
359
 
360
    *SA110_TIMER3_CONTROL = 0x000000cc; // Enable, Periodic (auto-reload),
361
                   // External clock (3.68MHz on irq_in_l[2] for Timer 3)
362
 
363
    *SA110_TIMER3_CLEAR = 0;            // Clear any pending interrupt again
364
 
365
    // That's all.
366
}
367
 
368
// This routine is called during a clock interrupt.
369
 
370
void hal_clock_reset(cyg_uint32 vector, cyg_uint32 period)
371
{
372
    *SA110_TIMER3_CLEAR = period; // Clear any pending interrupt (Data: don't care)
373
}
374
 
375
// Read the current value of the clock, returning the number of hardware
376
// "ticks" that have occurred (i.e. how far away the current value is from
377
// the start)
378
 
379
void hal_clock_read(cyg_uint32 *pvalue)
380
{
381
    *pvalue = (cyg_uint32)(_period) - *SA110_TIMER3_VALUE;
382
}
383
 
384
//
385
// Delay for some number of micro-seconds
386
//
387
void hal_delay_us(cyg_int32 usecs)
388
{
389
    int diff, diff2;
390
    cyg_uint32 val1, val2;
391
 
392
    while (usecs-- > 0) {
393
        diff = 0;
394
        val1 = *SA110_TIMER3_VALUE;
395
        while (diff < 3) {
396
            while ((val2 = *SA110_TIMER3_VALUE) == val1) ;
397
            if (*SA110_TIMER3_LOAD) {
398
                // A kernel is running, the counter may get reset as we watch
399
                diff2 = val2 - val1;
400
                if (diff2 < 0) diff2 += *SA110_TIMER3_LOAD;
401
                diff += diff2;
402
            } else {
403
                diff += val2 - val1;
404
            }
405
        }
406
    }
407
}
408
 
409
// -------------------------------------------------------------------------
410
 
411
// This routine is called to respond to a hardware interrupt (IRQ).  It
412
// should interrogate the hardware and return the IRQ vector number.
413
int hal_IRQ_handler(void)
414
{
415
    int sources;
416
    int index;
417
 
418
#if 0 // test FIQ and print alert if active - really for debugging
419
    sources = *SA110_IRQCONT_FIQSTATUS;
420
    if ( 0 != sources )
421
        diag_printf( "FIQ source active!!! - fiqstatus %08x irqstatus %08x\n",
422
                     sources, *SA110_IRQCONT_IRQSTATUS );
423
    else
424
#endif // Scan FIQ sources also
425
 
426
    sources = *SA110_IRQCONT_IRQSTATUS;
427
 
428
// if we come to support FIQ properly...
429
//    if ( 0 == sources )
430
//        sources = *SA110_IRQCONT_FIQSTATUS;
431
 
432
    // Nothing wrong with scanning them in the order provided...
433
    // and it'll make the serial device steal fewer cycles.
434
    // So, knowing this is an ARM:
435
    if ( sources & 0xff )
436
        index = 0;
437
    else if ( sources & 0xff00 )
438
        index = 8;
439
    else if ( sources & 0xff0000 )
440
        index = 16;
441
    else // if ( sources & 0xff000000 )
442
        index = 24;
443
 
444
    do {
445
        if ( (1 << index) & sources )
446
            return index;
447
        index++;
448
    } while ( index & 7 );
449
 
450
    return CYGNUM_HAL_INTERRUPT_NONE; // This shouldn't happen!
451
}
452
 
453
//
454
// Interrupt control
455
//
456
 
457
void hal_interrupt_mask(int vector)
458
{
459
    *SA110_IRQCONT_IRQENABLECLEAR = 1 << vector;
460
}
461
 
462
void hal_interrupt_unmask(int vector)
463
{
464
    *SA110_IRQCONT_IRQENABLESET = 1 << vector;
465
}
466
 
467
void hal_interrupt_acknowledge(int vector)
468
{
469
    // Nothing to do here.
470
}
471
 
472
void hal_interrupt_configure(int vector, int level, int up)
473
{
474
    // No interrupts are configurable on this hardware
475
}
476
 
477
void hal_interrupt_set_level(int vector, int level)
478
{
479
    // No interrupts are configurable on this hardware
480
}
481
 
482
#include CYGHWR_MEMORY_LAYOUT_H
483
typedef void code_fun(void);
484
void ebsa285_program_new_stack(void *func)
485
{
486
    register CYG_ADDRESS stack_ptr asm("sp");
487
    register CYG_ADDRESS old_stack asm("r4");
488
    register code_fun *new_func asm("r0");
489
    old_stack = stack_ptr;
490
    stack_ptr = CYGMEM_REGION_ram + CYGMEM_REGION_ram_SIZE - sizeof(CYG_ADDRESS);
491
    new_func = (code_fun*)func;
492
    new_func();
493
    stack_ptr = old_stack;
494
    return;
495
}
496
 
497
/*------------------------------------------------------------------------*/
498
// EOF ebsa285_misc.c

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.