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

Subversion Repositories openrisc

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

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 786 skrzyp
//==========================================================================
2
//
3
//      excalibur_misc.c
4
//
5
//      HAL misc board support code for ARM9/EXCALIBUR
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, jskov
44
// Date:         2001-08-06
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
 
56
#include <cyg/infra/cyg_type.h>         // base types
57
#include <cyg/infra/cyg_trac.h>         // tracing macros
58
#include <cyg/infra/cyg_ass.h>          // assertion macros
59
 
60
#include <cyg/hal/hal_io.h>             // IO macros
61
#include <cyg/hal/hal_arch.h>           // Register state info
62
#include <cyg/hal/hal_diag.h>
63
#include <cyg/hal/hal_intr.h>           // Interrupt names
64
#include <cyg/hal/hal_cache.h>
65
#include <cyg/hal/excalibur.h>          // Platform specifics
66
 
67
#include <cyg/infra/diag.h>             // diag_printf
68
 
69
#include <string.h> // memset
70
 
71
// -------------------------------------------------------------------------
72
// MMU initialization:
73
// 
74
// These structures are laid down in memory to define the translation
75
// table.
76
// 
77
 
78
// ARM Translation Table Base Bit Masks
79
#define ARM_TRANSLATION_TABLE_MASK               0xFFFFC000
80
 
81
// ARM Domain Access Control Bit Masks
82
#define ARM_ACCESS_TYPE_NO_ACCESS(domain_num)    (0x0 << (domain_num)*2)
83
#define ARM_ACCESS_TYPE_CLIENT(domain_num)       (0x1 << (domain_num)*2)
84
#define ARM_ACCESS_TYPE_MANAGER(domain_num)      (0x3 << (domain_num)*2)
85
 
86
struct ARM_MMU_FIRST_LEVEL_FAULT {
87
    int id : 2;
88
    int sbz : 30;
89
};
90
#define ARM_MMU_FIRST_LEVEL_FAULT_ID 0x0
91
 
92
struct ARM_MMU_FIRST_LEVEL_PAGE_TABLE {
93
    int id : 2;
94
    int imp : 2;
95
    int domain : 4;
96
    int sbz : 1;
97
    int base_address : 23;
98
};
99
#define ARM_MMU_FIRST_LEVEL_PAGE_TABLE_ID 0x1
100
 
101
struct ARM_MMU_FIRST_LEVEL_SECTION {
102
    int id : 2;
103
    int b : 1;
104
    int c : 1;
105
    int imp : 1;
106
    int domain : 4;
107
    int sbz0 : 1;
108
    int ap : 2;
109
    int sbz1 : 8;
110
    int base_address : 12;
111
};
112
#define ARM_MMU_FIRST_LEVEL_SECTION_ID 0x2
113
 
114
struct ARM_MMU_FIRST_LEVEL_RESERVED {
115
    int id : 2;
116
    int sbz : 30;
117
};
118
#define ARM_MMU_FIRST_LEVEL_RESERVED_ID 0x3
119
 
120
#define ARM_MMU_FIRST_LEVEL_DESCRIPTOR_ADDRESS(ttb_base, table_index) \
121
   (unsigned long *)((unsigned long)(ttb_base) + ((table_index) << 2))
122
 
123
#define ARM_FIRST_LEVEL_PAGE_TABLE_SIZE 0x4000
124
 
125
#define ARM_MMU_SECTION(ttb_base, actual_base, virtual_base,              \
126
                        cacheable, bufferable, perm)                      \
127
    CYG_MACRO_START                                                       \
128
        register union ARM_MMU_FIRST_LEVEL_DESCRIPTOR desc;               \
129
                                                                          \
130
        desc.word = 0;                                                    \
131
        desc.section.id = ARM_MMU_FIRST_LEVEL_SECTION_ID;                 \
132
        desc.section.imp = 1;                                             \
133
        desc.section.domain = 0;                                          \
134
        desc.section.c = (cacheable);                                     \
135
        desc.section.b = (bufferable);                                    \
136
        desc.section.ap = (perm);                                         \
137
        desc.section.base_address = (actual_base);                        \
138
        *ARM_MMU_FIRST_LEVEL_DESCRIPTOR_ADDRESS(ttb_base, (virtual_base)) \
139
                            = desc.word;                                  \
140
    CYG_MACRO_END
141
 
142
#define X_ARM_MMU_SECTION(abase,vbase,size,cache,buff,access)      \
143
    { int i; int j = abase; int k = vbase;                         \
144
      for (i = size; i > 0 ; i--,j++,k++)                          \
145
      {                                                            \
146
        ARM_MMU_SECTION(ttb_base, j, k, cache, buff, access);      \
147
      }                                                            \
148
    }
