~jsvoboda/helenos/dnsr

« back to all changes in this revision

Viewing changes to kernel/arch/arm32/src/exception.c

  • Committer: Jiri Svoboda
  • Date: 2013-04-19 18:38:18 UTC
  • mfrom: (1527.1.284 main-clone)
  • Revision ID: jiri@wiwaxia-20130419183818-nvfibuh4t5qol0e3
MergeĀ mainlineĀ chages.

Show diffs side-by-side

added added

removed removed

Lines of Context:
38
38
#include <arch/machine_func.h>
39
39
#include <interrupt.h>
40
40
#include <arch/mm/page_fault.h>
 
41
#include <arch/cp15.h>
41
42
#include <arch/barrier.h>
42
43
#include <print.h>
43
44
#include <syscall/syscall.h>
72
73
        
73
74
        /* make it LDR instruction and store at exception vector */
74
75
        *vector = handler_address_ptr | LDR_OPCODE;
75
 
        smc_coherence(*vector);
 
76
        smc_coherence(vector);
76
77
        
77
78
        /* store handler's address */
78
79
        *(vector + EXC_VECTORS) = handler_addr;
116
117
}
117
118
 
118
119
#ifdef HIGH_EXCEPTION_VECTORS
119
 
/** Activates use of high exception vectors addresses. */
 
120
/** Activates use of high exception vectors addresses.
 
121
 *
 
122
 * "High vectors were introduced into some implementations of ARMv4 and are
 
123
 * required in ARMv6 implementations. High vectors allow the exception vector
 
124
 * locations to be moved from their normal address range 0x00000000-0x0000001C
 
125
 * at the bottom of the 32-bit address space, to an alternative address range
 
126
 * 0xFFFF0000-0xFFFF001C near the top of the address space. These alternative
 
127
 * locations are known as the high vectors.
 
128
 *
 
129
 * Prior to ARMv6, it is IMPLEMENTATION DEFINED whether the high vectors are
 
130
 * supported. When they are, a hardware configuration input selects whether
 
131
 * the normal vectors or the high vectors are to be used from
 
132
 * reset." ARM Architecture Reference Manual A2.6.11 (p. 64 in the PDF).
 
133
 *
 
134
 * ARM920T (gta02) TRM A2.3.5 (PDF p. 36) and ARM926EJ-S (icp) 2.3.2 (PDF p. 42)
 
135
 * say that armv4 an armv5 chips that we support implement this.
 
136
 */
120
137
static void high_vectors(void)
121
138
{
122
 
        uint32_t control_reg;
123
 
        
124
 
        asm volatile (
125
 
                "mrc p15, 0, %[control_reg], c1, c0"
126
 
                : [control_reg] "=r" (control_reg)
127
 
        );
 
139
        uint32_t control_reg = SCTLR_read();
128
140
        
129
141
        /* switch on the high vectors bit */
130
 
        control_reg |= CP15_R1_HIGH_VECTORS_BIT;
 
142
        control_reg |= SCTLR_HIGH_VECTORS_EN_FLAG;
131
143
        
132
 
        asm volatile (
133
 
                "mcr p15, 0, %[control_reg], c1, c0"
134
 
                :: [control_reg] "r" (control_reg)
135
 
        );
 
144
        SCTLR_write(control_reg);
136
145
}
137
146
#endif
138
147
 
145
154
        machine_irq_exception(exc_no, istate);
146
155
}
147
156
 
 
157
/** Undefined instruction exception handler.
 
158
 *
 
159
 * Calls scheduler_fpu_lazy_request
 
160
 */
 
161
static void undef_insn_exception(unsigned int exc_no, istate_t *istate)
 
162
{
 
163
#ifdef CONFIG_FPU
 
164
        if (handle_if_fpu_exception()) {
 
165
                /*
 
166
                 * Retry the failing instruction,
 
167
                 * ARM Architecture Reference Manual says on p.B1-1169
 
168
                 * that offset for undef instruction exception is 4
 
169
                 */
 
170
                istate->pc -= 4;
 
171
                return;
 
172
        }
 
173
#endif
 
174
        fault_if_from_uspace(istate, "Undefined instruction.");
 
175
        panic_badtrap(istate, exc_no, "Undefined instruction.");
 
176
}
 
177
 
148
178
/** Initializes exception handling.
149
179
 *
150
180
 * Installs low-level exception handlers and then registers
152
182
 */
153
183
void exception_init(void)
154
184
{
 
185
        // TODO check for availability of high vectors for <= armv5
155
186
#ifdef HIGH_EXCEPTION_VECTORS
156
187
        high_vectors();
157
188
#endif
158
189
        install_exception_handlers();
159
190
        
 
191
        exc_register(EXC_UNDEF_INSTR, "undefined instruction", true,
 
192
            (iroutine_t) undef_insn_exception);
160
193
        exc_register(EXC_IRQ, "interrupt", true,
161
194
            (iroutine_t) irq_exception);
162
195
        exc_register(EXC_PREFETCH_ABORT, "prefetch abort", true,