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

Subversion Repositories openrisc

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

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 786 skrzyp
//==========================================================================
2
//
3
//      nano_misc.c
4
//
5
//      HAL misc board support code for StrongARM SA1110/nanoEngine
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: hmt
44
//               Travis C. Furrer <furrer@mit.edu>
45
// Date:         2001-02-12
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
 
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_arch.h>           // Register state info
63
#include <cyg/hal/hal_diag.h>
64
#include <cyg/hal/hal_intr.h>           // Interrupt names
65
#include <cyg/hal/hal_cache.h>
66
#include <cyg/hal/hal_sa11x0.h>         // Hardware definitions
67
#include <cyg/hal/nano.h>               // Platform specifics
68
 
69
#include <cyg/infra/diag.h>             // diag_printf
70
 
71
// All the MM table layout is here:
72
#include <cyg/hal/hal_mm.h>
73
 
74
#ifdef CYGPKG_IO_PCI
75
cyg_uint32 cyg_pci_window_real_base = 0;
76
#endif
77
 
78
#include <string.h> // memset
79
 
80
void
81
hal_mmu_init(void)
82
{
83
    unsigned long ttb_base = SA11X0_RAM_BANK0_BASE + 0x4000;
84
    unsigned long i;
85
 
86
#ifdef CYG_HAL_STARTUP_ROM
87
    // SDRAM Memory Sizing:
88
    //
89
    // The board can have 4 memory configurations:
90
    //
91
    //  * One 8Mb device on SDCS0 (with gaps <= A11 N/C in 8Mb devices)
92
    //  * Two 8Mb devices, SDCS0,SDCS1 (with gaps) making 16Mb
93
    //  * One 16Mb device on SDCS0
94
    //  * Two 16Mb devices on SDCS0,SDCS1 making 32Mb
95
    //
96
    // Gaps: the SDRAM setup and wiring are the same for both 8Mb and 16Mb
97
    // devices.  A11 of the SDRAM's addressing is not connected when 8Mb
98
    // devices are installed; the 8Mb device occupies 16Mb of space.  A11
99
    // on the SDRAM is the most significant bit below the two bank-select
100
    // bits, there are 4 banks each occupying 4Mb, so therefore in "real
101
    // money" it has the value 2Mb.
102
    //
103
    // SDCS0 maps to the 128Mb area 0xC00 Mb (0xC00000000)
104
    // SDCS1 maps to the 128Mb area 0xC80 Mb (0xC80000000)
105
    //
106
    // So therefore, if there are two 8Mb devices installed, we have memory
107
    // in these ranges:
108
    //
109
    //    0xC0000000...0xC01FFFFF
110
    //    0xC0400000...0xC05FFFFF
111
    //    0xC0800000...0xC09FFFFF
112
    //    0xC0C00000...0xC0DFFFFF
113
    //
114
    //    0xC8000000...0xC81FFFFF
115
    //    0xC8400000...0xC85FFFFF
116
    //    0xC8800000...0xC89FFFFF
117
    //    0xC8C00000...0xC8DFFFFF
118
    //
119
    // This function is currently executing on a stack in real memory
120
    // addresses, somewhere in that initial range 0xC0000000...0xC01FFFFF,
121
    // so we can probe other related addresses to discover how much memory
122
    // we really have, and then set up the Memory Map accordingly.
123
 
124
    typedef volatile cyg_uint32 *mptr; // for memory access
125
    typedef cyg_uint32 aptr;        // for arithmetic
126
    volatile int testmem[4] = {0};  // on my stack, ergo in base memory
127
 
128
    // Pointers to test memory, and into the possible gap:
129
    mptr basep =  &testmem[0];
130
    mptr basep2 = &testmem[1];
131
    mptr gapp =  (mptr)((2 * SZ_1M) | (aptr)basep);
132
 
133
    // And just look at any pair of words to discover whether there is
134
    // a 2nd device there.
135
    mptr dev2p = (mptr)((0xC80u * SZ_1M) | (aptr)basep);
136
    mptr dev2p2 = (mptr)(4 + (aptr)dev2p);
137
 
138
    // This is a pointer to where hal_dram_size is in physical memory,
139
    // since memory mapping is not yet set up:
140
    int *p_hdsize = (int *)((aptr)(&hal_dram_size) | (0xC00u *SZ_1M));
141
    int *p_hdtype = (int *)((aptr)(&hal_dram_type) | (0xC00u *SZ_1M));
142
 
143
    *p_hdsize = 0; // Initialize it to a bogus value here.
144
    *p_hdtype = 0x0108; // Initialize it to a bogus value here.
145
 
146
    // Equivalent of asserts for our assumptions, but too early to use
147
    // CYG_ASSERT( ..., "basep not in bank0 of device 0, lower half" );
148
    if ( 0xC0000000u >= (aptr)basep ) {
149
        *p_hdtype |= 1 << 16; // flag an error code
150
        goto breakout;
151
    }
152
    if ( 0xC0200000u < (aptr)basep ) {
153
        *p_hdtype |= 2 << 16;
154
        goto breakout;
155
    }
156
 
157
    // First confirm that the technique works for memory that's
158
    // definitely there!
159
    *basep  = 0x55667711;
160
    *basep2 = 0xCC33AA44;
161
    if ( 0x55667711 != *basep ||
162
         0xCC33AA44 != *basep2 ) {
163
        *p_hdtype |= 10 << 16;
164
        goto breakout;
165
    }
166
    // Now test writing to the gap...
167
    *gapp = 0xDD2288BB;
168
    if ( 0xCC33AA44 != *basep2 ) { // Should not be corrupted whatever
169
        *p_hdtype |= 20 << 16;
170
        goto breakout;
171
    }
172
    if ( 0xDD2288BB != *basep &&
173
         0x55667711 != *basep ) { // Should be one of those
174
        *p_hdtype |= 30 << 16;
175
        goto breakout;
176
    }
177
 
178
    if (0xDD2288BB == *basep)
179
        *p_hdtype = 8; // Lower byte is SDRAM size in Mb.
180
    else {
181
        // it could be 16Mb or 32Mb:
182
        basep2 = (mptr)((16 * SZ_1M) | (aptr)basep);
183
        *basep = 0xFF11AA00;
184
        *basep2 = 0x33557799;
185
        // (intersperse some other activity)
186
        testmem[2] += testmem[3];
187
        if ( 0xFF11AA00 != *basep &&
188
             0x33557799 != *basep ) { // Should be one of those
189
            *p_hdtype |= 40 << 16;
190
            goto breakout;
191
        }
192
        *p_hdtype = (0xFF11AA00 == *basep) ? 32 : 16;
193
    }
194
 
195
    // Now test whether dev2p stores data:
196
    *dev2p  = 0x11224488;
197
    *dev2p2 = 0x77BBDDEE;
198
    // (intersperse some other activity)
199
    testmem[2] += testmem[3];
200
 
201
    *p_hdtype |= ((( 0x11224488 == *dev2p ) && (0x77BBDDEE == *dev2p2 ))
202
                  ? 0x200 : 0x100); // Next byte is devcount.
203
 
204
 breakout:
205
    // NB: *p_hdtype is carefully crafted to make a system with an error
206
    // detected above default to a single 8Mb device in all the ensuing
207
    // setup.
208
 
209
    // So now we should know:
210
    *p_hdsize = (0xff & ((*p_hdtype) >> 8)) * (0xff & *p_hdtype) * SZ_1M;
211
 
212
    /*
213
     * Set the TTB register
214
     */
215
    asm volatile ("mcr  p15,0,%0,c2,c0,0" : : "r"(ttb_base) /*:*/);
216
 
217
    /*
218
     * Set the Domain Access Control Register
219
     */
220
    i = ARM_ACCESS_DACR_DEFAULT;
221
    asm volatile ("mcr  p15,0,%0,c3,c0,0" : : "r"(i) /*:*/);
222
 
223
    /*
224
     * First clear all TT entries - ie Set them to Faulting
225
     */
226
    memset((void *)ttb_base, 0, ARM_FIRST_LEVEL_PAGE_TABLE_SIZE);
227
 
228
    /*               Actual  Virtual  Size   Attributes                                                    Function  */
229
    /*               Base     Base     MB      cached?           buffered?        access permissions                 */
230
    /*             xxx00000  xxx00000                                                                                */
231
    X_ARM_MMU_SECTION(0x000,  0x500,    32,  ARM_CACHEABLE,   ARM_BUFFERABLE,   ARM_ACCESS_PERM_RW_RW); /* Boot flash ROMspace */
232
 
233
#endif // CYG_HAL_STARTUP_ROM - ROM start only
234
// We can do the mapping of the other stuff (NOT RAM) in RAM startup OK.
235
 
236
    X_ARM_MMU_SECTION(0x180,  0x180,    16,  ARM_UNCACHEABLE, ARM_UNBUFFERABLE, ARM_ACCESS_PERM_RW_RW); /* Ethernet Adaptor */
237
    X_ARM_MMU_SECTION(0x400,  0x400,   128,  ARM_UNCACHEABLE, ARM_UNBUFFERABLE, ARM_ACCESS_PERM_RW_RW); /* External IO Mux */
238
    X_ARM_MMU_SECTION(0x480,  0x480,   128,  ARM_UNCACHEABLE, ARM_UNBUFFERABLE, ARM_ACCESS_PERM_RW_RW); /* External IO NonMux */
239
 
240
#ifdef CYG_HAL_STARTUP_ROM // ROM start only
241
 
242
    X_ARM_MMU_SECTION(0x800,  0x800, 0x400,  ARM_UNCACHEABLE, ARM_UNBUFFERABLE, ARM_ACCESS_PERM_RW_RW); /* StrongARM(R) Registers */
243
 
244
//    X_ARM_MMU_SECTION(0xC00,      0,    32,  ARM_CACHEABLE,   ARM_BUFFERABLE,   ARM_ACCESS_PERM_RW_RW); /* DRAM Bank 0,... */
245
//    X_ARM_MMU_SECTION(0xC00,  0xC00,    32,  ARM_UNCACHEABLE, ARM_BUFFERABLE,   ARM_ACCESS_PERM_RW_RW); /* DRAM Bank 0,... */
246
 
247
    if ( (*p_hdtype & 32) ) { // Then they are 32Mb devices - KISS:
248
        X_ARM_MMU_SECTION(0xC00,      0,    32,  ARM_CACHEABLE,   ARM_BUFFERABLE,   ARM_ACCESS_PERM_RW_RW); /* DRAM Bank 0 */
249
        X_ARM_MMU_SECTION(0xC00,  0xC00,    32,  ARM_UNCACHEABLE, ARM_BUFFERABLE,   ARM_ACCESS_PERM_RW_RW); /* DRAM Bank 0 */
250
        if ( 0x200 & *p_hdtype ) { // Got the 2nd device?
251
            X_ARM_MMU_SECTION(0xC80,     32,    32,  ARM_CACHEABLE,   ARM_BUFFERABLE,   ARM_ACCESS_PERM_RW_RW); /* DRAM Bank 1 */
252
            X_ARM_MMU_SECTION(0xC80,  0xC80,    32,  ARM_UNCACHEABLE, ARM_BUFFERABLE,   ARM_ACCESS_PERM_RW_RW); /* DRAM Bank 1 */
253
        }
254
    }
255
    else if ( (*p_hdtype & 16) ) { // Then they are 16Mb devices - KISS:
256
        X_ARM_MMU_SECTION(0xC00,      0,    16,  ARM_CACHEABLE,   ARM_BUFFERABLE,   ARM_ACCESS_PERM_RW_RW); /* DRAM Bank 0 */
257
        X_ARM_MMU_SECTION(0xC00,  0xC00,    16,  ARM_UNCACHEABLE, ARM_BUFFERABLE,   ARM_ACCESS_PERM_RW_RW); /* DRAM Bank 0 */
258
        if ( 0x200 & *p_hdtype ) { // Got the 2nd device?
259
            X_ARM_MMU_SECTION(0xC80,     16,    16,  ARM_CACHEABLE,   ARM_BUFFERABLE,   ARM_ACCESS_PERM_RW_RW); /* DRAM Bank 1 */
260
            X_ARM_MMU_SECTION(0xC80,  0xC80,    16,  ARM_UNCACHEABLE, ARM_BUFFERABLE,   ARM_ACCESS_PERM_RW_RW); /* DRAM Bank 1 */
261
        }
262
    }
263
    else { // Then they are 8Mb devices, complicated:
264
        X_ARM_MMU_SECTION(0xC00,      0,     2,  ARM_CACHEABLE,   ARM_BUFFERABLE,   ARM_ACCESS_PERM_RW_RW); /* DRAM Bank 0 */
265
        X_ARM_MMU_SECTION(0xC04,      2,     2,  ARM_CACHEABLE,   ARM_BUFFERABLE,   ARM_ACCESS_PERM_RW_RW); /* DRAM Bank 0 */
266
        X_ARM_MMU_SECTION(0xC08,      4,     2,  ARM_CACHEABLE,   ARM_BUFFERABLE,   ARM_ACCESS_PERM_RW_RW); /* DRAM Bank 0 */
267
        X_ARM_MMU_SECTION(0xC0C,      6,     2,  ARM_CACHEABLE,   ARM_BUFFERABLE,   ARM_ACCESS_PERM_RW_RW); /* DRAM Bank 0 */
268
        // Next slot is 16Mb of space, with 2Mb gaps per 4Mb.
269
        X_ARM_MMU_SECTION(0xC00,  0xC00,    16,  ARM_UNCACHEABLE, ARM_BUFFERABLE,   ARM_ACCESS_PERM_RW_RW); /* DRAM Bank 0 */
270
        if ( 0x200 & *p_hdtype ) { // Got the 2nd device?
271
            X_ARM_MMU_SECTION(0xC80,      8,     2,  ARM_CACHEABLE,   ARM_BUFFERABLE,   ARM_ACCESS_PERM_RW_RW); /* DRAM Bank 1 */
272
            X_ARM_MMU_SECTION(0xC84,     10,     2,  ARM_CACHEABLE,   ARM_BUFFERABLE,   ARM_ACCESS_PERM_RW_RW); /* DRAM Bank 1 */
273
            X_ARM_MMU_SECTION(0xC88,     12,     2,  ARM_CACHEABLE,   ARM_BUFFERABLE,   ARM_ACCESS_PERM_RW_RW); /* DRAM Bank 1 */
274
            X_ARM_MMU_SECTION(0xC8C,     14,     2,  ARM_CACHEABLE,   ARM_BUFFERABLE,   ARM_ACCESS_PERM_RW_RW); /* DRAM Bank 1 */
275
            // Next slot is also 16Mb of space, with 2Mb gaps per 4Mb.
276
            X_ARM_MMU_SECTION(0xC80,  0xC80,    16,  ARM_UNCACHEABLE, ARM_BUFFERABLE,   ARM_ACCESS_PERM_RW_RW); /* DRAM Bank 1 */
277
        }
278
    }
279
#endif // CYG_HAL_STARTUP_ROM - ROM start only
280
 
281
#ifdef CYGPKG_IO_PCI
282
    /*
283
     * Actual Base = CYGHWR_HAL_ARM_EBSA285_PCI_MEM_MAP_BASE
284
     * Virtual Base = CYGHWR_HAL_ARM_EBSA285_PCI_MEM_MAP_BASE
285
     * Size = CYGHWR_HAL_ARM_EBSA285_PCI_MEM_MAP_SIZE
286
     * Memory accessible from PCI space. Overrides part of the above mapping.
287
     */
288
    for (i = CYGHWR_HAL_ARM_NANO_PCI_MEM_MAP_BASE >> 20;
289
         i < ((CYGHWR_HAL_ARM_NANO_PCI_MEM_MAP_BASE+CYGHWR_HAL_ARM_NANO_PCI_MEM_MAP_SIZE) >> 20);
290
         i++) {
291
#ifndef CYG_HAL_STARTUP_ROM
292
        // RAM start - common code below must go via uncached pointer
293
        int *p_hdsize = (int *)(((cyg_uint32)&hal_dram_size) | (0xC00u *SZ_1M));
294
#endif // not CYG_HAL_STARTUP_ROM - RAM start only
295
        // Find the actual real address as above if already mapped:
296
        cyg_uint32 phys = hal_virt_to_phys_address( ((cyg_uint32)i) << 20 );
297
        int j = phys >> 20;
298
        if ( ! ( 0xc00 < j && j < 0xe00 ) ) {
299
            // Not in physical SDRAM so yet mapped - so steal some from the main area.
300
            int k = (*p_hdsize) >> 20; // Top MegaByte
301
            k--;
302
            phys = hal_virt_to_phys_address( ((cyg_uint32)k) << 20 );
303
            j = phys >> 20;
304
            CYG_ASSERT( 0xc00 < j && j < 0xe00, "Top Mb physical address not in SDRAM" );
305
            (*p_hdsize) = (k << 20); // We just stole 1Mb.
306
            *(ARM_MMU_FIRST_LEVEL_DESCRIPTOR_ADDRESS(ttb_base, k)) = 0; // smash the old entry
307
        }
308
        CYG_ASSERT( 0xc00 < j && j < 0xe00, "PCI physical address not in SDRAM" );
309
        ARM_MMU_SECTION(ttb_base, j, i,
310
                        ARM_UNCACHEABLE, ARM_UNBUFFERABLE,
311
                        ARM_ACCESS_PERM_RW_RW);
312
    }
313
#endif
314
 
315
#ifdef CYG_HAL_STARTUP_ROM
316
    X_ARM_MMU_SECTION(0xE00,  0xE00,   128,  ARM_CACHEABLE,   ARM_BUFFERABLE,   ARM_ACCESS_PERM_RW_RW); /* Zeros (Cache Clean) Bank */
317
#endif // CYG_HAL_STARTUP_ROM - ROM start only
318
 
319
    // All done, phew!
320
}
321
 