149
 
150
union ARM_MMU_FIRST_LEVEL_DESCRIPTOR {
151
    unsigned long word;
152
    struct ARM_MMU_FIRST_LEVEL_FAULT fault;
153
    struct ARM_MMU_FIRST_LEVEL_PAGE_TABLE page_table;
154
    struct ARM_MMU_FIRST_LEVEL_SECTION section;
155
    struct ARM_MMU_FIRST_LEVEL_RESERVED reserved;
156
};
157
 
158
#define ARM_UNCACHEABLE                         0
159
#define ARM_CACHEABLE                           1
160
#define ARM_UNBUFFERABLE                        0
161
#define ARM_BUFFERABLE                          1
162
 
163
#define ARM_ACCESS_PERM_NONE_NONE               0
164
#define ARM_ACCESS_PERM_RO_NONE                 0
165
#define ARM_ACCESS_PERM_RO_RO                   0
166
#define ARM_ACCESS_PERM_RW_NONE                 1
167
#define ARM_ACCESS_PERM_RW_RO                   2
168
#define ARM_ACCESS_PERM_RW_RW                   3
169
 
170
void
171
hal_mmu_init(void)
172
{
173
    unsigned long ttb_base = EXCALIBUR_SDRAM_PHYS_BASE + 0x4000;
174
    unsigned long i;
175
 
176
    // Set the TTB register
177
    asm volatile ("mcr  p15,0,%0,c2,c0,0" : : "r"(ttb_base) /*:*/);
178
 
179
    // Set the Domain Access Control Register
180
    i = ARM_ACCESS_TYPE_MANAGER(0)    |
181
        ARM_ACCESS_TYPE_NO_ACCESS(1)  |
182
        ARM_ACCESS_TYPE_NO_ACCESS(2)  |
183
        ARM_ACCESS_TYPE_NO_ACCESS(3)  |
184
        ARM_ACCESS_TYPE_NO_ACCESS(4)  |
185
        ARM_ACCESS_TYPE_NO_ACCESS(5)  |
186
        ARM_ACCESS_TYPE_NO_ACCESS(6)  |
187
        ARM_ACCESS_TYPE_NO_ACCESS(7)  |
188
        ARM_ACCESS_TYPE_NO_ACCESS(8)  |
189
        ARM_ACCESS_TYPE_NO_ACCESS(9)  |
190
        ARM_ACCESS_TYPE_NO_ACCESS(10) |
191
        ARM_ACCESS_TYPE_NO_ACCESS(11) |
192
        ARM_ACCESS_TYPE_NO_ACCESS(12) |
193
        ARM_ACCESS_TYPE_NO_ACCESS(13) |
194
        ARM_ACCESS_TYPE_NO_ACCESS(14) |
195
        ARM_ACCESS_TYPE_NO_ACCESS(15);
196
    asm volatile ("mcr  p15,0,%0,c3,c0,0" : : "r"(i) /*:*/);
197
 
198
    // First clear all TT entries - ie Set them to Faulting
199
    memset((void *)ttb_base, 0, ARM_FIRST_LEVEL_PAGE_TABLE_SIZE);
200
 
201
    // Memory layout. This is set up in hal_platform_setup.h with
202
    // definitions from excalibur.h
203
    //
204
    //   SDRAM0_BASE_ADDRESS:    0x00000000, 64M
205
    //   SDRAM1_BASE_ADDRESS:    0x04000000, 64M
206
    //   SPSRAM0_BASE_ADDRESS:   0x08000000, 128k
207
    //   SPSRAM1_BASE_ADDRESS:   0x08020000, 128k
208
    //   DPSRAM0_BASE_ADDRESS:   0x08040000, 64k
209
    //   DPSRAM1_BASE_ADDRESS:   0x08050000, 64k
210
    //   PLD1_BASE_ADDRESS:      0x0f000000, 16k
211
    //   EBI0_BASE_ADDRESS:      0x40000000, 16M
212
    //   REGISTERS_BASE_ADDRESS: 0x7fffc000, 16k
213
    //   PLD0_BASE_ADDRESS:      0x80000000, 128k
214
 
215
    //               Actual  Virtual  Size   Attributes                                                    Function
216
    //               Base     Base     MB      cached?           buffered?        access permissions
217
    //             xxx00000  xxx00000
218
    X_ARM_MMU_SECTION(0x000,  0x000,   128,  ARM_CACHEABLE,   ARM_BUFFERABLE,   ARM_ACCESS_PERM_RW_RW); // SDRAM (& LCD registers?)
219
    X_ARM_MMU_SECTION(0x080,  0x080,     1,  ARM_CACHEABLE,   ARM_BUFFERABLE,   ARM_ACCESS_PERM_RW_RW); // SRAM regions
220
    X_ARM_MMU_SECTION(0x0f0,  0x0f0,     1,  ARM_UNCACHEABLE, ARM_UNBUFFERABLE, ARM_ACCESS_PERM_RW_RW); // PLD1
221
    X_ARM_MMU_SECTION(0x400,  0x400,    16,  ARM_UNCACHEABLE, ARM_BUFFERABLE,   ARM_ACCESS_PERM_RW_RW); // Boot flash ROMspace CS0
222
    X_ARM_MMU_SECTION(0x800,  0x800,     1,  ARM_UNCACHEABLE, ARM_UNBUFFERABLE, ARM_ACCESS_PERM_RW_RW); // PLD0/2/3
223
    X_ARM_MMU_SECTION(0x7ff,  0x7ff,     1,  ARM_UNCACHEABLE, ARM_UNBUFFERABLE, ARM_ACCESS_PERM_RW_RW); // EXCALIBUR registers
224
}
225
 
