aboutsummaryrefslogtreecommitdiff
path: root/kernel.c
diff options
context:
space:
mode:
authorWojtek Kosior <kwojtus@protonmail.com>2019-11-12 17:56:10 +0100
committerWojtek Kosior <kwojtus@protonmail.com>2019-11-12 17:56:10 +0100
commit533976feb8ea79c15fa905642d75adb58a0e6996 (patch)
tree11d5b9b56754e3457256d23c25535d19fc0402e1 /kernel.c
parent30b44ef0b1177d13dd4f58c47979e7a6e598d81a (diff)
downloadrpi-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.c57
1 files changed, 56 insertions, 1 deletions
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;