diff options
Diffstat (limited to 'src/exceptions')
-rw-r--r-- | src/exceptions/data.S | 29 | ||||
-rw-r--r-- | src/exceptions/fiq.S | 26 | ||||
-rw-r--r-- | src/exceptions/irq.S | 8 | ||||
-rw-r--r-- | src/exceptions/prefetch.S | 20 | ||||
-rw-r--r-- | src/exceptions/svc.S | 45 | ||||
-rw-r--r-- | src/exceptions/undefined.S | 34 |
6 files changed, 162 insertions, 0 deletions
diff --git a/src/exceptions/data.S b/src/exceptions/data.S new file mode 100644 index 0000000..2268de5 --- /dev/null +++ b/src/exceptions/data.S @@ -0,0 +1,29 @@ +.section ".text.exceptions" +.globl data +data: + cpsid aif + stmfd sp!, {r0-r12,lr} + mov r4, lr + mov r0, #0 + mov r1, #15 + ldr r2, =data_msg + bl draw_string + // Output return address + mov r0, #13 + mov r1, #15 + mov r2, r4 + sub r2, #8 + bl draw_hex32 + mov r0, #22 + mov r1, #15 + ldr r2, [r4, #-8] + bl draw_hex32 + mov r0, #32 + mov r1, #15 + mrs r2, spsr + bl draw_hex32 + ldmfd sp!, {r0-r12,lr} + subs pc, lr, #4 // Should be 8 once I can actually handle the abort + +.section .data +data_msg: .asciz "Data Handler" diff --git a/src/exceptions/fiq.S b/src/exceptions/fiq.S new file mode 100644 index 0000000..f323a02 --- /dev/null +++ b/src/exceptions/fiq.S @@ -0,0 +1,26 @@ +.section ".text.exceptions" +.globl fiq +fiq: + cpsid aif + stmfd sp!, {r0-r12,lr} + bl c_fiq_handler + cmp r0, #1 + bne 1f + mrs r1, spsr + and r1, r1, #0x1f + cmp r1, #0x10 + bne 1f + ldmfd sp!, {r0-r12,lr} + sub lr, #4 + push {r3} + ldr r3, =irqlr + str lr, [r3, #0] + pop {r3} + cps #0x13 + b schedule +1: + ldmfd sp!, {r0-r12,lr} + subs pc, lr, #4 + +.section .data +fiq_msg: .asciz "FIQ\n" diff --git a/src/exceptions/irq.S b/src/exceptions/irq.S new file mode 100644 index 0000000..025fc41 --- /dev/null +++ b/src/exceptions/irq.S @@ -0,0 +1,8 @@ +.section ".text.exceptions" +.globl irq +irq: + cpsid aif + push {r0,r1,r2,r3,r4,r5,r6,r7,r8,r9,r10,r11,r12,lr} + bl c_irq_handler + pop {r0,r1,r2,r3,r4,r5,r6,r7,r8,r9,r10,r11,r12,lr} + subs pc, lr, #4 diff --git a/src/exceptions/prefetch.S b/src/exceptions/prefetch.S new file mode 100644 index 0000000..1aeba10 --- /dev/null +++ b/src/exceptions/prefetch.S @@ -0,0 +1,20 @@ +.section ".text.exceptions" +.globl prefetch +prefetch: + cpsid aif + stmfd sp!, {r0-r12,lr} + mov r4, lr + mov r0, #0 + mov r1, #16 + ldr r2, =prefetch_msg + bl draw_string + // Output return address + mov r0, #17 + mov r1, #16 + mov r2, r4 + bl draw_hex32 + ldmfd sp!, {r0-r12,lr} + subs pc, lr, #4 + +.section .data +prefetch_msg: .asciz "Prefetch Handler" diff --git a/src/exceptions/svc.S b/src/exceptions/svc.S new file mode 100644 index 0000000..a5e9982 --- /dev/null +++ b/src/exceptions/svc.S @@ -0,0 +1,45 @@ +.section ".text.exceptions" +.globl svc +svc: + cpsid aif + stmfd sp!, {r0-r12,lr} + ldr r0, [lr, #-4] + bic r0, #0xFF000000 + // SVC #0 returns to supervisor mode + // TODO: Make supervisor mode return to a specific location + // (rather than to a user location) such as the kernel loop + cmp r0, #3 + bgt svc_exit + beq svc_000003 + cmp r0, #2 + beq svc_000002 + cmp r0, #1 + beq svc_000001 + cmp r0, #1 + beq svc_000000 +svc_000000: + cps #0x13 + b svc_exit +svc_000001: + b svc_exit +svc_000002: + ldmfd sp!, {r0-r12,lr} + b schedule +svc_000003: + ldr r3, =scheduler + ldr r2, [r3, #0] + ldr r1, [r2, #8] // sp_base + cmp r1, #-1 + beq svc_exit + ldr r3, =stacks_table + mov r0, #0 + strb r0, [r3, r1] + // Free the thread after freeing the stack + mov r0, r2 + bl free + b svc_exit +svc_exit: + ldmfd sp!, {r0-r12,pc}^ + +.section .data +svc_msg: .asciz "SVC Handler #" diff --git a/src/exceptions/undefined.S b/src/exceptions/undefined.S new file mode 100644 index 0000000..b8eab29 --- /dev/null +++ b/src/exceptions/undefined.S @@ -0,0 +1,34 @@ +.section ".text.exceptions" +.globl undefined +undefined: + cpsid aif + stmfd sp!, {r0-r12,lr} + ldr r4, [lr, #-4] + mov r0, #0 + mov r1, #17 + ldr r2, =undefined_msg + bl draw_string + mov r0, #18 + mov r1, #17 + mov r2, r4 + bl draw_hex32 + mov r0, #27 + mov r1, #17 + ldr r2, =undefined_at + bl draw_string + // Output lr + mov r1, #0x1000 + ldr r0, [r1, #-4] + sub r2, r0, #4 + mov r0, #31 + mov r1, #17 + bl draw_hex32 + // Skip instruction for now + // In future, + // ldmfd sp!, {r0-r12,lr} // Note the lack of ^ since subs will handle it + // subs pc, lr, #4 + ldmfd sp!, {r0-r12,pc}^ + +.section .data +undefined_msg: .asciz "Undefined Handler" +undefined_at: .asciz "@ 0x" |