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

Subversion Repositories openrisc

[/] [openrisc/] [trunk/] [rtos/] [ecos-2.0/] [packages/] [hal/] [arm/] [arm9/] [innovator/] [v2_0/] [src/] [innovator_misc.c] - Blame information for rev 27

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

Line No. Rev Author Line
1 27 unneback
//==========================================================================
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 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):    Patrick Doyle <wpd@delcomsys.com>
44
// Contributors: Patrick Doyle <wpd@delcomsys.com>
45
// Date:         2002-12-17
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/innovator.h>          // Platform specifics
67
 
68
#include <cyg/infra/diag.h>             // diag_printf
69
 
70
#include <string.h>                     // memset
71
 
72
// -------------------------------------------------------------------------
73
// MMU initialization:
74
// 
75
// These structures are laid down in memory to define the translation
76
// table.
77
// 
78
 
79
// ARM Translation Table Base Bit Masks
80
#define ARM_TRANSLATION_TABLE_MASK               0xFFFFC000
81
 
82
// ARM Domain Access Control Bit Masks
83
#define ARM_ACCESS_TYPE_NO_ACCESS(domain_num)    (0x0 << (domain_num)*2)
84
#define ARM_ACCESS_TYPE_CLIENT(domain_num)       (0x1 << (domain_num)*2)
85
#define ARM_ACCESS_TYPE_MANAGER(domain_num)      (0x3 << (domain_num)*2)
86
 
87
struct ARM_MMU_FIRST_LEVEL_FAULT {
88
    int id : 2;
89
    int sbz : 30;
90
};
91
#define ARM_MMU_FIRST_LEVEL_FAULT_ID 0x0
92
 
93
struct ARM_MMU_FIRST_LEVEL_PAGE_TABLE {
94
    int id : 2;
95
    int imp : 2;
96
    int domain : 4;
97
    int sbz : 1;
98
    int base_address : 23;
99
};
100
#define ARM_MMU_FIRST_LEVEL_PAGE_TABLE_ID 0x1
101
 
102
struct ARM_MMU_FIRST_LEVEL_SECTION {
103
    int id : 2;
104
    int b : 1;
105
    int c : 1;
106
    int imp : 1;
107
    int domain : 4;
108
    int sbz0 : 1;
109
    int ap : 2;
110
    int sbz1 : 8;
111
    int base_address : 12;
112
};
113
#define ARM_MMU_FIRST_LEVEL_SECTION_ID 0x2
114
 
115
struct ARM_MMU_FIRST_LEVEL_RESERVED {
116
    int id : 2;
117
    int sbz : 30;
118
};
119
#define ARM_MMU_FIRST_LEVEL_RESERVED_ID 0x3
120
 
121
#define ARM_MMU_FIRST_LEVEL_DESCRIPTOR_ADDRESS(ttb_base, table_index) \
122
   (unsigned long *)((unsigned long)(ttb_base) + ((table_index) << 2))
123
 
124
#define ARM_FIRST_LEVEL_PAGE_TABLE_SIZE 0x4000
125
 
126
#define ARM_MMU_SECTION(ttb_base, actual_base, virtual_base,              \
127
                        cacheable, bufferable, perm)                      \
128
    CYG_MACRO_START                                                       \
129
        register union ARM_MMU_FIRST_LEVEL_DESCRIPTOR desc;               \
130
                                                                          \
131
        desc.word = 0;                                                    \
132
        desc.section.id = ARM_MMU_FIRST_LEVEL_SECTION_ID;                 \
133
        desc.section.imp = 1;                                             \
134
        desc.section.domain = 0;                                          \
135
        desc.section.c = (cacheable);                                     \
136
        desc.section.b = (bufferable);                                    \
137
        desc.section.ap = (perm);                                         \
138
        desc.section.base_address = (actual_base);                        \
139
        *ARM_MMU_FIRST_LEVEL_DESCRIPTOR_ADDRESS(ttb_base, (virtual_base)) \
140
                            = desc.word;                                  \
141
    CYG_MACRO_END
142
 
143
#define X_ARM_MMU_SECTION(abase,vbase,size,cache,buff,access)      \
144
    { int i; int j = abase; int k = vbase;                         \
145
      for (i = size; i > 0 ; i--,j++,k++)                          \
146
      {                                                            \
147
        ARM_MMU_SECTION(ttb_base, j, k, cache, buff, access);      \
148
      }                                                            \
149
    }
150
 
151
union ARM_MMU_FIRST_LEVEL_DESCRIPTOR {
152
    unsigned long word;
153
    struct ARM_MMU_FIRST_LEVEL_FAULT fault;
154
    struct ARM_MMU_FIRST_LEVEL_PAGE_TABLE page_table;
155
    struct ARM_MMU_FIRST_LEVEL_SECTION section;
156
    struct ARM_MMU_FIRST_LEVEL_RESERVED reserved;
157
};
158
 
159
#define ARM_UNCACHEABLE                         0
160
#define ARM_CACHEABLE                           1
161
#define ARM_UNBUFFERABLE                        0
162
#define ARM_BUFFERABLE                          1
163
 
164
#define ARM_ACCESS_PERM_NONE_NONE               0
165
#define ARM_ACCESS_PERM_RO_NONE                 0
166
#define ARM_ACCESS_PERM_RO_RO                   0
167
#define ARM_ACCESS_PERM_RW_NONE                 1
168
#define ARM_ACCESS_PERM_RW_RO                   2
169
#define ARM_ACCESS_PERM_RW_RW                   3
170
 
171
void
172
hal_mmu_init(void)
173
{
174
    unsigned long ttb_base = INNOVATOR_SDRAM_PHYS_BASE + 0x4000;
175
    unsigned long i;
176
 
177
    // Set the TTB register
178
    asm volatile ("mcr  p15,0,%0,c2,c0,0" : : "r"(ttb_base) /*:*/);
179
 
180
    // Set the Domain Access Control Register
181
    i = ARM_ACCESS_TYPE_MANAGER(0)    |
182
        ARM_ACCESS_TYPE_NO_ACCESS(1)  |
183
        ARM_ACCESS_TYPE_NO_ACCESS(2)  |
184
        ARM_ACCESS_TYPE_NO_ACCESS(3)  |
185
        ARM_ACCESS_TYPE_NO_ACCESS(4)  |
186
        ARM_ACCESS_TYPE_NO_ACCESS(5)  |
187
        ARM_ACCESS_TYPE_NO_ACCESS(6)  |
188
        ARM_ACCESS_TYPE_NO_ACCESS(7)  |
189
        ARM_ACCESS_TYPE_NO_ACCESS(8)  |
190
        ARM_ACCESS_TYPE_NO_ACCESS(9)  |
191
        ARM_ACCESS_TYPE_NO_ACCESS(10) |
192
        ARM_ACCESS_TYPE_NO_ACCESS(11) |
193
        ARM_ACCESS_TYPE_NO_ACCESS(12) |
194
        ARM_ACCESS_TYPE_NO_ACCESS(13) |
195
        ARM_ACCESS_TYPE_NO_ACCESS(14) |
196
        ARM_ACCESS_TYPE_NO_ACCESS(15);
197
    asm volatile ("mcr  p15,0,%0,c3,c0,0" : : "r"(i) /*:*/);
198
 
199
    // First clear all TT entries - ie Set them to Faulting
200
    memset((void *)ttb_base, 0, ARM_FIRST_LEVEL_PAGE_TABLE_SIZE);
201
 
202
    //               Actual  Virtual  Size   Attributes                                                    Function
203
    //               Base     Base     MB      cached?           buffered?        access permissions
204
    //             xxx00000  xxx00000
205
    X_ARM_MMU_SECTION(0x000,  0x100,     4,  ARM_CACHEABLE,   ARM_UNBUFFERABLE, ARM_ACCESS_PERM_RW_RW); // FLASH CS0
206
    X_ARM_MMU_SECTION(0x100,  0x000,    32,  ARM_CACHEABLE,   ARM_BUFFERABLE,   ARM_ACCESS_PERM_RW_RW); // SDRAM
207
    X_ARM_MMU_SECTION(0x080,  0x080,     1,  ARM_UNCACHEABLE, ARM_UNBUFFERABLE, ARM_ACCESS_PERM_RW_RW); // FPGA
208
    X_ARM_MMU_SECTION(0x200,  0x200,     1,  ARM_CACHEABLE,   ARM_BUFFERABLE,   ARM_ACCESS_PERM_RW_RW); // Internal SRAM
209
    X_ARM_MMU_SECTION(0xE00,  0xE00,   512,  ARM_UNCACHEABLE, ARM_UNBUFFERABLE, ARM_ACCESS_PERM_RW_RW); // Internal Peripherals
210
}
211
 
