aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorWojtek Kosior <kwojtus@protonmail.com>2019-12-31 18:54:28 +0100
committerWojtek Kosior <kwojtus@protonmail.com>2019-12-31 18:54:28 +0100
commit0ec2016f80ffb5971362559b98b10744bb5bf893 (patch)
tree839991c83c04ef157cdc4b3d747a79ca5975445b
parent97612feede34cdd0099d72d0e6fa125dd65b5e9a (diff)
downloadrpi-MMU-example-0ec2016f80ffb5971362559b98b10744bb5bf893.tar.gz
rpi-MMU-example-0ec2016f80ffb5971362559b98b10744bb5bf893.zip
split stack into irq, fiq and supervisor stacks; add proper handling of those in interrupt handlers (asm code)
-rw-r--r--interrupt_vector.S25
-rw-r--r--kernel_stage2.ld22
-rw-r--r--memory.h18
3 files changed, 48 insertions, 17 deletions
diff --git a/interrupt_vector.S b/interrupt_vector.S
index 88b32bf..af80eec 100644
--- a/interrupt_vector.S
+++ b/interrupt_vector.S
@@ -9,39 +9,42 @@ _interrupt_vectors:
b fiq_handler_caller
reset_handler_caller:
- ldr sp, =_stack_top
+ ldr sp, =_supervisor_stack_top
ldr r5, =reset_handler
bx r5
undef_handler_caller:
- ldr sp, =_stack_top
+ ldr sp, =_supervisor_stack_top
ldr r5, =undefined_instruction_vector
bx r5
svc_handler_caller:
- ldr sp, =_stack_top
+ ldr sp, =_supervisor_stack_top
+ push {r5, lr}
ldr r5, =supervisor_call_handler
- push {lr}
blx r5
- ldm sp!, {pc} ^
+ ldm sp!, {r5, pc} ^
abort_handler_caller:
- ldr sp, =_stack_top
+ ldr sp, =_supervisor_stack_top
ldr r5, =abort_handler
bx r5
generic_handler_caller:
- ldr sp, =_stack_top
+ ldr sp, =_supervisor_stack_top
ldr r5, =generic_handler
bx r5
irq_handler_caller:
- ldr sp, =_stack_top
- ldr r5, =irq_handler
- bx r5
+ ldr sp, =_irq_stack_top
+ sub lr, #4
+ push {r0-r3, lr}
+ ldr r3, =irq_handler
+ blx r3
+ ldm sp!, {r0-r3, pc} ^
fiq_handler_caller:
- ldr sp, =_stack_top
+ ldr sp, =_fiq_stack_top
ldr r5, =fiq_handler
bx r5
diff --git a/kernel_stage2.ld b/kernel_stage2.ld
index a3df063..15b61ec 100644
--- a/kernel_stage2.ld
+++ b/kernel_stage2.ld
@@ -56,8 +56,24 @@ SECTIONS
{
_stack_start = .;
- . = . + MMU_SECTION_SIZE;
-
- _stack_top = .;
+ _fiq_stack_start = .;
+
+ . = . + (1 << 18);
+
+ _fiq_stack_top = .;
+
+ _irq_stack_start = .;
+
+ . = . + (1 << 18);
+
+ _irq_stack_top = .;
+
+ _supervisor_stack_start = .;
+
+ . = . + (1 << 19);
+
+ _supervisor_stack_top = .;
+
+ _stack_end = .;
}
}
diff --git a/memory.h b/memory.h
index c7952f0..bdeba52 100644
--- a/memory.h
+++ b/memory.h
@@ -28,7 +28,13 @@ extern char _translation_table_end;
extern char _sections_list_start;
extern char _sections_list_end;
extern char _stack_start;
-extern char _stack_top;
+extern char _fiq_stack_start;
+extern char _fiq_stack_top;
+extern char _irq_stack_start;
+extern char _irq_stack_top;
+extern char _supervisor_stack_start;
+extern char _supervisor_stack_top;
+extern char _stack_end;
#define KERNEL_START ((size_t) &__start) // this is 0x0
#define KERNEL_END ((size_t) &__end)
@@ -43,8 +49,14 @@ extern char _stack_top;
// first section after the translation table is left unused;
// the next section is used as the stack
-#define STACK_START ((size_t) &_stack_start)
-#define STACK_END ((size_t) &_stack_top)
+#define STACK_START ((size_t) &_stack_start)
+#define FIQ_STACK_START ((size_t) &_fiq_stack_start)
+#define FIQ_STACK_END ((size_t) &_fiq_stack_top)
+#define IRQ_STACK_START ((size_t) &_irq_stack_start)
+#define IRQ_STACK_END ((size_t) &_irq_stack_top)
+#define SUPERVISOR_STACK_START ((size_t) &_supervisor_stack_start)
+#define SUPERVISOR_STACK_END ((size_t) &_supervisor_stack_top)
+#define STACK_END ((size_t) &_stack_end)
#define PRIVILEGED_MEMORY_END STACK_END