![]() |
|
|||
File indexing completed on 2025-05-11 08:23:59
0001 /* 0002 * vectors.S 0003 * 0004 * This file contains the assembly code for the PowerPC exception veneers 0005 * for RTEMS. 0006 * 0007 * 0008 * MPC5xx port sponsored by Defence Research and Development Canada - Suffield 0009 * Copyright (C) 2004, Real-Time Systems Inc. (querbach@realtime.bc.ca) 0010 * 0011 * Derived from libbsp/powerpc/mbx8xx/vectors/vectors.S, 0012 * 0013 * (c) 1999, Eric Valette valette@crf.canon.fr 0014 */ 0015 0016 #include <rtems/asm.h> 0017 #include <rtems/score/cpu.h> 0018 #include <libcpu/vectors.h> 0019 #include <bsp.h> 0020 0021 #define SYNC \ 0022 sync; \ 0023 isync 0024 0025 0026 /* 0027 * Hardware exception vector table. 0028 * 0029 * The MPC555 can be configured to use a compressed vector table with 8 0030 * bytes per entry, rather than the usual 0x100 bytes of other PowerPC 0031 * devices. The following macro uses this feature to save the better part 0032 * of 8 kbytes of flash ROM. 0033 * 0034 * Each vector table entry has room for only a simple branch instruction 0035 * which branches to a prologue specific to that exception. This 0036 * exception-specific prologue begins the context save, loads the exception 0037 * number into a register, and jumps to a common exception prologue, below. 0038 */ 0039 0040 .macro vectors num=0, total=NUM_EXCEPTIONS /* create vector table */ 0041 0042 /* vector table entry */ 0043 .section .vectors, "ax" 0044 0045 ba specific_prologue\@ /* run specific prologue */ 0046 .long 0 /* each entry is 8 bytes */ 0047 0048 /* exception-specific prologue */ 0049 .text 0050 0051 specific_prologue\@: 0052 stwu r1, -EXCEPTION_FRAME_END(r1) /* open stack frame */ 0053 stw r4, GPR4_OFFSET(r1) /* preserve register */ 0054 li r4, \num /* get exception number */ 0055 b common_prologue /* run common prologue */ 0056 0057 /* invoke macro recursively to create remainder of table */ 0058 .if \total - (\num + 1) 0059 vectors "(\num + 1)", \total 0060 .endif 0061 0062 .endm 0063 0064 0065 /* invoke macro to create entire vector table */ 0066 vectors 0067 0068 0069 /* 0070 * Common exception prologue. 0071 * 0072 * Because the MPC555 vector table is in flash ROM, it's not possible to 0073 * change the exception handlers by overwriting them at run-time, so this 0074 * common exception prologue uses a table of exception handler pointers to 0075 * provide equivalent flexibility. 0076 * 0077 * When the actual exception handler is run, R1 points to the base of a new 0078 * exception stack frame, in which R3, R4 and LR have been saved. R4 holds 0079 * the exception number. 0080 */ 0081 .text 0082 0083 common_prologue: 0084 stw r3, GPR3_OFFSET(r1) /* preserve registers */ 0085 mflr r3 0086 stw r3, EXC_LR_OFFSET(r1) 0087 0088 slwi r3, r4, 2 /* make table offset */ 0089 addis r3, r3, exception_handler_table@ha /* point to entry */ 0090 addi r3, r3, exception_handler_table@l 0091 lwz r3, 0(r3) /* get entry */ 0092 mtlr r3 /* run it */ 0093 blr 0094 0095 0096 /* 0097 * Default exception handler. 0098 * 0099 * The function initialize_exceptions() initializes all of the entries in 0100 * the exception handler table with pointers to this routine, which saves 0101 * the remainder of the interrupted code's state, then calls 0102 * C_default_exception_handler() to dump registers. 0103 * 0104 * On entry, R1 points to a new exception stack frame in which R3, R4, and 0105 * LR have been saved. R4 holds the exception number. 0106 */ 0107 .text 0108 0109 PUBLIC_VAR(default_exception_handler) 0110 SYM (default_exception_handler): 0111 /* 0112 * Save the interrupted code's program counter and MSR. Beyond this 0113 * point, all exceptions are recoverable. Use an RCPU-specific SPR 0114 * to set the RI bit in the MSR to indicate the recoverable state. 0115 */ 0116 mfsrr0 r3 0117 stw r3, SRR0_FRAME_OFFSET(r1) 0118 mfsrr1 r3 0119 stw r3, SRR1_FRAME_OFFSET(r1) 0120 0121 mtspr eid, r3 /* set MSR[RI], clear MSR[EE] */ 0122 SYNC 0123 0124 /* 0125 * Save the remainder of the general-purpose registers. 0126 * 0127 * Compute the value of R1 at exception entry before storing it in 0128 * the frame. 0129 * 0130 * Note that R2 should never change (it's the EABI pointer to 0131 * .sdata2), but we save it just in case. 0132 * 0133 * Recall that R3 and R4 were saved by the specific- and 0134 * common-exception handlers before entry to this routine. 0135 */ 0136 stw r0, GPR0_OFFSET(r1) 0137 addi r0, r1, EXCEPTION_FRAME_END 0138 stw r0, GPR1_OFFSET(r1) 0139 stw r2, GPR2_OFFSET(r1) 0140 stmw r5, GPR5_OFFSET(r1) /* save R5 to R31 */ 0141 0142 /* 0143 * Save the remainder of the UISA special-purpose registers. Recall 0144 * that LR was saved before entry. 0145 */ 0146 mfcr r0 0147 stw r0, EXC_CR_OFFSET(r1) 0148 mfctr r0 0149 stw r0, EXC_CTR_OFFSET(r1) 0150 mfxer r0 0151 stw r0, EXC_XER_OFFSET(r1) 0152 0153 /* 0154 * Call C-language portion of the default exception handler, passing 0155 * in the address of the frame. 0156 * 0157 * To simplify things a bit, we assume that the target routine is 0158 * within +/- 32 Mbyte from here, which is a reasonable assumption 0159 * on the MPC555. 0160 */ 0161 stw r4, EXCEPTION_NUMBER_OFFSET(r1) /* save exception number */ 0162 addi r3, r1, 0x8 /* get frame address */ 0163 bl C_default_exception_handler /* call handler */ 0164 0165 /* 0166 * Restore UISA special-purpose registers. 0167 */ 0168 lwz r0, EXC_XER_OFFSET(r1) 0169 mtxer r0 0170 lwz r0, EXC_CTR_OFFSET(r1) 0171 mtctr r0 0172 lwz r0, EXC_CR_OFFSET(r1) 0173 mtcr r0 0174 lwz r0, EXC_LR_OFFSET(r1) 0175 mtlr r0 0176 0177 /* 0178 * Restore most general-purpose registers. 0179 */ 0180 lmw r2, GPR2_OFFSET(r1) 0181 0182 /* 0183 * Restore the interrupted code's program counter and MSR, but first 0184 * use an RCPU-specific special-purpose register to clear the RI 0185 * bit, indicating that exceptions are temporarily non-recoverable. 0186 */ 0187 mtspr nri, r0 /* clear MSR[RI] */ 0188 SYNC 0189 0190 lwz r0, SRR1_FRAME_OFFSET(r1) 0191 mtsrr1 r0 0192 lwz r0, SRR0_FRAME_OFFSET(r1) 0193 mtsrr0 r0 0194 0195 /* 0196 * Restore the final GPR, close the stack frame, and return to the 0197 * interrupted code. 0198 */ 0199 lwz r0, GPR0_OFFSET(r1) 0200 addi r1, r1, EXCEPTION_FRAME_END 0201 SYNC 0202 rfi
[ Source navigation ] | [ Diff markup ] | [ Identifier search ] | [ general search ] |
This page was automatically generated by the 2.3.7 LXR engine. The LXR team |
![]() ![]() |