2 #include "include/assembly.h"
3 #include "include/options.h"
6 @ Exception defs taken from ARM DDI 0406B
9 interrupt_vector_table:
10 ivt_reset: b _start @ 0x00 Reset
11 ivt_undef: b Undef_Handler @ 0x04 #UD
12 ivt_svc: b SVC_Handler @ 0x08 SVC (used to be called SWI)
13 ivt_prefetch: b PrefetchAbort @ 0x0C Prefetch abort
14 ivt_data: b DataAbort @ 0x10 Data abort
15 ivt_unused: b . @ 0x14 Not Used
16 ivt_irq: b IRQHandler @ 0x18 IRQ
17 ivt_fiq: b . @ 0x1C FIQ (Fast interrupt)
34 ldr r0, =kernel_table0-KERNEL_BASE
35 mcr p15, 0, r0, c2, c0, 1 @ Set TTBR1 to r0
36 mcr p15, 0, r0, c2, c0, 0 @ Set TTBR0 to r0 too (for identity)
42 mcr p15, 0, r0, c2, c0, 2 @ Set TTCR to 1 (50/50 split)
48 mcr p15, 0, r0, c3, c0, 0 @ Set Domain 0 to Manager
54 mrc p15, 0, r0, c1, c0, 0
57 mcr p15, 0, r0, c1, c0, 0
59 @ HACK: Set ASID to non zero
67 @ Enable access faults on domains 0 & 1
68 mov r0, #0x55 @ 01010101b
69 mcr p15, 0, r0, c3, c0, 0
75 @ Check for security extensions
77 mrc p15, 0, r0, c0, c1, 1
82 mcr p15, 0, r0, c12, c0, 0 @ Set the VBAR (brings exceptions into high memory)
83 b .exceptions_vectored
86 mrc p15, 0, r0, c1, c0, 0 @ Set SCTLR.V
88 mcr p15, 0, r0, c1, c0, 0
94 @ Prepare for interrupts
96 ldr sp, =irqstack+0x1000 @ Set up stack
98 ldr sp, =abortstack+0x1000
113 .extern bss_size_div_4
124 ldr sp, =0x80000000-8 @ Set up stack (top of user range)
127 1: b 1b @ Infinite loop
131 .comm irqstack, 0x1000 @ ; 4KiB Stack
132 .comm abortstack, 0x1000 @ ; 4KiB Stack
134 .extern SyscallHandler
137 srsdb sp!, #19 @ Save state to stack
138 cpsie ifa, #19 @ Ensure we're in supervisor with interrupts enabled (should already be there)
151 ldr r4, =SyscallHandler
154 @ ldr r0, =csSyscallPrintRetAddr
155 @ ldr r1, [sp,#9*4+5*4]
160 pop {r0,r1} @ Ret/RetHi
161 add sp, #2*4 @ Saved r2/r3
164 rfeia sp! @ Pop state (actually RFEFD)
168 mov r1, sp @ Arguments
170 ldr r4, =ARMv7_int_HandleSyscalls
179 gpIRQHandler: .long 0
180 IRQ_saved_sp: .long 0
181 IRQ_saved_lr: .long 0
184 sub lr, #4 @ Adjust LR to the correct value
185 srsdb sp!, #19 @ Switch to supervisor mode (DDI0406B D1.6.5) (actually SRSFD)
195 @ Call the registered handler
202 rfeia sp! @ Pop state (actually RFEFD)
207 sub lr, #8 @ Adjust LR to the correct value
208 srsdb sp!, #23 @ Switch to supervisor mode (DDI0406B D1.6.5) (actually SRSFD)
212 @ Get the user's LR value (and push to stack)
213 cps #31 @ Go to system mode
215 cps #19 @ Go to supervisor
217 cps #23 @ back to exception
220 mov r3, #0 @ not a prefetch abort
221 mrc p15, 0, r2, c5, c0, 0 @ Read DFSR (Data Fault Status Register) to R2
222 mrc p15, 0, r1, c6, c0, 0 @ Read DFAR (Data Fault Address Register) into R1
224 ldr r4, =MM_PageFault
226 add sp, #8 @ Undo push of the user/system LR
229 rfeia sp! @ Pop state (actually RFEFD)
233 sub lr, #4 @ Adjust LR to the correct value
234 srsdb sp!, #23 @ Switch to supervisor mode (DDI0406B D1.6.5) (actually SRSFD)
239 @ Get the user's LR value (and push to stack)
240 cps #31 @ Go to system mode
242 cps #23 @ back to supervisor
245 mrc p15, 0, r2, c5, c0, 1 @ Read IFSR (Instruction Fault Status Register) into R3
246 mrc p15, 0, r1, c6, c0, 2 @ Read IFAR (Instruction Fault Address Register) into R3
248 mov r3, #1 @ IS a prefetch abort
249 ldr r4, =MM_PageFault
251 add sp, #4 @ Undo push of the user LR
254 rfeia sp! @ Pop state (actually RFEFD)
270 .asciz "Data Abort - %p accessed %p, DFSR=%x Unk:%x Unk:%x"
272 .asciz "Prefetch Abort at %p, IFSR=%x, UserLR:0x%x"
273 csSyscallPrintRetAddr:
274 .asciz "Syscall ret to %p"
280 .long 0x00000402 @ Identity map the first 1 MiB
284 .long user_table1_map + 0x000 - KERNEL_BASE + 1 @ 0x7FC00000
285 .long user_table1_map + 0x400 - KERNEL_BASE + 1 @ 0x7FD00000
286 .long user_table1_map + 0x800 - KERNEL_BASE + 1 @ KStacks
287 .long user_table1_map + 0xC00 - KERNEL_BASE + 1
288 @ 0x80000000 - User/Kernel split
289 .long 0x00000402 @ Map first 4 MiB to 2GiB (KRW only)
293 .rept 0xF00 - 0x800 - 4
297 .long PCI_PADDR + 0*(1 << 20) + 0x402 @ Map PCI config space
298 .long PCI_PADDR + 1*(1 << 20) + 0x402
299 .long PCI_PADDR + 2*(1 << 20) + 0x402
300 .long PCI_PADDR + 3*(1 << 20) + 0x402
301 .long PCI_PADDR + 4*(1 << 20) + 0x402
302 .long PCI_PADDR + 5*(1 << 20) + 0x402
303 .long PCI_PADDR + 6*(1 << 20) + 0x402
304 .long PCI_PADDR + 7*(1 << 20) + 0x402
305 .long PCI_PADDR + 8*(1 << 20) + 0x402
306 .long PCI_PADDR + 9*(1 << 20) + 0x402
307 .long PCI_PADDR + 10*(1 << 20) + 0x402
308 .long PCI_PADDR + 11*(1 << 20) + 0x402
309 .long PCI_PADDR + 12*(1 << 20) + 0x402
310 .long PCI_PADDR + 13*(1 << 20) + 0x402
311 .long PCI_PADDR + 14*(1 << 20) + 0x402
312 .long PCI_PADDR + 15*(1 << 20) + 0x402
318 .long hwmap_table_0 + 0x000 - KERNEL_BASE + 1
319 .long hwmap_table_0 + 0x400 - KERNEL_BASE + 1
320 .long hwmap_table_0 + 0x800 - KERNEL_BASE + 1
321 .long hwmap_table_0 + 0xC00 - KERNEL_BASE + 1
322 .rept 0xFF8 - 0xF00 - 16 - 4
326 .long kernel_table1_map + 0x000 - KERNEL_BASE + 1
327 .long kernel_table1_map + 0x400 - KERNEL_BASE + 1
328 .long kernel_table1_map + 0x800 - KERNEL_BASE + 1
329 .long kernel_table1_map + 0xC00 - KERNEL_BASE + 1
330 .long kernel_exception_map + 0x000 - KERNEL_BASE + 1
331 .long kernel_exception_map + 0x400 - KERNEL_BASE + 1
332 .long kernel_exception_map + 0x800 - KERNEL_BASE + 1
333 .long kernel_exception_map + 0xC00 - KERNEL_BASE + 1
336 .globl user_table1_map
337 @ User table1 data table (only the first half is needed)
338 @ - Abused to provide kernel stacks in the unused half of the table
339 user_table1_map: @ Size = 4KiB (only 2KiB used)
343 .long user_table1_map - KERNEL_BASE + 0x13 @ ...1FF000 = 0x7FDFF000
345 .long kernel_table0 + 0x0000 - KERNEL_BASE + 0x13 @ ...200000 = 0x7FE00000
346 .long kernel_table0 + 0x1000 - KERNEL_BASE + 0x13 @ ...201000 = 0x7FE01000
347 .rept (0x800/4)-(MM_KSTACK_SIZE/0x1000)-2
350 #if MM_KSTACK_SIZE != 0x2000
351 #error Kernel stack size not changed in start.S
353 .long stack + 0x0000 - KERNEL_BASE + 0x13 @ Kernel Stack
354 .long stack + 0x1000 - KERNEL_BASE + 0x13 @
356 .globl kernel_table1_map
357 kernel_table1_map: @ Size = 4KiB
361 .long hwmap_table_0 - KERNEL_BASE + 0x13
362 .rept 0xFF8/4 - (0xF00+16)/4 - 1
365 .long kernel_table1_map - KERNEL_BASE + 0x13
366 .long kernel_exception_map - KERNEL_BASE + 0x13
371 .long UART0_PADDR + 0x13 @ UART0
375 .globl kernel_exception_map
376 kernel_exception_map:
381 @ Align to nearly the end
385 .long 0x212 @ Map first page for exceptions (Kernel RO, Execute)
389 .long gUsertextPhysStart + 0x22 @ User .text (User RO, Kernel RW, because both is COW)
394 .space MM_KSTACK_SIZE, 0 @ Original kernel stack
396 // vim: ts=8 ft=armv7