summaryrefslogtreecommitdiffstats
path: root/c/src/lib/libcpu/powerpc/mpc5xx/vectors
diff options
context:
space:
mode:
authorJoel Sherrill <joel.sherrill@OARcorp.com>2004-04-12 22:04:28 +0000
committerJoel Sherrill <joel.sherrill@OARcorp.com>2004-04-12 22:04:28 +0000
commit8430205c224c1bfcb67156e5b97dd44ecd81fd7d (patch)
tree5ce5170ec6f228407d7ebfab0c1efbf17c495595 /c/src/lib/libcpu/powerpc/mpc5xx/vectors
parent2004-04-12 David Querbach <querbach@realtime.bc.ca> (diff)
downloadrtems-8430205c224c1bfcb67156e5b97dd44ecd81fd7d.tar.bz2
2004-04-12 David Querbach <querbach@realtime.bc.ca>
* README, configure.ac, mpc5xx/Makefile.am, mpc5xx/exceptions/raw_exception.c, mpc5xx/exceptions/raw_exception.h, mpc5xx/timer/timer.c, shared/include/cpuIdent.h: addition of a significant amount of MPC5xx support as part of the addition of the SS555 BSP. * mpc5xx/README, mpc5xx/clock/clock.c, mpc5xx/console-generic/console-generic.c, mpc5xx/include/console.h, mpc5xx/include/mpc5xx.h, mpc5xx/irq/irq.c, mpc5xx/irq/irq.h, mpc5xx/irq/irq_asm.S, mpc5xx/irq/irq_init.c, mpc5xx/vectors/vectors.S, mpc5xx/vectors/vectors.h, mpc5xx/vectors/vectors_init.c: New files. * mpc5xx/exceptions/asm_utils.S: Removed.
Diffstat (limited to 'c/src/lib/libcpu/powerpc/mpc5xx/vectors')
-rw-r--r--c/src/lib/libcpu/powerpc/mpc5xx/vectors/vectors.S203
-rw-r--r--c/src/lib/libcpu/powerpc/mpc5xx/vectors/vectors.h156
-rw-r--r--c/src/lib/libcpu/powerpc/mpc5xx/vectors/vectors_init.c137
3 files changed, 496 insertions, 0 deletions
diff --git a/c/src/lib/libcpu/powerpc/mpc5xx/vectors/vectors.S b/c/src/lib/libcpu/powerpc/mpc5xx/vectors/vectors.S
new file mode 100644
index 0000000000..125e3f60a4
--- /dev/null
+++ b/c/src/lib/libcpu/powerpc/mpc5xx/vectors/vectors.S
@@ -0,0 +1,203 @@
+/*
+ * vectors.S
+ *
+ * This file contains the assembly code for the PowerPC exception veneers
+ * for RTEMS.
+ *
+ *
+ * MPC5xx port sponsored by Defence Research and Development Canada - Suffield
+ * Copyright (C) 2004, Real-Time Systems Inc. (querbach@realtime.bc.ca)
+ *
+ * Derived from libbsp/powerpc/mbx8xx/vectors/vectors.S,
+ *
+ * (c) 1999, Eric Valette valette@crf.canon.fr
+ *
+ * $Id$
+ */
+
+#include <asm.h>
+#include <rtems/score/cpu.h>
+#include <libcpu/vectors.h>
+
+#define SYNC \
+ sync; \
+ isync
+
+
+/*
+ * Hardware exception vector table.
+ *
+ * The MPC555 can be configured to use a compressed vector table with 8
+ * bytes per entry, rather than the usual 0x100 bytes of other PowerPC
+ * devices. The following macro uses this feature to save the better part
+ * of 8 kbytes of flash ROM.
+ *
+ * Each vector table entry has room for only a simple branch instruction
+ * which branches to a prologue specific to that exception. This
+ * exception-specific prologue begins the context save, loads the exception
+ * number into a register, and jumps to a common exception prologue, below.
+ */
+
+ .macro vectors num=0, total=NUM_EXCEPTIONS /* create vector table */
+
+/* vector table entry */
+ .section .vectors, "ax"
+
+ ba specific_prologue\@ /* run specific prologue */
+ .long 0 /* each entry is 8 bytes */
+
+/* exception-specific prologue */
+ .text
+
+specific_prologue\@:
+ stwu r1, -EXCEPTION_FRAME_END(r1) /* open stack frame */
+ stw r4, GPR4_OFFSET(r1) /* preserve register */
+ li r4, \num /* get exception number */
+ b common_prologue /* run common prologue */
+
+/* invoke macro recursively to create remainder of table */
+ .if \total - (\num + 1)
+ vectors "(\num + 1)", \total
+ .endif
+
+ .endm
+
+
+/* invoke macro to create entire vector table */
+ vectors
+
+
+/*
+ * Common exception prologue.
+ *
+ * Because the MPC555 vector table is in flash ROM, it's not possible to
+ * change the exception handlers by overwriting them at run-time, so this
+ * common exception prologue uses a table of exception handler pointers to
+ * provide equivalent flexibility.
+ *
+ * When the actual exception handler is run, R1 points to the base of a new
+ * exception stack frame, in which R3, R4 and LR have been saved. R4 holds
+ * the exception number.
+ */
+ .text
+
+common_prologue:
+ stw r3, GPR3_OFFSET(r1) /* preserve registers */
+ mflr r3
+ stw r3, EXC_LR_OFFSET(r1)
+
+ slwi r3, r4, 2 /* make table offset */
+ addis r3, r3, exception_handler_table@ha /* point to entry */
+ addi r3, r3, exception_handler_table@l
+ lwz r3, 0(r3) /* get entry */
+ mtlr r3 /* run it */
+ blr
+
+
+/*
+ * Default exception handler.
+ *
+ * The function initialize_exceptions() initializes all of the entries in
+ * the exception handler table with pointers to this routine, which saves
+ * the remainder of the interrupted code's state, then calls
+ * C_default_exception_handler() to dump registers.
+ *
+ * On entry, R1 points to a new exception stack frame in which R3, R4, and
+ * LR have been saved. R4 holds the exception number.
+ */
+ .text
+
+PUBLIC_VAR(default_exception_handler)
+SYM (default_exception_handler):
+ /*
+ * Save the interrupted code's program counter and MSR. Beyond this
+ * point, all exceptions are recoverable. Use an RCPU-specific SPR
+ * to set the RI bit in the MSR to indicate the recoverable state.
+ */
+ mfsrr0 r3
+ stw r3, SRR0_FRAME_OFFSET(r1)
+ mfsrr1 r3
+ stw r3, SRR1_FRAME_OFFSET(r1)
+
+ mtspr eid, r3 /* set MSR[RI], clear MSR[EE] */
+ SYNC
+
+ /*
+ * Save the remainder of the general-purpose registers.
+ *
+ * Compute the value of R1 at exception entry before storing it in
+ * the frame.
+ *
+ * Note that R2 should never change (it's the EABI pointer to
+ * .sdata2), but we save it just in case.
+ *
+ * Recall that R3 and R4 were saved by the specific- and
+ * common-exception handlers before entry to this routine.
+ */
+ stw r0, GPR0_OFFSET(r1)
+ addi r0, r1, EXCEPTION_FRAME_END
+ stw r0, GPR1_OFFSET(r1)
+ stw r2, GPR2_OFFSET(r1)
+ stmw r5, GPR5_OFFSET(r1) /* save R5 to R31 */
+
+ /*
+ * Save the remainder of the UISA special-purpose registers. Recall
+ * that LR was saved before entry.
+ */
+ mfcr r0
+ stw r0, EXC_CR_OFFSET(r1)
+ mfctr r0
+ stw r0, EXC_CTR_OFFSET(r1)
+ mfxer r0
+ stw r0, EXC_XER_OFFSET(r1)
+
+ /*
+ * Call C-language portion of the default exception handler, passing
+ * in the address of the frame.
+ *
+ * To simplify things a bit, we assume that the target routine is
+ * within +/- 32 Mbyte from here, which is a reasonable assumption
+ * on the MPC555.
+ */
+ stw r4, EXCEPTION_NUMBER_OFFSET(r1) /* save exception number */
+ addi r3, r1, 0x8 /* get frame address */
+ bl C_default_exception_handler /* call handler */
+
+ /*
+ * Restore UISA special-purpose registers.
+ */
+ lwz r0, EXC_XER_OFFSET(r1)
+ mtxer r0
+ lwz r0, EXC_CTR_OFFSET(r1)
+ mtctr r0
+ lwz r0, EXC_CR_OFFSET(r1)
+ mtcr r0
+ lwz r0, EXC_LR_OFFSET(r1)
+ mtlr r0
+
+ /*
+ * Restore most general-purpose registers.
+ */
+ lmw r2, GPR2_OFFSET(r1)
+
+ /*
+ * Restore the interrupted code's program counter and MSR, but first
+ * use an RCPU-specific special-purpose register to clear the RI
+ * bit, indicating that exceptions are temporarily non-recoverable.
+ */
+ mtspr nri, r0 /* clear MSR[RI] */
+ SYNC
+
+ lwz r0, SRR1_FRAME_OFFSET(r1)
+ mtsrr1 r0
+ lwz r0, SRR0_FRAME_OFFSET(r1)
+ mtsrr0 r0
+
+ /*
+ * Restore the final GPR, close the stack frame, and return to the
+ * interrupted code.
+ */
+ lwz r0, GPR0_OFFSET(r1)
+ addi r1, r1, EXCEPTION_FRAME_END
+ SYNC
+ rfi
diff --git a/c/src/lib/libcpu/powerpc/mpc5xx/vectors/vectors.h b/c/src/lib/libcpu/powerpc/mpc5xx/vectors/vectors.h
new file mode 100644
index 0000000000..ce1d3fca17
--- /dev/null
+++ b/c/src/lib/libcpu/powerpc/mpc5xx/vectors/vectors.h
@@ -0,0 +1,156 @@
+/*
+ * vectors.h Exception frame related contant and API.
+ *
+ * This include file describe the data structure and the functions implemented
+ * by rtems to handle exceptions.
+ *
+ *
+ * MPC5xx port sponsored by Defence Research and Development Canada - Suffield
+ * Copyright (C) 2004, Real-Time Systems Inc. (querbach@realtime.bc.ca)
+ *
+ * Derived from libbsp/powerpc/mbx8xx/vectors/vectors.h:
+ *
+ * CopyRight (C) 1999 valette@crf.canon.fr
+ *
+ * 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$
+ */
+#ifndef LIBCPU_POWERPC_MBX5XX_VECTORS_H
+#define LIBCPU_POWERPC_MBX5XX_VECTORS_H
+
+
+/*
+ * Size of hardware vector table.
+ */
+#define NUM_EXCEPTIONS 0x20
+
+/*
+ * The callee (high level exception code written in C)
+ * will store the Link Registers (return address) at entry r1 + 4 !!!.
+ * So let room for it!!!.
+ */
+#define LINK_REGISTER_CALLEE_UPDATE_ROOM 4
+#define SRR0_FRAME_OFFSET 8
+#define SRR1_FRAME_OFFSET 12
+#define EXCEPTION_NUMBER_OFFSET 16
+#define GPR0_OFFSET 20
+#define GPR1_OFFSET 24
+#define GPR2_OFFSET 28
+#define GPR3_OFFSET 32
+#define GPR4_OFFSET 36
+#define GPR5_OFFSET 40
+#define GPR6_OFFSET 44
+#define GPR7_OFFSET 48
+#define GPR8_OFFSET 52
+#define GPR9_OFFSET 56
+#define GPR10_OFFSET 60
+#define GPR11_OFFSET 64
+#define GPR12_OFFSET 68
+#define GPR13_OFFSET 72
+#define GPR14_OFFSET 76
+#define GPR15_OFFSET 80
+#define GPR16_OFFSET 84
+#define GPR17_OFFSET 88
+#define GPR18_OFFSET 92
+#define GPR19_OFFSET 96
+#define GPR20_OFFSET 100
+#define GPR21_OFFSET 104
+#define GPR22_OFFSET 108
+#define GPR23_OFFSET 112
+#define GPR24_OFFSET 116
+#define GPR25_OFFSET 120
+#define GPR26_OFFSET 124
+#define GPR27_OFFSET 128
+#define GPR28_OFFSET 132
+#define GPR29_OFFSET 136
+#define GPR30_OFFSET 140
+#define GPR31_OFFSET 144
+#define EXC_CR_OFFSET 148
+#define EXC_CTR_OFFSET 152
+#define EXC_XER_OFFSET 156
+#define EXC_LR_OFFSET 160
+#define EXC_DAR_OFFSET 164
+/*
+ * maintain the EABI requested 8 bytes aligment
+ * As SVR4 ABI requires 16, make it 16 (as some
+ * exception may need more registers to be processed...)
+ */
+#define EXCEPTION_FRAME_END 176
+
+#ifndef ASM
+/*
+ * default raw exception handlers
+ */
+
+extern void default_exception_vector_code_prolog();
+extern int default_exception_vector_code_prolog_size;
+extern void initialize_exceptions();
+
+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;
+}CPU_Exception_frame;
+
+
+typedef void rtems_exception_handler_t (CPU_Exception_frame* excPtr);
+/*DEBUG typedef rtems_exception_handler_t cpuExcHandlerType; */
+
+/*
+ * Exception handler table.
+ *
+ * This table contains pointers to assembly-language exception handlers.
+ * The common exception prologue in vectors.S looks up an entry in this
+ * table and jumps to it. No return address is saved, so the handlers in
+ * this table must return directly to the interrupted code.
+ *
+ * On entry to an exception handler, R1 points to a new exception stack
+ * frame in which R3, R4, and LR have been saved. R4 holds the exception
+ * number.
+ */
+extern rtems_exception_handler_t* exception_handler_table[NUM_EXCEPTIONS];
+
+#endif /* ASM */
+
+#endif /* LIBCPU_POWERPC_MPC5XX_VECTORS_H */
diff --git a/c/src/lib/libcpu/powerpc/mpc5xx/vectors/vectors_init.c b/c/src/lib/libcpu/powerpc/mpc5xx/vectors/vectors_init.c
new file mode 100644
index 0000000000..e5314ee50a
--- /dev/null
+++ b/c/src/lib/libcpu/powerpc/mpc5xx/vectors/vectors_init.c
@@ -0,0 +1,137 @@
+/*
+ * vectors_init.c Exception hanlding initialisation (and generic handler).
+ *
+ * This include file describe the data structure and the functions implemented
+ * by rtems to handle exceptions.
+ *
+ *
+ * MPC5xx port sponsored by Defence Research and Development Canada - Suffield
+ * Copyright (C) 2004, Real-Time Systems Inc. (querbach@realtime.bc.ca)
+ *
+ * Derived from libbsp/powerpc/mbx8xx/vectors/vectors_init.c:
+ *
+ * CopyRight (C) 1999 valette@crf.canon.fr
+ *
+ * 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$
+ */
+#include <rtems/bspIo.h>
+#include <libcpu/vectors.h>
+#include <libcpu/raw_exception.h>
+
+extern rtems_exception_handler_t default_exception_handler;
+
+static rtems_raw_except_global_settings exception_config;
+static rtems_raw_except_connect_data exception_table[NUM_EXCEPTIONS];
+rtems_exception_handler_t* exception_handler_table[NUM_EXCEPTIONS];
+
+
+void C_default_exception_handler(CPU_Exception_frame* excPtr)
+{
+ int recoverable = 0;
+
+ printk("exception handler called for exception %d\n", excPtr->_EXC_number);
+ printk("\t Next PC or Address of fault = %x\n", excPtr->EXC_SRR0);
+ printk("\t Saved MSR = %x\n", excPtr->EXC_SRR1);
+ printk("\t R0 = %x\n", excPtr->GPR0);
+ printk("\t R1 = %x\n", excPtr->GPR1);
+ printk("\t R2 = %x\n", excPtr->GPR2);
+ printk("\t R3 = %x\n", excPtr->GPR3);
+ printk("\t R4 = %x\n", excPtr->GPR4);
+ printk("\t R5 = %x\n", excPtr->GPR5);
+ printk("\t R6 = %x\n", excPtr->GPR6);
+ printk("\t R7 = %x\n", excPtr->GPR7);
+ printk("\t R8 = %x\n", excPtr->GPR8);
+ printk("\t R9 = %x\n", excPtr->GPR9);
+ printk("\t R10 = %x\n", excPtr->GPR10);
+ printk("\t R11 = %x\n", excPtr->GPR11);
+ printk("\t R12 = %x\n", excPtr->GPR12);
+ printk("\t R13 = %x\n", excPtr->GPR13);
+ printk("\t R14 = %x\n", excPtr->GPR14);
+ printk("\t R15 = %x\n", excPtr->GPR15);
+ printk("\t R16 = %x\n", excPtr->GPR16);
+ printk("\t R17 = %x\n", excPtr->GPR17);
+ printk("\t R18 = %x\n", excPtr->GPR18);
+ printk("\t R19 = %x\n", excPtr->GPR19);
+ printk("\t R20 = %x\n", excPtr->GPR20);
+ printk("\t R21 = %x\n", excPtr->GPR21);
+ printk("\t R22 = %x\n", excPtr->GPR22);
+ printk("\t R23 = %x\n", excPtr->GPR23);
+ printk("\t R24 = %x\n", excPtr->GPR24);
+ printk("\t R25 = %x\n", excPtr->GPR25);
+ printk("\t R26 = %x\n", excPtr->GPR26);
+ printk("\t R27 = %x\n", excPtr->GPR27);
+ printk("\t R28 = %x\n", excPtr->GPR28);
+ printk("\t R29 = %x\n", excPtr->GPR29);
+ printk("\t R30 = %x\n", excPtr->GPR30);
+ printk("\t R31 = %x\n", excPtr->GPR31);
+ printk("\t CR = %x\n", excPtr->EXC_CR);
+ printk("\t CTR = %x\n", excPtr->EXC_CTR);
+ printk("\t XER = %x\n", excPtr->EXC_XER);
+ printk("\t LR = %x\n", excPtr->EXC_LR);
+ printk("\t MSR = %x\n", excPtr->EXC_MSR);
+ if (excPtr->_EXC_number == ASM_DEC_VECTOR)
+ recoverable = 1;
+ if (excPtr->_EXC_number == ASM_SYS_VECTOR)
+#ifdef TEST_RAW_EXCEPTION_CODE
+ recoverable = 1;
+#else
+ recoverable = 0;
+#endif
+ if (!recoverable) {
+ printk("unrecoverable exception!!! Push reset button\n");
+ while(1);
+ }
+}
+
+void nop_except_enable(const rtems_raw_except_connect_data* ptr)
+{
+}
+
+int except_always_enabled(const rtems_raw_except_connect_data* ptr)
+{
+ return 1;
+}
+
+void initialize_exceptions()
+{
+ int i;
+
+ /*
+ * Initialize all entries of the exception table with a description of the
+ * default exception handler.
+ */
+ exception_config.exceptSize = NUM_EXCEPTIONS;
+ exception_config.rawExceptHdlTbl = &exception_table[0];
+ exception_config.defaultRawEntry.exceptIndex = 0;
+ exception_config.defaultRawEntry.hdl.vector = 0;
+ exception_config.defaultRawEntry.hdl.raw_hdl = default_exception_handler;
+
+ for (i = 0; i < exception_config.exceptSize; i++) {
+ printk("installing exception number %d\n", i);
+ exception_table[i].exceptIndex = i;
+ exception_table[i].hdl = exception_config.defaultRawEntry.hdl;
+ exception_table[i].hdl.vector = i;
+ exception_table[i].on = nop_except_enable;
+ exception_table[i].off = nop_except_enable;
+ exception_table[i].isOn = except_always_enabled;
+ }
+
+ /*
+ * Now pass the initialized exception table to the exceptions module which
+ * will install the handler pointers in the exception handler table.
+ */
+ if (!mpc5xx_init_exceptions(&exception_config)) {
+ /*
+ * At this stage we may not call CPU_Panic because it uses exceptions!!!
+ */
+ printk("Exception handling initialization failed\n");
+ printk("System locked\n"); while(1);
+ }
+ else {
+ printk("Exception handling initialization done\n");
+ }
+}