forked from Imagelibrary/rtems
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.
This commit is contained in:
@@ -3,7 +3,7 @@
|
||||
*
|
||||
* Modified and partially rewritten by Till Straumann, 2007-2008
|
||||
*
|
||||
* Modified by Sebastian Huber <sebastian.huber@embedded-brains.de>, 2008.
|
||||
* Modified by Sebastian Huber <sebastian.huber@embedded-brains.de>, 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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -19,8 +19,6 @@
|
||||
|
||||
#include <bsp/vectors.h>
|
||||
|
||||
exception_handler_t globalExceptHdl = C_exception_handler;
|
||||
|
||||
void C_exception_handler(BSP_Exception_frame *excPtr)
|
||||
{
|
||||
rtems_fatal(
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -9,7 +9,7 @@
|
||||
/*
|
||||
* Copyright (C) 2007 Till Straumann <strauman@slac.stanford.edu>
|
||||
*
|
||||
* 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;
|
||||
|
||||
@@ -35,6 +35,8 @@
|
||||
#ifndef LIBCPU_VECTORS_H
|
||||
#define LIBCPU_VECTORS_H
|
||||
|
||||
#include <bspopts.h>
|
||||
|
||||
#include <libcpu/powerpc-utility.h>
|
||||
|
||||
#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);
|
||||
|
||||
|
||||
Reference in New Issue
Block a user