1/*  *********************************************************************
2    *  Broadcom Common Firmware Environment (CFE)
3    *
4    *  "catch" and "throw" stuff		File: lib_try.c
5    *
6    *  Try/Except routines - a crude exception catcher that we can
7    *  use to deal with bus errors and other stuff.
8    *
9    *  Author:  Binh Vo, Mitch Lichtenberg
10    *
11    *********************************************************************
12    *
13    *  Copyright 2000,2001,2002,2003
14    *  Broadcom Corporation. All rights reserved.
15    *
16    *  This software is furnished under license and may be used and
17    *  copied only in accordance with the following terms and
18    *  conditions.  Subject to these conditions, you may download,
19    *  copy, install, use, modify and distribute modified or unmodified
20    *  copies of this software in source and/or binary form.  No title
21    *  or ownership is transferred hereby.
22    *
23    *  1) Any source code used, modified or distributed must reproduce
24    *     and retain this copyright notice and list of conditions
25    *     as they appear in the source file.
26    *
27    *  2) No right is granted to use any trade name, trademark, or
28    *     logo of Broadcom Corporation.  The "Broadcom Corporation"
29    *     name may not be used to endorse or promote products derived
30    *     from this software without the prior written permission of
31    *     Broadcom Corporation.
32    *
33    *  3) THIS SOFTWARE IS PROVIDED "AS-IS" AND ANY EXPRESS OR
34    *     IMPLIED WARRANTIES, INCLUDING BUT NOT LIMITED TO, ANY IMPLIED
35    *     WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
36    *     PURPOSE, OR NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT
37    *     SHALL BROADCOM BE LIABLE FOR ANY DAMAGES WHATSOEVER, AND IN
38    *     PARTICULAR, BROADCOM SHALL NOT BE LIABLE FOR DIRECT, INDIRECT,
39    *     INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
40    *     (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
41    *     GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
42    *     BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
43    *     OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR
44    *     TORT (INCLUDING NEGLIGENCE OR OTHERWISE), EVEN IF ADVISED OF
45    *     THE POSSIBILITY OF SUCH DAMAGE.
46    ********************************************************************* */
47
48#include "lib_types.h"
49#include "lib_queue.h"
50#include "lib_malloc.h"
51#include "lib_setjmp.h"
52#include "lib_try.h"
53
54exc_handler_t exc_handler;
55
56
57/*  *********************************************************************
58    *  exc_initialize_block()
59    *
60    *  Set up the exception handler.  Allow exceptions to be caught.
61    *  Allocate memory for jmpbuf and store it away.
62    *
63    *  Returns NULL if error in memory allocation.
64    *
65    *  Input parameters:
66    *  	   nothing
67    *
68    *  Return value:
69    *  	   jmpbuf_t structure, or NULL if no memory
70    ********************************************************************* */
71jmpbuf_t *exc_initialize_block(void)
72{
73    jmpbuf_t *jmpbuf_local;
74
75    exc_handler.catch_exc = 1;
76
77    /* Create the jmpbuf_t object */
78    jmpbuf_local = (jmpbuf_t *) KMALLOC((sizeof(jmpbuf_t)),0);
79
80    if (jmpbuf_local == NULL) {
81	return NULL;
82	}
83
84    q_enqueue( &(exc_handler.jmpbuf_stack), &((*jmpbuf_local).stack));
85
86    return jmpbuf_local;
87}
88
89/*  *********************************************************************
90    *  exc_cleanup_block(dq_jmpbuf)
91    *
92    *  Remove dq_jmpbuf from the exception handler stack and free
93    *  the memory.
94    *
95    *  Input parameters:
96    *  	   dq_jmpbuf - block to deallocate
97    *
98    *  Return value:
99    *  	   nothing
100    ********************************************************************* */
101
102void exc_cleanup_block(jmpbuf_t *dq_jmpbuf)
103{
104    int count;
105
106    if (dq_jmpbuf == NULL) {
107	return;
108	}
109
110    count = q_count( &(exc_handler.jmpbuf_stack));
111
112    if( count > 0 ) {
113	q_dequeue( &(*dq_jmpbuf).stack );
114	KFREE(dq_jmpbuf);
115	}
116}
117
118/*  *********************************************************************
119    *  exc_cleanup_handler(dq_jmpbuf,chain_exc)
120    *
121    *  Clean a block, then chain to the next exception if required.
122    *
123    *  Input parameters:
124    *  	   dq_jmpbuf - current exception
125    *  	   chain_exc - true if we should chain to the next handler
126    *
127    *  Return value:
128    *  	   nothing
129    ********************************************************************* */
130
131void exc_cleanup_handler(jmpbuf_t *dq_jmpbuf, int chain_exc)
132{
133    exc_cleanup_block(dq_jmpbuf);
134
135    if( chain_exc == EXC_CHAIN_EXC ) {
136	/*Go to next exception on stack */
137	exc_longjmp_handler();
138	}
139}
140
141
142
143/*  *********************************************************************
144    *  exc_longjmp_handler()
145    *
146    *  This routine long jumps to the exception handler on the top
147    *  of the exception stack.
148    *
149    *  Input parameters:
150    *  	   nothing
151    *
152    *  Return value:
153    *  	   nothing
154    ********************************************************************* */
155void exc_longjmp_handler(void)
156{
157    int count;
158    jmpbuf_t *jmpbuf_local;
159
160    count = q_count( &(exc_handler.jmpbuf_stack));
161
162    if( count > 0 ) {
163	jmpbuf_local = (jmpbuf_t *) q_getlast(&(exc_handler.jmpbuf_stack));
164
165	lib_longjmp( (*jmpbuf_local).jmpbuf, -1);
166	}
167}
168