1 /* *********************************************************************
2 * Broadcom Common Firmware Environment (CFE)
4 * Exception Handler File: exchandler.c
6 * This is the "C" part of the exception handler and the
7 * associated setup routines. We call these routines from
8 * the assembly-language exception handler.
12 *********************************************************************
14 * Copyright 2000,2001,2002,2003
15 * Broadcom Corporation. All rights reserved.
17 * This software is furnished under license and may be used and
18 * copied only in accordance with the following terms and
19 * conditions. Subject to these conditions, you may download,
20 * copy, install, use, modify and distribute modified or unmodified
21 * copies of this software in source and/or binary form. No title
22 * or ownership is transferred hereby.
24 * 1) Any source code used, modified or distributed must reproduce
25 * and retain this copyright notice and list of conditions
26 * as they appear in the source file.
28 * 2) No right is granted to use any trade name, trademark, or
29 * logo of Broadcom Corporation. The "Broadcom Corporation"
30 * name may not be used to endorse or promote products derived
31 * from this software without the prior written permission of
32 * Broadcom Corporation.
34 * 3) THIS SOFTWARE IS PROVIDED "AS-IS" AND ANY EXPRESS OR
35 * IMPLIED WARRANTIES, INCLUDING BUT NOT LIMITED TO, ANY IMPLIED
36 * WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
37 * PURPOSE, OR NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT
38 * SHALL BROADCOM BE LIABLE FOR ANY DAMAGES WHATSOEVER, AND IN
39 * PARTICULAR, BROADCOM SHALL NOT BE LIABLE FOR DIRECT, INDIRECT,
40 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
41 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
42 * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
43 * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
44 * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR
45 * TORT (INCLUDING NEGLIGENCE OR OTHERWISE), EVEN IF ADVISED OF
46 * THE POSSIBILITY OF SUCH DAMAGE.
47 ********************************************************************* */
50 #include "lib_types.h"
51 #include "lib_string.h"
52 #include "lib_printf.h"
53 #include "lib_queue.h"
54 #include "lib_malloc.h"
55 #include <hndrte_armtrap.h>
56 #include "exception.h"
58 #include "cfe_error.h"
60 #include "exchandler.h"
61 #include "cpu_config.h"
62 #include "bsp_config.h"
64 /* *********************************************************************
66 ********************************************************************* */
68 /* *********************************************************************
70 ********************************************************************* */
72 exc_handler_t exc_handler
;
73 //extern void _exc_entry(void);
74 //extern void _exc_setup_locore(long);
75 extern void CPUCFG_TLBHANDLER(void);
76 extern void cfe_flushcache(uint32_t,long,long);
77 extern uint32_t _getstatus(void);
78 extern void _setstatus(uint32_t);
81 /* *********************************************************************
82 * cfe_exception(code,info)
84 * Exception handler. This routine is called when any CPU
85 * exception that is handled by the assembly-language
86 * vectors is reached. The usual thing to do here is just to
90 * code - exception type
91 * info - exception stack frame
95 ********************************************************************* */
96 void cfe_exception(trap_t
*tr
)
99 * ARM7TDMI trap types:
100 * 0=RST, 1=UND, 2=SWI, 3=IAB, 4=DAB, 5=BAD, 6=IRQ, 7=FIQ
102 * ARM CM3 trap types:
103 * 1=RST, 2=NMI, 3=FAULT, 4=MM, 5=BUS, 6=USAGE, 11=SVC,
104 * 12=DMON, 14=PENDSV, 15=SYSTICK, 16+=ISR
106 * ARM CA9 trap types:
107 * 0=RST, 1=UND, 2=SWI, 3=IAB, 4=DAB, 5=BAD, 6=IRQ, 7=FIQ
110 uint32
*stack
= (uint32
*)tr
->r13
;
111 char *tr_type_str
[8] = {"RST", "UND", "SWI", "IAB", "DAB", "BAD", "IRQ", "FIQ"};
112 char *type_str
= "UKN";
115 type_str
= tr_type_str
[tr
->type
];
117 /* Note that UTF parses the first line, so the format should not be changed. */
118 printf("\nTRAP [%s](x)[%x]: pc[%x], lr[%x], sp[%x], cpsr[%x], spsr[%x]\n",
119 type_str
, tr
->type
, (uint32
)tr
, tr
->pc
, tr
->r14
, tr
->r13
, tr
->cpsr
, tr
->spsr
);
120 printf(" r0[%x], r1[%x], r2[%x], r3[%x], r4[%x], r5[%x], r6[%x]\n",
121 tr
->r0
, tr
->r1
, tr
->r2
, tr
->r3
, tr
->r4
, tr
->r5
, tr
->r6
);
122 printf(" r7[%x], r8[%x], r9[%x], r10[%x], r11[%x], r12[%x]\n",
123 tr
->r7
, tr
->r8
, tr
->r9
, tr
->r10
, tr
->r11
, tr
->r12
);
126 * stack content before trap occured
128 printf("\n sp+0 %08x %08x %08x %08x\n",
129 stack
[0], stack
[1], stack
[2], stack
[3]);
130 printf(" sp+10 %08x %08x %08x %08x\n\n",
131 stack
[4], stack
[5], stack
[6], stack
[7]);
137 /* *********************************************************************
138 * cfe_setup_exceptions()
140 * Set up the exception handlers.
147 ********************************************************************* */
148 void cfe_setup_exceptions(void)
150 /* Set trap handler */
151 hndrte_set_trap((uint32
)cfe_exception
);
155 /* *********************************************************************
156 * exc_initialize_block()
158 * Set up the exception handler. Allow exceptions to be caught.
159 * Allocate memory for jmpbuf and store it away.
161 * Returns NULL if error in memory allocation.
167 * jmpbuf_t structure, or NULL if no memory
168 ********************************************************************* */
169 jmpbuf_t
*exc_initialize_block(void)
171 jmpbuf_t
*jmpbuf_local
;
173 exc_handler
.catch_exc
= 1;
175 /* Create the jmpbuf_t object */
176 jmpbuf_local
= (jmpbuf_t
*) KMALLOC((sizeof(jmpbuf_t
)),0);
178 if (jmpbuf_local
== NULL
) {
182 q_enqueue( &(exc_handler
.jmpbuf_stack
), &((*jmpbuf_local
).stack
));
187 /* *********************************************************************
188 * exc_cleanup_block(dq_jmpbuf)
190 * Remove dq_jmpbuf from the exception handler stack and free
194 * dq_jmpbuf - block to deallocate
198 ********************************************************************* */
200 void exc_cleanup_block(jmpbuf_t
*dq_jmpbuf
)
204 if (dq_jmpbuf
== NULL
) {
208 count
= q_count( &(exc_handler
.jmpbuf_stack
));
211 q_dequeue( &(*dq_jmpbuf
).stack
);
216 /* *********************************************************************
217 * exc_cleanup_handler(dq_jmpbuf,chain_exc)
219 * Clean a block, then chain to the next exception if required.
222 * dq_jmpbuf - current exception
223 * chain_exc - true if we should chain to the next handler
227 ********************************************************************* */
229 void exc_cleanup_handler(jmpbuf_t
*dq_jmpbuf
, int chain_exc
)
231 exc_cleanup_block(dq_jmpbuf
);
233 if( chain_exc
== EXC_CHAIN_EXC
) {
234 /*Go to next exception on stack */
235 exc_longjmp_handler();
241 /* *********************************************************************
242 * exc_longjmp_handler()
244 * This routine long jumps to the exception handler on the top
245 * of the exception stack.
252 ********************************************************************* */
253 void exc_longjmp_handler(void)
256 jmpbuf_t
*jmpbuf_local
;
258 count
= q_count( &(exc_handler
.jmpbuf_stack
));
261 jmpbuf_local
= (jmpbuf_t
*) q_getlast(&(exc_handler
.jmpbuf_stack
));
265 lib_longjmp( (*jmpbuf_local
).jmpbuf
, -1);
270 /* *********************************************************************
271 * mem_peek(d,addr,type)
273 * Read memory of the specified type at the specified address.
274 * Exceptions are caught in the case of a bad memory reference.
277 * d - pointer to where data should be placed
278 * addr - address to read
279 * type - type of read to do (MEM_BYTE, etc.)
284 ********************************************************************* */
286 int mem_peek(void *d
, long addr
, int type
)
291 jb
= exc_initialize_block();
293 return CFE_ERR_NOMEM
;
296 if (exc_try(jb
) == 0) {
300 *(uint8_t *)d
= *((volatile uint8_t *) addr
);
303 *(uint16_t *)d
= *((volatile uint16_t *) addr
);
306 *(uint32_t *)d
= *((volatile uint32_t *) addr
);
309 *(uint64_t *)d
= *((volatile uint64_t *) addr
);
312 return CFE_ERR_INV_PARAM
;
315 exc_cleanup_block(jb
);
318 /*Exception handler*/
320 exc_cleanup_handler(jb
, EXC_NORMAL_RETURN
);
321 return CFE_ERR_GETMEM
;
327 /* *********************************************************************
328 * Write memory of type at address addr with value val.
329 * Exceptions are caught, handled (error message) and function
334 ********************************************************************* */
336 int mem_poke(long addr
, uint64_t val
, int type
)
341 jb
= exc_initialize_block();
343 return CFE_ERR_NOMEM
;
346 if (exc_try(jb
) == 0) {
350 *((volatile uint8_t *) addr
) = (uint8_t) val
;
353 *((volatile uint16_t *) addr
) = (uint16_t) val
;
356 *((volatile uint32_t *) addr
) = (uint32_t) val
;
359 *((volatile uint64_t *) addr
) = (uint64_t) val
;
362 return CFE_ERR_INV_PARAM
;
365 exc_cleanup_block(jb
);
368 /*Exception handler*/
370 exc_cleanup_handler(jb
, EXC_NORMAL_RETURN
);
371 return CFE_ERR_SETMEM
;