From 4bd4c9e1f9fad33b2ddf13e246326f16f22ccccd Mon Sep 17 00:00:00 2001 From: Sebastian Huber Date: Fri, 23 Nov 2012 09:32:52 +0100 Subject: bsps/powerpc: Add PPC_EXC_CONFIG_USE_FIXED_HANDLER In case a BSP enables this option, then fixed high level exception handler will be used. For normal asynchronous exceptions this is bsp_interrupt_dispatch() and for other exceptions this is the handler from the read-only ppc_exc_handler_table. The global handler is C_exception_handler(). This avoids some dependencies on valid read-write data. --- .../new-exceptions/bspsupport/ppc_exc_asm_macros.h | 11 ++++- .../bspsupport/ppc_exc_async_normal.S | 21 ++++++++- .../bspsupport/ppc_exc_global_handler.c | 2 - .../new-exceptions/bspsupport/ppc_exc_hdl.c | 18 +++++-- .../new-exceptions/bspsupport/ppc_exc_prologue.c | 6 ++- .../powerpc/new-exceptions/bspsupport/vectors.h | 55 +++++++++++++++------- 6 files changed, 89 insertions(+), 24 deletions(-) (limited to 'c/src/lib/libcpu/powerpc') diff --git a/c/src/lib/libcpu/powerpc/new-exceptions/bspsupport/ppc_exc_asm_macros.h b/c/src/lib/libcpu/powerpc/new-exceptions/bspsupport/ppc_exc_asm_macros.h index ea5a3f9614..d4bbaf4fcc 100644 --- a/c/src/lib/libcpu/powerpc/new-exceptions/bspsupport/ppc_exc_asm_macros.h +++ b/c/src/lib/libcpu/powerpc/new-exceptions/bspsupport/ppc_exc_asm_macros.h @@ -3,7 +3,7 @@ * * Modified and partially rewritten by Till Straumann, 2007-2008 * - * Modified by Sebastian Huber , 2008. + * Modified by Sebastian Huber , 2008-2012. * * Low-level assembly code for PPC exceptions (macros). * @@ -825,6 +825,8 @@ wrap_call_global_handler_\_FLVR: /* First parameter = exception frame pointer + FRAME_LINK_SPACE */ addi r3, FRAME_REGISTER, FRAME_LINK_SPACE +#ifndef PPC_EXC_CONFIG_USE_FIXED_HANDLER + /* Load global handler address */ LW SCRATCH_REGISTER_0, globalExceptHdl @@ -836,6 +838,13 @@ wrap_call_global_handler_\_FLVR: mtctr SCRATCH_REGISTER_0 bctrl +#else /* PPC_EXC_CONFIG_USE_FIXED_HANDLER */ + + /* Call fixed global handler */ + bl C_exception_handler + +#endif /* PPC_EXC_CONFIG_USE_FIXED_HANDLER */ + b wrap_handler_done_\_FLVR .endm diff --git a/c/src/lib/libcpu/powerpc/new-exceptions/bspsupport/ppc_exc_async_normal.S b/c/src/lib/libcpu/powerpc/new-exceptions/bspsupport/ppc_exc_async_normal.S index dd6f694cc8..f123166b0d 100644 --- a/c/src/lib/libcpu/powerpc/new-exceptions/bspsupport/ppc_exc_async_normal.S +++ b/c/src/lib/libcpu/powerpc/new-exceptions/bspsupport/ppc_exc_async_normal.S @@ -1,5 +1,5 @@ /* - * Copyright (c) 2011 embedded brains GmbH. All rights reserved. + * Copyright (c) 2011-2012 embedded brains GmbH. All rights reserved. * * embedded brains GmbH * Obere Lagerstr. 30 @@ -46,14 +46,21 @@ */ #define FRAME_OFFSET(reg) GPR2_OFFSET(reg) +#ifdef PPC_EXC_CONFIG_USE_FIXED_HANDLER + .global bsp_interrupt_dispatch +#endif /* PPC_EXC_CONFIG_USE_FIXED_HANDLER */ + .global ppc_exc_min_prolog_async_tmpl_normal .global ppc_exc_wrap_async_normal ppc_exc_min_prolog_async_tmpl_normal: stwu r1, -PPC_EXC_MINIMAL_FRAME_SIZE(r1) + +#ifndef PPC_EXC_CONFIG_USE_FIXED_HANDLER stw VECTOR_REGISTER, PPC_EXC_VECTOR_PROLOGUE_OFFSET(r1) li VECTOR_REGISTER, 0xffff8000 +#endif /* PPC_EXC_CONFIG_USE_FIXED_HANDLER */ /* * We store the absolute branch target address here. It will be used @@ -87,6 +94,7 @@ ppc_exc_wrap_async_normal: PPC_GPR_STORE SCRATCH_0_REGISTER, SCRATCH_0_OFFSET(r1) +#ifndef PPC_EXC_CONFIG_USE_FIXED_HANDLER #ifdef __SPE__ /* * Save high order part of VECTOR_REGISTER here. The low order part @@ -95,9 +103,14 @@ ppc_exc_wrap_async_normal: evmergehi SCRATCH_0_REGISTER, SCRATCH_0_REGISTER, VECTOR_REGISTER stw SCRATCH_0_REGISTER, VECTOR_OFFSET(r1) #endif +#else /* PPC_EXC_CONFIG_USE_FIXED_HANDLER */ + /* The vector register has no special purpose in this case */ + PPC_GPR_STORE VECTOR_REGISTER, VECTOR_OFFSET(r1) +#endif /* PPC_EXC_CONFIG_USE_FIXED_HANDLER */ PPC_GPR_STORE HANDLER_REGISTER, HANDLER_OFFSET(r1) +#ifndef PPC_EXC_CONFIG_USE_FIXED_HANDLER /* * Load the handler address. Get the handler table index from the * vector number. We have to discard the exception type. Take only @@ -108,6 +121,7 @@ ppc_exc_wrap_async_normal: lis HANDLER_REGISTER, ppc_exc_handler_table@h ori HANDLER_REGISTER, HANDLER_REGISTER, ppc_exc_handler_table@l lwzx HANDLER_REGISTER, HANDLER_REGISTER, SCRATCH_0_REGISTER +#endif /* PPC_EXC_CONFIG_USE_FIXED_HANDLER */ PPC_GPR_STORE SCRATCH_1_REGISTER, SCRATCH_1_OFFSET(r1) PPC_GPR_STORE SCRATCH_2_REGISTER, SCRATCH_2_OFFSET(r1) @@ -149,6 +163,7 @@ ppc_exc_wrap_async_normal: mfspr SCRATCH_0_REGISTER, SPRG1 iselgt r1, r1, SCRATCH_0_REGISTER +#ifndef PPC_EXC_CONFIG_USE_FIXED_HANDLER /* * Call high level exception handler. * @@ -159,6 +174,10 @@ ppc_exc_wrap_async_normal: rlwinm VECTOR_REGISTER, VECTOR_REGISTER, 0, 27, 31 mtctr HANDLER_REGISTER bctrl +#else /* PPC_EXC_CONFIG_USE_FIXED_HANDLER */ + /* Call fixed high level handler */ + bl bsp_interrupt_dispatch +#endif /* PPC_EXC_CONFIG_USE_FIXED_HANDLER */ /* Load ISR nest level and thread dispatch disable level */ lis ISR_NEST_HADDR_REGISTER, ISR_NEST_LEVEL@ha diff --git a/c/src/lib/libcpu/powerpc/new-exceptions/bspsupport/ppc_exc_global_handler.c b/c/src/lib/libcpu/powerpc/new-exceptions/bspsupport/ppc_exc_global_handler.c index 008611c6ff..463f429c58 100644 --- a/c/src/lib/libcpu/powerpc/new-exceptions/bspsupport/ppc_exc_global_handler.c +++ b/c/src/lib/libcpu/powerpc/new-exceptions/bspsupport/ppc_exc_global_handler.c @@ -19,8 +19,6 @@ #include -exception_handler_t globalExceptHdl = C_exception_handler; - void C_exception_handler(BSP_Exception_frame *excPtr) { rtems_fatal( diff --git a/c/src/lib/libcpu/powerpc/new-exceptions/bspsupport/ppc_exc_hdl.c b/c/src/lib/libcpu/powerpc/new-exceptions/bspsupport/ppc_exc_hdl.c index 25d6b26faa..b24467b8e9 100644 --- a/c/src/lib/libcpu/powerpc/new-exceptions/bspsupport/ppc_exc_hdl.c +++ b/c/src/lib/libcpu/powerpc/new-exceptions/bspsupport/ppc_exc_hdl.c @@ -39,16 +39,22 @@ uint32_t ppc_exc_vector_register_mchk = 0; */ uint32_t ppc_exc_msr_bits = MSR_IR | MSR_DR | MSR_RI; -static int ppc_exc_handler_default(BSP_Exception_frame *f, unsigned int vector) +int ppc_exc_handler_default(BSP_Exception_frame *f, unsigned int vector) { return -1; } +#ifndef PPC_EXC_CONFIG_USE_FIXED_HANDLER + +exception_handler_t globalExceptHdl = C_exception_handler; + /* Table of C-handlers */ ppc_exc_handler_t ppc_exc_handler_table [LAST_VALID_EXC + 1] = { [0 ... LAST_VALID_EXC] = ppc_exc_handler_default }; +#endif /* PPC_EXC_CONFIG_USE_FIXED_HANDLER */ + ppc_exc_handler_t ppc_exc_get_handler(unsigned vector) { if ( @@ -65,9 +71,15 @@ rtems_status_code ppc_exc_set_handler(unsigned vector, ppc_exc_handler_t handler { if (vector <= LAST_VALID_EXC) { if (handler == NULL) { - ppc_exc_handler_table [vector] = ppc_exc_handler_default; - } else { + handler = ppc_exc_handler_default; + } + + if (ppc_exc_handler_table [vector] != handler) { +#ifndef PPC_EXC_CONFIG_USE_FIXED_HANDLER ppc_exc_handler_table [vector] = handler; +#else /* PPC_EXC_CONFIG_USE_FIXED_HANDLER */ + return RTEMS_RESOURCE_IN_USE; +#endif /* PPC_EXC_CONFIG_USE_FIXED_HANDLER */ } return RTEMS_SUCCESSFUL; diff --git a/c/src/lib/libcpu/powerpc/new-exceptions/bspsupport/ppc_exc_prologue.c b/c/src/lib/libcpu/powerpc/new-exceptions/bspsupport/ppc_exc_prologue.c index 9aa56d1c13..7518f5e496 100644 --- a/c/src/lib/libcpu/powerpc/new-exceptions/bspsupport/ppc_exc_prologue.c +++ b/c/src/lib/libcpu/powerpc/new-exceptions/bspsupport/ppc_exc_prologue.c @@ -9,7 +9,7 @@ /* * Copyright (C) 2007 Till Straumann * - * Copyright (C) 2009 embedded brains GmbH. + * Copyright (C) 2009-2012 embedded brains GmbH. * * The license and distribution terms for this file may be * found in the file LICENSE in this distribution or at @@ -135,8 +135,12 @@ rtems_status_code ppc_exc_make_prologue( && (ppc_interrupt_get_disable_mask() & MSR_CE) == 0 ) { prologue_template = ppc_exc_min_prolog_async_tmpl_normal; +#ifndef PPC_EXC_CONFIG_USE_FIXED_HANDLER prologue_template_size = (size_t) ppc_exc_min_prolog_size; fixup_vector = true; +#else /* PPC_EXC_CONFIG_USE_FIXED_HANDLER */ + prologue_template_size = 8; +#endif /* PPC_EXC_CONFIG_USE_FIXED_HANDLER */ } else { prologue_template = ppc_exc_prologue_templates [category]; prologue_template_size = (size_t) ppc_exc_min_prolog_size; 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 2f1ec37290..bcb3b9a114 100644 --- a/c/src/lib/libcpu/powerpc/new-exceptions/bspsupport/vectors.h +++ b/c/src/lib/libcpu/powerpc/new-exceptions/bspsupport/vectors.h @@ -35,6 +35,8 @@ #ifndef LIBCPU_VECTORS_H #define LIBCPU_VECTORS_H +#include + #include #ifdef __cplusplus @@ -261,11 +263,6 @@ typedef CPU_Exception_frame BSP_Exception_frame; */ typedef void (*exception_handler_t)(BSP_Exception_frame*); -/** - * @brief Global exception handler. - */ -extern exception_handler_t globalExceptHdl; - /** * @brief Default global exception handler. */ @@ -399,16 +396,20 @@ void ppc_exc_initialize( /** * @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. + * @retval 0 The exception was handled and normal execution may resume. + * @retval -1 Reject the exception resulting in a call of the global exception + * handler. + * @retval other Reserved, do not use. */ typedef int (*ppc_exc_handler_t)(BSP_Exception_frame *f, unsigned vector); +/** + * @brief Default high-level exception handler. + * + * @retval -1 Always. + */ +int ppc_exc_handler_default(BSP_Exception_frame *f, unsigned int vector); + /** * @brief Bits for MSR update. * @@ -436,10 +437,27 @@ extern uint32_t ppc_exc_msr_bits; */ extern uint32_t ppc_exc_cache_wb_check; -/** - * @brief High-level exception handler table. - */ -extern ppc_exc_handler_t ppc_exc_handler_table [LAST_VALID_EXC + 1]; +#ifndef PPC_EXC_CONFIG_USE_FIXED_HANDLER + /** + * @brief High-level exception handler table. + */ + extern ppc_exc_handler_t ppc_exc_handler_table [LAST_VALID_EXC + 1]; + + /** + * @brief Global exception handler. + */ + extern exception_handler_t globalExceptHdl; +#else /* PPC_EXC_CONFIG_USE_FIXED_HANDLER */ + /** + * @brief High-level exception handler table. + */ + extern const ppc_exc_handler_t ppc_exc_handler_table [LAST_VALID_EXC + 1]; + + /** + * @brief Interrupt dispatch routine provided by BSP. + */ + void bsp_interrupt_dispatch(void); +#endif /* PPC_EXC_CONFIG_USE_FIXED_HANDLER */ /** * @brief Set high-level exception handler. @@ -457,6 +475,11 @@ extern ppc_exc_handler_t ppc_exc_handler_table [LAST_VALID_EXC + 1]; * * It is legal to set a NULL handler. This leads to the globalExcHdl * being called if an exception for 'vector' occurs. + * + * @retval RTEMS_SUCCESSFUL Successful operation. + * @retval RTEMS_INVALID_ID Invalid vector number. + * @retval RTEMS_RESOURCE_IN_USE Handler table is read-only and handler does + * not match. */ rtems_status_code ppc_exc_set_handler(unsigned vector, ppc_exc_handler_t hdl); -- cgit v1.2.3