diff options
author | Wojtek Kosior <kwojtus@protonmail.com> | 2019-11-12 17:56:10 +0100 |
---|---|---|
committer | Wojtek Kosior <kwojtus@protonmail.com> | 2019-11-12 17:56:10 +0100 |
commit | 533976feb8ea79c15fa905642d75adb58a0e6996 (patch) | |
tree | 11d5b9b56754e3457256d23c25535d19fc0402e1 /kernel.c | |
parent | 30b44ef0b1177d13dd4f58c47979e7a6e598d81a (diff) | |
download | rpi-MMU-example-533976feb8ea79c15fa905642d75adb58a0e6996.tar.gz rpi-MMU-example-533976feb8ea79c15fa905642d75adb58a0e6996.zip |
TEST CODE: prepare for switching to PL0
Diffstat (limited to 'kernel.c')
-rw-r--r-- | kernel.c | 57 |
1 files changed, 56 insertions, 1 deletions
@@ -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; |