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

Subversion Repositories openrisc

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

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 786 skrzyp
//==========================================================================
2
//
3
//      innovator_misc.c
4
//
5
//      HAL misc board support code for ARM9/INNOVATOR
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):    Patrick Doyle <wpd@delcomsys.com>
43
// Contributors: Patrick Doyle <wpd@delcomsys.com>
44
// Date:         2002-12-17
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/innovator.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 = INNOVATOR_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
    //               Actual  Virtual  Size   Attributes                                                    Function
202
    //               Base     Base     MB      cached?           buffered?        access permissions
203
    //             xxx00000  xxx00000
204
    X_ARM_MMU_SECTION(0x000,  0x100,     4,  ARM_CACHEABLE,   ARM_UNBUFFERABLE, ARM_ACCESS_PERM_RW_RW); // FLASH CS0
205
    X_ARM_MMU_SECTION(0x100,  0x000,    32,  ARM_CACHEABLE,   ARM_BUFFERABLE,   ARM_ACCESS_PERM_RW_RW); // SDRAM
206
    X_ARM_MMU_SECTION(0x080,  0x080,     1,  ARM_UNCACHEABLE, ARM_UNBUFFERABLE, ARM_ACCESS_PERM_RW_RW); // FPGA
207
    X_ARM_MMU_SECTION(0x200,  0x200,     1,  ARM_CACHEABLE,   ARM_BUFFERABLE,   ARM_ACCESS_PERM_RW_RW); // Internal SRAM
208
    X_ARM_MMU_SECTION(0xE00,  0xE00,   512,  ARM_UNCACHEABLE, ARM_UNBUFFERABLE, ARM_ACCESS_PERM_RW_RW); // Internal Peripherals
209
}
210
 
211
//----------------------------------------------------------------------------
212
// Platform specific initialization
213
 
214
void
215
plf_hardware_init(void)
216
{
217
#ifdef LATER
218
    // Disable PLD interrupts
219
    HAL_WRITE_UINT32(INNOVATOR_INT_MASK_CLEAR,
220
                     INNOVATOR_INT_SOURCE_P0 | INNOVATOR_INT_SOURCE_P1 |
221
                     INNOVATOR_INT_SOURCE_P2 | INNOVATOR_INT_SOURCE_P3 |
222
                     INNOVATOR_INT_SOURCE_P4 | INNOVATOR_INT_SOURCE_P5);
223
    // Make PLD0 generate IRQ
224
    HAL_WRITE_UINT32(INNOVATOR_INT_PRIORITY_0, 0);
225
#endif
226
    cyg_uint8 tmp;
227
    // This should be protected by some sort of #ifdef to test to see if
228
    // the ethernet has been enabled or not.  I'll add that later.
229
    HAL_READ_UINT8(0x0800000B, tmp);
230
    HAL_WRITE_UINT8(0x0800000B, tmp & ~1);
231
    HAL_DELAY_US(750);
232
 
233
}
234
 
235
// -------------------------------------------------------------------------
236
void
237
hal_clock_initialize(cyg_uint32 period)
238
{
239
#ifdef LATER
240
    cyg_uint32 cr;
241
 
242
    HAL_WRITE_UINT32(INNOVATOR_TIMER0_CR, 0);
243
    HAL_WRITE_UINT32(INNOVATOR_TIMER0_PRE, CYGNUM_HAL_ARM_INNOVATOR_TIMER_PRESCALE - 1);
244
    HAL_WRITE_UINT32(INNOVATOR_TIMER0_LIMIT, period);
245
    cr = INNOVATOR_TIMER_CR_MODE_HEARBEAT | INNOVATOR_TIMER_CR_IE;
246
    HAL_WRITE_UINT32(INNOVATOR_TIMER0_CR, cr);
247
    HAL_WRITE_UINT32(INNOVATOR_TIMER0_CR, cr | INNOVATOR_TIMER_CR_S);
248
 
249
    // Unmask timer 0 interrupt
250
    HAL_INTERRUPT_CONFIGURE( CYGNUM_HAL_INTERRUPT_RTC, 1, 1 );
251
    HAL_INTERRUPT_UNMASK( CYGNUM_HAL_INTERRUPT_RTC );
252
#endif
253
}
254
 
