diff options
author | Joel Sherrill <joel.sherrill@OARcorp.com> | 2004-04-12 22:04:28 +0000 |
---|---|---|
committer | Joel Sherrill <joel.sherrill@OARcorp.com> | 2004-04-12 22:04:28 +0000 |
commit | 8430205c224c1bfcb67156e5b97dd44ecd81fd7d (patch) | |
tree | 5ce5170ec6f228407d7ebfab0c1efbf17c495595 /c/src/lib/libcpu/powerpc/mpc5xx/vectors | |
parent | 2004-04-12 David Querbach <querbach@realtime.bc.ca> (diff) | |
download | rtems-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.S | 203 | ||||
-rw-r--r-- | c/src/lib/libcpu/powerpc/mpc5xx/vectors/vectors.h | 156 | ||||
-rw-r--r-- | c/src/lib/libcpu/powerpc/mpc5xx/vectors/vectors_init.c | 137 |
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"); + } +} |