diff options
-rw-r--r-- | Makefile | 2 | ||||
-rw-r--r-- | demo_functionality.c | 22 | ||||
-rw-r--r-- | demo_functionality.h | 2 | ||||
-rw-r--r-- | interrupt_vector.S | 20 | ||||
-rw-r--r-- | interrupts.c | 13 | ||||
-rw-r--r-- | kernel.c | 2 | ||||
-rw-r--r-- | linker.ld | 13 |
7 files changed, 71 insertions, 3 deletions
@@ -30,7 +30,7 @@ libkernel_renamed.o : libkernel.o PL_0_test.elf : PL0_test.o uart.o arm-none-eabi-gcc -T PL0_test.ld -o $@ $(ELFFLAGS) $^ -kernel.elf : boot.o kernel.o uart.o PL_0_test_embeddable.o demo_functionality.o paging.o libkernel_renamed.o +kernel.elf : boot.o kernel.o uart.o PL_0_test_embeddable.o demo_functionality.o paging.o libkernel_renamed.o interrupt_vector.o interrupts.o arm-none-eabi-gcc -T linker.ld -o $@ $(ELFFLAGS) $^ loader_stage2.elf : loader_stage2.o uart.o diff --git a/demo_functionality.c b/demo_functionality.c index fbf5eb4..60b0bfa 100644 --- a/demo_functionality.c +++ b/demo_functionality.c @@ -165,3 +165,25 @@ void demo_go_unprivileged(void) "r" (VIRTUAL_PL0_MEMORY_START) : "memory", "r4", "r5", "r0"); } + +extern char + __interrupt_vectors_start, + __interrupt_vectors_end, + __interrupt_vectors_size; + +extern void (*volatile system_reentry_point)(void); + +void system_reentry(void) +{ + uart_puts("re-entered system"); + while(1); +} + +void demo_setup_interrupts(void) +{ + system_reentry_point = system_reentry; + + for (size_t i = 0; i < (size_t) &__interrupt_vectors_size; i++) + ((volatile char*) 0)[i] = + (&__interrupt_vectors_start)[i]; +} diff --git a/demo_functionality.h b/demo_functionality.h index 5d6e659..73a284b 100644 --- a/demo_functionality.h +++ b/demo_functionality.h @@ -11,4 +11,6 @@ void demo_setup_PL0(void); void demo_go_unprivileged(void); +void demo_setup_interrupts(void); + #endif // DEMO_FUNCTIONALITY_H diff --git a/interrupt_vector.S b/interrupt_vector.S new file mode 100644 index 0000000..f71330b --- /dev/null +++ b/interrupt_vector.S @@ -0,0 +1,20 @@ +.section ".interrupt_vectors.text" + +.global abort_handler +.local generic_handler +.global _interrupt_vectors +_interrupt_vectors: + b generic_handler + b generic_handler + b generic_handler + b abort_handler_caller + b abort_handler_caller + b generic_handler + b generic_handler + +generic_handler: + b generic_handler +abort_handler_caller: + mov sp, #0x8000 + ldr r5, =abort_handler + bx r5 diff --git a/interrupts.c b/interrupts.c index 3dc3d6f..191ce40 100644 --- a/interrupts.c +++ b/interrupts.c @@ -12,4 +12,15 @@ void __attribute__((interrupt("UNDEF"))) undefined_instruction_vector(void) { /* Do Nothing! */ } -}
\ No newline at end of file +} + +void __attribute__((section(".interrupt_vectors.data"))) +(*system_reentry_point) (void); + +void +__attribute__((interrupt("ABORT"))) +__attribute__((section(".interrupt_vectors.text"))) +abort_handler(void) +{ + system_reentry_point(); +} @@ -31,7 +31,7 @@ void kernel_main(uint32_t r0, uint32_t r1, uint32_t atags) demo_setup_PL0(); - demo_go_unprivileged(); + demo_setup_interrupts(); // prints some info and sets up a section for PL0 code, loads a blob // there and jumps to it... never, ever, ever returns @@ -89,6 +89,19 @@ SECTIONS __renamed_bss_size = __renamed_bss_end - __renamed_bss_start; __renamed_end = .; __renamed_size = __renamed_end - __renamed_start; + + + . = ALIGN(4096); /* align to page size */ + __interrupt_vectors_start = .; + .interrupt_vectors : + { + interrupt_vectors = .; + *(.interrupt_vectors.text) + *(.interrupt_vectors.data) + } + . = ALIGN(4096); /* align to page size */ + __interrupt_vectors_end = .; + __interrupt_vectors_size = __interrupt_vectors_end - __interrupt_vectors_start; __end = .; } |