[acc25ee] | 1 | /* |
---|
| 2 | * (c) 1999, Eric Valette valette@crf.canon.fr |
---|
| 3 | * |
---|
| 4 | * |
---|
| 5 | * This file contains the assembly code for the PowerPC |
---|
| 6 | * exception veneers for RTEMS. |
---|
| 7 | * |
---|
| 8 | * $Id$ |
---|
| 9 | */ |
---|
| 10 | |
---|
| 11 | |
---|
| 12 | |
---|
| 13 | #include <bsp/vectors.h> |
---|
| 14 | #include <libcpu/cpu.h> |
---|
| 15 | #include <rtems/score/targopts.h> |
---|
| 16 | #include "asm.h" |
---|
| 17 | |
---|
| 18 | |
---|
| 19 | #define SYNC \ |
---|
| 20 | sync; \ |
---|
| 21 | isync |
---|
| 22 | |
---|
| 23 | PUBLIC_VAR (__rtems_start) |
---|
| 24 | .section .entry_point_section,"awx",@progbits |
---|
| 25 | /* |
---|
| 26 | * Entry point information used by bootloader code |
---|
| 27 | */ |
---|
| 28 | SYM (__rtems_start): |
---|
| 29 | .long __rtems_entry_point |
---|
| 30 | |
---|
| 31 | /* |
---|
| 32 | * end of special Entry point section |
---|
| 33 | */ |
---|
| 34 | .text |
---|
| 35 | .p2align 5 |
---|
| 36 | |
---|
| 37 | PUBLIC_VAR(default_exception_vector_code_prolog) |
---|
| 38 | SYM (default_exception_vector_code_prolog): |
---|
| 39 | /* |
---|
| 40 | * let room for exception frame |
---|
| 41 | */ |
---|
| 42 | stwu r1, - (EXCEPTION_FRAME_END)(r1) |
---|
| 43 | stw r3, GPR3_OFFSET(r1) |
---|
| 44 | stw r2, GPR2_OFFSET(r1) |
---|
| 45 | mflr r2 |
---|
| 46 | stw r2, EXC_LR_OFFSET(r1) |
---|
| 47 | bl 0f |
---|
| 48 | 0: /* |
---|
| 49 | * r3 = exception vector entry point |
---|
| 50 | * (256 * vector number) + few instructions |
---|
| 51 | */ |
---|
| 52 | mflr r3 |
---|
| 53 | /* |
---|
| 54 | * r3 = r3 >> 8 = vector |
---|
| 55 | */ |
---|
| 56 | srwi r3,r3,8 |
---|
| 57 | ba push_normalized_frame |
---|
| 58 | |
---|
| 59 | PUBLIC_VAR (default_exception_vector_code_prolog_size) |
---|
| 60 | |
---|
| 61 | default_exception_vector_code_prolog_size= . - default_exception_vector_code_prolog |
---|
| 62 | |
---|
| 63 | .p2align 5 |
---|
| 64 | PUBLIC_VAR (push_normalized_frame) |
---|
| 65 | SYM (push_normalized_frame): |
---|
| 66 | stw r3, EXCEPTION_NUMBER_OFFSET(r1) |
---|
| 67 | stw r0, GPR0_OFFSET(r1) |
---|
| 68 | mfsrr0 r2 |
---|
| 69 | stw r2, SRR0_FRAME_OFFSET(r1) |
---|
| 70 | mfsrr1 r3 |
---|
| 71 | stw r3, SRR1_FRAME_OFFSET(r1) |
---|
| 72 | /* |
---|
| 73 | * Save general purpose registers |
---|
| 74 | * Already saved in prolog : R1, R2, R3, LR. |
---|
| 75 | * Saved a few line above : R0 |
---|
| 76 | * |
---|
| 77 | * Manual says that "stmw" instruction may be slower than |
---|
| 78 | * series of individual "stw" but who cares about performance |
---|
| 79 | * for the DEFAULT exception handler? |
---|
| 80 | */ |
---|
| 81 | stmw r4, GPR4_OFFSET(r1) /* save R4->R31 */ |
---|
| 82 | |
---|
| 83 | mfcr r31 |
---|
| 84 | stw r31, EXC_CR_OFFSET(r1) |
---|
| 85 | mfctr r30 |
---|
| 86 | stw r30, EXC_CTR_OFFSET(r1) |
---|
| 87 | mfxer r28 |
---|
| 88 | stw r28, EXC_XER_OFFSET(r1) |
---|
| 89 | /* |
---|
| 90 | * compute SP at exception entry |
---|
| 91 | */ |
---|
| 92 | addi r2, r1, EXCEPTION_FRAME_END |
---|
| 93 | /* |
---|
| 94 | * store it at the right place |
---|
| 95 | */ |
---|
| 96 | stw r2, GPR1_OFFSET(r1) |
---|
| 97 | /* |
---|
| 98 | * Enable data and instruction address translation, exception nesting |
---|
| 99 | */ |
---|
| 100 | mfmsr r3 |
---|
| 101 | ori r3,r3, MSR_RI | MSR_IR | MSR_DR |
---|
| 102 | mtmsr r3 |
---|
| 103 | SYNC |
---|
| 104 | |
---|
| 105 | /* |
---|
| 106 | * Call C exception handler |
---|
| 107 | */ |
---|
| 108 | /* |
---|
| 109 | * store the execption frame address in r3 (first param) |
---|
| 110 | */ |
---|
| 111 | addi r3, r1, 0x8 |
---|
| 112 | /* |
---|
| 113 | * globalExceptHdl(r3) |
---|
| 114 | */ |
---|
| 115 | addis r4, 0, globalExceptHdl@ha |
---|
| 116 | lwz r5, globalExceptHdl@l(r4) |
---|
| 117 | mtlr r5 |
---|
| 118 | blrl |
---|
| 119 | /* |
---|
| 120 | * Restore registers status |
---|
| 121 | */ |
---|
| 122 | lwz r31, EXC_CR_OFFSET(r1) |
---|
| 123 | mtcr r31 |
---|
| 124 | lwz r30, EXC_CTR_OFFSET(r1) |
---|
| 125 | mtctr r30 |
---|
| 126 | lwz r29, EXC_LR_OFFSET(r1) |
---|
| 127 | mtlr r29 |
---|
| 128 | lwz r28, EXC_XER_OFFSET(r1) |
---|
| 129 | mtxer r28 |
---|
| 130 | |
---|
| 131 | lmw r4, GPR4_OFFSET(r1) |
---|
| 132 | lwz r2, GPR2_OFFSET(r1) |
---|
| 133 | lwz r0, GPR0_OFFSET(r1) |
---|
| 134 | |
---|
| 135 | /* |
---|
| 136 | * Disable data and instruction translation. Make path non recoverable... |
---|
| 137 | */ |
---|
| 138 | mfmsr r3 |
---|
| 139 | xori r3, r3, MSR_RI | MSR_IR | MSR_DR |
---|
| 140 | mtmsr r3 |
---|
| 141 | SYNC |
---|
| 142 | /* |
---|
| 143 | * Restore rfi related settings |
---|
| 144 | */ |
---|
| 145 | |
---|
| 146 | lwz r3, SRR1_FRAME_OFFSET(r1) |
---|
| 147 | mtsrr1 r3 |
---|
| 148 | lwz r3, SRR0_FRAME_OFFSET(r1) |
---|
| 149 | mtsrr0 r3 |
---|
| 150 | |
---|
| 151 | lwz r3, GPR3_OFFSET(r1) |
---|
| 152 | addi r1,r1, EXCEPTION_FRAME_END |
---|
| 153 | SYNC |
---|
| 154 | rfi |
---|