Mercurial > flash_v2
annotate packages/kernel/current/src/common/except.cxx @ 64:c38311975d4f ecos-sw-2000-01-28
Merge from eCos master repository on 2000-01-28-04:28:11-GMT
| author | jlarmour |
|---|---|
| date | Fri, 28 Jan 2000 04:59:39 +0000 |
| parents | 443894e2e912 |
| children | bf00f99aec69 |
| rev | line source |
|---|---|
| 0 | 1 //========================================================================== |
| 2 // | |
| 2 | 3 // common/except.cxx |
| 0 | 4 // |
| 2 | 5 // Exception handling implementation |
| 0 | 6 // |
| 7 //========================================================================== | |
| 8 //####COPYRIGHTBEGIN#### | |
|
64
c38311975d4f
Merge from eCos master repository on 2000-01-28-04:28:11-GMT
jlarmour
parents:
2
diff
changeset
|
9 // |
|
c38311975d4f
Merge from eCos master repository on 2000-01-28-04:28:11-GMT
jlarmour
parents:
2
diff
changeset
|
10 // ------------------------------------------- |
|
c38311975d4f
Merge from eCos master repository on 2000-01-28-04:28:11-GMT
jlarmour
parents:
2
diff
changeset
|
11 // The contents of this file are subject to the Red Hat eCos Public License |
|
c38311975d4f
Merge from eCos master repository on 2000-01-28-04:28:11-GMT
jlarmour
parents:
2
diff
changeset
|
12 // Version 1.0 (the "License"); you may not use this file except in |
|
c38311975d4f
Merge from eCos master repository on 2000-01-28-04:28:11-GMT
jlarmour
parents:
2
diff
changeset
|
13 // compliance with the License. You may obtain a copy of the License at |
|
c38311975d4f
Merge from eCos master repository on 2000-01-28-04:28:11-GMT
jlarmour
parents:
2
diff
changeset
|
14 // http://sourceware.cygnus.com/ecos |
|
c38311975d4f
Merge from eCos master repository on 2000-01-28-04:28:11-GMT
jlarmour
parents:
2
diff
changeset
|
15 // |
|
c38311975d4f
Merge from eCos master repository on 2000-01-28-04:28:11-GMT
jlarmour
parents:
2
diff
changeset
|
16 // Software distributed under the License is distributed on an |
|
c38311975d4f
Merge from eCos master repository on 2000-01-28-04:28:11-GMT
jlarmour
parents:
2
diff
changeset
|
17 // basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See the |
|
c38311975d4f
Merge from eCos master repository on 2000-01-28-04:28:11-GMT
jlarmour
parents:
2
diff
changeset
|
18 // License for the specific language governing rights and limitations under |
|
c38311975d4f
Merge from eCos master repository on 2000-01-28-04:28:11-GMT
jlarmour
parents:
2
diff
changeset
|
19 // the License. |
|
c38311975d4f
Merge from eCos master repository on 2000-01-28-04:28:11-GMT
jlarmour
parents:
2
diff
changeset
|
20 // |
|
c38311975d4f
Merge from eCos master repository on 2000-01-28-04:28:11-GMT
jlarmour
parents:
2
diff
changeset
|
21 // The Original Code is eCos - Embedded Configurable Operating System, |
|
c38311975d4f
Merge from eCos master repository on 2000-01-28-04:28:11-GMT
jlarmour
parents:
2
diff
changeset
|
22 // released September 30, 1998. |
|
c38311975d4f
Merge from eCos master repository on 2000-01-28-04:28:11-GMT
jlarmour
parents:
2
diff
changeset
|
23 // |
|
c38311975d4f
Merge from eCos master repository on 2000-01-28-04:28:11-GMT
jlarmour
parents:
2
diff
changeset
|
24 // The Initial Developer of the Original Code is Red Hat. |
|
c38311975d4f
Merge from eCos master repository on 2000-01-28-04:28:11-GMT
jlarmour
parents:
2
diff
changeset
|
25 // Portions created by Red Hat are |
|
c38311975d4f
Merge from eCos master repository on 2000-01-28-04:28:11-GMT
jlarmour
parents:
2
diff
changeset
|
26 // Copyright (C) 1998, 1999, 2000 Red Hat, Inc. |
|
c38311975d4f
Merge from eCos master repository on 2000-01-28-04:28:11-GMT
jlarmour
parents:
2
diff
changeset
|
27 // All Rights Reserved. |
|
c38311975d4f
Merge from eCos master repository on 2000-01-28-04:28:11-GMT
jlarmour
parents:
2
diff
changeset
|
28 // ------------------------------------------- |
|
c38311975d4f
Merge from eCos master repository on 2000-01-28-04:28:11-GMT
jlarmour
parents:
2
diff
changeset
|
29 // |
| 0 | 30 //####COPYRIGHTEND#### |
| 31 //========================================================================== | |
| 32 //#####DESCRIPTIONBEGIN#### | |
| 33 // | |
| 2 | 34 // Author(s): nickg |
| 35 // Contributors: nickg, jlarmour | |
| 36 // Date: 1999-02-16 | |
| 37 // Purpose: Exception handling implementation | |
| 38 // Description: This file contains the code that registers and delivers | |
| 39 // exceptions. | |
| 0 | 40 // |
| 41 //####DESCRIPTIONEND#### | |
| 42 // | |
| 43 //========================================================================== | |
| 44 | |
| 45 #include <pkgconf/kernel.h> | |
| 46 | |
| 47 #include <cyg/kernel/ktypes.h> // base kernel types | |
| 48 #include <cyg/infra/cyg_trac.h> // tracing macros | |
| 49 #include <cyg/infra/cyg_ass.h> // assertion macros | |
| 50 #include <cyg/kernel/instrmnt.h> // instrumentation | |
| 51 | |
| 52 #include <cyg/kernel/except.hxx> // our header | |
| 53 | |
| 54 #include <cyg/hal/hal_arch.h> // architecture definitions | |
| 55 #include <cyg/hal/hal_intr.h> // vector definitions | |
| 56 | |
| 57 #include <cyg/kernel/thread.hxx> // thread interface | |
| 58 | |
| 59 #include <cyg/kernel/thread.inl> // thread inlines | |
| 60 | |
| 61 #ifdef CYGPKG_KERNEL_EXCEPTIONS | |
| 62 | |
| 63 // ------------------------------------------------------------------------- | |
| 64 // Null exception handler. This is used to capture exceptions that are | |
| 65 // not caught by user supplied handlers. | |
| 66 | |
| 2 | 67 void |
| 68 cyg_null_exception_handler( | |
| 0 | 69 CYG_ADDRWORD data, // user supplied data |
| 70 cyg_code exception_number, // exception being raised | |
| 71 CYG_ADDRWORD exception_info // any exception specific info | |
| 72 ) | |
| 73 { | |
| 2 | 74 CYG_REPORT_FUNCTION(); |
| 75 CYG_REPORT_FUNCARG3("data=%08x, exception=%d, info=%08x", data, | |
| 76 exception_number, exception_info); | |
| 0 | 77 CYG_TRACE1( 1, "Uncaught exception: %d", exception_number); |
| 2 | 78 CYG_REPORT_RETURN(); |
| 0 | 79 } |
| 80 | |
| 81 // ------------------------------------------------------------------------- | |
| 82 // Exception Controller constructor. | |
| 83 | |
| 84 Cyg_Exception_Control::Cyg_Exception_Control() | |
| 85 { | |
| 2 | 86 CYG_REPORT_FUNCTION(); |
| 0 | 87 #ifdef CYGSEM_KERNEL_EXCEPTIONS_DECODE |
| 88 | |
| 2 | 89 for( int i = 0; i < CYGNUM_HAL_EXCEPTION_COUNT ; i++ ) |
| 0 | 90 exception_handler[i] = cyg_null_exception_handler, |
| 91 exception_data[i] = 0; | |
| 92 #else | |
| 93 | |
| 94 exception_handler = cyg_null_exception_handler; | |
| 95 exception_data = 0; | |
| 96 | |
| 97 #endif | |
| 2 | 98 CYG_REPORT_RETURN(); |
| 0 | 99 } |
| 100 | |
| 101 // ------------------------------------------------------------------------- | |
| 102 // Exception registation. Stores the handler function and data to be used | |
| 103 // for handling the given exception number. Where exceptions are not decoded | |
| 104 // only a single handler may be registered for all exceptions. This function | |
| 105 // also returns the old values of the exception handler and data to allow | |
| 106 // chaining to be implemented. | |
| 107 | |
| 2 | 108 void |
| 109 Cyg_Exception_Control::register_exception( | |
| 0 | 110 cyg_code exception_number, // exception number |
| 111 cyg_exception_handler handler, // handler function | |
| 112 CYG_ADDRWORD data, // data argument | |
| 113 cyg_exception_handler **old_handler, // handler function | |
| 114 CYG_ADDRWORD *old_data // data argument | |
| 115 ) | |
| 116 { | |
| 117 CYG_REPORT_FUNCTION(); | |
| 2 | 118 CYG_REPORT_FUNCARG5("exception=%d, handler func=%08x, data=%08x, " |
| 119 "space for old handler=%08x,space for old data=%08x", | |
| 120 exception_number, handler, data, old_handler, | |
| 121 old_data); | |
| 0 | 122 |
| 2 | 123 CYG_ASSERT( exception_number <= CYGNUM_HAL_EXCEPTION_MAX, |
| 0 | 124 "Out of range exception number"); |
| 2 | 125 CYG_ASSERT( exception_number >= CYGNUM_HAL_EXCEPTION_MIN, |
| 0 | 126 "Out of range exception number"); |
| 127 | |
| 128 | |
| 129 // Should we complain if there is already a registered | |
| 130 // handler, or should we just replace is silently? | |
| 131 | |
| 132 #ifdef CYGSEM_KERNEL_EXCEPTIONS_DECODE | |
| 133 | |
| 134 if( old_handler != NULL ) | |
| 2 | 135 *old_handler = exception_handler[exception_number - |
| 136 CYGNUM_HAL_EXCEPTION_MIN]; | |
| 0 | 137 if( old_data != NULL ) |
| 2 | 138 *old_data = exception_data[exception_number - |
| 139 CYGNUM_HAL_EXCEPTION_MIN]; | |
| 140 exception_handler[exception_number - CYGNUM_HAL_EXCEPTION_MIN] = handler; | |
| 141 exception_data[exception_number - CYGNUM_HAL_EXCEPTION_MIN] = data; | |
| 0 | 142 |
| 143 #else | |
| 144 | |
| 145 if( old_handler != NULL ) | |
| 146 *old_handler = exception_handler; | |
| 147 if( old_data != NULL ) | |
| 148 *old_data = exception_data; | |
| 149 exception_handler = handler; | |
| 150 exception_data = data; | |
| 151 | |
| 152 #endif | |
| 2 | 153 CYG_REPORT_RETURN(); |
| 0 | 154 } |
| 155 | |
| 156 // ------------------------------------------------------------------------- | |
| 157 // Exception deregistation. Revert the handler for the exception number | |
| 158 // to the default. | |
| 159 | |
| 2 | 160 void |
| 161 Cyg_Exception_Control::deregister_exception( | |
| 0 | 162 cyg_code exception_number // exception number |
| 163 ) | |
| 164 { | |
| 165 CYG_REPORT_FUNCTION(); | |
| 2 | 166 CYG_REPORT_FUNCARG1("exception number=%d", exception_number); |
| 0 | 167 |
| 2 | 168 CYG_ASSERT( exception_number <= CYGNUM_HAL_EXCEPTION_MAX, |
| 0 | 169 "Out of range exception number"); |
| 2 | 170 CYG_ASSERT( exception_number >= CYGNUM_HAL_EXCEPTION_MIN, |
| 0 | 171 "Out of range exception number"); |
| 172 | |
| 173 #ifdef CYGSEM_KERNEL_EXCEPTIONS_DECODE | |
| 174 | |
| 2 | 175 exception_handler[exception_number - CYGNUM_HAL_EXCEPTION_MIN] = |
| 176 cyg_null_exception_handler; | |
| 177 exception_data[exception_number - CYGNUM_HAL_EXCEPTION_MIN] = 0; | |
| 0 | 178 |
| 179 #else | |
| 180 | |
| 181 exception_handler = cyg_null_exception_handler; | |
| 182 exception_data = 0; | |
| 183 | |
| 184 #endif | |
| 2 | 185 |
| 186 CYG_REPORT_RETURN(); | |
| 0 | 187 } |
| 188 | |
| 189 // ------------------------------------------------------------------------- | |
| 190 // Exception delivery. Call the appropriate exception handler. | |
| 191 | |
| 2 | 192 void |
| 193 Cyg_Exception_Control::deliver_exception( | |
| 0 | 194 cyg_code exception_number, // exception being raised |
| 195 CYG_ADDRWORD exception_info // exception specific info | |
| 196 ) | |
| 197 { | |
| 2 | 198 CYG_REPORT_FUNCTION(); |
| 199 CYG_REPORT_FUNCARG2("exception number=%d, exception info=%08x", | |
| 200 exception_number, exception_info); | |
| 201 | |
| 0 | 202 cyg_exception_handler *handler = NULL; |
| 203 CYG_ADDRWORD data = 0; | |
| 204 | |
| 2 | 205 CYG_ASSERT( exception_number <= CYGNUM_HAL_EXCEPTION_MAX, |
| 0 | 206 "Out of range exception number"); |
| 2 | 207 CYG_ASSERT( exception_number >= CYGNUM_HAL_EXCEPTION_MIN, |
| 0 | 208 "Out of range exception number"); |
| 209 | |
| 210 #ifdef CYGSEM_KERNEL_EXCEPTIONS_DECODE | |
| 211 | |
| 2 | 212 handler = exception_handler[exception_number - CYGNUM_HAL_EXCEPTION_MIN]; |
| 213 data = exception_data[exception_number - CYGNUM_HAL_EXCEPTION_MIN]; | |
| 0 | 214 |
| 215 #else | |
| 216 | |
| 217 handler = exception_handler; | |
| 218 data = exception_data; | |
| 219 | |
| 220 #endif | |
| 221 | |
| 222 // The handler will always be a callable function: either the user's | |
| 223 // registered function or the null handler. So it is always safe to | |
| 224 // just go ahead and call it. | |
| 225 | |
| 226 handler( data, exception_number, exception_info ); | |
| 2 | 227 |
| 228 CYG_REPORT_RETURN(); | |
| 0 | 229 } |
| 230 | |
| 231 // ------------------------------------------------------------------------- | |
| 232 // Exception delivery function called from the HAL as a result of a | |
| 233 // hardware exception being raised. | |
| 234 | |
| 2 | 235 externC void |
| 236 cyg_hal_deliver_exception( CYG_WORD code, CYG_ADDRWORD data ) | |
| 0 | 237 { |
| 2 | 238 CYG_REPORT_FUNCTION(); |
| 239 Cyg_Thread::self()->deliver_exception( (cyg_code)code, data ); | |
| 240 CYG_REPORT_RETURN(); | |
| 0 | 241 } |
| 242 | |
| 243 // ------------------------------------------------------------------------- | |
| 244 // Where exceptions are global, there is a single static instance of the | |
| 245 // exception control object. Define it here. | |
| 246 | |
| 247 #ifdef CYGSEM_KERNEL_EXCEPTIONS_GLOBAL | |
| 248 | |
| 2 | 249 Cyg_Exception_Control Cyg_Thread::exception_control |
| 250 CYG_INIT_PRIORITY(INTERRUPTS); | |
| 0 | 251 |
| 252 #endif | |
| 253 | |
| 254 // ------------------------------------------------------------------------- | |
| 255 | |
| 2 | 256 #endif // ifdef CYGPKG_KERNEL_EXCEPTIONS |
| 0 | 257 |
| 258 // ------------------------------------------------------------------------- | |
| 259 // EOF common/except.cxx |
