From 401bf03070458cf3a5ee6947bd01a8f397fe2909 Mon Sep 17 00:00:00 2001 From: Wojtek Kosior Date: Mon, 2 Dec 2019 16:37:22 +0100 Subject: create a separate library for kernel code that should run in PL0 mode --- demo_functionality.c | 51 ++++++++++++++++++++++++++++++++++++++++++--------- 1 file changed, 42 insertions(+), 9 deletions(-) (limited to 'demo_functionality.c') diff --git a/demo_functionality.c b/demo_functionality.c index eddb1d2..753a7d3 100644 --- a/demo_functionality.c +++ b/demo_functionality.c @@ -2,6 +2,7 @@ #include "psr.h" #include "memory.h" #include "translation_table_descriptors.h" +#include "libkernel.h" void demo_paging_support(void) { @@ -55,6 +56,11 @@ void demo_mode_to_system(void) set_system_mode(); } +extern char + __renamed_start, + __renamed_end, + __renamed_size; + extern char _binary_PL_0_test_img_start, _binary_PL_0_test_img_end, @@ -65,15 +71,26 @@ void demo_go_unprivileged(void) short_section_descriptor_t *translation_table = (short_section_descriptor_t*) TRANSLATION_TABLE_BASE; + short_section_descriptor_t volatile *libkernel_section_entry = + &translation_table[LIBKERNEL_SECTION_NUMBER]; short_section_descriptor_t volatile *PL0_section_entry = &translation_table[PL0_SECTION_NUMBER]; short_section_descriptor_t volatile *UART_memory_section_entry = &translation_table[((uint32_t) GPIO_BASE) >> 20]; short_section_descriptor_t + libkernel_section = *libkernel_section_entry, PL0_section = *PL0_section_entry, UART_memory_section = *UART_memory_section_entry; + // make libkernel section executable and read-only for + // unprivileged code + libkernel_section.ACCESS_PERMISSIONS_2 = + AP_2_0_MODEL_RW_PL1_RO_PL0 >> 2; + libkernel_section.ACCESS_PERMISSIONS_1_0 = + AP_2_0_MODEL_RW_PL1_RO_PL0 & 0b011; + + // set up address of PL0 section PL0_section.SECTION_BASE_ADDRESS_31_20 = UNPRIVILEGED_MEMORY_START >> 20; @@ -88,6 +105,7 @@ void demo_go_unprivileged(void) UART_memory_section.ACCESS_PERMISSIONS_1_0 = AP_2_0_MODEL_RW_ALL & 0b011; + *libkernel_section_entry = libkernel_section; *PL0_section_entry = PL0_section; *UART_memory_section_entry = UART_memory_section; @@ -105,17 +123,32 @@ void demo_go_unprivileged(void) uart_puts((char*) VIRTUAL_PL0_MEMORY_START); - // now paste a userspace program to that section, jump to it and - // switch to PL0 + // copy libkernel code to libkernel section + for (size_t i = 0; i < (size_t) &__renamed_size; i++) + ((volatile char*) LIBKERNEL_SECTION_START)[i] = + (&__renamed_start)[i]; + + // now paste a userspace program to that section for (size_t i = 0; i < (size_t) &_binary_PL_0_test_img_size; i++) ((volatile char*) VIRTUAL_PL0_MEMORY_START)[i] = (&_binary_PL_0_test_img_start)[i]; - // jump to that copied code (switch to PL0 is done by that code) - asm volatile("mov r5, #0\n\r" - "movt r5, #"PL0_SECTION_NUMBER_STR"1111\n\r" - "mov sp, r5\n\r" // setting stack is important :D - "mov r5, #0\n\r" - "movt r5, #"PL0_SECTION_NUMBER_STR"0000\n\r" - "blx r5\n\r"); + uart_puts("copied PL0 and libkernel code to their sections"); + + size_t call_unprivileged_offset = + (size_t) &call_unprivileged - (size_t) &__renamed_start; + + void *call_unprivileged_new_location = + (void*) (LIBKERNEL_SECTION_START + call_unprivileged_offset); + + // call call_unprivileged from libkernel + asm volatile("mov r5, %0\n\r" + "mov r0, %1\n\r" + "mov r4, #0\n\r" + "movt r4, #"PL0_SECTION_NUMBER_STR"1111\n\r" + "mov sp, r4\n\r" // setting stack is important :D + "blx r5\n\r" :: + "r" (call_unprivileged_new_location), + "r" (VIRTUAL_PL0_MEMORY_START) + : "memory", "r4", "r5", "r0"); } -- cgit v1.2.3