1 |
27 |
unneback |
//==========================================================================
|
2 |
|
|
//
|
3 |
|
|
// ebsa285_misc.c
|
4 |
|
|
//
|
5 |
|
|
// HAL misc board support code for StrongARM EBSA285-1
|
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: gthomas
|
45 |
|
|
// Date: 1999-02-20
|
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 |
|
|
#include CYGHWR_MEMORY_LAYOUT_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_if.h> // calling interface API
|
64 |
|
|
#include <cyg/hal/hal_arch.h> // Register state info
|
65 |
|
|
#include <cyg/hal/hal_diag.h>
|
66 |
|
|
#include <cyg/hal/hal_intr.h> // Interrupt names
|
67 |
|
|
#include <cyg/hal/hal_cache.h>
|
68 |
|
|
#include <cyg/hal/hal_ebsa285.h> // Hardware definitions
|
69 |
|
|
|
70 |
|
|
#include <cyg/infra/diag.h> // diag_printf
|
71 |
|
|
|
72 |
|
|
#include <string.h> // memset
|
73 |
|
|
|
74 |
|
|
/*
|
75 |
|
|
* Toggle LED for debugging purposes.
|
76 |
|
|
*/
|
77 |
|
|
/*
|
78 |
|
|
* EBSA-285 Soft I/O Register
|
79 |
|
|
*/
|
80 |
|
|
#define EBSA_285_SOFT_IO_REGISTER ((cyg_uint32 *)0x40012000)
|
81 |
|
|
|
82 |
|
|
/*
|
83 |
|
|
* EBSA-285 Soft I/O Register Bit Field definitions
|
84 |
|
|
*/
|
85 |
|
|
#define EBSA_285_SOFT_IO_TOGGLE 0x80
|
86 |
|
|
#define EBSA_285_SOFT_IO_RED_LED 0x04
|
87 |
|
|
#define EBSA_285_SOFT_IO_GREEN_LED 0x02
|
88 |
|
|
#define EBSA_285_SOFT_IO_AMBER_LED 0x01
|
89 |
|
|
#define EBSA_285_SOFT_IO_J9_9_10_MASK 0x40
|
90 |
|
|
#define EBSA_285_SOFT_IO_J9_11_12_MASK 0x20
|
91 |
|
|
#define EBSA_285_SOFT_IO_J9_13_14_MASK 0x10
|
92 |
|
|
#define EBSA_285_SOFT_IO_SWITCH_L_MASK 0x0F
|
93 |
|
|
|
94 |
|
|
static void
|
95 |
|
|
hal_bsp_mmu_init(int sdram_size);
|
96 |
|
|
|
97 |
|
|
// Some initialization has already been done before we get here.
|
98 |
|
|
//
|
99 |
|
|
// Set up the interrupt environment.
|
100 |
|
|
// Set up the MMU so that we can use caches.
|
101 |
|
|
// Enable caches.
|
102 |
|
|
// - All done!
|
103 |
|
|
|
104 |
|
|
|
105 |
|
|
void hal_hardware_init(void)
|
106 |
|
|
{
|
107 |
|
|
// Disable all interrupt sources:
|
108 |
|
|
*SA110_IRQCONT_IRQENABLECLEAR = 0xffffffff;
|
109 |
|
|
*SA110_IRQCONT_FIQENABLECLEAR = 0xffffffff; // including FIQ
|
110 |
|
|
// Disable the timers
|
111 |
|
|
*SA110_TIMER1_CONTROL = 0;
|
112 |
|
|
*SA110_TIMER2_CONTROL = 0;
|
113 |
|
|
*SA110_TIMER3_CONTROL = 0;
|
114 |
|
|
*SA110_TIMER4_CONTROL = 0;
|
115 |
|
|
|
116 |
|
|
*SA110_TIMER1_CLEAR = 0; // Clear any pending interrupt
|
117 |
|
|
*SA110_TIMER2_CLEAR = 0; // (Data: don't care)
|
118 |
|
|
*SA110_TIMER3_CLEAR = 0;
|
119 |
|
|
*SA110_TIMER4_CLEAR = 0;
|
120 |
|
|
|
121 |
|
|
// Let the timer run at a default rate (for delays)
|
122 |
|
|
hal_clock_initialize(CYGNUM_HAL_RTC_PERIOD);
|
123 |
|
|
|
124 |
|
|
// Set up MMU so that we can use caches
|
125 |
|
|
hal_bsp_mmu_init( hal_dram_size );
|
126 |
|
|
|
127 |
|
|
// Enable caches
|
128 |
|
|
HAL_DCACHE_ENABLE();
|
129 |
|
|
HAL_ICACHE_ENABLE();
|
130 |
|
|
|
131 |
|
|
// Set up eCos/ROM interfaces
|
132 |
|
|
hal_if_init();
|
133 |
|
|
}
|
134 |
|
|
|
135 |
|
|
// -------------------------------------------------------------------------
|
136 |
|
|
// MMU initialization:
|
137 |
|
|
|
138 |
|
|
static void
|
139 |
|
|
hal_bsp_mmu_init(int sdram_size)
|
140 |
|
|
{
|
141 |
|
|
unsigned long ttb_base = ((unsigned long)0x4000); // could be external
|
142 |
|
|
unsigned long i;
|
143 |
|
|
|
144 |
|
|
*EBSA_285_SOFT_IO_REGISTER = ~EBSA_285_SOFT_IO_RED_LED; // Red LED on
|
145 |
|
|
|
146 |
|
|
|
147 |
|
|
// For if we assign the ttb base dynamically:
|
148 |
|
|
// if ((ttb_base & ARM_TRANSLATION_TABLE_MASK) != ttb_base) {
|
149 |
|
|
// // we cannot do this:
|
150 |
|
|
// while ( 1 ) {
|
151 |
|
|
// *EBSA_285_SOFT_IO_REGISTER = 0; // All LEDs on
|
152 |
|
|
// for ( i = 100000; i > 0 ; i++ ) ;
|
153 |
|
|
// *EBSA_285_SOFT_IO_REGISTER = 7; // All LEDs off
|
154 |
|
|
// for ( i = 100000; i > 0 ; i++ ) ;
|
155 |
|
|
//#ifdef CYG_HAL_STARTUP_RAM
|
156 |
|
|
// return; // Do not bother looping forever...
|
157 |
|
|
//#endif
|
158 |
|
|
// }
|
159 |
|
|
// }
|
160 |
|
|
|
161 |
|
|
/*
|
162 |
|
|
* Set the TTB register
|
163 |
|
|
*/
|
164 |
|
|
asm volatile ("mcr p15,0,%0,c2,c0,0"
|
165 |
|
|
:
|
166 |
|
|
: "r"(ttb_base)
|
167 |
|
|
/*:*/
|
168 |
|
|
);
|
169 |
|
|
/*
|
170 |
|
|
* Set the Domain Access Control Register
|
171 |
|
|
*/
|
172 |
|
|
i = ARM_ACCESS_TYPE_MANAGER(0) |
|
173 |
|
|
ARM_ACCESS_TYPE_NO_ACCESS(1) |
|
174 |
|
|
ARM_ACCESS_TYPE_NO_ACCESS(2) |
|
175 |
|
|
ARM_ACCESS_TYPE_NO_ACCESS(3) |
|
176 |
|
|
ARM_ACCESS_TYPE_NO_ACCESS(4) |
|
177 |
|
|
ARM_ACCESS_TYPE_NO_ACCESS(5) |
|
178 |
|
|
ARM_ACCESS_TYPE_NO_ACCESS(6) |
|
179 |
|
|
ARM_ACCESS_TYPE_NO_ACCESS(7) |
|
180 |
|
|
ARM_ACCESS_TYPE_NO_ACCESS(8) |
|
181 |
|
|
ARM_ACCESS_TYPE_NO_ACCESS(9) |
|
182 |
|
|
ARM_ACCESS_TYPE_NO_ACCESS(10) |
|
183 |
|
|
ARM_ACCESS_TYPE_NO_ACCESS(11) |
|
184 |
|
|
ARM_ACCESS_TYPE_NO_ACCESS(12) |
|
185 |
|
|
ARM_ACCESS_TYPE_NO_ACCESS(13) |
|
186 |
|
|
ARM_ACCESS_TYPE_NO_ACCESS(14) |
|
187 |
|
|
ARM_ACCESS_TYPE_NO_ACCESS(15);
|
188 |
|
|
|
189 |
|
|
asm volatile ("mcr p15,0,%0,c3,c0,0"
|
190 |
|
|
:
|
191 |
|
|
: "r"(i)
|
192 |
|
|
/*:*/
|
193 |
|
|
);
|
194 |
|
|
|
195 |
|
|
/*
|
196 |
|
|
* First clear all TT entries - ie Set them to Faulting
|
197 |
|
|
*/
|
198 |
|
|
memset((void *)ttb_base, 0, ARM_FIRST_LEVEL_PAGE_TABLE_SIZE);
|
199 |
|
|
|
200 |
|
|
/*
|
201 |
|
|
* We only do direct mapping for the EBSA board. That is, all
|
202 |
|
|
* virt_addr == phys_addr.
|
203 |
|
|
*/
|
204 |
|
|
|
205 |
|
|
/*
|
206 |
|
|
* Actual Base = 0x000(00000)
|
207 |
|
|
* Virtual Base = 0x000(00000)
|
208 |
|
|
* Size = Max SDRAM
|
209 |
|
|
* SDRAM
|
210 |
|
|
*/
|
211 |
|
|
for (i = 0x000; i < (sdram_size >> 20); i++) {
|
212 |
|
|
ARM_MMU_SECTION(ttb_base, i, i,
|
213 |
|
|
ARM_CACHEABLE, ARM_BUFFERABLE,
|
214 |
|
|
ARM_ACCESS_PERM_RW_RW);
|
215 |
|
|
}
|
216 |
|
|
|
217 |
|
|
#ifdef CYGPKG_IO_PCI
|
218 |
|
|
/*
|
219 |
|
|
* Actual Base = CYGHWR_HAL_ARM_EBSA285_PCI_MEM_MAP_BASE
|
220 |
|
|
* Virtual Base = CYGHWR_HAL_ARM_EBSA285_PCI_MEM_MAP_BASE
|
221 |
|
|
* Size = CYGHWR_HAL_ARM_EBSA285_PCI_MEM_MAP_SIZE
|
222 |
|
|
* Memory accessible from PCI space. Overrides part of the above mapping.
|
223 |
|
|
*/
|
224 |
|
|
for (i = CYGHWR_HAL_ARM_EBSA285_PCI_MEM_MAP_BASE >> 20;
|
225 |
|
|
i < ((CYGHWR_HAL_ARM_EBSA285_PCI_MEM_MAP_BASE+CYGHWR_HAL_ARM_EBSA285_PCI_MEM_MAP_SIZE) >> 20);
|
226 |
|
|
i++) {
|
227 |
|
|
ARM_MMU_SECTION(ttb_base, i, i,
|
228 |
|
|
ARM_UNCACHEABLE, ARM_UNBUFFERABLE,
|
229 |
|
|
ARM_ACCESS_PERM_RW_RW);
|
230 |
|
|
}
|
231 |
|
|
#endif
|
232 |
|
|
|
233 |
|
|
/*
|
234 |
|
|
* Actual Base = 0x400(00000)
|
235 |
|
|
* Virtual Base = 0x400(00000)
|
236 |
|
|
* Size = 1M
|
237 |
|
|
* 21285 Registers
|
238 |
|
|
*
|
239 |
|
|
* Actual Base = 0x400(10000)
|
240 |
|
|
* Virtual Base = 0x400(10000)
|
241 |
|
|
* Size = 1M
|
242 |
|
|
* Soft I/O port and XBus IO
|
243 |
|
|
*/
|
244 |
|
|
ARM_MMU_SECTION(ttb_base, 0x400, 0x400,
|
245 |
|
|
ARM_UNCACHEABLE, ARM_UNBUFFERABLE,
|
246 |
|
|
ARM_ACCESS_PERM_RW_RW);
|
247 |
|
|
|
248 |
|
|
/*
|
249 |
|
|
* Actual Base = 0x410(00000) - 0x413(FFFFF)
|
250 |
|
|
* Virtual Base = 0x410(00000) - 0x413(FFFFF)
|
251 |
|
|
* Size = 4M
|
252 |
|
|
* FLASH ROM
|
253 |
|
|
*/
|
254 |
|
|
for (i = 0x410; i <= 0x413; i++) {
|
255 |
|
|
ARM_MMU_SECTION(ttb_base, i, i,
|
256 |
|
|
ARM_CACHEABLE, ARM_UNBUFFERABLE,
|
257 |
|
|
ARM_ACCESS_PERM_RW_RW);
|
258 |
|
|
}
|
259 |
|
|
|
260 |
|
|
/*
|
261 |
|
|
* Actual Base = 0x420(00000)
|
262 |
|
|
* Virtual Base = 0x420(00000)
|
263 |
|
|
* Size = 1M
|
264 |
|
|
* 21285 CSR Space
|
265 |
|
|
*/
|
266 |
|
|
ARM_MMU_SECTION(ttb_base, 0x420, 0x420,
|
267 |
|
|
ARM_UNCACHEABLE, ARM_UNBUFFERABLE,
|
268 |
|
|
ARM_ACCESS_PERM_RW_RW);
|
269 |
|
|
|
270 |
|
|
/*
|
271 |
|
|
* Actual Base = 0x500(00000)-0x50F(FFFFF)
|
272 |
|
|
* Virtual Base = 0x500(00000)-0x50F(FFFFF)
|
273 |
|
|
* Size = 16M
|
274 |
|
|
* Zeros (Cache Clean) Bank
|
275 |
|
|
*/
|
276 |
|
|
for (i = 0x500; i <= 0x50F; i++) {
|
277 |
|
|
ARM_MMU_SECTION(ttb_base, i, i,
|
278 |
|
|
ARM_CACHEABLE, ARM_BUFFERABLE,
|
279 |
|
|
ARM_ACCESS_PERM_RW_RW);
|
280 |
|
|
}
|
281 |
|
|
|
282 |
|
|
/*
|
283 |
|
|
* Actual Base = 0x780(00000)-0x78F(FFFFF)
|
284 |
|
|
* Virtual Base = 0x780(00000)-0x78F(FFFFF)
|
285 |
|
|
* Size = 16M
|
286 |
|
|
* Outbound Write Flush
|
287 |
|
|
*/
|
288 |
|
|
for (i = 0x780; i <= 0x78F; i++) {
|
289 |
|
|
ARM_MMU_SECTION(ttb_base, i, i,
|
290 |
|
|
ARM_UNCACHEABLE, ARM_UNBUFFERABLE,
|
291 |
|
|
ARM_ACCESS_PERM_RW_RW);
|
292 |
|
|
}
|
293 |
|
|
|
294 |
|
|
/*
|
295 |
|
|
* Actual Base = 0x790(00000)-0x7C0(FFFFF)
|
296 |
|
|
* Virtual Base = 0x790(00000)-0x7C0(FFFFF)
|
297 |
|
|
* Size = 65M
|
298 |
|
|
* PCI IACK/Config/IO Space
|
299 |
|
|
*/
|
300 |
|
|
for (i = 0x790; i <= 0x7C0; i++) {
|
301 |
|
|
ARM_MMU_SECTION(ttb_base, i, i,
|
302 |
|
|
ARM_UNCACHEABLE, ARM_UNBUFFERABLE,
|
303 |
|
|
ARM_ACCESS_PERM_RW_RW);
|
304 |
|
|
}
|
305 |
|
|
|
306 |
|
|
/*
|
307 |
|
|
* Actual Base = 0x800(00000) - 0xFFF(FFFFF)
|
308 |
|
|
* Virtual Base = 0x800(00000) - 0xFFF(FFFFF)
|
309 |
|
|
* Size = 2G
|
310 |
|
|
* PCI Memory Space
|
311 |
|
|
*/
|
312 |
|
|
for (i = 0x800; i <= 0xFFF; i++) {
|
313 |
|
|
ARM_MMU_SECTION(ttb_base, i, i,
|
314 |
|
|
ARM_UNCACHEABLE, ARM_BUFFERABLE,
|
315 |
|
|
ARM_ACCESS_PERM_RW_RW);
|
316 |
|
|
}
|
317 |
|
|
|
318 |
|
|
*EBSA_285_SOFT_IO_REGISTER = ~EBSA_285_SOFT_IO_AMBER_LED; // AmberLED on
|
319 |
|
|
|
320 |
|
|
}
|
321 |
|
|
|
322 |
|
|
/*------------------------------------------------------------------------*/
|
323 |
|
|
|
324 |
|
|
//
|
325 |
|
|
// Memory layout
|
326 |
|
|
//
|
327 |
|
|
|
328 |
|
|
externC cyg_uint8 *
|
329 |
|
|
hal_arm_mem_real_region_top( cyg_uint8 *regionend )
|
330 |
|
|
{
|
331 |
|
|
CYG_ASSERT( hal_dram_size > 0, "Didn't detect DRAM size!" );
|
332 |
|
|
CYG_ASSERT( hal_dram_size <= 256<<20,
|
333 |
|
|
"More than 256MB reported - that can't be right" );
|
334 |
|
|
|
335 |
|
|
// is it the "normal" end of the DRAM region? If so, it should be
|
336 |
|
|
// replaced by the real size
|
337 |
|
|
if ( regionend ==
|
338 |
|
|
((cyg_uint8 *)CYGMEM_REGION_ram + CYGMEM_REGION_ram_SIZE) ) {
|
339 |
|
|
regionend = (cyg_uint8 *)CYGMEM_REGION_ram + hal_dram_size;
|
340 |
|
|
}
|
341 |
|
|
return regionend;
|
342 |
|
|
} // hal_arm_mem_real_region_top()
|
343 |
|
|
|
344 |
|
|
|
345 |
|
|
|
346 |
|
|
// -------------------------------------------------------------------------
|
347 |
|
|
static cyg_uint32 _period;
|
348 |
|
|
|
349 |
|
|
void hal_clock_initialize(cyg_uint32 period)
|
350 |
|
|
{
|
351 |
|
|
_period = period;
|
352 |
|
|
|
353 |
|
|
*SA110_TIMER3_CONTROL = 0; // Disable while we are setting up
|
354 |
|
|
|
355 |
|
|
*SA110_TIMER3_LOAD = period; // Reload value
|
356 |
|
|
|
357 |
|
|
*SA110_TIMER3_CLEAR = 0; // Clear any pending interrupt
|
358 |
|
|
// (Data: don't care)
|
359 |
|
|
|
360 |
|
|
*SA110_TIMER3_CONTROL = 0x000000cc; // Enable, Periodic (auto-reload),
|
361 |
|
|
// External clock (3.68MHz on irq_in_l[2] for Timer 3)
|
362 |
|
|
|
363 |
|
|
*SA110_TIMER3_CLEAR = 0; // Clear any pending interrupt again
|
364 |
|
|
|
365 |
|
|
// That's all.
|
366 |
|
|
}
|
367 |
|
|
|
368 |
|
|
// This routine is called during a clock interrupt.
|
369 |
|
|
|
370 |
|
|
void hal_clock_reset(cyg_uint32 vector, cyg_uint32 period)
|
371 |
|
|
{
|
372 |
|
|
*SA110_TIMER3_CLEAR = period; // Clear any pending interrupt (Data: don't care)
|
373 |
|
|
}
|
374 |
|
|
|
375 |
|
|
// Read the current value of the clock, returning the number of hardware
|
376 |
|
|
// "ticks" that have occurred (i.e. how far away the current value is from
|
377 |
|
|
// the start)
|
378 |
|
|
|
379 |
|
|
void hal_clock_read(cyg_uint32 *pvalue)
|
380 |
|
|
{
|
381 |
|
|
*pvalue = (cyg_uint32)(_period) - *SA110_TIMER3_VALUE;
|
382 |
|
|
}
|
383 |
|
|
|
384 |
|
|
//
|
385 |
|
|
// Delay for some number of micro-seconds
|
386 |
|
|
//
|
387 |
|
|
void hal_delay_us(cyg_int32 usecs)
|
388 |
|
|
{
|
389 |
|
|
int diff, diff2;
|
390 |
|
|
cyg_uint32 val1, val2;
|
391 |
|
|
|
392 |
|
|
while (usecs-- > 0) {
|
393 |
|
|
diff = 0;
|
394 |
|
|
val1 = *SA110_TIMER3_VALUE;
|
395 |
|
|
while (diff < 3) {
|
396 |
|
|
while ((val2 = *SA110_TIMER3_VALUE) == val1) ;
|
397 |
|
|
if (*SA110_TIMER3_LOAD) {
|
398 |
|
|
// A kernel is running, the counter may get reset as we watch
|
399 |
|
|
diff2 = val2 - val1;
|
400 |
|
|
if (diff2 < 0) diff2 += *SA110_TIMER3_LOAD;
|
401 |
|
|
diff += diff2;
|
402 |
|
|
} else {
|
403 |
|
|
diff += val2 - val1;
|
404 |
|
|
}
|
405 |
|
|
}
|
406 |
|
|
}
|
407 |
|
|
}
|
408 |
|
|
|
409 |
|
|
// -------------------------------------------------------------------------
|
410 |
|
|
|
411 |
|
|
// This routine is called to respond to a hardware interrupt (IRQ). It
|
412 |
|
|
// should interrogate the hardware and return the IRQ vector number.
|
413 |
|
|
int hal_IRQ_handler(void)
|
414 |
|
|
{
|
415 |
|
|
int sources;
|
416 |
|
|
int index;
|
417 |
|
|
|
418 |
|
|
#if 0 // test FIQ and print alert if active - really for debugging
|
419 |
|
|
sources = *SA110_IRQCONT_FIQSTATUS;
|
420 |
|
|
if ( 0 != sources )
|
421 |
|
|
diag_printf( "FIQ source active!!! - fiqstatus %08x irqstatus %08x\n",
|
422 |
|
|
sources, *SA110_IRQCONT_IRQSTATUS );
|
423 |
|
|
else
|
424 |
|
|
#endif // Scan FIQ sources also
|
425 |
|
|
|
426 |
|
|
sources = *SA110_IRQCONT_IRQSTATUS;
|
427 |
|
|
|
428 |
|
|
// if we come to support FIQ properly...
|
429 |
|
|
// if ( 0 == sources )
|
430 |
|
|
// sources = *SA110_IRQCONT_FIQSTATUS;
|
431 |
|
|
|
432 |
|
|
// Nothing wrong with scanning them in the order provided...
|
433 |
|
|
// and it'll make the serial device steal fewer cycles.
|
434 |
|
|
// So, knowing this is an ARM:
|
435 |
|
|
if ( sources & 0xff )
|
436 |
|
|
index = 0;
|
437 |
|
|
else if ( sources & 0xff00 )
|
438 |
|
|
index = 8;
|
439 |
|
|
else if ( sources & 0xff0000 )
|
440 |
|
|
index = 16;
|
441 |
|
|
else // if ( sources & 0xff000000 )
|
442 |
|
|
index = 24;
|
443 |
|
|
|
444 |
|
|
do {
|
445 |
|
|
if ( (1 << index) & sources )
|
446 |
|
|
return index;
|
447 |
|
|
index++;
|
448 |
|
|
} while ( index & 7 );
|
449 |
|
|
|
450 |
|
|
return CYGNUM_HAL_INTERRUPT_NONE; // This shouldn't happen!
|
451 |
|
|
}
|
452 |
|
|
|
453 |
|
|
//
|
454 |
|
|
// Interrupt control
|
455 |
|
|
//
|
456 |
|
|
|
457 |
|
|
void hal_interrupt_mask(int vector)
|
458 |
|
|
{
|
459 |
|
|
*SA110_IRQCONT_IRQENABLECLEAR = 1 << vector;
|
460 |
|
|
}
|
461 |
|
|
|
462 |
|
|
void hal_interrupt_unmask(int vector)
|
463 |
|
|
{
|
464 |
|
|
*SA110_IRQCONT_IRQENABLESET = 1 << vector;
|
465 |
|
|
}
|
466 |
|
|
|
467 |
|
|
void hal_interrupt_acknowledge(int vector)
|
468 |
|
|
{
|
469 |
|
|
// Nothing to do here.
|
470 |
|
|
}
|
471 |
|
|
|
472 |
|
|
void hal_interrupt_configure(int vector, int level, int up)
|
473 |
|
|
{
|
474 |
|
|
// No interrupts are configurable on this hardware
|
475 |
|
|
}
|
476 |
|
|
|
477 |
|
|
void hal_interrupt_set_level(int vector, int level)
|
478 |
|
|
{
|
479 |
|
|
// No interrupts are configurable on this hardware
|
480 |
|
|
}
|
481 |
|
|
|
482 |
|
|
#include CYGHWR_MEMORY_LAYOUT_H
|
483 |
|
|
typedef void code_fun(void);
|
484 |
|
|
void ebsa285_program_new_stack(void *func)
|
485 |
|
|
{
|
486 |
|
|
register CYG_ADDRESS stack_ptr asm("sp");
|
487 |
|
|
register CYG_ADDRESS old_stack asm("r4");
|
488 |
|
|
register code_fun *new_func asm("r0");
|
489 |
|
|
old_stack = stack_ptr;
|
490 |
|
|
stack_ptr = CYGMEM_REGION_ram + CYGMEM_REGION_ram_SIZE - sizeof(CYG_ADDRESS);
|
491 |
|
|
new_func = (code_fun*)func;
|
492 |
|
|
new_func();
|
493 |
|
|
stack_ptr = old_stack;
|
494 |
|
|
return;
|
495 |
|
|
}
|
496 |
|
|
|
497 |
|
|
/*------------------------------------------------------------------------*/
|
498 |
|
|
// EOF ebsa285_misc.c
|