226
//----------------------------------------------------------------------------
227
// Platform specific initialization
228
 
229
void
230
plf_hardware_init(void)
231
{
232
    // Disable PLD interrupts
233
    HAL_WRITE_UINT32(EXCALIBUR_INT_MASK_CLEAR,
234
                     EXCALIBUR_INT_SOURCE_P0 | EXCALIBUR_INT_SOURCE_P1 |
235
                     EXCALIBUR_INT_SOURCE_P2 | EXCALIBUR_INT_SOURCE_P3 |
236
                     EXCALIBUR_INT_SOURCE_P4 | EXCALIBUR_INT_SOURCE_P5);
237
    // Make PLD0 generate IRQ
238
    HAL_WRITE_UINT32(EXCALIBUR_INT_PRIORITY_0, 0);
239
}
240
 
241
// -------------------------------------------------------------------------
242
void
243
hal_clock_initialize(cyg_uint32 period)
244
{
245
    cyg_uint32 cr;
246
 
247
    HAL_WRITE_UINT32(EXCALIBUR_TIMER0_CR, 0);
248
    HAL_WRITE_UINT32(EXCALIBUR_TIMER0_PRE, CYGNUM_HAL_ARM_EXCALIBUR_TIMER_PRESCALE - 1);
249
    HAL_WRITE_UINT32(EXCALIBUR_TIMER0_LIMIT, period);
250
    cr = EXCALIBUR_TIMER_CR_MODE_HEARBEAT | EXCALIBUR_TIMER_CR_IE;
251
    HAL_WRITE_UINT32(EXCALIBUR_TIMER0_CR, cr);
252
    HAL_WRITE_UINT32(EXCALIBUR_TIMER0_CR, cr | EXCALIBUR_TIMER_CR_S);
253
 
254
    // Unmask timer 0 interrupt
255
    HAL_INTERRUPT_CONFIGURE( CYGNUM_HAL_INTERRUPT_RTC, 1, 1 );
256
    HAL_INTERRUPT_UNMASK( CYGNUM_HAL_INTERRUPT_RTC );
257
}
258
 
259
// This routine is called during a clock interrupt.
260
void
261
hal_clock_reset(cyg_uint32 vector, cyg_uint32 period)
262
{
263
    cyg_uint32 cr;
264
 
265
    // Clear pending interrupt bit
266
    HAL_READ_UINT32(EXCALIBUR_TIMER0_CR, cr);
267
    cr |= EXCALIBUR_TIMER_CR_CI;
268
    HAL_WRITE_UINT32(EXCALIBUR_TIMER0_CR, cr);
269
}
270
 
271
// Read the current value of the clock, returning the number of hardware
272
// "ticks" that have occurred (i.e. how far away the current value is from
273
// the start)
274
 
275
void
276
hal_clock_read(cyg_uint32 *pvalue)
277
{
278
    cyg_uint32 ctr;
279
 
280
    HAL_READ_UINT32(EXCALIBUR_TIMER0_READ, ctr);
281
    *pvalue = ctr;
282
}
283
 
