diff options
-rw-r--r-- | PL0_test.c | 15 | ||||
-rw-r--r-- | demo_functionality.c | 17 | ||||
-rw-r--r-- | interrupt_vector.S | 4 | ||||
-rw-r--r-- | interrupts.c | 2 |
4 files changed, 26 insertions, 12 deletions
@@ -1,18 +1,25 @@ #include "uart.h" #include "psr.h" +// entry point - must remain the only function in the file! void PL0_main(void) { - // if all went correct, Success! gets printed + // If all went correct, Success! gets printed uart_puts("Success!\n\r"); - // if we're indeed i PL0, we should crash now, when trying to access + uart_puts("calling supervisor\n\r"); + + asm volatile("svc #0"); + + uart_puts("back from supervisor call\n\r"); + + // if we're indeed in PL0, we should crash now, when trying to access // memory we're not allowed to char first_kernel_byte[2]; - first_kernel_byte[0] = *(char*) ((uint32_t) 0x8000); + first_kernel_byte[0] = *(char*) ((uint32_t) 0x0); first_kernel_byte[1] = '\0'; - + uart_puts(first_kernel_byte); while (1) diff --git a/demo_functionality.c b/demo_functionality.c index 420639b..12bba9b 100644 --- a/demo_functionality.c +++ b/demo_functionality.c @@ -135,9 +135,8 @@ void *memset(void *s, int c, size_t n) void demo_go_unprivileged(void) { - uint32_t PL0_regs[16] = {0}; - PL0_regs[15] = VIRTUAL_PL0_MEMORY_START; // the new pc - PL0_regs[13] = (PL0_SECTION_NUMBER + 1) << 20; // the new sp + uint32_t PL0_regs[14] = {0}; + PL0_regs[13] = VIRTUAL_PL0_MEMORY_START; // the new pc PSR_t new_SPSR = read_CPSR(); new_SPSR.fields.PSR_MODE_4_0 = MODE_USER; @@ -145,6 +144,14 @@ void demo_go_unprivileged(void) uart_puts("All ready, jumping to PL0 code\n\r"); - asm volatile("ldm %0, {r0 - r15} ^" :: - "r" (PL0_regs)); + asm volatile("cps %[sysmode]\n\r" + "mov sp, %[stackaddr]\n\r" + "cps %[supmode]\n\r" + "ldm %[contextaddr], {r0 - r12, pc} ^" :: + [sysmode]"I" (MODE_SYSTEM), + [supmode]"I" (MODE_SUPERVISOR), + [stackaddr]"r" ((PL0_SECTION_NUMBER + 1) << 20), + [contextaddr]"r" (PL0_regs) : "memory"); + + __builtin_unreachable(); } diff --git a/interrupt_vector.S b/interrupt_vector.S index 6037b7c..88b32bf 100644 --- a/interrupt_vector.S +++ b/interrupt_vector.S @@ -21,7 +21,9 @@ undef_handler_caller: svc_handler_caller: ldr sp, =_stack_top ldr r5, =supervisor_call_handler - bx r5 + push {lr} + blx r5 + ldm sp!, {pc} ^ abort_handler_caller: ldr sp, =_stack_top diff --git a/interrupts.c b/interrupts.c index 1a0150e..7932d23 100644 --- a/interrupts.c +++ b/interrupts.c @@ -27,8 +27,6 @@ void undefined_instruction_vector(void) void supervisor_call_handler(void) { uart_puts("something svc happened\n\r"); - - while(1); } void abort_handler(void) |