255
// This routine is called during a clock interrupt.
256
void
257
hal_clock_reset(cyg_uint32 vector, cyg_uint32 period)
258
{
259
#ifdef LATER
260
    cyg_uint32 cr;
261
 
262
    // Clear pending interrupt bit
263
    HAL_READ_UINT32(INNOVATOR_TIMER0_CR, cr);
264
    cr |= INNOVATOR_TIMER_CR_CI;
265
    HAL_WRITE_UINT32(INNOVATOR_TIMER0_CR, cr);
266
#endif
267
}
268
 
269
// Read the current value of the clock, returning the number of hardware
270
// "ticks" that have occurred (i.e. how far away the current value is from
271
// the start)
272
 
273
void
274
hal_clock_read(cyg_uint32 *pvalue)
275
{
276
#ifdef LATER
277
    cyg_uint32 ctr;
278
 
279
    HAL_READ_UINT32(INNOVATOR_TIMER0_READ, ctr);
280
    *pvalue = ctr;
281
#endif
282
}
283
 
284
//
285
// Delay for some number of micro-seconds
286
//
287
void
288
hal_delay_us(cyg_int32 usecs)
289
{
290
#ifdef LATER
291
    // Use timer 2 
292
    cyg_uint32 cr;
293
    // Divide by 1000000 in two steps to preserve precision.
294
    cyg_uint32 wait_clocks = ((CYGNUM_HAL_ARM_INNOVATOR_PERIPHERAL_CLOCK/100000)*usecs)/10;
295
 
296
    HAL_WRITE_UINT32(INNOVATOR_TIMER1_CR, 0);
297
    HAL_WRITE_UINT32(INNOVATOR_TIMER1_PRE, 0);
298
    HAL_WRITE_UINT32(INNOVATOR_TIMER1_LIMIT, wait_clocks);
299
    cr = INNOVATOR_TIMER_CR_MODE_ONE_SHOT|INNOVATOR_TIMER_CR_CI;
300
    HAL_WRITE_UINT32(INNOVATOR_TIMER1_CR, cr);
301
    HAL_WRITE_UINT32(INNOVATOR_TIMER1_CR, cr | INNOVATOR_TIMER_CR_S);
302
 
303
    // wait for start bit to clear
304
    do {
305
        HAL_READ_UINT32(INNOVATOR_TIMER1_CR, cr);
306
    } while ((INNOVATOR_TIMER_CR_S & cr) != 0);
307
 
308
    //clear interrupt flag
309
    HAL_WRITE_UINT32(INNOVATOR_TIMER1_CR, 0);
310
#else
311
#if 0
312
    volatile unsigned long long x;
313
    volatile unsigned long long loop_count = usecs / 10 + 1;
314
 
315
    for (x = 0; x < loop_count; x++) ;
316
#else
317
    volatile cyg_uint32 *CNTL_TIMER = (volatile cyg_uint32 *)(0xFFFEC500 + 0x00);
318
    volatile cyg_uint32 *LOAD_TIM   = (volatile cyg_uint32 *)(0xFFFEC500 + 0x04);
319
    volatile cyg_uint32 *READ_TIM   = (volatile cyg_uint32 *)(0xFFFEC500 + 0x08);
320
    cyg_uint32 timer_val, prev_val;
321
    int too_long = 0;
322
 
323
    if (usecs <= 0) {
324
      return;
325
    } else if (usecs > 357913941) {
326
      /* Clamp at MAX_INT32 / 6 */
327
      usecs = 357913941;
328
    }
329
    /* Enable the clock and halt the timer */
330
    HAL_WRITE_UINT32(CNTL_TIMER, 0x00000020);
331
 
332
    /* Load the timer */
333
    HAL_WRITE_UINT32(LOAD_TIM, 6 * usecs);
334
 
335
    /* Start the timer */
336
    HAL_READ_UINT32(READ_TIM, prev_val);
337
    HAL_WRITE_UINT32(CNTL_TIMER, 0x00000021);
338
 
339
    /* Wait for it to load (but not too long) */
340
    do {
341
      HAL_READ_UINT32(READ_TIM, timer_val);
342
      if (++too_long >= 100) {
343
        break;
344
      }
345
    } while (timer_val == prev_val);
346
 
347
    /* Wait for it to count down to zero */
348
    do {
349
      HAL_READ_UINT32(READ_TIM, timer_val);
350
    } while (timer_val > 0);
351
#endif
352
#endif
353
}
354
 