284
//
285
// Delay for some number of micro-seconds
286
//
287
void
288
hal_delay_us(cyg_int32 usecs)
289
{
290
    // Use timer 2 
291
    cyg_uint32 cr;
292
    // Divide by 1000000 in two steps to preserve precision.
293
    cyg_uint32 wait_clocks = ((CYGNUM_HAL_ARM_EXCALIBUR_PERIPHERAL_CLOCK/100000)*usecs)/10;
294
 
295
    HAL_WRITE_UINT32(EXCALIBUR_TIMER1_CR, 0);
296
    HAL_WRITE_UINT32(EXCALIBUR_TIMER1_PRE, 0);
297
    HAL_WRITE_UINT32(EXCALIBUR_TIMER1_LIMIT, wait_clocks);
298
    cr = EXCALIBUR_TIMER_CR_MODE_ONE_SHOT|EXCALIBUR_TIMER_CR_CI;
299
    HAL_WRITE_UINT32(EXCALIBUR_TIMER1_CR, cr);
300
    HAL_WRITE_UINT32(EXCALIBUR_TIMER1_CR, cr | EXCALIBUR_TIMER_CR_S);
301
 
302
    // wait for start bit to clear
303
    do {
304
        HAL_READ_UINT32(EXCALIBUR_TIMER1_CR, cr);
305
    } while ((EXCALIBUR_TIMER_CR_S & cr) != 0);
306
 
307
    //clear interrupt flag
308
    HAL_WRITE_UINT32(EXCALIBUR_TIMER1_CR, 0);
309
}
310
 
311
// -------------------------------------------------------------------------
312
 
313
// This routine is called to respond to a hardware interrupt (IRQ).  It
314
// should interrogate the hardware and return the IRQ vector number.
315
int
316
hal_IRQ_handler(void)
317
{
318
    int vec;
319
    cyg_uint32 isr;
320
 
321
    HAL_READ_UINT32(EXCALIBUR_INT_REQUEST_STATUS, isr);
322
    for (vec = CYGNUM_HAL_INTERRUPT_PLD_0;
323
         vec <= CYGNUM_HAL_INTERRUPT_FAST_COMMS; vec++) {
324
        if (isr & (1<<vec)) {
325
            return vec;
326
        }
327
    }
328
 
329
    return CYGNUM_HAL_INTERRUPT_NONE;
330
}
331
 
332
//----------------------------------------------------------------------------
333
// Interrupt control
334
//
335
void
336
hal_interrupt_mask(int vector)
337
{
338
    CYG_ASSERT(vector <= CYGNUM_HAL_ISR_MAX &&
339
               vector >= CYGNUM_HAL_ISR_MIN , "Invalid vector");
340
 
341
    HAL_WRITE_UINT32(EXCALIBUR_INT_MASK_CLEAR, 1<<vector);
342
}
343
 
344
void
345
hal_interrupt_unmask(int vector)
346
{
347
    CYG_ASSERT(vector <= CYGNUM_HAL_ISR_MAX &&
348
               vector >= CYGNUM_HAL_ISR_MIN , "Invalid vector");
349
 
350
    HAL_WRITE_UINT32(EXCALIBUR_INT_MASK_SET, 1<<vector);
351
}
352
 
353
void
354
hal_interrupt_acknowledge(int vector)
355
{
356
    CYG_ASSERT(vector <= CYGNUM_HAL_ISR_MAX &&
357
               vector >= CYGNUM_HAL_ISR_MIN , "Invalid vector");
358
 
359
}
360
 
361
void
362
hal_interrupt_configure(int vector, int level, int up)
363
{
364
    CYG_ASSERT(vector <= CYGNUM_HAL_ISR_MAX &&
365
               vector >= CYGNUM_HAL_ISR_MIN, "Invalid vector");
366
    CYG_ASSERT(level || up, "Cannot do falling edge");
367
 
368
}
369
 
370
void
371
hal_interrupt_set_level(int vector, int level)
372
{
373
    cyg_uint32 reg;
374
    CYG_ASSERT(vector <= CYGNUM_HAL_ISR_MAX &&
375
               vector >= CYGNUM_HAL_ISR_MIN, "Invalid vector");
376
    CYG_ASSERT(level <= 63 && level >= 0, "Invalid level");
377
 
378
    HAL_READ_UINT32(EXCALIBUR_INT_PRIORITY_0+4*vector, reg);
379
    reg &= ~EXCALIBUR_INT_PRIORITY_LVL_mask;
380
    reg |= (level & EXCALIBUR_INT_PRIORITY_LVL_mask);
381
    HAL_WRITE_UINT32(EXCALIBUR_INT_PRIORITY_0+4*vector, reg);
382
}
383
 
384
#include CYGHWR_MEMORY_LAYOUT_H
385
typedef void code_fun(void);
386
void excalibur_program_new_stack(void *func)
387
{
388
    register CYG_ADDRESS stack_ptr asm("sp");
389
    register CYG_ADDRESS old_stack asm("r4");
390
    register code_fun *new_func asm("r0");
391
    old_stack = stack_ptr;
392
    stack_ptr = CYGMEM_REGION_ram + CYGMEM_REGION_ram_SIZE - sizeof(CYG_ADDRESS);
393
    new_func = (code_fun*)func;
394
    new_func();
395
    stack_ptr = old_stack;
396
    return;
397
}

powered by: WebSVN 2.1.0

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