]> git.kernelconcepts.de Git - karo-tx-redboot.git/blob - packages/hal/arm/arch/v2_0/src/hal_misc.c
TX51 pre-release
[karo-tx-redboot.git] / packages / hal / arm / arch / v2_0 / src / hal_misc.c
1 /*==========================================================================
2 //
3 //      hal_misc.c
4 //
5 //      HAL miscellaneous functions
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):    nickg, gthomas
44 // Contributors: nickg, gthomas
45 // Date:         1999-02-20
46 // Purpose:      HAL miscellaneous functions
47 // Description:  This file contains miscellaneous functions provided by the
48 //               HAL.
49 //
50 //####DESCRIPTIONEND####
51 //
52 //=========================================================================*/
53
54 #include <pkgconf/hal.h>
55 #include <pkgconf/hal_arm.h>
56 #ifdef CYGPKG_KERNEL
57 #include <pkgconf/kernel.h>
58 #endif
59 #ifdef CYGPKG_CYGMON
60 #include <pkgconf/cygmon.h>
61 #endif
62
63 #include <cyg/infra/cyg_type.h>
64 #include <cyg/infra/cyg_trac.h>                 // tracing macros
65 #include <cyg/infra/cyg_ass.h>                  // assertion macros
66
67 #include <cyg/hal/hal_arch.h>                   // HAL header
68 #include <cyg/hal/hal_intr.h>                   // HAL header
69
70 #include <cyg/infra/diag.h>
71
72 /*------------------------------------------------------------------------*/
73 /* First level C exception handler.                                                                               */
74
75 externC void __handle_exception (void);
76
77 externC HAL_SavedRegisters *_hal_registers;
78 #ifdef CYGDBG_HAL_DEBUG_GDB_INCLUDE_STUBS
79 externC void* volatile __mem_fault_handler;
80 #endif
81
82
83 #ifdef CYGDBG_HAL_DEBUG_GDB_INCLUDE_STUBS
84 /* Force exception handling into the GDB stubs.  This is done by taking over
85    the exception vectors while executing in the stubs.  This allows for the
86    debugged program to handle exceptions itself, except while the GDB
87    processing is underway.  The only vector that can't be handled this way
88    is the illegal instruction vector which is used for breakpoint/single-step
89    and must be maintained by the stubs at all times.
90    Note: the interrupt vectors are _not_ preempted as the stubs probably can't
91    handle them properly.
92 */
93
94 #define ARM_VECTORS 8
95 extern unsigned long vectors[];  // exception vectors as defined by the stubs
96
97 #if !defined(CYGPKG_CYGMON)
98 static unsigned long *hardware_vectors = (unsigned long *)0x20;
99 static unsigned long hold_vectors[ARM_VECTORS];
100 static int exception_level;
101
102 static void
103 __take_over_debug_traps(void)
104 {
105         hold_vectors[CYGNUM_HAL_VECTOR_ABORT_PREFETCH] = hardware_vectors[CYGNUM_HAL_VECTOR_ABORT_PREFETCH];
106         hardware_vectors[CYGNUM_HAL_VECTOR_ABORT_PREFETCH] = vectors[CYGNUM_HAL_VECTOR_ABORT_PREFETCH];
107         hold_vectors[CYGNUM_HAL_VECTOR_ABORT_DATA] = hardware_vectors[CYGNUM_HAL_VECTOR_ABORT_DATA];
108         hardware_vectors[CYGNUM_HAL_VECTOR_ABORT_DATA] = vectors[CYGNUM_HAL_VECTOR_ABORT_DATA];
109 }
110
111 static void
112 __restore_debug_traps(void)
113 {
114         hardware_vectors[CYGNUM_HAL_VECTOR_ABORT_PREFETCH] = hold_vectors[CYGNUM_HAL_VECTOR_ABORT_PREFETCH];
115         hardware_vectors[CYGNUM_HAL_VECTOR_ABORT_DATA] = hold_vectors[CYGNUM_HAL_VECTOR_ABORT_DATA];
116 }
117 #endif // !CYGPKG_CYGMON
118 #endif
119
120 void
121 exception_handler(HAL_SavedRegisters *regs)
122 {
123         // Special case handler for code which has chosen to take care
124         // of data exceptions (i.e. code which expects them to happen)
125         // This is common in discovery code, e.g. checking for a particular
126         // device which may generate an exception when probing if the
127         // device is not present
128 #ifdef CYGDBG_HAL_DEBUG_GDB_INCLUDE_STUBS
129         if (__mem_fault_handler &&
130                 regs->vector == CYGNUM_HAL_EXCEPTION_DATA_ACCESS) {
131                 regs->pc = (unsigned long)__mem_fault_handler;
132                 return; // Caught an exception inside stubs
133         }
134 #endif
135
136 #if defined(CYGDBG_HAL_DEBUG_GDB_INCLUDE_STUBS) && !defined(CYGPKG_CYGMON)
137         if (++exception_level == 1) __take_over_debug_traps();
138
139         _hal_registers = regs;
140         __handle_exception();
141
142         if (--exception_level == 0) __restore_debug_traps();
143
144 #elif defined(CYGPKG_KERNEL_EXCEPTIONS)
145
146         // We should decode the vector and pass a more appropriate
147         // value as the second argument. For now we simply pass a
148         // pointer to the saved registers. We should also divert
149         // breakpoint and other debug vectors into the debug stubs.
150
151         cyg_hal_deliver_exception( regs->vector, (CYG_ADDRWORD)regs );
152
153 #else
154
155         CYG_FAIL("Exception!!!");
156
157 #endif
158
159         return;
160 }
161
162 void hal_spurious_IRQ(HAL_SavedRegisters *regs) CYGBLD_ATTRIB_WEAK;
163 void
164 hal_spurious_IRQ(HAL_SavedRegisters *regs)
165 {
166 #if defined(CYGDBG_HAL_DEBUG_GDB_INCLUDE_STUBS)
167         exception_handler(regs);
168 #else
169         CYG_FAIL("Spurious interrupt!!");
170 #endif
171 }
172
173 /*------------------------------------------------------------------------*/
174 /* C++ support - run initial constructors                                 */
175
176 #ifdef CYGSEM_HAL_STOP_CONSTRUCTORS_ON_FLAG
177 cyg_bool cyg_hal_stop_constructors;
178 #endif
179
180 typedef void (*pfunc) (void);
181 extern pfunc __CTOR_LIST__[];
182 extern pfunc __CTOR_END__[];
183
184 void
185 cyg_hal_invoke_constructors (void)
186 {
187 #ifdef CYGSEM_HAL_STOP_CONSTRUCTORS_ON_FLAG
188         static pfunc *p = &__CTOR_END__[-1];
189
190         cyg_hal_stop_constructors = 0;
191         for (; p >= __CTOR_LIST__; p--) {
192                 (*p) ();
193                 if (cyg_hal_stop_constructors) {
194                         p--;
195                         break;
196                 }
197         }
198 #else
199         pfunc *p;
200
201         for (p = &__CTOR_END__[-1]; p >= __CTOR_LIST__; p--)
202                 (*p) ();
203 #endif
204 }
205
206 /*------------------------------------------------------------------------*/
207 /* Architecture default ISR                                               */
208
209 externC cyg_uint32
210 hal_arch_default_isr(CYG_ADDRWORD vector, CYG_ADDRWORD data)
211 {
212         CYG_TRACE1(true, "Interrupt: %d", vector);
213
214         CYG_FAIL("Spurious Interrupt!!!");
215         return 0;
216 }
217
218 /*-------------------------------------------------------------------------*/
219 /* Misc functions                                                          */
220
221 #ifdef CYGDBG_HAL_DEBUG_GDB_INCLUDE_STUBS
222 /* This function will generate a breakpoint exception.  It is used at the
223    beginning of a program to sync up with a debugger and can be used
224    otherwise as a quick means to stop program execution and "break" into
225    the debugger. */
226
227 void
228 breakpoint(void)
229 {
230         HAL_BREAKPOINT(_breakinst);
231 }
232
233
234 /* This function returns the opcode for a 'trap' instruction.  */
235
236 unsigned long
237 __break_opcode (void)
238 {
239         return HAL_BREAKINST;
240 }
241 #endif
242
243 int
244 hal_lsbindex(int mask)
245 {
246         int i;
247         for (i = 0;  i < 32;  i++) {
248                 if (mask & (1<<i)) return (i);
249         }
250         return (-1);
251 }
252
253 int
254 hal_msbindex(int mask)
255 {
256         int i;
257         for (i = 31;  i >= 0;  i--) {
258                 if (mask & (1<<i)) return (i);
259         }
260         return (-1);
261 }
262
263 #ifdef  CYGHWR_HAL_ARM_DUMP_EXCEPTIONS
264 void
265 dump_frame(unsigned char *frame)
266 {
267         HAL_SavedRegisters *rp = (HAL_SavedRegisters *)frame;
268         int i;
269         diag_dump_buf(frame, 128);
270         diag_printf("Registers:\n");
271         for (i = 0;  i <= 10;  i++) {
272                 if ((i == 0) || (i == 6)) diag_printf("R%d: ", i);
273                 diag_printf("%08X ", rp->d[i]);
274                 if ((i == 5) || (i == 10)) diag_printf("\n");
275         }
276         diag_printf("FP: %08X, SP: %08X, LR: %08X, PC: %08X, PSR: %08X\n",
277                                 rp->fp, rp->sp, rp->lr, rp->pc, rp->cpsr);
278 }
279 #endif
280
281 #if 0
282 void
283 show_frame_in(HAL_SavedRegisters *frame)
284 {
285         int old;
286         HAL_DISABLE_INTERRUPTS(old);
287         diag_printf("[IN] IRQ Frame:\n");
288         dump_frame((unsigned char *)frame);
289         HAL_RESTORE_INTERRUPTS(old);
290 }
291
292 void
293 show_frame_out(HAL_SavedRegisters *frame)
294 {
295         int old;
296         HAL_DISABLE_INTERRUPTS(old);
297         diag_printf("[OUT] IRQ Frame:\n");
298         dump_frame((unsigned char *)frame);
299         HAL_RESTORE_INTERRUPTS(old);
300 }
301 #endif
302
303 #ifdef  CYGHWR_HAL_ARM_DUMP_EXCEPTIONS
304 // Debug routines
305 void cyg_hal_report_undefined_instruction(HAL_SavedRegisters *frame)
306 {
307         int old;
308         HAL_DISABLE_INTERRUPTS(old);
309         diag_printf("[UNDEFINED INSTRUCTION] Frame:\n");
310         dump_frame((unsigned char *)frame);
311         HAL_RESTORE_INTERRUPTS(old);
312 }
313
314 void cyg_hal_report_software_interrupt(HAL_SavedRegisters *frame)
315 {
316         int old;
317         HAL_DISABLE_INTERRUPTS(old);
318         diag_printf("[SOFTWARE INTERRUPT] Frame:\n");
319         dump_frame((unsigned char *)frame);
320         HAL_RESTORE_INTERRUPTS(old);
321 }
322
323 void cyg_hal_report_abort_prefetch(HAL_SavedRegisters *frame)
324 {
325         int old;
326         HAL_DISABLE_INTERRUPTS(old);
327         diag_printf("[ABORT PREFETCH] Frame:\n");
328         dump_frame((unsigned char *)frame);
329         HAL_RESTORE_INTERRUPTS(old);
330 }
331
332 void cyg_hal_report_abort_data(HAL_SavedRegisters *frame)
333 {
334         int old;
335         HAL_DISABLE_INTERRUPTS(old);
336         diag_printf("[ABORT DATA] Frame:\n");
337         dump_frame((unsigned char *)frame);
338         HAL_RESTORE_INTERRUPTS(old);
339 }
340
341 void cyg_hal_report_exception_handler_returned(HAL_SavedRegisters *frame)
342 {
343         int old;
344         HAL_DISABLE_INTERRUPTS(old);
345         diag_printf("Exception handler returned!\n");
346         dump_frame((unsigned char *)frame);
347         HAL_RESTORE_INTERRUPTS(old);
348 }
349 #endif
350
351 /*------------------------------------------------------------------------*/
352 // EOF hal_misc.c