/*
* Vector stubs.
*
- * This code is copied to 0x200 or 0xffff0200 so we can use branches in the
- * vectors, rather than ldr's.
+ * This code is copied to 0xffff0200 so we can use branches in the
+ * vectors, rather than ldr's. Note that this code must not
+ * exceed 0x300 bytes.
*
* Common stub entry macro:
* Enter in IRQ mode, spsr = SVC/USR CPSR, lr = SVC/USR PC
movs pc, lr @ Changes mode and branches
.endm
+ .globl __stubs_start
__stubs_start:
/*
* Interrupt dispatcher
.LCsabt:
.word __temp_abt
+ .globl __stubs_end
__stubs_end:
- .equ __real_stubs_start, .LCvectors + 0x200
+ .equ stubs_offset, __vectors_start + 0x200 - __stubs_start
-.LCvectors:
+ .globl __vectors_start
+__vectors_start:
swi SYS_ERROR0
- b __real_stubs_start + (vector_und - __stubs_start)
- ldr pc, __real_stubs_start + (.LCvswi - __stubs_start)
- b __real_stubs_start + (vector_pabt - __stubs_start)
- b __real_stubs_start + (vector_dabt - __stubs_start)
- b __real_stubs_start + (vector_addrexcptn - __stubs_start)
- b __real_stubs_start + (vector_irq - __stubs_start)
- b __real_stubs_start + (vector_fiq - __stubs_start)
-
-ENTRY(__trap_init)
- stmfd sp!, {r4 - r6, lr}
-
- mov r0, #0xff000000
- orr r0, r0, #0x00ff0000 @ high vectors position
- adr r1, .LCvectors @ set up the vectors
- ldmia r1, {r1, r2, r3, r4, r5, r6, ip, lr}
- stmia r0, {r1, r2, r3, r4, r5, r6, ip, lr}
-
- add r2, r0, #0x200
- adr r0, __stubs_start @ copy stubs to 0x200
- adr r1, __stubs_end
-1: ldr r3, [r0], #4
- str r3, [r2], #4
- cmp r0, r1
- blt 1b
- LOADREGS(fd, sp!, {r4 - r6, pc})
+ b vector_und + stubs_offset
+ ldr pc, .LCvswi + stubs_offset
+ b vector_pabt + stubs_offset
+ b vector_dabt + stubs_offset
+ b vector_addrexcptn + stubs_offset
+ b vector_irq + stubs_offset
+ b vector_fiq + stubs_offset
+
+ .globl __vectors_end
+__vectors_end:
.data
void __init trap_init(void)
{
- extern void __trap_init(void);
+ extern char __stubs_start[], __stubs_end[];
+ extern char __vectors_start[], __vectors_end[];
- __trap_init();
+ /*
+ * Copy the vectors and stubs (in entry-armv.S) into the
+ * vector page, mapped at 0xffff0000, and ensure these are
+ * visible to the instruction stream.
+ */
+ memcpy((void *)0xffff0000, __vectors_start, __vectors_end - __vectors_start);
+ memcpy((void *)0xffff0200, __stubs_start, __stubs_end - __stubs_start);
flush_icache_range(0xffff0000, 0xffff0000 + PAGE_SIZE);
modify_domain(DOMAIN_USER, DOMAIN_CLIENT);
}