212
//----------------------------------------------------------------------------
213
// Platform specific initialization
214
 
215
void
216
plf_hardware_init(void)
217
{
218
#ifdef LATER
219
    // Disable PLD interrupts
220
    HAL_WRITE_UINT32(INNOVATOR_INT_MASK_CLEAR,
221
                     INNOVATOR_INT_SOURCE_P0 | INNOVATOR_INT_SOURCE_P1 |
222
                     INNOVATOR_INT_SOURCE_P2 | INNOVATOR_INT_SOURCE_P3 |
223
                     INNOVATOR_INT_SOURCE_P4 | INNOVATOR_INT_SOURCE_P5);
224
    // Make PLD0 generate IRQ
225
    HAL_WRITE_UINT32(INNOVATOR_INT_PRIORITY_0, 0);
226
#endif
227
    cyg_uint8 tmp;
228
    // This should be protected by some sort of #ifdef to test to see if
229
    // the ethernet has been enabled or not.  I'll add that later.
230
    HAL_READ_UINT8(0x0800000B, tmp);
231
    HAL_WRITE_UINT8(0x0800000B, tmp & ~1);
232
    HAL_DELAY_US(750);
233
 
234
}
235
 
236
// -------------------------------------------------------------------------
237
void
238
hal_clock_initialize(cyg_uint32 period)
239
{
240
#ifdef LATER
241
    cyg_uint32 cr;
242
 
243
    HAL_WRITE_UINT32(INNOVATOR_TIMER0_CR, 0);
244
    HAL_WRITE_UINT32(INNOVATOR_TIMER0_PRE, CYGNUM_HAL_ARM_INNOVATOR_TIMER_PRESCALE - 1);
245
    HAL_WRITE_UINT32(INNOVATOR_TIMER0_LIMIT, period);
246
    cr = INNOVATOR_TIMER_CR_MODE_HEARBEAT | INNOVATOR_TIMER_CR_IE;
247
    HAL_WRITE_UINT32(INNOVATOR_TIMER0_CR, cr);
248
    HAL_WRITE_UINT32(INNOVATOR_TIMER0_CR, cr | INNOVATOR_TIMER_CR_S);
249
 
250
    // Unmask timer 0 interrupt
251
    HAL_INTERRUPT_CONFIGURE( CYGNUM_HAL_INTERRUPT_RTC, 1, 1 );
252
    HAL_INTERRUPT_UNMASK( CYGNUM_HAL_INTERRUPT_RTC );
253
#endif
254
}
255
 
256
// This routine is called during a clock interrupt.
257
void
258
hal_clock_reset(cyg_uint32 vector, cyg_uint32 period)
259
{
260
#ifdef LATER
261
    cyg_uint32 cr;
262
 
263
    // Clear pending interrupt bit
264
    HAL_READ_UINT32(INNOVATOR_TIMER0_CR, cr);
265
    cr |= INNOVATOR_TIMER_CR_CI;
266
    HAL_WRITE_UINT32(INNOVATOR_TIMER0_CR, cr);
267
#endif
268
}
269
 
