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

Subversion Repositories openrisc

[/] [openrisc/] [trunk/] [rtos/] [ecos-3.0/] [packages/] [hal/] [arm/] [ebsa285/] [current/] [src/] [ebsa285_misc.c] - Blame information for rev 786

Details | Compare with Previous | View Log

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

powered by: WebSVN 2.1.0

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