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 @ Reset
12 ivt_svc: b SVC_Handler @ SVC (used to be called SWI)
13 ivt_prefetch: b PrefetchAbort @ Prefetch abort
14 ivt_data: b DataAbort @ Data abort
15 ivt_unused: b . @ Not Used
16 ivt_irq: b IRQHandler @ IRQ
17 ivt_fiq: b . @ FIQ (Fast interrupt)
21 ldr r0, =kernel_table0-KERNEL_BASE
22 mcr p15, 0, r0, c2, c0, 1 @ Set TTBR1 to r0
23 mcr p15, 0, r0, c2, c0, 0 @ Set TTBR0 to r0 too (for identity)
26 mcr p15, 0, r0, c2, c0, 2 @ Set TTCR to 1 (50/50 split)
29 mcr p15, 0, r0, c3, c0, 0 @ Set Domain 0 to Manager
32 mrc p15, 0, r0, c1, c0, 0
35 mcr p15, 0, r0, c1, c0, 0
38 @ Check for security extensions
40 mrc p15, 0, r0, c0, c1, 1
44 mcrne p15, 0, r0, c12, c0, 0 @ Set the VBAR (brings exceptions into high memory)
46 mrceq p15, 0, r0, c1, c0, 0 @ Set SCTLR.V
48 mcreq p15, 0, r0, c1, c0, 0
51 @ Prepare for interrupts
53 ldr sp, =irqstack+0x1000 @ Set up stack
55 ldr sp, =abortstack+0x1000
58 ldr sp, =0x80000000-4 @ Set up stack (top of user range)
61 1: b 1b @ Infinite loop
65 .comm irqstack, 0x1000 @ ; 4KiB Stack
66 .comm abortstack, 0x1000 @ ; 4KiB Stack
68 .extern SyscallHandler
71 srsdb sp!, #19 @ Switch to supervisor mode (DDI0406B D1.6.5) (actually SRSFD)
85 ldr r4, =SyscallHandler
89 pop {r0,r1} @ Ret/RetHi
90 add sp, #2*4 @ Saved r2/r3
93 rfeia sp! @ Pop state (actually RFEFD)
109 cmpls r1, #0x78000000
117 mcrlt p15, 0, r0, c7, c5, 1
118 mcrlt p15, 0, r0, c7, c6, 1
136 gpIRQHandler: .long 0
137 IRQ_saved_sp: .long 0
138 IRQ_saved_lr: .long 0
141 sub lr, #4 @ Adjust LR to the correct value
142 srsdb sp!, #19 @ Switch to supervisor mode (DDI0406B D1.6.5) (actually SRSFD)
152 @ Call the registered handler
159 rfeia sp! @ Pop state (actually RFEFD)
164 sub lr, #8 @ Adjust LR to the correct value
165 @ srsdb sp!, #19 @ Switch to supervisor mode (DDI0406B D1.6.5) (actually SRSFD)
169 mrc p15, 0, r4, c5, c0, 0 @ Read DFSR (Data Fault Address Register) to stack
171 mrc p15, 0, r3, c6, c0, 0 @ Read DFAR (Data Fault Address Register) into R3
173 ldr r1, =csDataAbort_Fmt
180 @ rfeia sp! @ Pop state (actually RFEFD)
185 sub lr, #4 @ Adjust LR to the correct value
186 @ srsdb sp!, #19 @ Switch to supervisor mode (DDI0406B D1.6.5) (actually SRSFD)
191 ldr r1, =csPrefetchAbort_Fmt
193 mrc p15, 0, r3, c5, c0, 0 @ Read IFSR (Instruction Fault Address Register) into R3
204 .asciz "Data Abort - %p accessed %p, DFSR=%x Unk:%x Unk:%x"
206 .asciz "Prefetch Abort at %p, IFSR=%x"
212 .long 0x00000002 @ Identity map the first 1 MiB
216 .long user_table1_map + 0x000 - KERNEL_BASE + 1 @ 0x7FC00000
217 .long user_table1_map + 0x400 - KERNEL_BASE + 1 @ 0x7FD00000
218 .long user_table1_map + 0x800 - KERNEL_BASE + 1 @ KStacks
219 .long user_table1_map + 0xC00 - KERNEL_BASE + 1
220 @ 0x80000000 - User/Kernel split
221 .long 0x00000002 @ Map first 4 MiB to 2GiB
225 .rept 0xF00 - 0x800 - 4
229 .long PCI_PADDR + 0*(1 << 20) + 2 @ Map PCI config space
230 .long PCI_PADDR + 1*(1 << 20) + 2
231 .long PCI_PADDR + 2*(1 << 20) + 2
232 .long PCI_PADDR + 3*(1 << 20) + 2
233 .long PCI_PADDR + 4*(1 << 20) + 2
234 .long PCI_PADDR + 5*(1 << 20) + 2
235 .long PCI_PADDR + 6*(1 << 20) + 2
236 .long PCI_PADDR + 7*(1 << 20) + 2
237 .long PCI_PADDR + 8*(1 << 20) + 2
238 .long PCI_PADDR + 9*(1 << 20) + 2
239 .long PCI_PADDR + 10*(1 << 20) + 2
240 .long PCI_PADDR + 11*(1 << 20) + 2
241 .long PCI_PADDR + 12*(1 << 20) + 2
242 .long PCI_PADDR + 13*(1 << 20) + 2
243 .long PCI_PADDR + 14*(1 << 20) + 2
244 .long PCI_PADDR + 15*(1 << 20) + 2
250 .long hwmap_table_0 + 0x000 - KERNEL_BASE + 1
251 .long hwmap_table_0 + 0x400 - KERNEL_BASE + 1
252 .long hwmap_table_0 + 0x800 - KERNEL_BASE + 1
253 .long hwmap_table_0 + 0xC00 - KERNEL_BASE + 1
254 .rept 0xFF8 - 0xF00 - 16 - 4
258 .long kernel_table1_map + 0x000 - KERNEL_BASE + 1
259 .long kernel_table1_map + 0x400 - KERNEL_BASE + 1
260 .long kernel_table1_map + 0x800 - KERNEL_BASE + 1
261 .long kernel_table1_map + 0xC00 - KERNEL_BASE + 1
262 .long kernel_exception_map + 0x000 - KERNEL_BASE + 1
263 .long kernel_exception_map + 0x400 - KERNEL_BASE + 1
264 .long kernel_exception_map + 0x800 - KERNEL_BASE + 1
265 .long kernel_exception_map + 0xC00 - KERNEL_BASE + 1
268 .globl user_table1_map
269 @ User table1 data table (only the first half is needed)
270 @ - Abused to provide kernel stacks in upper half
271 user_table1_map: @ Size = 4KiB (only 2KiB used)
275 .long user_table1_map - KERNEL_BASE + 0x10 + 3 @ ...1FF000 = 0x7FDFF000
277 .long kernel_table0 + 0x0000 - KERNEL_BASE + 0x10 + 3 @ ...200000 = 0x7FE00000
278 .long kernel_table0 + 0x1000 - KERNEL_BASE + 0x10 + 3 @ ...201000 = 0x7FE01000
279 .rept (0x800/4)-(MM_KSTACK_SIZE/0x1000)-2
282 #if MM_KSTACK_SIZE != 0x2000
283 #error Kernel stack size not changed in start.S
285 .long stack + 0x0000 - KERNEL_BASE + 0x10 + 3 @ Kernel Stack
286 .long stack + 0x1000 - KERNEL_BASE + 0x10 + 3 @
288 .globl kernel_table1_map
289 kernel_table1_map: @ Size = 4KiB
293 .long hwmap_table_0 - KERNEL_BASE + (1 << 4) + 3
294 .rept 0xFF8/4 - (0xF00+16)/4 - 1
297 .long kernel_table1_map - KERNEL_BASE + (1 << 4) + 3
298 .long kernel_exception_map - KERNEL_BASE + 0x13
303 .long UART0_PADDR + (1 << 4) + 3 @ UART0
307 .globl kernel_exception_map
308 kernel_exception_map:
313 @ Align to nearly the end
317 .long 0x213 @ Map first page for exceptions (Kernel RO)
324 .space MM_KSTACK_SIZE, 0 @ Original kernel stack