[PATCH 2/3] bsps/powerpc: Add PPC_EXC_CONFIG_USE_FIXED_HANDLER

Sebastian Huber sebastian.huber at embedded-brains.de
Fri Nov 30 08:50:13 UTC 2012


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.
---
 .../powerpc/shared/src/ppc-exc-handler-table.c     |   61 ++++++++++++++++++++
 .../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 +++++++++++++-----
 7 files changed, 150 insertions(+), 24 deletions(-)
 create mode 100644 c/src/lib/libbsp/powerpc/shared/src/ppc-exc-handler-table.c

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 0000000..f9fe0e2
--- /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 at 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 ea5a3f9..d4bbaf4 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 at embedded-brains.de>, 2008.
+ * Modified by Sebastian Huber <sebastian.huber at 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 dd6f694..f123166 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 at h
 	ori	HANDLER_REGISTER, HANDLER_REGISTER, ppc_exc_handler_table at 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 at 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 008611c..463f429 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 25d6b26..b24467b 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 9aa56d1..7518f5e 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 at 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 2f1ec37..bcb3b9a 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);
 
-- 
1.7.7




More information about the devel mailing list