aboutsummaryrefslogtreecommitdiff
path: root/demo_functionality.c
diff options
context:
space:
mode:
Diffstat (limited to 'demo_functionality.c')
-rw-r--r--demo_functionality.c96
1 files changed, 74 insertions, 22 deletions
diff --git a/demo_functionality.c b/demo_functionality.c
index 7bba6a6..fbf5eb4 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,35 +56,73 @@ void demo_mode_to_system(void)
set_system_mode();
}
+#define TRANSLATION_TABLE \
+ ((short_section_descriptor_t volatile*) TRANSLATION_TABLE_BASE)
+
+extern char
+ __renamed_start,
+ __renamed_end,
+ __renamed_size;
+
+void demo_setup_libkernel(void) {
+ short_section_descriptor_t volatile *libkernel_section_entry =
+ &TRANSLATION_TABLE[LIBKERNEL_SECTION_NUMBER];
+
+ short_section_descriptor_t
+ libkernel_section = *libkernel_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;
+
+ *libkernel_section_entry = libkernel_section;
+
+ // invalidate main Translation Lookup Buffer (just in case)
+ asm("mcr p15, 0, %0, c8, c7, 0\n\r"
+ "isb" :: "r" (0) : "memory");
+
+ // 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];
+}
+
extern char
_binary_PL_0_test_img_start,
_binary_PL_0_test_img_end,
_binary_PL_0_test_img_size;
-void demo_go_unprivileged(void)
+void demo_setup_PL0(void)
{
- short_section_descriptor_t *translation_table =
- (short_section_descriptor_t*) TRANSLATION_TABLE_BASE;
+ 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];
- volatile short_section_descriptor_t *PL0_section =
- &translation_table[PL0_SECTION_NUMBER];
- volatile short_section_descriptor_t *UART_memory_section =
- &translation_table[((uint32_t) GPIO_BASE) >> 20];
+ short_section_descriptor_t
+ PL0_section = *PL0_section_entry,
+ UART_memory_section = *UART_memory_section_entry;
- PL0_section->SECTION_BASE_ADDRESS_31_20 =
+ // set up address of PL0 section
+ PL0_section.SECTION_BASE_ADDRESS_31_20 =
UNPRIVILEGED_MEMORY_START >> 20;
// make the selected section and uart section available for PL0
- PL0_section->ACCESS_PERMISSIONS_2 =
+ PL0_section.ACCESS_PERMISSIONS_2 =
AP_2_0_MODEL_RW_ALL >> 2;
- PL0_section->ACCESS_PERMISSIONS_1_0 =
+ PL0_section.ACCESS_PERMISSIONS_1_0 =
AP_2_0_MODEL_RW_ALL & 0b011;
- UART_memory_section->ACCESS_PERMISSIONS_2 =
+ UART_memory_section.ACCESS_PERMISSIONS_2 =
AP_2_0_MODEL_RW_ALL >> 2;
- UART_memory_section->ACCESS_PERMISSIONS_1_0 =
+ UART_memory_section.ACCESS_PERMISSIONS_1_0 =
AP_2_0_MODEL_RW_ALL & 0b011;
-
+
+ *PL0_section_entry = PL0_section;
+ *UART_memory_section_entry = UART_memory_section;
// invalidate main Translation Lookup Buffer (just in case)
asm("mcr p15, 0, %0, c8, c7, 0\n\r"
@@ -99,17 +138,30 @@ 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
+ // 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");
+}
+
+void demo_go_unprivileged(void)
+{
+ 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");
}