[2d2de4eb] | 1 | /** |
---|
| 2 | * @file |
---|
[94e1931c] | 3 | * |
---|
[2d2de4eb] | 4 | * @ingroup ppc_exc |
---|
| 5 | * @ingroup ppc_exc_frame |
---|
[94e1931c] | 6 | * |
---|
[2d2de4eb] | 7 | * @brief PowerPC Exceptions API. |
---|
| 8 | */ |
---|
| 9 | |
---|
[359e537] | 10 | /* |
---|
| 11 | * Copyright (C) 1999 Eric Valette (valette@crf.canon.fr) |
---|
| 12 | * Canon Centre Recherche France. |
---|
[94e1931c] | 13 | * |
---|
[2d2de4eb] | 14 | * Copyright (C) 2007 Till Straumann <strauman@slac.stanford.edu> |
---|
[359e537] | 15 | * |
---|
| 16 | * Copyright (C) 2009 embedded brains GmbH. |
---|
| 17 | * |
---|
| 18 | * Enhanced by Jay Kulpinski <jskulpin@eng01.gdds.com> |
---|
| 19 | * to support 603, 603e, 604, 604e exceptions |
---|
| 20 | * |
---|
| 21 | * Moved to "libcpu/powerpc/new-exceptions" and consolidated |
---|
| 22 | * by Thomas Doerfler <Thomas.Doerfler@embedded-brains.de> |
---|
| 23 | * to be common for all PPCs with new exceptions. |
---|
| 24 | * |
---|
[2d2de4eb] | 25 | * Derived from file "libcpu/powerpc/new-exceptions/raw_exception.h". |
---|
| 26 | * Derived from file "libcpu/powerpc/new-exceptions/bspsupport/ppc_exc_bspsupp.h". |
---|
[359e537] | 27 | * |
---|
| 28 | * The license and distribution terms for this file may be |
---|
[e71a3a84] | 29 | * found in the file LICENSE in this distribution or at |
---|
[c499856] | 30 | * http://www.rtems.org/license/LICENSE. |
---|
[2d2de4eb] | 31 | */ |
---|
| 32 | |
---|
| 33 | /* DO NOT INTRODUCE #ifdef <cpu_flavor> in this file */ |
---|
| 34 | |
---|
| 35 | #ifndef LIBCPU_VECTORS_H |
---|
| 36 | #define LIBCPU_VECTORS_H |
---|
| 37 | |
---|
[4bd4c9e] | 38 | #include <bspopts.h> |
---|
[2599c8e] | 39 | #include <rtems/score/cpuimpl.h> |
---|
[2d2de4eb] | 40 | #include <libcpu/powerpc-utility.h> |
---|
| 41 | |
---|
[0f7b6eff] | 42 | #ifdef __cplusplus |
---|
| 43 | extern "C" { |
---|
| 44 | #endif |
---|
| 45 | |
---|
[2d2de4eb] | 46 | /** |
---|
| 47 | * @defgroup ppc_exc PowerPC Exceptions |
---|
| 48 | * |
---|
| 49 | * @brief XXX |
---|
[94e1931c] | 50 | * |
---|
[2d2de4eb] | 51 | * @{ |
---|
| 52 | */ |
---|
| 53 | |
---|
| 54 | #define ASM_RESET_VECTOR 0x01 |
---|
| 55 | #define ASM_MACH_VECTOR 0x02 |
---|
| 56 | #define ASM_PROT_VECTOR 0x03 |
---|
| 57 | #define ASM_ISI_VECTOR 0x04 |
---|
| 58 | #define ASM_EXT_VECTOR 0x05 |
---|
| 59 | #define ASM_ALIGN_VECTOR 0x06 |
---|
| 60 | #define ASM_PROG_VECTOR 0x07 |
---|
| 61 | #define ASM_FLOAT_VECTOR 0x08 |
---|
| 62 | #define ASM_DEC_VECTOR 0x09 |
---|
| 63 | #define ASM_SYS_VECTOR 0x0C |
---|
| 64 | #define ASM_TRACE_VECTOR 0x0D |
---|
| 65 | |
---|
| 66 | #define ASM_PPC405_APU_UNAVAIL_VECTOR ASM_60X_VEC_ASSIST_VECTOR |
---|
[25a92bc1] | 67 | |
---|
[2d2de4eb] | 68 | #define ASM_8XX_FLOATASSIST_VECTOR 0x0E |
---|
| 69 | #define ASM_8XX_SOFTEMUL_VECTOR 0x10 |
---|
| 70 | #define ASM_8XX_ITLBMISS_VECTOR 0x11 |
---|
| 71 | #define ASM_8XX_DTLBMISS_VECTOR 0x12 |
---|
| 72 | #define ASM_8XX_ITLBERROR_VECTOR 0x13 |
---|
| 73 | #define ASM_8XX_DTLBERROR_VECTOR 0x14 |
---|
| 74 | #define ASM_8XX_DBREAK_VECTOR 0x1C |
---|
| 75 | #define ASM_8XX_IBREAK_VECTOR 0x1D |
---|
| 76 | #define ASM_8XX_PERIFBREAK_VECTOR 0x1E |
---|
| 77 | #define ASM_8XX_DEVPORT_VECTOR 0x1F |
---|
| 78 | |
---|
| 79 | #define ASM_5XX_FLOATASSIST_VECTOR 0x0E |
---|
| 80 | #define ASM_5XX_SOFTEMUL_VECTOR 0x10 |
---|
| 81 | #define ASM_5XX_IPROT_VECTOR 0x13 |
---|
| 82 | #define ASM_5XX_DPROT_VECTOR 0x14 |
---|
| 83 | #define ASM_5XX_DBREAK_VECTOR 0x1C |
---|
| 84 | #define ASM_5XX_IBREAK_VECTOR 0x1D |
---|
| 85 | #define ASM_5XX_MEBREAK_VECTOR 0x1E |
---|
| 86 | #define ASM_5XX_NMEBREAK_VECTOR 0x1F |
---|
| 87 | |
---|
| 88 | #define ASM_60X_VEC_VECTOR 0x0A |
---|
| 89 | #define ASM_60X_PERFMON_VECTOR 0x0F |
---|
| 90 | #define ASM_60X_IMISS_VECTOR 0x10 |
---|
| 91 | #define ASM_60X_DLMISS_VECTOR 0x11 |
---|
| 92 | #define ASM_60X_DSMISS_VECTOR 0x12 |
---|
| 93 | #define ASM_60X_ADDR_VECTOR 0x13 |
---|
| 94 | #define ASM_60X_SYSMGMT_VECTOR 0x14 |
---|
| 95 | #define ASM_60X_VEC_ASSIST_VECTOR 0x16 |
---|
| 96 | #define ASM_60X_ITM_VECTOR 0x17 |
---|
| 97 | |
---|
[644448f] | 98 | /* Book E */ |
---|
| 99 | #define ASM_BOOKE_CRIT_VECTOR 0x01 |
---|
| 100 | /* We could use the std. decrementer vector # on bookE, too, |
---|
| 101 | * but the bookE decrementer has slightly different semantics |
---|
| 102 | * so we use a different vector (which happens to be |
---|
| 103 | * the PIT vector on the 405 which is like the booke decrementer) |
---|
| 104 | */ |
---|
| 105 | #define ASM_BOOKE_DEC_VECTOR 0x10 |
---|
| 106 | #define ASM_BOOKE_ITLBMISS_VECTOR 0x11 |
---|
| 107 | #define ASM_BOOKE_DTLBMISS_VECTOR 0x12 |
---|
| 108 | #define ASM_BOOKE_FIT_VECTOR 0x13 |
---|
| 109 | #define ASM_BOOKE_WDOG_VECTOR 0x14 |
---|
| 110 | #define ASM_BOOKE_APU_VECTOR 0x18 |
---|
| 111 | #define ASM_BOOKE_DEBUG_VECTOR ASM_TRACE_VECTOR |
---|
| 112 | |
---|
| 113 | /* e200 and e500 */ |
---|
| 114 | #define ASM_E500_SPE_UNAVAILABLE_VECTOR ASM_60X_VEC_VECTOR |
---|
| 115 | #define ASM_E500_EMB_FP_DATA_VECTOR 0x19 |
---|
| 116 | #define ASM_E500_EMB_FP_ROUND_VECTOR 0x1A |
---|
| 117 | #define ASM_E500_PERFMON_VECTOR ASM_60X_PERFMON_VECTOR |
---|
[2d2de4eb] | 118 | |
---|
| 119 | /* e300 */ |
---|
| 120 | #define ASM_E300_CRIT_VECTOR 0x0A |
---|
[644448f] | 121 | #define ASM_E300_PERFMON_VECTOR ASM_60X_PERFMON_VECTOR |
---|
[2d2de4eb] | 122 | #define ASM_E300_IMISS_VECTOR ASM_60X_IMISS_VECTOR /* Special case: Shadowed GPRs */ |
---|
| 123 | #define ASM_E300_DLMISS_VECTOR ASM_60X_DLMISS_VECTOR /* Special case: Shadowed GPRs */ |
---|
| 124 | #define ASM_E300_DSMISS_VECTOR ASM_60X_DSMISS_VECTOR /* Special case: Shadowed GPRs */ |
---|
[644448f] | 125 | #define ASM_E300_ADDR_VECTOR ASM_60X_ADDR_VECTOR |
---|
| 126 | #define ASM_E300_SYSMGMT_VECTOR ASM_60X_SYSMGMT_VECTOR |
---|
[2d2de4eb] | 127 | |
---|
| 128 | /* |
---|
| 129 | * If you change that number make sure to adjust the wrapper code in ppc_exc.S |
---|
| 130 | * and that ppc_exc_handler_table will be correctly initialized. |
---|
| 131 | */ |
---|
| 132 | #define LAST_VALID_EXC 0x1F |
---|
| 133 | |
---|
| 134 | /* DO NOT USE -- this symbol is DEPRECATED |
---|
| 135 | * (only used by libbsp/shared/vectors/vectors.S |
---|
| 136 | * which should not be used by new BSPs). |
---|
| 137 | */ |
---|
| 138 | #define ASM_60X_VEC_VECTOR_OFFSET 0xf20 |
---|
| 139 | |
---|
| 140 | #define ASM_PPC405_FIT_VECTOR_OFFSET 0x1010 |
---|
| 141 | #define ASM_PPC405_WDOG_VECTOR_OFFSET 0x1020 |
---|
| 142 | #define ASM_PPC405_TRACE_VECTOR_OFFSET 0x2000 |
---|
| 143 | |
---|
| 144 | /** @} */ |
---|
| 145 | |
---|
| 146 | /** |
---|
| 147 | * @defgroup ppc_exc_frame PowerPC Exception Frame |
---|
| 148 | * |
---|
| 149 | * @brief XXX |
---|
| 150 | * |
---|
| 151 | * @{ |
---|
| 152 | */ |
---|
[94e1931c] | 153 | |
---|
| 154 | /* |
---|
| 155 | * The callee (high level exception code written in C) |
---|
| 156 | * will store the Link Registers (return address) at entry r1 + 4 !!!. |
---|
| 157 | * So let room for it!!!. |
---|
| 158 | */ |
---|
| 159 | #define LINK_REGISTER_CALLEE_UPDATE_ROOM 4 |
---|
[2888a65] | 160 | |
---|
[a6f84b27] | 161 | #define EXC_GENERIC_SIZE (PPC_EXC_FRAME_SIZE + PPC_STACK_RED_ZONE_SIZE) |
---|
[c7f8408d] | 162 | |
---|
[a8694035] | 163 | #define PPC_EXC_INTERRUPT_FRAME_SIZE CPU_INTERRUPT_FRAME_SIZE |
---|
| 164 | |
---|
[3e2647a7] | 165 | #if defined(__ALTIVEC__) && !defined(PPC_MULTILIB_ALTIVEC) |
---|
[c7f8408d] | 166 | #define EXC_VEC_OFFSET EXC_GENERIC_SIZE |
---|
| 167 | #ifndef PPC_CACHE_ALIGNMENT |
---|
| 168 | #error "Missing include file!" |
---|
| 169 | #endif |
---|
| 170 | /* 20 volatile registers |
---|
| 171 | * + cache-aligned area for vcsr, vrsave |
---|
| 172 | * + area for alignment |
---|
| 173 | */ |
---|
| 174 | #define EXC_VEC_SIZE (16*20 + 2*PPC_CACHE_ALIGNMENT) |
---|
| 175 | #else |
---|
| 176 | #define EXC_VEC_SIZE (0) |
---|
| 177 | #endif |
---|
| 178 | |
---|
[94e1931c] | 179 | /* |
---|
| 180 | * maintain the EABI requested 8 bytes aligment |
---|
| 181 | * As SVR4 ABI requires 16, make it 16 (as some |
---|
| 182 | * exception may need more registers to be processed...) |
---|
| 183 | */ |
---|
[c7f8408d] | 184 | #define EXCEPTION_FRAME_END (EXC_GENERIC_SIZE + EXC_VEC_SIZE) |
---|
[94e1931c] | 185 | |
---|
[2d2de4eb] | 186 | /** @} */ |
---|
| 187 | |
---|
[94e1931c] | 188 | #ifndef ASM |
---|
| 189 | |
---|
[2d2de4eb] | 190 | /** |
---|
| 191 | * @ingroup ppc_exc_frame |
---|
| 192 | * |
---|
| 193 | * @{ |
---|
| 194 | */ |
---|
| 195 | |
---|
[d2202ac] | 196 | typedef CPU_Exception_frame BSP_Exception_frame; |
---|
[2d2de4eb] | 197 | |
---|
| 198 | /** @} */ |
---|
| 199 | |
---|
| 200 | /** |
---|
| 201 | * @ingroup ppc_exc |
---|
| 202 | * |
---|
| 203 | * @{ |
---|
| 204 | */ |
---|
| 205 | |
---|
| 206 | /** |
---|
| 207 | * @brief Global exception handler type. |
---|
| 208 | */ |
---|
| 209 | typedef void (*exception_handler_t)(BSP_Exception_frame*); |
---|
| 210 | |
---|
| 211 | /** |
---|
| 212 | * @brief Default global exception handler. |
---|
| 213 | */ |
---|
| 214 | void C_exception_handler(BSP_Exception_frame* excPtr); |
---|
| 215 | |
---|
[7e32b62] | 216 | void BSP_printStackTrace(const BSP_Exception_frame *excPtr); |
---|
[2d2de4eb] | 217 | |
---|
| 218 | /** |
---|
| 219 | * @brief Exception categories. |
---|
| 220 | * |
---|
| 221 | * Exceptions of different categories use different SRR registers to save the |
---|
| 222 | * machine state and do different things in the prologue and epilogue. |
---|
| 223 | * |
---|
| 224 | * For now, the CPU descriptions assume this fits into 8 bits. |
---|
| 225 | */ |
---|
| 226 | typedef enum { |
---|
| 227 | PPC_EXC_INVALID = 0, |
---|
| 228 | PPC_EXC_ASYNC = 1, |
---|
| 229 | PPC_EXC_CLASSIC = 2, |
---|
| 230 | PPC_EXC_CLASSIC_ASYNC = PPC_EXC_CLASSIC | PPC_EXC_ASYNC, |
---|
| 231 | PPC_EXC_405_CRITICAL = 4, |
---|
| 232 | PPC_EXC_405_CRITICAL_ASYNC = PPC_EXC_405_CRITICAL | PPC_EXC_ASYNC, |
---|
| 233 | PPC_EXC_BOOKE_CRITICAL = 6, |
---|
| 234 | PPC_EXC_BOOKE_CRITICAL_ASYNC = PPC_EXC_BOOKE_CRITICAL | PPC_EXC_ASYNC, |
---|
| 235 | PPC_EXC_E500_MACHCHK = 8, |
---|
| 236 | PPC_EXC_E500_MACHCHK_ASYNC = PPC_EXC_E500_MACHCHK | PPC_EXC_ASYNC, |
---|
| 237 | PPC_EXC_NAKED = 10 |
---|
| 238 | } ppc_exc_category; |
---|
| 239 | |
---|
| 240 | /** |
---|
| 241 | * @brief Categorie set type. |
---|
| 242 | */ |
---|
| 243 | typedef uint8_t ppc_exc_categories [LAST_VALID_EXC + 1]; |
---|
| 244 | |
---|
| 245 | static inline bool ppc_exc_is_valid_category(ppc_exc_category category) |
---|
| 246 | { |
---|
| 247 | return (unsigned) category <= (unsigned) PPC_EXC_NAKED; |
---|
| 248 | } |
---|
| 249 | |
---|
| 250 | /** |
---|
[5f91272] | 251 | * @brief Returns the entry address of the vector. |
---|
[2d2de4eb] | 252 | * |
---|
[5f91272] | 253 | * @param[in] vector The vector number. |
---|
| 254 | * @param[in] vector_base The vector table base address. |
---|
[2d2de4eb] | 255 | */ |
---|
[5f91272] | 256 | void *ppc_exc_vector_address(unsigned vector, void *vector_base); |
---|
[2d2de4eb] | 257 | |
---|
| 258 | /** |
---|
| 259 | * @brief Returns the category set for a CPU of type @a cpu, or @c NULL if |
---|
| 260 | * there is no category set available for this CPU. |
---|
| 261 | */ |
---|
| 262 | const ppc_exc_categories *ppc_exc_categories_for_cpu(ppc_cpu_id_t cpu); |
---|
| 263 | |
---|
| 264 | /** |
---|
| 265 | * @brief Returns the category set for the current CPU, or @c NULL if there is |
---|
| 266 | * no category set available for this CPU. |
---|
| 267 | */ |
---|
| 268 | static inline const ppc_exc_categories *ppc_exc_current_categories(void) |
---|
| 269 | { |
---|
| 270 | return ppc_exc_categories_for_cpu(ppc_cpu_current()); |
---|
| 271 | } |
---|
[25a92bc1] | 272 | |
---|
[2d2de4eb] | 273 | /** |
---|
| 274 | * @brief Returns the category for the vector @a vector using the category set |
---|
| 275 | * @a categories. |
---|
[94e1931c] | 276 | */ |
---|
[2d2de4eb] | 277 | ppc_exc_category ppc_exc_category_for_vector( |
---|
| 278 | const ppc_exc_categories *categories, |
---|
| 279 | unsigned vector |
---|
| 280 | ); |
---|
| 281 | |
---|
| 282 | /** |
---|
| 283 | * @brief Makes a minimal prologue for the vector @a vector with the category |
---|
| 284 | * @a category. |
---|
| 285 | * |
---|
[5f91272] | 286 | * The minimal prologue will be copied to @a prologue. Not more than |
---|
| 287 | * @a prologue_size bytes will be copied. Returns the actual minimal prologue |
---|
[2d2de4eb] | 288 | * size in bytes in @a prologue_size. |
---|
| 289 | * |
---|
| 290 | * @retval RTEMS_SUCCESSFUL Minimal prologue successfully made. |
---|
| 291 | * @retval RTEMS_INVALID_ID Invalid vector number. |
---|
| 292 | * @retval RTEMS_INVALID_NUMBER Invalid category. |
---|
| 293 | * @retval RTEMS_INVALID_SIZE Prologue size to small. |
---|
| 294 | */ |
---|
| 295 | rtems_status_code ppc_exc_make_prologue( |
---|
| 296 | unsigned vector, |
---|
[5f91272] | 297 | void *vector_base, |
---|
[2d2de4eb] | 298 | ppc_exc_category category, |
---|
| 299 | uint32_t *prologue, |
---|
| 300 | size_t *prologue_size |
---|
| 301 | ); |
---|
[25a92bc1] | 302 | |
---|
[71b611d] | 303 | static inline void ppc_exc_initialize_interrupt_stack( |
---|
| 304 | uintptr_t stack_begin, |
---|
| 305 | uintptr_t stack_size |
---|
| 306 | ) |
---|
| 307 | { |
---|
| 308 | uintptr_t stack_end = stack_begin + stack_size; |
---|
| 309 | uintptr_t stack_pointer = stack_end - PPC_MINIMUM_STACK_FRAME_SIZE; |
---|
| 310 | |
---|
| 311 | /* Ensure proper interrupt stack alignment */ |
---|
| 312 | stack_pointer &= ~((uintptr_t) CPU_STACK_ALIGNMENT - 1); |
---|
| 313 | |
---|
| 314 | /* Tag interrupt stack bottom */ |
---|
| 315 | *(uint32_t *) stack_pointer = 0; |
---|
| 316 | |
---|
| 317 | /* Move interrupt stack values to special purpose registers */ |
---|
| 318 | PPC_SET_SPECIAL_PURPOSE_REGISTER(SPRG1, stack_pointer); |
---|
| 319 | PPC_SET_SPECIAL_PURPOSE_REGISTER(SPRG2, stack_begin); |
---|
| 320 | } |
---|
| 321 | |
---|
[5f91272] | 322 | /** |
---|
| 323 | * @brief Initializes the exception handling. |
---|
| 324 | * |
---|
| 325 | * @see ppc_exc_initialize(). |
---|
| 326 | */ |
---|
| 327 | void ppc_exc_initialize_with_vector_base( |
---|
| 328 | uintptr_t interrupt_stack_begin, |
---|
| 329 | uintptr_t interrupt_stack_size, |
---|
| 330 | void *vector_base |
---|
| 331 | ); |
---|
| 332 | |
---|
[2d2de4eb] | 333 | /** |
---|
| 334 | * @brief Initializes the exception handling. |
---|
| 335 | * |
---|
[b1e8a58] | 336 | * If the initialization fails, then this is a fatal error. The fatal error |
---|
[33cb8bf] | 337 | * source is RTEMS_FATAL_SOURCE_BSP and the fatal error code is |
---|
| 338 | * PPC_FATAL_EXCEPTION_INITIALIZATION. |
---|
[b1e8a58] | 339 | * |
---|
| 340 | * Possible error reasons are |
---|
| 341 | * - no category set available for the current CPU, |
---|
| 342 | * - the register r13 does not point to the small data area anchor required by |
---|
| 343 | * SVR4/EABI, or |
---|
| 344 | * - the minimal prologue creation failed. |
---|
[2d2de4eb] | 345 | */ |
---|
[5f91272] | 346 | static inline void ppc_exc_initialize( |
---|
[2d2de4eb] | 347 | uintptr_t interrupt_stack_begin, |
---|
| 348 | uintptr_t interrupt_stack_size |
---|
[5f91272] | 349 | ) |
---|
| 350 | { |
---|
| 351 | ppc_exc_initialize_with_vector_base( |
---|
| 352 | interrupt_stack_begin, |
---|
| 353 | interrupt_stack_size, |
---|
| 354 | NULL |
---|
| 355 | ); |
---|
| 356 | } |
---|
[94e1931c] | 357 | |
---|
[2d2de4eb] | 358 | /** |
---|
| 359 | * @brief High-level exception handler type. |
---|
| 360 | * |
---|
[4bd4c9e] | 361 | * @retval 0 The exception was handled and normal execution may resume. |
---|
| 362 | * @retval -1 Reject the exception resulting in a call of the global exception |
---|
| 363 | * handler. |
---|
| 364 | * @retval other Reserved, do not use. |
---|
[2d2de4eb] | 365 | */ |
---|
| 366 | typedef int (*ppc_exc_handler_t)(BSP_Exception_frame *f, unsigned vector); |
---|
| 367 | |
---|
[4bd4c9e] | 368 | /** |
---|
| 369 | * @brief Default high-level exception handler. |
---|
| 370 | * |
---|
| 371 | * @retval -1 Always. |
---|
| 372 | */ |
---|
| 373 | int ppc_exc_handler_default(BSP_Exception_frame *f, unsigned int vector); |
---|
| 374 | |
---|
[f665f13] | 375 | #ifndef PPC_EXC_CONFIG_BOOKE_ONLY |
---|
| 376 | |
---|
[2d2de4eb] | 377 | /** |
---|
| 378 | * @brief Bits for MSR update. |
---|
| 379 | * |
---|
[359e537] | 380 | * Bits in MSR that are enabled during execution of exception handlers / ISRs |
---|
[2d2de4eb] | 381 | * (on classic PPC these are DR/IR/RI [default], on bookE-style CPUs they should |
---|
| 382 | * be set to 0 during initialization) |
---|
| 383 | * |
---|
| 384 | * By default, the setting of these bits that is in effect when exception |
---|
| 385 | * handling is initialized is used. |
---|
| 386 | */ |
---|
| 387 | extern uint32_t ppc_exc_msr_bits; |
---|
| 388 | |
---|
[f665f13] | 389 | #endif /* PPC_EXC_CONFIG_BOOKE_ONLY */ |
---|
| 390 | |
---|
[2d2de4eb] | 391 | /** |
---|
| 392 | * @brief Cache write back check flag. |
---|
| 393 | * |
---|
| 394 | * (See README under CAVEATS). During initialization |
---|
| 395 | * a check is performed to assert that write-back |
---|
| 396 | * caching is enabled for memory accesses. If a BSP |
---|
| 397 | * runs entirely without any caching then it should |
---|
| 398 | * set this variable to zero prior to initializing |
---|
| 399 | * exceptions in order to skip the test. |
---|
| 400 | * NOTE: The code does NOT support mapping memory |
---|
| 401 | * with cache-attributes other than write-back |
---|
| 402 | * (unless the entire cache is physically disabled) |
---|
| 403 | */ |
---|
| 404 | extern uint32_t ppc_exc_cache_wb_check; |
---|
| 405 | |
---|
[4bd4c9e] | 406 | #ifndef PPC_EXC_CONFIG_USE_FIXED_HANDLER |
---|
| 407 | /** |
---|
| 408 | * @brief High-level exception handler table. |
---|
| 409 | */ |
---|
| 410 | extern ppc_exc_handler_t ppc_exc_handler_table [LAST_VALID_EXC + 1]; |
---|
| 411 | |
---|
| 412 | /** |
---|
| 413 | * @brief Global exception handler. |
---|
| 414 | */ |
---|
| 415 | extern exception_handler_t globalExceptHdl; |
---|
| 416 | #else /* PPC_EXC_CONFIG_USE_FIXED_HANDLER */ |
---|
| 417 | /** |
---|
| 418 | * @brief High-level exception handler table. |
---|
| 419 | */ |
---|
| 420 | extern const ppc_exc_handler_t ppc_exc_handler_table [LAST_VALID_EXC + 1]; |
---|
| 421 | |
---|
| 422 | /** |
---|
| 423 | * @brief Interrupt dispatch routine provided by BSP. |
---|
| 424 | */ |
---|
[599e6fbd] | 425 | void bsp_interrupt_dispatch(uintptr_t exception_number); |
---|
[4bd4c9e] | 426 | #endif /* PPC_EXC_CONFIG_USE_FIXED_HANDLER */ |
---|
[4263155] | 427 | |
---|
[2d2de4eb] | 428 | /** |
---|
| 429 | * @brief Set high-level exception handler. |
---|
| 430 | * |
---|
| 431 | * Hook C exception handlers. |
---|
| 432 | * - handlers for asynchronous exceptions run on the ISR stack |
---|
| 433 | * with thread-dispatching disabled. |
---|
| 434 | * - handlers for synchronous exceptions run on the task stack |
---|
| 435 | * with thread-dispatching enabled. |
---|
| 436 | * |
---|
| 437 | * If a particular slot is NULL then the traditional 'globalExcHdl' is used. |
---|
| 438 | * |
---|
| 439 | * ppc_exc_set_handler() registers a handler (returning 0 on success, |
---|
| 440 | * -1 if the vector argument is too big). |
---|
| 441 | * |
---|
| 442 | * It is legal to set a NULL handler. This leads to the globalExcHdl |
---|
| 443 | * being called if an exception for 'vector' occurs. |
---|
[4bd4c9e] | 444 | * |
---|
| 445 | * @retval RTEMS_SUCCESSFUL Successful operation. |
---|
| 446 | * @retval RTEMS_INVALID_ID Invalid vector number. |
---|
| 447 | * @retval RTEMS_RESOURCE_IN_USE Handler table is read-only and handler does |
---|
| 448 | * not match. |
---|
[2d2de4eb] | 449 | */ |
---|
| 450 | rtems_status_code ppc_exc_set_handler(unsigned vector, ppc_exc_handler_t hdl); |
---|
| 451 | |
---|
| 452 | /** |
---|
| 453 | * @brief Returns the currently active high-level exception handler. |
---|
| 454 | */ |
---|
| 455 | ppc_exc_handler_t ppc_exc_get_handler(unsigned vector); |
---|
| 456 | |
---|
| 457 | /** |
---|
| 458 | * @brief Function for DAR access. |
---|
| 459 | * |
---|
| 460 | * CPU support may store the address of a function here |
---|
| 461 | * that can be used by the default exception handler to |
---|
| 462 | * obtain fault-address info which is helpful. Unfortunately, |
---|
| 463 | * the SPR holding this information is not uniform |
---|
| 464 | * across PPC families so we need assistance from |
---|
| 465 | * CPU support |
---|
| 466 | */ |
---|
| 467 | extern uint32_t (*ppc_exc_get_DAR)(void); |
---|
| 468 | |
---|
| 469 | void |
---|
| 470 | ppc_exc_wrapup(BSP_Exception_frame *f); |
---|
| 471 | |
---|
[88dcb841] | 472 | /** |
---|
| 473 | * @brief Standard aligment handler. |
---|
| 474 | * |
---|
| 475 | * @retval 0 Performed a dcbz instruction. |
---|
| 476 | * @retval -1 Otherwise. |
---|
| 477 | */ |
---|
| 478 | int ppc_exc_alignment_handler(BSP_Exception_frame *frame, unsigned excNum); |
---|
| 479 | |
---|
[2d2de4eb] | 480 | /** @} */ |
---|
[94e1931c] | 481 | |
---|
| 482 | /* |
---|
| 483 | * Compatibility with pc386 |
---|
| 484 | */ |
---|
| 485 | typedef exception_handler_t cpuExcHandlerType; |
---|
| 486 | |
---|
| 487 | #endif /* ASM */ |
---|
| 488 | |
---|
[0f7b6eff] | 489 | #ifdef __cplusplus |
---|
| 490 | } |
---|
| 491 | #endif |
---|
| 492 | |
---|
[2d2de4eb] | 493 | #endif /* LIBCPU_VECTORS_H */ |
---|