aboutsummaryrefslogtreecommitdiff
path: root/src/exceptions
diff options
context:
space:
mode:
Diffstat (limited to 'src/exceptions')
-rw-r--r--src/exceptions/data.S29
-rw-r--r--src/exceptions/fiq.S26
-rw-r--r--src/exceptions/irq.S8
-rw-r--r--src/exceptions/prefetch.S20
-rw-r--r--src/exceptions/svc.S45
-rw-r--r--src/exceptions/undefined.S34
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"