322
//
323
// Platform specific initialization
324
//
325
 
326
void
327
plf_hardware_init(void)
328
{
329
// RAM startup only - rewrite relevent bits depending on config
330
#ifndef CYG_HAL_STARTUP_ROM
331
    HAL_DCACHE_SYNC();            // Force data out
332
    hal_mmu_init();               // This works on real addresses only
333
    HAL_DCACHE_INVALIDATE_ALL();  // Flush TLBs: make new mmu state effective
334
#endif // ! CYG_HAL_STARTUP_ROM - RAM start only
335
#ifdef CYGPKG_IO_PCI
336
    cyg_pci_window_real_base =
337
        hal_virt_to_phys_address( CYGHWR_HAL_ARM_NANO_PCI_MEM_MAP_BASE );
338
#endif
339
}
340
 
341
#include CYGHWR_MEMORY_LAYOUT_H
342
typedef void code_fun(void);
343
void nano_program_new_stack(void *func)
344
{
345
    register CYG_ADDRESS stack_ptr asm("sp");
346
    register CYG_ADDRESS old_stack asm("r4");
347
    register code_fun *new_func asm("r0");
348
    old_stack = stack_ptr;
349
    stack_ptr = CYGMEM_REGION_ram + CYGMEM_REGION_ram_SIZE - sizeof(CYG_ADDRESS);
350
    new_func = (code_fun*)func;
351
    new_func();
352
    stack_ptr = old_stack;
353
    return;
354
}
355
 
