diff options
Diffstat (limited to '')
-rw-r--r-- | c/src/lib/libcpu/powerpc/new-exceptions/bspsupport/vectors.h | 486 |
1 files changed, 409 insertions, 77 deletions
diff --git a/c/src/lib/libcpu/powerpc/new-exceptions/bspsupport/vectors.h b/c/src/lib/libcpu/powerpc/new-exceptions/bspsupport/vectors.h index eb60413232..63fd206f70 100644 --- a/c/src/lib/libcpu/powerpc/new-exceptions/bspsupport/vectors.h +++ b/c/src/lib/libcpu/powerpc/new-exceptions/bspsupport/vectors.h @@ -1,21 +1,147 @@ -/* - * vectors.h Exception frame related contant and API. +/** + * @file * - * This include file describe the data structure and the functions implemented - * by rtems to handle exceptions. + * @ingroup ppc_exc + * @ingroup ppc_exc_frame * - * CopyRight (C) 1999 valette@crf.canon.fr + * @brief PowerPC Exceptions API. + */ + +/* + * Copyright (C) 1999 Eric Valette (valette@crf.canon.fr) + * Canon Centre Recherche France. * - * The license and distribution terms for this file may be - * found in found in the file LICENSE in this distribution or at - * http://www.rtems.com/license/LICENSE. + * Copyright (C) 2007 Till Straumann <strauman@slac.stanford.edu> + * + * Copyright (C) 2009 embedded brains GmbH. + * + * Enhanced by Jay Kulpinski <jskulpin@eng01.gdds.com> + * to support 603, 603e, 604, 604e exceptions + * + * Moved to "libcpu/powerpc/new-exceptions" and consolidated + * by Thomas Doerfler <Thomas.Doerfler@embedded-brains.de> + * to be common for all PPCs with new exceptions. + * + * Derived from file "libcpu/powerpc/new-exceptions/raw_exception.h". + * Derived from file "libcpu/powerpc/new-exceptions/bspsupport/ppc_exc_bspsupp.h". + * + * The license and distribution terms for this file may be + * found in found in the file LICENSE in this distribution or at + * http://www.rtems.com/license/LICENSE. + * + * $Id$ + */ + +/* DO NOT INTRODUCE #ifdef <cpu_flavor> in this file */ + +#ifndef LIBCPU_VECTORS_H +#define LIBCPU_VECTORS_H + +#include <libcpu/powerpc-utility.h> + +/** + * @defgroup ppc_exc PowerPC Exceptions + * + * @brief XXX * - * $Id$ + * @{ + */ + +#define ASM_RESET_VECTOR 0x01 +#define ASM_MACH_VECTOR 0x02 +#define ASM_PROT_VECTOR 0x03 +#define ASM_ISI_VECTOR 0x04 +#define ASM_EXT_VECTOR 0x05 +#define ASM_ALIGN_VECTOR 0x06 +#define ASM_PROG_VECTOR 0x07 +#define ASM_FLOAT_VECTOR 0x08 +#define ASM_DEC_VECTOR 0x09 +#define ASM_SYS_VECTOR 0x0C +#define ASM_TRACE_VECTOR 0x0D + +#define ASM_BOOKE_CRIT_VECTOR 0x01 +/* We could use the std. decrementer vector # on bookE, too, + * but the bookE decrementer has slightly different semantics + * so we use a different vector (which happens to be + * the PIT vector on the 405 which is like the booke decrementer) */ -#ifndef LIBCPU_POWERPC_BSPSUPP_VECTORS_H -#define LIBCPU_POWERPC_BSPSUPP_VECTORS_H +#define ASM_BOOKE_DEC_VECTOR 0x10 +#define ASM_BOOKE_ITLBMISS_VECTOR 0x11 +#define ASM_BOOKE_DTLBMISS_VECTOR 0x12 +#define ASM_BOOKE_FIT_VECTOR 0x13 +#define ASM_BOOKE_WDOG_VECTOR 0x14 + +#define ASM_PPC405_APU_UNAVAIL_VECTOR ASM_60X_VEC_ASSIST_VECTOR -#include <libcpu/raw_exception.h> +#define ASM_8XX_FLOATASSIST_VECTOR 0x0E +#define ASM_8XX_SOFTEMUL_VECTOR 0x10 +#define ASM_8XX_ITLBMISS_VECTOR 0x11 +#define ASM_8XX_DTLBMISS_VECTOR 0x12 +#define ASM_8XX_ITLBERROR_VECTOR 0x13 +#define ASM_8XX_DTLBERROR_VECTOR 0x14 +#define ASM_8XX_DBREAK_VECTOR 0x1C +#define ASM_8XX_IBREAK_VECTOR 0x1D +#define ASM_8XX_PERIFBREAK_VECTOR 0x1E +#define ASM_8XX_DEVPORT_VECTOR 0x1F + +#define ASM_5XX_FLOATASSIST_VECTOR 0x0E +#define ASM_5XX_SOFTEMUL_VECTOR 0x10 +#define ASM_5XX_IPROT_VECTOR 0x13 +#define ASM_5XX_DPROT_VECTOR 0x14 +#define ASM_5XX_DBREAK_VECTOR 0x1C +#define ASM_5XX_IBREAK_VECTOR 0x1D +#define ASM_5XX_MEBREAK_VECTOR 0x1E +#define ASM_5XX_NMEBREAK_VECTOR 0x1F + +#define ASM_60X_VEC_VECTOR 0x0A +#define ASM_60X_PERFMON_VECTOR 0x0F +#define ASM_60X_IMISS_VECTOR 0x10 +#define ASM_60X_DLMISS_VECTOR 0x11 +#define ASM_60X_DSMISS_VECTOR 0x12 +#define ASM_60X_ADDR_VECTOR 0x13 +#define ASM_60X_SYSMGMT_VECTOR 0x14 +#define ASM_60X_VEC_ASSIST_VECTOR 0x16 +#define ASM_60X_ITM_VECTOR 0x17 + +/* e200 */ +#define ASM_E200_SPE_UNAVAILABLE_VECTOR 0x15 +#define ASM_E200_SPE_DATA_VECTOR 0x16 +#define ASM_E200_SPE_ROUND_VECTOR 0x17 + +/* e300 */ +#define ASM_E300_CRIT_VECTOR 0x0A +#define ASM_E300_PERFMON_VECTOR 0x0F +#define ASM_E300_IMISS_VECTOR ASM_60X_IMISS_VECTOR /* Special case: Shadowed GPRs */ +#define ASM_E300_DLMISS_VECTOR ASM_60X_DLMISS_VECTOR /* Special case: Shadowed GPRs */ +#define ASM_E300_DSMISS_VECTOR ASM_60X_DSMISS_VECTOR /* Special case: Shadowed GPRs */ +#define ASM_E300_ADDR_VECTOR 0x13 +#define ASM_E300_SYSMGMT_VECTOR 0x14 + +/* + * If you change that number make sure to adjust the wrapper code in ppc_exc.S + * and that ppc_exc_handler_table will be correctly initialized. + */ +#define LAST_VALID_EXC 0x1F + +/* DO NOT USE -- this symbol is DEPRECATED + * (only used by libbsp/shared/vectors/vectors.S + * which should not be used by new BSPs). + */ +#define ASM_60X_VEC_VECTOR_OFFSET 0xf20 + +#define ASM_PPC405_FIT_VECTOR_OFFSET 0x1010 +#define ASM_PPC405_WDOG_VECTOR_OFFSET 0x1020 +#define ASM_PPC405_TRACE_VECTOR_OFFSET 0x2000 + +/** @} */ + +/** + * @defgroup ppc_exc_frame PowerPC Exception Frame + * + * @brief XXX + * + * @{ + */ /* * The callee (high level exception code written in C) @@ -73,85 +199,291 @@ */ #define EXCEPTION_FRAME_END 176 +/** @} */ + #ifndef ASM -#include <stdint.h> +/** + * @ingroup ppc_exc_frame + * + * @{ + */ + +typedef struct { + unsigned EXC_SRR0; + unsigned EXC_SRR1; + unsigned _EXC_number; + unsigned GPR0; + unsigned GPR1; + unsigned GPR2; + unsigned GPR3; + unsigned GPR4; + unsigned GPR5; + unsigned GPR6; + unsigned GPR7; + unsigned GPR8; + unsigned GPR9; + unsigned GPR10; + unsigned GPR11; + unsigned GPR12; + unsigned GPR13; + unsigned GPR14; + unsigned GPR15; + unsigned GPR16; + unsigned GPR17; + unsigned GPR18; + unsigned GPR19; + unsigned GPR20; + unsigned GPR21; + unsigned GPR22; + unsigned GPR23; + unsigned GPR24; + unsigned GPR25; + unsigned GPR26; + unsigned GPR27; + unsigned GPR28; + unsigned GPR29; + unsigned GPR30; + unsigned GPR31; + unsigned EXC_CR; + unsigned EXC_CTR; + unsigned EXC_XER; + unsigned EXC_LR; + unsigned EXC_MSR; + unsigned EXC_DAR; +} BSP_Exception_frame; + +/** @} */ + +/** + * @ingroup ppc_exc + * + * @{ + */ + +/** + * @brief Global exception handler type. + */ +typedef void (*exception_handler_t)(BSP_Exception_frame*); + +/** + * @brief Global exception handler. + */ +extern exception_handler_t globalExceptHdl; + +/** + * @brief Default global exception handler. + */ +void C_exception_handler(BSP_Exception_frame* excPtr); + +void BSP_printStackTrace(BSP_Exception_frame *excPtr); + +/** + * @brief Exception categories. + * + * Exceptions of different categories use different SRR registers to save the + * machine state and do different things in the prologue and epilogue. + * + * For now, the CPU descriptions assume this fits into 8 bits. + */ +typedef enum { + PPC_EXC_INVALID = 0, + PPC_EXC_ASYNC = 1, + PPC_EXC_CLASSIC = 2, + PPC_EXC_CLASSIC_ASYNC = PPC_EXC_CLASSIC | PPC_EXC_ASYNC, + PPC_EXC_405_CRITICAL = 4, + PPC_EXC_405_CRITICAL_ASYNC = PPC_EXC_405_CRITICAL | PPC_EXC_ASYNC, + PPC_EXC_BOOKE_CRITICAL = 6, + PPC_EXC_BOOKE_CRITICAL_ASYNC = PPC_EXC_BOOKE_CRITICAL | PPC_EXC_ASYNC, + PPC_EXC_E500_MACHCHK = 8, + PPC_EXC_E500_MACHCHK_ASYNC = PPC_EXC_E500_MACHCHK | PPC_EXC_ASYNC, + PPC_EXC_NAKED = 10 +} ppc_exc_category; + +/** + * @brief Categorie set type. + */ +typedef uint8_t ppc_exc_categories [LAST_VALID_EXC + 1]; + +static inline bool ppc_exc_is_valid_category(ppc_exc_category category) +{ + return (unsigned) category <= (unsigned) PPC_EXC_NAKED; +} + +/** + * @brief Indicates if exception entry table resides in a writable memory. + * + * This variable is initialized to 'TRUE' by default; + * BSPs which have their vectors in ROM should set it + * to FALSE prior to initializing raw exceptions. + * + * I suspect the only candidate is the simulator. + * After all, the value of this variable is used to + * determine where to install the prologue code and + * installing to ROM on anyting that's real ROM + * will fail anyways. + * + * This should probably go away... (T.S. 2007/11/30) + */ +extern bool bsp_exceptions_in_RAM; + +/** + * @brief Vector base address for CPUs (for example e200 and e500) with IVPR + * and IVOR registers. + */ +extern uint32_t ppc_exc_vector_base; + +/** + * @brief Returns the entry address of the vector @a vector. + */ +void *ppc_exc_vector_address(unsigned vector); + +/** + * @brief Returns the category set for a CPU of type @a cpu, or @c NULL if + * there is no category set available for this CPU. + */ +const ppc_exc_categories *ppc_exc_categories_for_cpu(ppc_cpu_id_t cpu); + +/** + * @brief Returns the category set for the current CPU, or @c NULL if there is + * no category set available for this CPU. + */ +static inline const ppc_exc_categories *ppc_exc_current_categories(void) +{ + return ppc_exc_categories_for_cpu(ppc_cpu_current()); +} -/* codemove is like memmove, but it also gets the cache line size - * as 4th parameter to synchronize them. If this last parameter is - * zero, it performs more or less like memmove. No copy is performed if - * source and destination addresses are equal. However the caches - * are synchronized. Note that the size is always rounded up to the - * next mutiple of 4. +/** + * @brief Returns the category for the vector @a vector using the category set + * @a categories. */ -extern void * codemove(void *, const void *, unsigned int, unsigned long); -extern void exception_nop_enable(const rtems_raw_except_connect_data* ptr); -extern int exception_always_enabled(const rtems_raw_except_connect_data* ptr); +ppc_exc_category ppc_exc_category_for_vector( + const ppc_exc_categories *categories, + unsigned vector +); + +/** + * @brief Makes a minimal prologue for the vector @a vector with the category + * @a category. + * + * The minimal prologue will be copied to @a prologue. Not more than @a + * prologue_size bytes will be copied. Returns the actual minimal prologue + * size in bytes in @a prologue_size. + * + * @retval RTEMS_SUCCESSFUL Minimal prologue successfully made. + * @retval RTEMS_INVALID_ID Invalid vector number. + * @retval RTEMS_INVALID_NUMBER Invalid category. + * @retval RTEMS_INVALID_SIZE Prologue size to small. + */ +rtems_status_code ppc_exc_make_prologue( + unsigned vector, + ppc_exc_category category, + uint32_t *prologue, + size_t *prologue_size +); -void ppc_exc_initialize( +/** + * @brief Initializes the exception handling. + * + * @retval RTEMS_SUCCESSFUL Successful initialization. + * @retval RTEMS_NOT_IMPLEMENTED No category set available for the current CPU. + * @retval RTEMS_NOT_CONFIGURED Register r13 does not point to the small data + * area anchor required by SVR4/EABI. + * @retval RTEMS_INTERNAL_ERROR Minimal prologue creation failed. + */ +rtems_status_code ppc_exc_initialize( uint32_t interrupt_disable_mask, - uint32_t interrupt_stack_start, - uint32_t interrupt_stack_size + uintptr_t interrupt_stack_begin, + uintptr_t interrupt_stack_size ); -typedef struct _BSP_Exception_frame { - unsigned EXC_SRR0; - unsigned EXC_SRR1; - unsigned _EXC_number; - unsigned GPR0; - unsigned GPR1; - unsigned GPR2; - unsigned GPR3; - unsigned GPR4; - unsigned GPR5; - unsigned GPR6; - unsigned GPR7; - unsigned GPR8; - unsigned GPR9; - unsigned GPR10; - unsigned GPR11; - unsigned GPR12; - unsigned GPR13; - unsigned GPR14; - unsigned GPR15; - unsigned GPR16; - unsigned GPR17; - unsigned GPR18; - unsigned GPR19; - unsigned GPR20; - unsigned GPR21; - unsigned GPR22; - unsigned GPR23; - unsigned GPR24; - unsigned GPR25; - unsigned GPR26; - unsigned GPR27; - unsigned GPR28; - unsigned GPR29; - unsigned GPR30; - unsigned GPR31; - unsigned EXC_CR; - unsigned EXC_CTR; - unsigned EXC_XER; - unsigned EXC_LR; - unsigned EXC_MSR; - unsigned EXC_DAR; -} BSP_Exception_frame; +/** + * @brief High-level exception handler type. + * + * Exception handlers should return zero if the exception was handled and + * normal execution may resume. + * + * They should return minus one to reject the exception resulting in the + * globalExcHdl() being called. + * + * Other return values are reserved. + */ +typedef int (*ppc_exc_handler_t)(BSP_Exception_frame *f, unsigned vector); + +/** + * @brief Bits for MSR update. + * + * Bits in MSR that are enabled during execution of exception handlers / ISRs + * (on classic PPC these are DR/IR/RI [default], on bookE-style CPUs they should + * be set to 0 during initialization) + * + * By default, the setting of these bits that is in effect when exception + * handling is initialized is used. + */ +extern uint32_t ppc_exc_msr_bits; + +/** + * @brief Cache write back check flag. + * + * (See README under CAVEATS). During initialization + * a check is performed to assert that write-back + * caching is enabled for memory accesses. If a BSP + * runs entirely without any caching then it should + * set this variable to zero prior to initializing + * exceptions in order to skip the test. + * NOTE: The code does NOT support mapping memory + * with cache-attributes other than write-back + * (unless the entire cache is physically disabled) + */ +extern uint32_t ppc_exc_cache_wb_check; + +/** + * @brief Set high-level exception handler. + * + * Hook C exception handlers. + * - handlers for asynchronous exceptions run on the ISR stack + * with thread-dispatching disabled. + * - handlers for synchronous exceptions run on the task stack + * with thread-dispatching enabled. + * + * If a particular slot is NULL then the traditional 'globalExcHdl' is used. + * + * ppc_exc_set_handler() registers a handler (returning 0 on success, + * -1 if the vector argument is too big). + * + * It is legal to set a NULL handler. This leads to the globalExcHdl + * being called if an exception for 'vector' occurs. + */ +rtems_status_code ppc_exc_set_handler(unsigned vector, ppc_exc_handler_t hdl); + +/** + * @brief Returns the currently active high-level exception handler. + */ +ppc_exc_handler_t ppc_exc_get_handler(unsigned vector); + +/** + * @brief Function for DAR access. + * + * CPU support may store the address of a function here + * that can be used by the default exception handler to + * obtain fault-address info which is helpful. Unfortunately, + * the SPR holding this information is not uniform + * across PPC families so we need assistance from + * CPU support + */ +extern uint32_t (*ppc_exc_get_DAR)(void); + +void +ppc_exc_wrapup(BSP_Exception_frame *f); + +/** @} */ -typedef void (*exception_handler_t) (BSP_Exception_frame* excPtr); -extern exception_handler_t globalExceptHdl; /* * Compatibility with pc386 */ typedef BSP_Exception_frame CPU_Exception_frame; typedef exception_handler_t cpuExcHandlerType; -/* - * dummy functions for exception interface - */ -void exception_nop_enable(const rtems_raw_except_connect_data* ptr); -int exception_always_enabled(const rtems_raw_except_connect_data* ptr); - #endif /* ASM */ -#endif /* LIBCPU_POWERPC_BSPSUPP_VECTORS_H */ +#endif /* LIBCPU_VECTORS_H */ |