X-Git-Url: https://git.ucc.asn.au/?a=blobdiff_plain;ds=sidebyside;f=Kernel%2Farch%2Farmv7%2Fstart.S;h=8b19ede22a8168bd0770fd3e3a7f3f79b8c533df;hb=95a9132bcc024715a0a87cb323d58967ea5b1803;hp=faf10ea943b84f97ce436b734057b45b5aeb6c34;hpb=d3f9be02956fb2633d2322ffad4198e03117d353;p=tpg%2Facess2.git diff --git a/Kernel/arch/armv7/start.S b/Kernel/arch/armv7/start.S index faf10ea9..8b19ede2 100644 --- a/Kernel/arch/armv7/start.S +++ b/Kernel/arch/armv7/start.S @@ -7,14 +7,14 @@ @ .section .init interrupt_vector_table: -ivt_reset: b _start @ Reset -ivt_undef: b . @ #UD -ivt_svc: b SyscallHandler @ SVC (SWI assume) -ivt_prefetch: b PrefetchAbort @ Prefetch abort -ivt_data: b DataAbort @ Data abort -ivt_unused: b . @ Not Used -ivt_irq: b IRQHandler @ IRQ -ivt_fiq: b . @ FIQ (Fast interrupt) +ivt_reset: b _start @ 0x00 Reset +ivt_undef: b . @ 0x04 #UD +ivt_svc: b SVC_Handler @ 0x08 SVC (used to be called SWI) +ivt_prefetch: b PrefetchAbort @ 0x0C Prefetch abort +ivt_data: b DataAbort @ 0x10 Data abort +ivt_unused: b . @ 0x14 Not Used +ivt_irq: b IRQHandler @ 0x18 IRQ +ivt_fiq: b . @ 0x1C FIQ (Fast interrupt) .globl _start _start: @@ -28,17 +28,33 @@ _start: mov r0, #3 mcr p15, 0, r0, c3, c0, 0 @ Set Domain 0 to Manager + @ Enable VMSA mrc p15, 0, r0, c1, c0, 0 orr r0, r0, #1 orr r0, r0, #1 << 23 mcr p15, 0, r0, c1, c0, 0 + @ + @ Check for security extensions + @ + mrc p15, 0, r0, c0, c1, 1 + and r0, #0xF0 + @ - Present + ldrne r0,=KERNEL_BASE + mcrne p15, 0, r0, c12, c0, 0 @ Set the VBAR (brings exceptions into high memory) + @ - Absent + mrceq p15, 0, r0, c1, c0, 0 @ Set SCTLR.V + orreq r0, #0x2000 + mcreq p15, 0, r0, c1, c0, 0 + + @ Prepare for interrupts cps #18 @ IRQ Mode ldr sp, =irqstack+0x1000 @ Set up stack + cps #23 @ Abort Mode + ldr sp, =abortstack+0x1000 cps #19 -@ ldr sp, =stack+0x10000 @ Set up stack ldr sp, =0x80000000-4 @ Set up stack (top of user range) ldr r0, =kmain mov pc, r0 @@ -47,9 +63,46 @@ _ptr_kmain: .long kmain .comm irqstack, 0x1000 @ ; 4KiB Stack +.comm abortstack, 0x1000 @ ; 4KiB Stack + +.extern SyscallHandler +SVC_Handler: +@ sub lr, #4 + srsdb sp!, #19 @ Save state to stack + cpsie ifa, #19 @ Ensure we're in supervisor with interrupts enabled (should already be there) + push {r0-r12} + + ldr r4, [lr,#-4] + mvn r5, #0xFF000000 + and r4, r5 + + tst r4, #0x1000 + bne .arm_specifics + + push {r4} + + mov r0, sp + ldr r4, =SyscallHandler + blx r4 + + pop {r2} @ errno + pop {r0,r1} @ Ret/RetHi + add sp, #2*4 @ Saved r2/r3 + + pop {r4-r12} + rfeia sp! @ Pop state (actually RFEFD) +.arm_specifics: + and r4, #0xFF + mov r0, r4 @ Number + mov r1, sp @ Arguments + + ldr r4, =ARMv7_int_HandleSyscalls + blx r4 + + add sp, #4*4 + pop {r4-r12} + rfeia sp! -SyscallHandler: - b . .globl gpIRQHandler gpIRQHandler: .long 0 @@ -63,10 +116,10 @@ IRQHandler: PUSH_GPRS -@ ldr r0, =csIRQ_Tag -@ ldr r1, =csIRQ_Fmt -@ ldr r4, =Log_Debug -@ blx r4 + ldr r0, =csIRQ_Tag + ldr r1, =csIRQ_Fmt + ldr r4, =Log_Debug + blx r4 @ Call the registered handler ldr r0, gpIRQHandler @@ -81,8 +134,8 @@ IRQHandler: .globl DataAbort DataAbort: sub lr, #8 @ Adjust LR to the correct value - srsdb sp!, #19 @ Switch to supervisor mode (DDI0406B D1.6.5) (actually SRSFD) - cpsid ifa, #19 +@ srsdb sp!, #19 @ Switch to supervisor mode (DDI0406B D1.6.5) (actually SRSFD) +@ cpsid ifa, #19 @ PUSH_GPRS mrc p15, 0, r4, c5, c0, 0 @ Read DFSR (Data Fault Address Register) to stack @@ -95,16 +148,15 @@ DataAbort: blx r4 b . - POP_GPRS - rfeia sp! @ Pop state (actually RFEFD) - bx lr +@ POP_GPRS +@ rfeia sp! @ Pop state (actually RFEFD) .globl PrefetchAbort PrefetchAbort: sub lr, #4 @ Adjust LR to the correct value - srsdb sp!, #19 @ Switch to supervisor mode (DDI0406B D1.6.5) (actually SRSFD) - cpsid ifa, #19 - PUSH_GPRS +@ srsdb sp!, #19 @ Switch to supervisor mode (DDI0406B D1.6.5) (actually SRSFD) +@ cpsid ifa, #19 +@ PUSH_GPRS ldr r0, =csAbort_Tag ldr r1, =csPrefetchAbort_Fmt @@ -114,6 +166,7 @@ PrefetchAbort: blx r4 b . +.section .rodata csIRQ_Tag: csAbort_Tag: .asciz "ARMv7" @@ -178,24 +231,24 @@ kernel_table0: .long kernel_table1_map + 0x400 - KERNEL_BASE + 1 .long kernel_table1_map + 0x800 - KERNEL_BASE + 1 .long kernel_table1_map + 0xC00 - KERNEL_BASE + 1 - .rept 0x1000 - 0xFFC - .long 0 - .endr + .long kernel_exception_map + 0x000 - KERNEL_BASE + 1 + .long kernel_exception_map + 0x400 - KERNEL_BASE + 1 + .long kernel_exception_map + 0x800 - KERNEL_BASE + 1 + .long kernel_exception_map + 0xC00 - KERNEL_BASE + 1 @ PID0 user table .globl user_table1_map @ User table1 data table (only the first half is needed) @ - Abused to provide kernel stacks in upper half user_table1_map: @ Size = 4KiB (only 2KiB used) - .rept 0x800/4-4 + .rept 0x800/4-1 .long 0 .endr - .long kernel_table0 + 0x0000 - KERNEL_BASE + 0x10 + 3 @ ...1FC000 = 0x7FDDC000 - .long kernel_table0 + 0x1000 - KERNEL_BASE + 0x10 + 3 @ ...1FD000 = 0x7FDDD000 - .long 0 .long user_table1_map - KERNEL_BASE + 0x10 + 3 @ ...1FF000 = 0x7FDFF000 @ Kernel stack zone - .rept (0x800/4)-(MM_KSTACK_SIZE/0x1000) + .long kernel_table0 + 0x0000 - KERNEL_BASE + 0x10 + 3 @ ...200000 = 0x7FE00000 + .long kernel_table0 + 0x1000 - KERNEL_BASE + 0x10 + 3 @ ...201000 = 0x7FE01000 + .rept (0x800/4)-(MM_KSTACK_SIZE/0x1000)-2 .long 0 .endr #if MM_KSTACK_SIZE != 0x2000 @@ -214,7 +267,7 @@ kernel_table1_map: @ Size = 4KiB .long 0 .endr .long kernel_table1_map - KERNEL_BASE + (1 << 4) + 3 - .long 0 + .long kernel_exception_map - KERNEL_BASE + 0x13 @ Hardware mappings .globl hwmap_table_0 @@ -223,6 +276,20 @@ hwmap_table_0: .rept 1024 - 1 .long 0 .endr +.globl kernel_exception_map +kernel_exception_map: + @ Padding + .rept 1024-256 + .long 0 + .endr + @ Align to nearly the end + .rept 256-16 + .long 0 + .endr + .long 0x213 @ Map first page for exceptions (Kernel RO) + .rept 15 + .long 0 + .endr .section .padata stack: