• Home
  • History
  • Annotate
  • Line#
  • Navigate
  • Raw
  • Download
  • only in /asuswrt-rt-n18u-9.0.0.4.380.2695/release/src-rt-6.x.4708/cfe/cfe/arch/arm/common/src/
1/*  *********************************************************************
2    *  Broadcom Common Firmware Environment (CFE)
3    *
4    *  Exception Handler			File: exchandler.c
5    *
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.
9    *
10    *  Author:
11    *
12    *********************************************************************
13    *
14    *  Copyright 2000,2001,2002,2003
15    *  Broadcom Corporation. All rights reserved.
16    *
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.
23    *
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.
27    *
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.
33    *
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    ********************************************************************* */
48
49
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"
57#include "cfe.h"
58#include "cfe_error.h"
59#include "cfe_iocb.h"
60#include "exchandler.h"
61#include "cpu_config.h"
62#include "bsp_config.h"
63
64/*  *********************************************************************
65    *  Constants
66    ********************************************************************* */
67
68/*  *********************************************************************
69    *  Globals
70    ********************************************************************* */
71
72exc_handler_t exc_handler;
73//extern void _exc_entry(void);
74//extern void _exc_setup_locore(long);
75extern void CPUCFG_TLBHANDLER(void);
76extern void cfe_flushcache(uint32_t,long,long);
77extern uint32_t _getstatus(void);
78extern void _setstatus(uint32_t);
79
80
81/*  *********************************************************************
82    *  cfe_exception(code,info)
83    *
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
87    *  reboot.
88    *
89    *  Input parameters:
90    *  	   code - exception type
91    *  	   info - exception stack frame
92    *
93    *  Return value:
94    *  	   usually reboots
95    ********************************************************************* */
96void cfe_exception(trap_t *tr)
97{
98	/*
99	 * ARM7TDMI trap types:
100	 *	0=RST, 1=UND, 2=SWI, 3=IAB, 4=DAB, 5=BAD, 6=IRQ, 7=FIQ
101	 *
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
105 	 *
106	 * ARM CA9 trap types:
107	 *	0=RST, 1=UND, 2=SWI, 3=IAB, 4=DAB, 5=BAD, 6=IRQ, 7=FIQ
108	 */
109
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";
113
114	if (tr->type < 8)
115		type_str = tr_type_str[tr->type];
116
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);
124
125	/*
126	 * stack content before trap occured
127	 */
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]);
132
133	xprintf("\n");
134	_exc_restart();
135}
136
137/*  *********************************************************************
138    *  cfe_setup_exceptions()
139    *
140    *  Set up the exception handlers.
141    *
142    *  Input parameters:
143    *  	   nothing
144    *
145    *  Return value:
146    *  	   nothing
147    ********************************************************************* */
148void cfe_setup_exceptions(void)
149{
150	/* Set trap handler */
151	hndrte_set_trap((uint32)cfe_exception);
152}
153
154
155/*  *********************************************************************
156    *  exc_initialize_block()
157    *
158    *  Set up the exception handler.  Allow exceptions to be caught.
159    *  Allocate memory for jmpbuf and store it away.
160    *
161    *  Returns NULL if error in memory allocation.
162    *
163    *  Input parameters:
164    *  	   nothing
165    *
166    *  Return value:
167    *  	   jmpbuf_t structure, or NULL if no memory
168    ********************************************************************* */
169jmpbuf_t *exc_initialize_block(void)
170{
171    jmpbuf_t *jmpbuf_local;
172
173    exc_handler.catch_exc = 1;
174
175    /* Create the jmpbuf_t object */
176    jmpbuf_local = (jmpbuf_t *) KMALLOC((sizeof(jmpbuf_t)),0);
177
178    if (jmpbuf_local == NULL) {
179	return NULL;
180	}
181
182    q_enqueue( &(exc_handler.jmpbuf_stack), &((*jmpbuf_local).stack));
183
184    return jmpbuf_local;
185}
186
187/*  *********************************************************************
188    *  exc_cleanup_block(dq_jmpbuf)
189    *
190    *  Remove dq_jmpbuf from the exception handler stack and free
191    *  the memory.
192    *
193    *  Input parameters:
194    *  	   dq_jmpbuf - block to deallocate
195    *
196    *  Return value:
197    *  	   nothing
198    ********************************************************************* */
199
200void exc_cleanup_block(jmpbuf_t *dq_jmpbuf)
201{
202    int count;
203
204    if (dq_jmpbuf == NULL) {
205	return;
206	}
207
208    count = q_count( &(exc_handler.jmpbuf_stack));
209
210    if( count > 0 ) {
211	q_dequeue( &(*dq_jmpbuf).stack );
212	KFREE(dq_jmpbuf);
213	}
214}
215
216/*  *********************************************************************
217    *  exc_cleanup_handler(dq_jmpbuf,chain_exc)
218    *
219    *  Clean a block, then chain to the next exception if required.
220    *
221    *  Input parameters:
222    *  	   dq_jmpbuf - current exception
223    *  	   chain_exc - true if we should chain to the next handler
224    *
225    *  Return value:
226    *  	   nothing
227    ********************************************************************* */
228
229void exc_cleanup_handler(jmpbuf_t *dq_jmpbuf, int chain_exc)
230{
231    exc_cleanup_block(dq_jmpbuf);
232
233    if( chain_exc == EXC_CHAIN_EXC ) {
234	/*Go to next exception on stack */
235	exc_longjmp_handler();
236	}
237}
238
239
240
241/*  *********************************************************************
242    *  exc_longjmp_handler()
243    *
244    *  This routine long jumps to the exception handler on the top
245    *  of the exception stack.
246    *
247    *  Input parameters:
248    *  	   nothing
249    *
250    *  Return value:
251    *  	   nothing
252    ********************************************************************* */
253void exc_longjmp_handler(void)
254{
255    int count;
256    jmpbuf_t *jmpbuf_local;
257
258    count = q_count( &(exc_handler.jmpbuf_stack));
259
260    if( count > 0 ) {
261	jmpbuf_local = (jmpbuf_t *) q_getlast(&(exc_handler.jmpbuf_stack));
262
263	SETLEDS("CFE ");
264
265	lib_longjmp( (*jmpbuf_local).jmpbuf, -1);
266	}
267}
268
269
270/*  *********************************************************************
271    *  mem_peek(d,addr,type)
272    *
273    *  Read memory of the specified type at the specified address.
274    *  Exceptions are caught in the case of a bad memory reference.
275    *
276    *  Input parameters:
277    *  	   d - pointer to where data should be placed
278    *  	   addr - address to read
279    *  	   type - type of read to do (MEM_BYTE, etc.)
280    *
281    *  Return value:
282    *  	   0 if ok
283    *  	   else error code
284    ********************************************************************* */
285
286int mem_peek(void *d, long addr, int type)
287{
288
289    jmpbuf_t *jb;
290
291    jb = exc_initialize_block();
292    if( jb == NULL ) {
293	return CFE_ERR_NOMEM;
294	}
295
296    if (exc_try(jb) == 0) {
297
298	switch (type) {
299	    case MEM_BYTE:
300		*(uint8_t *)d = *((volatile uint8_t *) addr);
301		break;
302	    case MEM_HALFWORD:
303		*(uint16_t *)d = *((volatile uint16_t *) addr);
304		break;
305	    case MEM_WORD:
306		*(uint32_t *)d = *((volatile uint32_t *) addr);
307		break;
308	    case MEM_QUADWORD:
309		*(uint64_t *)d = *((volatile uint64_t *) addr);
310		break;
311	    default:
312		return CFE_ERR_INV_PARAM;
313	    }
314
315	exc_cleanup_block(jb);
316	}
317    else {
318	/*Exception handler*/
319
320	exc_cleanup_handler(jb, EXC_NORMAL_RETURN);
321	return CFE_ERR_GETMEM;
322	}
323
324    return 0;
325}
326
327/* *********************************************************************
328   *  Write memory of type at address addr with value val.
329   *  Exceptions are caught, handled (error message) and function
330   *  returns with 0.
331   *
332   *  1 success
333   *  0 failure
334   ********************************************************************* */
335
336int mem_poke(long addr, uint64_t val, int type)
337{
338
339    jmpbuf_t *jb;
340
341    jb = exc_initialize_block();
342    if( jb == NULL ) {
343	return CFE_ERR_NOMEM;
344	}
345
346    if (exc_try(jb) == 0) {
347
348	switch (type) {
349	    case MEM_BYTE:
350		*((volatile uint8_t *) addr) = (uint8_t) val;
351		break;
352	    case MEM_HALFWORD:
353		*((volatile uint16_t *) addr) = (uint16_t) val;
354		break;
355	    case MEM_WORD:
356		*((volatile uint32_t *) addr) = (uint32_t) val;
357		break;
358	    case MEM_QUADWORD:
359		*((volatile uint64_t *) addr) = (uint64_t) val;
360		break;
361	    default:
362		return CFE_ERR_INV_PARAM;
363	    }
364
365	exc_cleanup_block(jb);
366	}
367    else {
368	/*Exception handler*/
369
370	exc_cleanup_handler(jb, EXC_NORMAL_RETURN);
371	return CFE_ERR_SETMEM;
372	}
373
374    return 0;
375}
376