summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorSebastian Huber <sebastian.huber@embedded-brains.de>2012-11-23 09:32:52 +0100
committerSebastian Huber <sebastian.huber@embedded-brains.de>2012-12-03 13:17:08 +0100
commit4bd4c9e1f9fad33b2ddf13e246326f16f22ccccd (patch)
treec0a9eea940eed0257b300add42d6a93216e9992d
parentbsps/powerpc: Declare ppc_exc_handler_table (diff)
downloadrtems-4bd4c9e1f9fad33b2ddf13e246326f16f22ccccd.tar.bz2
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.
-rw-r--r--c/src/lib/libbsp/powerpc/shared/src/ppc-exc-handler-table.c61
-rw-r--r--c/src/lib/libcpu/powerpc/new-exceptions/bspsupport/ppc_exc_asm_macros.h11
-rw-r--r--c/src/lib/libcpu/powerpc/new-exceptions/bspsupport/ppc_exc_async_normal.S21
-rw-r--r--c/src/lib/libcpu/powerpc/new-exceptions/bspsupport/ppc_exc_global_handler.c2
-rw-r--r--c/src/lib/libcpu/powerpc/new-exceptions/bspsupport/ppc_exc_hdl.c18
-rw-r--r--c/src/lib/libcpu/powerpc/new-exceptions/bspsupport/ppc_exc_prologue.c6
-rw-r--r--c/src/lib/libcpu/powerpc/new-exceptions/bspsupport/vectors.h55
7 files changed, 150 insertions, 24 deletions
diff --git a/c/src/lib/libbsp/powerpc/shared/src/ppc-exc-handler-table.c b/c/src/lib/libbsp/powerpc/shared/src/ppc-exc-handler-table.c
new file mode 100644
index 0000000000..f9fe0e2470
--- /dev/null
+++ b/c/src/lib/libbsp/powerpc/shared/src/ppc-exc-handler-table.c
@@ -0,0 +1,61 @@
+/*
+ * Copyright (c) 2012 embedded brains GmbH. All rights reserved.
+ *
+ * embedded brains GmbH
+ * Obere Lagerstr. 30
+ * 82178 Puchheim
+ * Germany
+ * <rtems@embedded-brains.de>
+ *
+ * The license and distribution terms for this file may be
+ * found in the file LICENSE in this distribution or at
+ * http://www.rtems.com/license/LICENSE.
+ */
+
+#include <bsp/vectors.h>
+
+#ifdef PPC_EXC_CONFIG_USE_FIXED_HANDLER
+
+static int ppc_exc_interrupt_dispatch(BSP_Exception_frame *f, unsigned vector)
+{
+ bsp_interrupt_dispatch();
+
+ return 0;
+}
+
+const ppc_exc_handler_t ppc_exc_handler_table [LAST_VALID_EXC + 1] = {
+ ppc_exc_handler_default,
+ ppc_exc_handler_default,
+ ppc_exc_handler_default,
+ ppc_exc_handler_default,
+ ppc_exc_handler_default,
+ ppc_exc_interrupt_dispatch,
+ ppc_exc_handler_default,
+ ppc_exc_handler_default,
+ ppc_exc_handler_default,
+ ppc_exc_handler_default,
+ ppc_exc_handler_default,
+ ppc_exc_handler_default,
+ ppc_exc_handler_default,
+ ppc_exc_handler_default,
+ ppc_exc_handler_default,
+ ppc_exc_handler_default,
+ ppc_exc_handler_default,
+ ppc_exc_handler_default,
+ ppc_exc_handler_default,
+ ppc_exc_handler_default,
+ ppc_exc_handler_default,
+ ppc_exc_handler_default,
+ ppc_exc_handler_default,
+ ppc_exc_handler_default,
+ ppc_exc_handler_default,
+ ppc_exc_handler_default,
+ ppc_exc_handler_default,
+ ppc_exc_handler_default,
+ ppc_exc_handler_default,
+ ppc_exc_handler_default,
+ ppc_exc_handler_default,
+ ppc_exc_handler_default
+};
+
+#endif /* PPC_EXC_CONFIG_USE_FIXED_HANDLER */
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 <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
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 <bsp/vectors.h>
-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 <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;
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 <bspopts.h>
+
#include <libcpu/powerpc-utility.h>
#ifdef __cplusplus
@@ -262,11 +264,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.
*/
void C_exception_handler(BSP_Exception_frame* excPtr);
@@ -399,17 +396,21 @@ 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.
*
* Bits in MSR that are enabled during execution of exception handlers / ISRs
@@ -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);