270
// Read the current value of the clock, returning the number of hardware
271
// "ticks" that have occurred (i.e. how far away the current value is from
272
// the start)
273
 
274
void
275
hal_clock_read(cyg_uint32 *pvalue)
276
{
277
#ifdef LATER
278
    cyg_uint32 ctr;
279
 
280
    HAL_READ_UINT32(INNOVATOR_TIMER0_READ, ctr);
281
    *pvalue = ctr;
282
#endif
283
}
284
 
285
//
286
// Delay for some number of micro-seconds
287
//
288
void
289
hal_delay_us(cyg_int32 usecs)
290
{
291
#ifdef LATER
292
    // Use timer 2 
293
    cyg_uint32 cr;
294
    // Divide by 1000000 in two steps to preserve precision.
295
    cyg_uint32 wait_clocks = ((CYGNUM_HAL_ARM_INNOVATOR_PERIPHERAL_CLOCK/100000)*usecs)/10;
296
 
297
    HAL_WRITE_UINT32(INNOVATOR_TIMER1_CR, 0);
298
    HAL_WRITE_UINT32(INNOVATOR_TIMER1_PRE, 0);
299
    HAL_WRITE_UINT32(INNOVATOR_TIMER1_LIMIT, wait_clocks);
300
    cr = INNOVATOR_TIMER_CR_MODE_ONE_SHOT|INNOVATOR_TIMER_CR_CI;
301
    HAL_WRITE_UINT32(INNOVATOR_TIMER1_CR, cr);
302
    HAL_WRITE_UINT32(INNOVATOR_TIMER1_CR, cr | INNOVATOR_TIMER_CR_S);
303
 
304
    // wait for start bit to clear
305
    do {
306
        HAL_READ_UINT32(INNOVATOR_TIMER1_CR, cr);
307
    } while ((INNOVATOR_TIMER_CR_S & cr) != 0);
308
 
309
    //clear interrupt flag
310
    HAL_WRITE_UINT32(INNOVATOR_TIMER1_CR, 0);
311
#else
312
#if 0
313
    volatile unsigned long long x;
314
    volatile unsigned long long loop_count = usecs / 10 + 1;
315
 
316
    for (x = 0; x < loop_count; x++) ;
317
#else
318
    volatile cyg_uint32 *CNTL_TIMER = (volatile cyg_uint32 *)(0xFFFEC500 + 0x00);
319
    volatile cyg_uint32 *LOAD_TIM   = (volatile cyg_uint32 *)(0xFFFEC500 + 0x04);
320
    volatile cyg_uint32 *READ_TIM   = (volatile cyg_uint32 *)(0xFFFEC500 + 0x08);
321
    cyg_uint32 timer_val, prev_val;
322
    int too_long = 0;
323
 
324
    if (usecs <= 0) {
325
      return;
326
    } else if (usecs > 357913941) {
327
      /* Clamp at MAX_INT32 / 6 */
328
      usecs = 357913941;
329
    }
330
    /* Enable the clock and halt the timer */
331
    HAL_WRITE_UINT32(CNTL_TIMER, 0x00000020);
332
 
333
    /* Load the timer */
334
    HAL_WRITE_UINT32(LOAD_TIM, 6 * usecs);
335
 
336
    /* Start the timer */
337
    HAL_READ_UINT32(READ_TIM, prev_val);
338
    HAL_WRITE_UINT32(CNTL_TIMER, 0x00000021);
339
 
340
    /* Wait for it to load (but not too long) */
341
    do {
342
      HAL_READ_UINT32(READ_TIM, timer_val);
343
      if (++too_long >= 100) {
344
        break;
345
      }
346
    } while (timer_val == prev_val);
347
 
348
    /* Wait for it to count down to zero */
349
    do {
350
      HAL_READ_UINT32(READ_TIM, timer_val);
351
    } while (timer_val > 0);
352
#endif
353
#endif
354
}
355
 
356
// -------------------------------------------------------------------------
357
 
