aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--demo_functionality.c59
-rw-r--r--demo_functionality.h4
-rw-r--r--kernel.c6
-rw-r--r--memory.h4
4 files changed, 48 insertions, 25 deletions
diff --git a/demo_functionality.c b/demo_functionality.c
index 753a7d3..fbf5eb4 100644
--- a/demo_functionality.c
+++ b/demo_functionality.c
@@ -56,40 +56,56 @@ 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 *libkernel_section_entry =
- &translation_table[LIBKERNEL_SECTION_NUMBER];
short_section_descriptor_t volatile *PL0_section_entry =
- &translation_table[PL0_SECTION_NUMBER];
+ &TRANSLATION_TABLE[PL0_SECTION_NUMBER];
short_section_descriptor_t volatile *UART_memory_section_entry =
- &translation_table[((uint32_t) GPIO_BASE) >> 20];
+ &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;
@@ -105,7 +121,6 @@ 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;
@@ -123,18 +138,16 @@ void demo_go_unprivileged(void)
uart_puts((char*) VIRTUAL_PL0_MEMORY_START);
- // 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];
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;
diff --git a/demo_functionality.h b/demo_functionality.h
index c8b163f..5d6e659 100644
--- a/demo_functionality.h
+++ b/demo_functionality.h
@@ -5,6 +5,10 @@ void demo_paging_support(void);
void demo_mode_to_system(void);
+void demo_setup_libkernel(void);
+
+void demo_setup_PL0(void);
+
void demo_go_unprivileged(void);
#endif // DEMO_FUNCTIONALITY_H
diff --git a/kernel.c b/kernel.c
index f23ef78..1a3b87d 100644
--- a/kernel.c
+++ b/kernel.c
@@ -27,6 +27,12 @@ void kernel_main(uint32_t r0, uint32_t r1, uint32_t atags)
// prints some info and sets upp translation table, turns on MMU
setup_flat_map();
+ demo_setup_libkernel();
+
+ demo_setup_PL0();
+
+ demo_go_unprivileged();
+
// prints some info and sets up a section for PL0 code, loads a blob
// there and jumps to it... never, ever, ever returns
demo_go_unprivileged();
diff --git a/memory.h b/memory.h
index 2211c9d..1c9ae35 100644
--- a/memory.h
+++ b/memory.h
@@ -10,8 +10,8 @@
#define STACK_START ((uint32_t) 0x4000)
#define STACK_END ((uint32_t) 0x8000)
-extern char __end;
-extern char __start;
+extern const char __end;
+extern const char __start;
#define KERNEL_START ((uint32_t) &__start)
#define KERNEL_END ((uint32_t) &__end)