From 533976feb8ea79c15fa905642d75adb58a0e6996 Mon Sep 17 00:00:00 2001 From: Wojtek Kosior Date: Tue, 12 Nov 2019 17:56:10 +0100 Subject: TEST CODE: prepare for switching to PL0 --- kernel.c | 57 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 56 insertions(+), 1 deletion(-) (limited to 'kernel.c') diff --git a/kernel.c b/kernel.c index 7a10b24..bd4426d 100644 --- a/kernel.c +++ b/kernel.c @@ -6,6 +6,11 @@ extern char __end; +extern char + _binary_PL_0_test_img_start, + _binary_PL_0_test_img_end, + _binary_PL_0_test_img_size; + void enabling_code_from_the_net(void); void kernel_main(uint32_t r0, uint32_t r1, uint32_t atags) @@ -85,7 +90,7 @@ void kernel_main(uint32_t r0, uint32_t r1, uint32_t atags) // flat map all memory uart_puts("preparing translation table\n\r"); - short_descriptor_lvl1_t *translation_table = + short_descriptor_lvl1_t volatile *translation_table = (short_descriptor_lvl1_t*) translation_table_base; for (uint32_t i = 0; i < 4096; i++) @@ -178,6 +183,56 @@ void kernel_main(uint32_t r0, uint32_t r1, uint32_t atags) asm("mcr p15, 0, %0, c1, c0, 0\n\r" "isb" :: "r" (SCTLR.raw) : "memory"); + volatile short_section_descriptor_t *PL0_code_section = + &translation_table[0b101010101010].section_fields; + volatile short_section_descriptor_t *UART_memory_section = + &translation_table[((uint32_t) GPIO_BASE) >> 20].section_fields; + + // map code section to the memory right after out kernel + uint32_t kernel_memory_end = (uint32_t) (translation_table + 4096); + uint32_t unprivileged_memory_start = + (((kernel_memory_end - 1) >> 20) + 1) << 20; + + PL0_code_section->SECTION_BASE_ADDRESS_31_20 = + unprivileged_memory_start >> 20; + + // make the selected section and uart section available for PL0 + PL0_code_section->ACCESS_PERMISSIONS_2 = + AP_2_0_MODEL_RW_ALL >> 2; + PL0_code_section->ACCESS_PERMISSIONS_1_0 = + AP_2_0_MODEL_RW_ALL & 0b011; + + UART_memory_section->ACCESS_PERMISSIONS_2 = + AP_2_0_MODEL_RW_ALL >> 2; + UART_memory_section->ACCESS_PERMISSIONS_1_0 = + AP_2_0_MODEL_RW_ALL & 0b011; + + + // invalidate main Translation Lookup Buffer (just in case) + asm("mcr p15, 0, %0, c8, c7, 0\n\r" + "isb" :: "r" (0) : "memory"); + + // check that translation works... by copying a string using one + // mapping and reading it using other :D + char message[] = "mapped sections for PL0 code\n\r"; + + unsigned int i; + for (i = 0; i < sizeof(message); i++) + ((volatile char*) unprivileged_memory_start)[i] = message[i]; + + uart_puts((char*) (((uint32_t) 0b101010101010) << 20)); + + // now paste a userspace program to that section, jump to it and + // switch to PL0 + for (size_t i = 0; i < (size_t) &_binary_PL_0_test_img_size; i++) + ((char*) (((uint32_t) 0b101010101010) << 20))[i] = + (&_binary_PL_0_test_img_start)[i]; + + // jump to that copied code (no switch to PL0 yet, just testing) + ((void(*)(void)) (((uint32_t) 0b101010101010) << 20))(); + + while(1); + while (1) { char c; -- cgit v1.2.3