358
// This routine is called to respond to a hardware interrupt (IRQ).  It
359
// should interrogate the hardware and return the IRQ vector number.
360
int
361
hal_IRQ_handler(void)
362
{
363
#ifdef LATER
364
    int vec;
365
    cyg_uint32 isr;
366
 
367
    HAL_READ_UINT32(INNOVATOR_INT_REQUEST_STATUS, isr);
368
    for (vec = CYGNUM_HAL_INTERRUPT_PLD_0;
369
         vec <= CYGNUM_HAL_INTERRUPT_FAST_COMMS; vec++) {
370
        if (isr & (1<<vec)) {
371
            return vec;
372
        }
373
    }
374
#endif
375
    return CYGNUM_HAL_INTERRUPT_NONE;
376
}
377
 
378
//----------------------------------------------------------------------------
379
// Interrupt control
380
//
381
void
382
hal_interrupt_mask(int vector)
383
{
384
#ifdef LATER
385
    CYG_ASSERT(vector <= CYGNUM_HAL_ISR_MAX &&
386
               vector >= CYGNUM_HAL_ISR_MIN , "Invalid vector");
387
 
388
    HAL_WRITE_UINT32(INNOVATOR_INT_MASK_CLEAR, 1<<vector);
389
#endif
390
}
391
 
392
void
393
hal_interrupt_unmask(int vector)
394
{
395
#ifdef LATER
396
    CYG_ASSERT(vector <= CYGNUM_HAL_ISR_MAX &&
397
               vector >= CYGNUM_HAL_ISR_MIN , "Invalid vector");
398
 
399
    HAL_WRITE_UINT32(INNOVATOR_INT_MASK_SET, 1<<vector);
400
#endif
401
}
402
 
403
void
404
hal_interrupt_acknowledge(int vector)
405
{
406
#ifdef LATER
407
    CYG_ASSERT(vector <= CYGNUM_HAL_ISR_MAX &&
408
               vector >= CYGNUM_HAL_ISR_MIN , "Invalid vector");
409
#endif
410
 
411
}
412
 
413
void
414
hal_interrupt_configure(int vector, int level, int up)
415
{
416
#ifdef LATER
417
    CYG_ASSERT(vector <= CYGNUM_HAL_ISR_MAX &&
418
               vector >= CYGNUM_HAL_ISR_MIN, "Invalid vector");
419
    CYG_ASSERT(level || up, "Cannot do falling edge");
420
#endif
421
}
422
 
423
void
424
hal_interrupt_set_level(int vector, int level)
425
{
426
#ifdef LATER
427
    cyg_uint32 reg;
428
    CYG_ASSERT(vector <= CYGNUM_HAL_ISR_MAX &&
429
               vector >= CYGNUM_HAL_ISR_MIN, "Invalid vector");
430
    CYG_ASSERT(level <= 63 && level >= 0, "Invalid level");
431
 
432
    HAL_READ_UINT32(INNOVATOR_INT_PRIORITY_0+4*vector, reg);
433
    reg &= ~INNOVATOR_INT_PRIORITY_LVL_mask;
434
    reg |= (level & INNOVATOR_INT_PRIORITY_LVL_mask);
435
    HAL_WRITE_UINT32(INNOVATOR_INT_PRIORITY_0+4*vector, reg);
436
#endif
437
}
438
 
439
#include CYGHWR_MEMORY_LAYOUT_H
440
typedef void code_fun(void);
441
void innovator_program_new_stack(void *func)
442
{
443
    register CYG_ADDRESS stack_ptr asm("sp");
444
    register CYG_ADDRESS old_stack asm("r4");
445
    register code_fun *new_func asm("r0");
446
    old_stack = stack_ptr;
447
    stack_ptr = CYGMEM_REGION_ram + CYGMEM_REGION_ram_SIZE - sizeof(CYG_ADDRESS);
448
    new_func = (code_fun*)func;
449
    new_func();
450
    stack_ptr = old_stack;
451
    return;
452
}

powered by: WebSVN 2.1.0

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