Print this page
trap: don't mislead about SCTLR.V being not set
It's been quite a while since the exception table got moved via the high
vector bit (SCTLR.V).
Split |
Close |
Expand all |
Collapse all |
--- old/usr/src/uts/armv6/ml/trap.s
+++ new/usr/src/uts/armv6/ml/trap.s
1 1 /*
2 2 * This file and its contents are supplied under the terms of the
3 3 * Common Development and Distribution License ("CDDL"), version 1.0.
4 4 * You may only use this file in accordance with the terms of version
5 5 * 1.0 of the CDDL.
6 6 *
7 7 * A full copy of the text of the CDDL should have accompanied this
8 8 * source. A copy of the CDDL is also available via the Internet at
↓ open down ↓ |
8 lines elided |
↑ open up ↑ |
9 9 * http://www.illumos.org/license/CDDL.
10 10 */
11 11
12 12 .file "trap.s"
13 13
14 14 #include <sys/asm_linkage.h>
15 15 #include <sys/cpu_asm.h>
16 16
17 17 /*
18 18 * Create a section into which to place the exception vector, such that we can
19 - * force it to be mapped where it needs to be. Currently at 0x0, since
20 - * we don't set the high vector bit (SCTLR.V)
19 + * force it to be mapped where it needs to be.
21 20 *
22 21 * Each instruction in the vector jumps to its own address + 24, which is the
23 22 * matching entry in exception_table. We do this to insure that we get
24 23 * effectively infinite displacement, which we can't achieve in one
25 24 * instruction otherwise (and gas complains).
26 25 *
27 26 * The handler for each exception type saves a trap frame (struct regs, though
28 27 * with some bits unusual) and calls the associated handler from trap_table.
29 28 *
30 29 * XXX: On CPUs with the security extensions, there are actually 2 additional
31 30 * exception vectors: secure, and monitor. We ignore them.
32 31 */
33 32 .pushsection ".exception_vector", "ax"
34 33 ldr pc, [pc, #24]
35 34 ldr pc, [pc, #24]
36 35 ldr pc, [pc, #24]
37 36 ldr pc, [pc, #24]
38 37 ldr pc, [pc, #24]
39 38 ldr pc, [pc, #24]
40 39 ldr pc, [pc, #24]
41 40 ldr pc, [pc, #24]
42 41 .exception_table:
43 42 .word handle_reset /* Reset */
44 43 .word handle_undef /* Undefined insn */
45 44 .word handle_svc /* Supervisor Call */
46 45 .word handle_prefetchabt /* Prefetch abort */
47 46 .word handle_dataabt /* Data abort */
48 47 .word 0x00000014 /* Reserved (infinite loops) */
49 48 .word handle_irq /* IRQ */
50 49 .word handle_fiq /* FIQ */
51 50 .popsection
52 51
53 52 /* Clobbers r0 */
54 53 #define CALL_HANDLER(scratch, trapno) \
55 54 ldr scratch, =(trap_table + (4 * trapno)); \
56 55 ldr scratch, [scratch]; \
57 56 cmp scratch, #0; \
58 57 beq 1f; \
59 58 mov r0, sp; /* Pass our saved frame to the handler */ \
60 59 blx scratch; /* Call the handler */ \
61 60 1:
62 61
63 62 /*
64 63 * XXX: Note that we go to some contortions here to save in 'struct regs' style.
65 64 *
66 65 * This includes saving our own lr/spsr, for our own return _and_ saving them
67 66 * into the 'struct regs', and doing the register save unusually such that we
68 67 * get the 'struct regs' in order.
69 68 *
70 69 * Depending on the exact nature of 'struct regs', perhaps we should be
71 70 * bending it to our will, rather than letting it bend us?
72 71 *
73 72 * XXX: Note also that we're saving the current registers assuming that we
74 73 * came from supervisor mode. We should probably be saving the banked
75 74 * registers based on the mode in the spsr. (or we'll screw up when nested,
76 75 * or when userland traps, or...)
77 76 */
78 77 #define PUSH_TRAP_FRAME(scratch) \
79 78 srsdb sp!, #(CPU_MODE_SVC); /* Save lr and spsr for ourselves */ \
80 79 cps #(CPU_MODE_SVC); \
81 80 ldr lr, [sp]; /* Get lr back for the trap frame */ \
82 81 sub sp, sp, #(4 * 17); /* Space for all our registers */ \
83 82 stmia sp, {r0-r14}; /* XXX: Note we don't save pc */ \
84 83 ldr scratch, [sp, #(4 * 18)]; /* skip 17 regs and the lr */ \
85 84 str scratch, [sp, #(4 * 16)];
86 85
87 86 #define POP_TRAP_FRAME_AND_RET() \
88 87 ldmia sp, {r0-r14}; \
89 88 add sp, sp, #(4 * 19); /* 17 regs + 2 for lr and spsr */ \
90 89 rfedb sp; /* Return */
91 90
92 91 /*
93 92 * XXX: None of these handlers are even vaguely aware that usermode exists,
94 93 * and make no effort to do the traditional things we would probably do on
95 94 * returning to user mode. They will need to be rethought at such a time
96 95 */
97 96 .globl trap_table
98 97
99 98 #define DEFINE_HANDLER(name, code) \
100 99 ENTRY(name) \
101 100 PUSH_TRAP_FRAME(r0) \
102 101 CALL_HANDLER(r1, code) \
103 102 POP_TRAP_FRAME_AND_RET() \
104 103 SET_SIZE(name)
105 104
106 105 DEFINE_HANDLER(handle_reset, ARM_EXCPT_RESET)
107 106
108 107 /*
109 108 * XXX: Note that in practice, if we use this for emulation, things
110 109 * might look pretty different, but I think that giving the handler the
111 110 * entire real frame which we restore gives us the flexibility to do it
112 111 * this way.
113 112 */
114 113 DEFINE_HANDLER(handle_undef, ARM_EXCPT_UNDINS)
115 114
116 115 DEFINE_HANDLER(handle_svc, ARM_EXCPT_SVC)
117 116 DEFINE_HANDLER(handle_prefetchabt, ARM_EXCPT_PREFETCH)
118 117 DEFINE_HANDLER(handle_dataabt, ARM_EXCPT_DATA)
119 118
120 119 /*
121 120 * XXX: These assume that we really want vectored interrupts, and thus that
122 121 * we'll only ever see these if something went wrong (we took a
123 122 * non-vectored interrupt
124 123 *
125 124 * They may need extension (to pull info from the PIC this early, or
126 125 * whatever.) if we choose to use non-vectored interrupts.
127 126 */
128 127 DEFINE_HANDLER(handle_irq, ARM_EXCPT_IRQ)
129 128 DEFINE_HANDLER(handle_fiq, ARM_EXCPT_FIQ)
↓ open down ↓ |
99 lines elided |
↑ open up ↑ |
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX