Mercurial > ecos
annotate packages/kernel/current/src/common/except.cxx @ 208:e0c0827131d1 ecos
Merge from eCos master repository on 2002-05-20-20:11:54-BST
| author | jlarmour |
|---|---|
| date | Mon, 20 May 2002 22:19:26 +0000 |
| parents | bf00f99aec69 |
| children | d2c90368aeef |
| rev | line source |
|---|---|
| 0 | 1 //========================================================================== |
| 2 // | |
| 2 | 3 // common/except.cxx |
| 0 | 4 // |
| 2 | 5 // Exception handling implementation |
| 0 | 6 // |
| 7 //========================================================================== | |
|
208
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
66
diff
changeset
|
8 //####ECOSGPLCOPYRIGHTBEGIN#### |
|
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
66
diff
changeset
|
9 // ------------------------------------------- |
|
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
66
diff
changeset
|
10 // This file is part of eCos, the Embedded Configurable Operating System. |
|
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
66
diff
changeset
|
11 // Copyright (C) 1998, 1999, 2000, 2001, 2002 Red Hat, Inc. |
|
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
66
diff
changeset
|
12 // |
|
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
66
diff
changeset
|
13 // eCos is free software; you can redistribute it and/or modify it under |
|
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
66
diff
changeset
|
14 // the terms of the GNU General Public License as published by the Free |
|
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
66
diff
changeset
|
15 // Software Foundation; either version 2 or (at your option) any later version. |
|
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
66
diff
changeset
|
16 // |
|
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
66
diff
changeset
|
17 // eCos is distributed in the hope that it will be useful, but WITHOUT ANY |
|
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
66
diff
changeset
|
18 // WARRANTY; without even the implied warranty of MERCHANTABILITY or |
|
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
66
diff
changeset
|
19 // FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License |
|
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
66
diff
changeset
|
20 // for more details. |
|
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
66
diff
changeset
|
21 // |
|
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
66
diff
changeset
|
22 // You should have received a copy of the GNU General Public License along |
|
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
66
diff
changeset
|
23 // with eCos; if not, write to the Free Software Foundation, Inc., |
|
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
66
diff
changeset
|
24 // 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. |
|
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
66
diff
changeset
|
25 // |
|
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
66
diff
changeset
|
26 // As a special exception, if other files instantiate templates or use macros |
|
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
66
diff
changeset
|
27 // or inline functions from this file, or you compile this file and link it |
|
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
66
diff
changeset
|
28 // with other works to produce a work based on this file, this file does not |
|
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
66
diff
changeset
|
29 // by itself cause the resulting work to be covered by the GNU General Public |
|
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
66
diff
changeset
|
30 // License. However the source code for this file must still be made available |
|
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
66
diff
changeset
|
31 // in accordance with section (3) of the GNU General Public License. |
|
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
66
diff
changeset
|
32 // |
|
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
66
diff
changeset
|
33 // This exception does not invalidate any other reasons why a work based on |
|
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
66
diff
changeset
|
34 // this file might be covered by the GNU General Public License. |
|
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
66
diff
changeset
|
35 // |
|
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
66
diff
changeset
|
36 // Alternative licenses for eCos may be arranged by contacting Red Hat, Inc. |
|
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
66
diff
changeset
|
37 // at http://sources.redhat.com/ecos/ecos-license |
|
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
66
diff
changeset
|
38 // ------------------------------------------- |
|
e0c0827131d1
Merge from eCos master repository on 2002-05-20-20:11:54-BST
jlarmour
parents:
66
diff
changeset
|
39 //####ECOSGPLCOPYRIGHTEND#### |
| 0 | 40 //========================================================================== |
| 41 //#####DESCRIPTIONBEGIN#### | |
| 42 // | |
| 2 | 43 // Author(s): nickg |
| 44 // Contributors: nickg, jlarmour | |
| 45 // Date: 1999-02-16 | |
| 46 // Purpose: Exception handling implementation | |
| 47 // Description: This file contains the code that registers and delivers | |
| 48 // exceptions. | |
| 0 | 49 // |
| 50 //####DESCRIPTIONEND#### | |
| 51 // | |
| 52 //========================================================================== | |
| 53 | |
| 54 #include <pkgconf/kernel.h> | |
| 55 | |
| 56 #include <cyg/kernel/ktypes.h> // base kernel types | |
| 57 #include <cyg/infra/cyg_trac.h> // tracing macros | |
| 58 #include <cyg/infra/cyg_ass.h> // assertion macros | |
| 59 #include <cyg/kernel/instrmnt.h> // instrumentation | |
| 60 | |
| 61 #include <cyg/kernel/except.hxx> // our header | |
| 62 | |
| 63 #include <cyg/hal/hal_arch.h> // architecture definitions | |
| 64 #include <cyg/hal/hal_intr.h> // vector definitions | |
| 65 | |
| 66 #include <cyg/kernel/thread.hxx> // thread interface | |
| 67 | |
| 68 #include <cyg/kernel/thread.inl> // thread inlines | |
| 69 | |
| 70 #ifdef CYGPKG_KERNEL_EXCEPTIONS | |
| 71 | |
| 72 // ------------------------------------------------------------------------- | |
| 73 // Null exception handler. This is used to capture exceptions that are | |
| 74 // not caught by user supplied handlers. | |
| 75 | |
| 2 | 76 void |
| 77 cyg_null_exception_handler( | |
| 0 | 78 CYG_ADDRWORD data, // user supplied data |
| 79 cyg_code exception_number, // exception being raised | |
| 80 CYG_ADDRWORD exception_info // any exception specific info | |
| 81 ) | |
| 82 { | |
| 2 | 83 CYG_REPORT_FUNCTION(); |
| 84 CYG_REPORT_FUNCARG3("data=%08x, exception=%d, info=%08x", data, | |
| 85 exception_number, exception_info); | |
| 0 | 86 CYG_TRACE1( 1, "Uncaught exception: %d", exception_number); |
| 2 | 87 CYG_REPORT_RETURN(); |
| 0 | 88 } |
| 89 | |
| 90 // ------------------------------------------------------------------------- | |
| 91 // Exception Controller constructor. | |
| 92 | |
| 93 Cyg_Exception_Control::Cyg_Exception_Control() | |
| 94 { | |
| 2 | 95 CYG_REPORT_FUNCTION(); |
| 0 | 96 #ifdef CYGSEM_KERNEL_EXCEPTIONS_DECODE |
| 97 | |
| 2 | 98 for( int i = 0; i < CYGNUM_HAL_EXCEPTION_COUNT ; i++ ) |
| 0 | 99 exception_handler[i] = cyg_null_exception_handler, |
| 100 exception_data[i] = 0; | |
| 101 #else | |
| 102 | |
| 103 exception_handler = cyg_null_exception_handler; | |
| 104 exception_data = 0; | |
| 105 | |
| 106 #endif | |
| 2 | 107 CYG_REPORT_RETURN(); |
| 0 | 108 } |
| 109 | |
| 110 // ------------------------------------------------------------------------- | |
| 111 // Exception registation. Stores the handler function and data to be used | |
| 112 // for handling the given exception number. Where exceptions are not decoded | |
| 113 // only a single handler may be registered for all exceptions. This function | |
| 114 // also returns the old values of the exception handler and data to allow | |
| 115 // chaining to be implemented. | |
| 116 | |
| 2 | 117 void |
| 118 Cyg_Exception_Control::register_exception( | |
| 0 | 119 cyg_code exception_number, // exception number |
| 120 cyg_exception_handler handler, // handler function | |
| 121 CYG_ADDRWORD data, // data argument | |
| 122 cyg_exception_handler **old_handler, // handler function | |
| 123 CYG_ADDRWORD *old_data // data argument | |
| 124 ) | |
| 125 { | |
| 126 CYG_REPORT_FUNCTION(); | |
| 2 | 127 CYG_REPORT_FUNCARG5("exception=%d, handler func=%08x, data=%08x, " |
| 128 "space for old handler=%08x,space for old data=%08x", | |
| 129 exception_number, handler, data, old_handler, | |
| 130 old_data); | |
| 0 | 131 |
| 2 | 132 CYG_ASSERT( exception_number <= CYGNUM_HAL_EXCEPTION_MAX, |
| 0 | 133 "Out of range exception number"); |
| 2 | 134 CYG_ASSERT( exception_number >= CYGNUM_HAL_EXCEPTION_MIN, |
| 0 | 135 "Out of range exception number"); |
| 136 | |
| 137 | |
| 138 // Should we complain if there is already a registered | |
| 139 // handler, or should we just replace is silently? | |
| 140 | |
| 141 #ifdef CYGSEM_KERNEL_EXCEPTIONS_DECODE | |
| 142 | |
| 143 if( old_handler != NULL ) | |
| 2 | 144 *old_handler = exception_handler[exception_number - |
| 145 CYGNUM_HAL_EXCEPTION_MIN]; | |
| 0 | 146 if( old_data != NULL ) |
| 2 | 147 *old_data = exception_data[exception_number - |
| 148 CYGNUM_HAL_EXCEPTION_MIN]; | |
| 149 exception_handler[exception_number - CYGNUM_HAL_EXCEPTION_MIN] = handler; | |
| 150 exception_data[exception_number - CYGNUM_HAL_EXCEPTION_MIN] = data; | |
| 0 | 151 |
| 152 #else | |
| 153 | |
| 154 if( old_handler != NULL ) | |
| 155 *old_handler = exception_handler; | |
| 156 if( old_data != NULL ) | |
| 157 *old_data = exception_data; | |
| 158 exception_handler = handler; | |
| 159 exception_data = data; | |
| 160 | |
| 161 #endif | |
| 2 | 162 CYG_REPORT_RETURN(); |
| 0 | 163 } |
| 164 | |
| 165 // ------------------------------------------------------------------------- | |
| 166 // Exception deregistation. Revert the handler for the exception number | |
| 167 // to the default. | |
| 168 | |
| 2 | 169 void |
| 170 Cyg_Exception_Control::deregister_exception( | |
| 0 | 171 cyg_code exception_number // exception number |
| 172 ) | |
| 173 { | |
| 174 CYG_REPORT_FUNCTION(); | |
| 2 | 175 CYG_REPORT_FUNCARG1("exception number=%d", exception_number); |
| 0 | 176 |
| 2 | 177 CYG_ASSERT( exception_number <= CYGNUM_HAL_EXCEPTION_MAX, |
| 0 | 178 "Out of range exception number"); |
| 2 | 179 CYG_ASSERT( exception_number >= CYGNUM_HAL_EXCEPTION_MIN, |
| 0 | 180 "Out of range exception number"); |
| 181 | |
| 182 #ifdef CYGSEM_KERNEL_EXCEPTIONS_DECODE | |
| 183 | |
| 2 | 184 exception_handler[exception_number - CYGNUM_HAL_EXCEPTION_MIN] = |
| 185 cyg_null_exception_handler; | |
| 186 exception_data[exception_number - CYGNUM_HAL_EXCEPTION_MIN] = 0; | |
| 0 | 187 |
| 188 #else | |
| 189 | |
| 190 exception_handler = cyg_null_exception_handler; | |
| 191 exception_data = 0; | |
| 192 | |
| 193 #endif | |
| 2 | 194 |
| 195 CYG_REPORT_RETURN(); | |
| 0 | 196 } |
| 197 | |
| 198 // ------------------------------------------------------------------------- | |
| 199 // Exception delivery. Call the appropriate exception handler. | |
| 200 | |
| 2 | 201 void |
| 202 Cyg_Exception_Control::deliver_exception( | |
| 0 | 203 cyg_code exception_number, // exception being raised |
| 204 CYG_ADDRWORD exception_info // exception specific info | |
| 205 ) | |
| 206 { | |
| 2 | 207 CYG_REPORT_FUNCTION(); |
| 208 CYG_REPORT_FUNCARG2("exception number=%d, exception info=%08x", | |
| 209 exception_number, exception_info); | |
| 210 | |
| 0 | 211 cyg_exception_handler *handler = NULL; |
| 212 CYG_ADDRWORD data = 0; | |
| 213 | |
| 2 | 214 CYG_ASSERT( exception_number <= CYGNUM_HAL_EXCEPTION_MAX, |
| 0 | 215 "Out of range exception number"); |
| 2 | 216 CYG_ASSERT( exception_number >= CYGNUM_HAL_EXCEPTION_MIN, |
| 0 | 217 "Out of range exception number"); |
| 218 | |
| 219 #ifdef CYGSEM_KERNEL_EXCEPTIONS_DECODE | |
| 220 | |
| 2 | 221 handler = exception_handler[exception_number - CYGNUM_HAL_EXCEPTION_MIN]; |
| 222 data = exception_data[exception_number - CYGNUM_HAL_EXCEPTION_MIN]; | |
| 0 | 223 |
| 224 #else | |
| 225 | |
| 226 handler = exception_handler; | |
| 227 data = exception_data; | |
| 228 | |
| 229 #endif | |
| 230 | |
| 231 // The handler will always be a callable function: either the user's | |
| 232 // registered function or the null handler. So it is always safe to | |
| 233 // just go ahead and call it. | |
| 234 | |
| 235 handler( data, exception_number, exception_info ); | |
| 2 | 236 |
| 237 CYG_REPORT_RETURN(); | |
| 0 | 238 } |
| 239 | |
| 240 // ------------------------------------------------------------------------- | |
| 241 // Exception delivery function called from the HAL as a result of a | |
| 242 // hardware exception being raised. | |
| 243 | |
| 2 | 244 externC void |
| 245 cyg_hal_deliver_exception( CYG_WORD code, CYG_ADDRWORD data ) | |
| 0 | 246 { |
| 2 | 247 CYG_REPORT_FUNCTION(); |
| 248 Cyg_Thread::self()->deliver_exception( (cyg_code)code, data ); | |
| 249 CYG_REPORT_RETURN(); | |
| 0 | 250 } |
| 251 | |
| 252 // ------------------------------------------------------------------------- | |
| 253 // Where exceptions are global, there is a single static instance of the | |
| 254 // exception control object. Define it here. | |
| 255 | |
| 256 #ifdef CYGSEM_KERNEL_EXCEPTIONS_GLOBAL | |
| 257 | |
| 2 | 258 Cyg_Exception_Control Cyg_Thread::exception_control |
| 259 CYG_INIT_PRIORITY(INTERRUPTS); | |
| 0 | 260 |
| 261 #endif | |
| 262 | |
| 263 // ------------------------------------------------------------------------- | |
| 264 | |
| 2 | 265 #endif // ifdef CYGPKG_KERNEL_EXCEPTIONS |
| 0 | 266 |
| 267 // ------------------------------------------------------------------------- | |
| 268 // EOF common/except.cxx |