355
// -------------------------------------------------------------------------
356
 
357
// This routine is called to respond to a hardware interrupt (IRQ).  It
358
// should interrogate the hardware and return the IRQ vector number.
359
int
360
hal_IRQ_handler(void)
361
{
362
#ifdef LATER
363
    int vec;
364
    cyg_uint32 isr;
365
 
366
    HAL_READ_UINT32(INNOVATOR_INT_REQUEST_STATUS, isr);
367
    for (vec = CYGNUM_HAL_INTERRUPT_PLD_0;
368
         vec <= CYGNUM_HAL_INTERRUPT_FAST_COMMS; vec++) {
369
        if (isr & (1<<vec)) {
370
            return vec;
371
        }
372
    }
373
#endif
374
    return CYGNUM_HAL_INTERRUPT_NONE;
375
}
376
 
377
//----------------------------------------------------------------------------
378
// Interrupt control
379
//
380
void
381
hal_interrupt_mask(int vector)
382
{
383
#ifdef LATER
384
    CYG_ASSERT(vector <= CYGNUM_HAL_ISR_MAX &&
385
               vector >= CYGNUM_HAL_ISR_MIN , "Invalid vector");
386
 
387
    HAL_WRITE_UINT32(INNOVATOR_INT_MASK_CLEAR, 1<<vector);
388
#endif
389
}
390
 
391
void
392
hal_interrupt_unmask(int vector)
393
{
394
#ifdef LATER
395
    CYG_ASSERT(vector <= CYGNUM_HAL_ISR_MAX &&
396
               vector >= CYGNUM_HAL_ISR_MIN , "Invalid vector");
397
 
398
    HAL_WRITE_UINT32(INNOVATOR_INT_MASK_SET, 1<<vector);
399
#endif
400
}
401
 
402
void
403
hal_interrupt_acknowledge(int vector)
404
{
405
#ifdef LATER
406
    CYG_ASSERT(vector <= CYGNUM_HAL_ISR_MAX &&
407
               vector >= CYGNUM_HAL_ISR_MIN , "Invalid vector");
408
#endif
409
 
410
}
411
 
412
void
413
hal_interrupt_configure(int vector, int level, int up)
414
{
415
#ifdef LATER
416
    CYG_ASSERT(vector <= CYGNUM_HAL_ISR_MAX &&
417
               vector >= CYGNUM_HAL_ISR_MIN, "Invalid vector");
418
    CYG_ASSERT(level || up, "Cannot do falling edge");
419
#endif
420
}
421
 
422
void
423
hal_interrupt_set_level(int vector, int level)
424
{
425
#ifdef LATER
426
    cyg_uint32 reg;
427
    CYG_ASSERT(vector <= CYGNUM_HAL_ISR_MAX &&
428
               vector >= CYGNUM_HAL_ISR_MIN, "Invalid vector");
429
    CYG_ASSERT(level <= 63 && level >= 0, "Invalid level");
430
 
431
    HAL_READ_UINT32(INNOVATOR_INT_PRIORITY_0+4*vector, reg);
432
    reg &= ~INNOVATOR_INT_PRIORITY_LVL_mask;
433
    reg |= (level & INNOVATOR_INT_PRIORITY_LVL_mask);
434
    HAL_WRITE_UINT32(INNOVATOR_INT_PRIORITY_0+4*vector, reg);
435
#endif
436
}
437
 
438
#include CYGHWR_MEMORY_LAYOUT_H
439
typedef void code_fun(void);
440
void innovator_program_new_stack(void *func)
441
{
442
    register CYG_ADDRESS stack_ptr asm("sp");
443
    register CYG_ADDRESS old_stack asm("r4");
444
    register code_fun *new_func asm("r0");
445
    old_stack = stack_ptr;
446
    stack_ptr = CYGMEM_REGION_ram + CYGMEM_REGION_ram_SIZE - sizeof(CYG_ADDRESS);
447
    new_func = (code_fun*)func;
448
    new_func();
449
    stack_ptr = old_stack;
450
    return;
451
}

powered by: WebSVN 2.1.0

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