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

Subversion Repositories openrisc

[/] [openrisc/] [trunk/] [rtos/] [ecos-2.0/] [packages/] [hal/] [arm/] [sa11x0/] [nano/] [v2_0/] [src/] [nano_misc.c] - Blame information for rev 616

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

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

powered by: WebSVN 2.1.0

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