356
//
357
// Memory layout
358
//
359
 
360
externC cyg_uint8 *
361
hal_arm_mem_real_region_top( cyg_uint8 *regionend )
362
{
363
    CYG_ASSERT( hal_dram_size > 0, "Didn't detect DRAM size!" );
364
    CYG_ASSERT( hal_dram_size <=  256<<20,
365
                "More than 256MB reported - that can't be right" );
366
    CYG_ASSERT( 0 == (hal_dram_size & 0xfffff),
367
                "hal_dram_size not whole Mb" );
368
    // is it the "normal" end of the DRAM region? If so, it should be
369
    // replaced by the real size
370
    if ( regionend ==
371
         ((cyg_uint8 *)CYGMEM_REGION_ram + CYGMEM_REGION_ram_SIZE) ) {
372
        regionend = (cyg_uint8 *)CYGMEM_REGION_ram + hal_dram_size;
373
    }
374
    // Also, we must check for the top of the heap having moved.  This is
375
    // because the heap does not abut the top of memory.
376
#ifdef CYGMEM_SECTION_heap1
377
    else
378
    if ( regionend ==
379
         ((cyg_uint8 *)CYGMEM_SECTION_heap1 + CYGMEM_SECTION_heap1_SIZE) ) {
380
        // hal_dram_size excludes the PCI window on this platform.
381
        if ( regionend > (cyg_uint8 *)CYGMEM_REGION_ram + hal_dram_size )
382
            // Only report if the heap shrank; if it abuts RAMtop, the
383
            // previous test will have caught it already.  If RAM enlarged,
384
            // but the heap did not abut RAMtop then there is likely
385
            // something in the way, so don't trample it.
386
            regionend = (cyg_uint8 *)CYGMEM_REGION_ram + hal_dram_size;
387
    }
388
#endif
389
    return regionend;
390
}
391
 
392
 
393
// ------------------------------------------------------------------------
394
// EOF nano_misc.c

powered by: WebSVN 2.1.0

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