From a03a7ffd52661330da92b5156fc2296f05aa9a89 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Paul=20Wei=C3=9F=20=28Poohl=29?= <45500341+Poohl@users.noreply.github.com> Date: Sat, 22 Jan 2022 19:07:41 +0100 Subject: [PATCH] u6 working --- apps/u5_demo.c | 6 ++-- apps/u6_demo.c | 62 +++++++++++++++++++++++++++++++++++++ apps/u6_demo.h | 9 ++++++ boards/portux/board.h | 7 ++++- boards/portux/drivers/mmu.c | 43 +++++++++++++++++++++++++ boards/portux/drivers/mmu.h | 16 ++++++++++ boards/portux/kernel.lds | 3 ++ boards/portux/startup.c | 9 ++++-- kernel/process_mgmt.c | 2 +- kernel/syscalls.c | 7 ++++- libs/hardware.c | 9 ++++-- 11 files changed, 163 insertions(+), 10 deletions(-) create mode 100644 apps/u6_demo.c create mode 100644 apps/u6_demo.h create mode 100644 boards/portux/drivers/mmu.c create mode 100644 boards/portux/drivers/mmu.h diff --git a/apps/u5_demo.c b/apps/u5_demo.c index 0ec3fb9..88f1001 100644 --- a/apps/u5_demo.c +++ b/apps/u5_demo.c @@ -4,21 +4,21 @@ #include "libs/printf.h" #include "libs/delay.h" -void write_active(char c) { +__attribute__ ((section (".usertext"))) void write_active(char c) { for (int i = 0; i < c; ++i) { sys_debug_put_char(c); worstdelayever(100); } } -void write_passive(char c) { +__attribute__ ((section (".usertext"))) void write_passive(char c) { for (int i = 0; i < c; ++i) { sys_debug_put_char(c); sys_sleep(0, 10000); } } -void reader() { +__attribute__ ((section (".usertext"))) void reader() { while (1) { int c = sys_debug_get_char(); init_thread_state_args next_thread = default_init_thread_state_args; diff --git a/apps/u6_demo.c b/apps/u6_demo.c new file mode 100644 index 0000000..b673d62 --- /dev/null +++ b/apps/u6_demo.c @@ -0,0 +1,62 @@ + + +#include "kernel/syscalls.h" +#include "kernel/process_mgmt.h" +#include "libs/printf.h" +#include "libs/delay.h" + +__attribute__ ((section (".usertext.rodata"))) +char intro[] = + "Please Select the kind of MMU fault you wish to trigger:\r\n" + "1: Read Nullpointer\r\n" + "2: Read Kernel data\r\n" + "3: Execute Kernel code\r\n" + "4: Write own code\r\n" + "5: Stackoverflow\r\n" + "6: read undefined memeory\r\n"; + +__attribute__ ((section (".usertext"))) int brick_it() { + for (int i = 0; i < 190; ++i) + sys_debug_put_char(intro[i]); + volatile u32 test; + switch (sys_debug_get_char()) { + case '1': + test = *((u32*) 0x0); + break; + case '2': + test = *((u32*) init_process_mgmt); + break; + case '3': + init_process_mgmt(); + break; + case '4': + *((u32*) brick_it) = 4; + break; + case '5': + asm volatile( + "mov r0, #1\n" + "mov r1, #2\n" + "mov r2, #3\n" + "mov r3, #4\n" + "mov r4, #5\n" + "mov r5, #6\n" + "mov r6, #7\n" + "mov r7, #8\n" + "mov r8, #9\n" + "mov r9, #10\n" + "mov r10, #11\n" + "mov r11, #12\n" + "mov r12, #13\n" + "push {r0-r12}\n" + "push {r0-r12}\n" + "push {r0-r12}\n" + "push {r0-r12}\n" + "add pc, pc, #-20" + : : : "memory" + ); + break; + case '6': + test = *((u32*) UNDEF_MEMORY1 + 200); + break; + } +} \ No newline at end of file diff --git a/apps/u6_demo.h b/apps/u6_demo.h new file mode 100644 index 0000000..dc6bb62 --- /dev/null +++ b/apps/u6_demo.h @@ -0,0 +1,9 @@ + + +#include "kernel/syscalls.h" +#include "kernel/process_mgmt.h" +#include "libs/printf.h" +#include "libs/delay.h" + + +__attribute__ ((section (".usertext"))) int brick_it(); diff --git a/boards/portux/board.h b/boards/portux/board.h index cc1012e..59bb87b 100644 --- a/boards/portux/board.h +++ b/boards/portux/board.h @@ -7,7 +7,12 @@ #define INTERNAL_SRAM 0x200000 -#define PROCESS_STACKS 0x260000 +#define EXTERNAL_SRAM 0x20000000 +#define PROCESS_STACKS 0x20200000 +#define UNDEF_MEMORY1 0x90000000 +#define UNDEF_MEMORY1_END 0xF0000000 +#define UNDEF_MEMORY2 0x00400000 +#define UNDEF_MEMORY2_END 0x10000000 #define INIT_STACK 0x270000 #define INIT_SYS_STACK INIT_STACK diff --git a/boards/portux/drivers/mmu.c b/boards/portux/drivers/mmu.c new file mode 100644 index 0000000..4adcb67 --- /dev/null +++ b/boards/portux/drivers/mmu.c @@ -0,0 +1,43 @@ + + +#include "mmu.h" +#include "board.h" + +static first_level_pagetable l1table; + +void init_first_level_pagetable() { + // 1:1 mapping for all memories with priv-only access and domain 0 + for (uint i = 0; i < 4096; ++i) { + l1table.desc[i] = (i << 20) | (AP_RW_NONE << 10) | 0b10; + } + // No access to Undefined memory even for priv + for (uint i = (UNDEF_MEMORY1 >> 20); i < 1519; ++i) + l1table.desc[i] = (AP_NONE_NONE << 10) | 0b10; + for (uint i = (UNDEF_MEMORY2 >> 20); i < 249; ++i) + l1table.desc[i] = (AP_NONE_NONE << 10) | 0b10; + + uint userland_desc = EXTERNAL_SRAM >> 20; + l1table.desc[userland_desc] = (userland_desc << 20) | (AP_RW_R << 10) | 0b10; + for (uint i = 0; i < 63; ++i) { + l1table.desc[userland_desc + 1 + i] |= (AP_RW_RW << 10); + } +} + +void init_mmu() { + asm volatile( // set domain 0 as manager + "mov r0, #0x1\n" + "mcr p15, 0, r0, c3, c0, 0" + : : : "memory"); + asm volatile( // set page-base-table + "mcr p15, 0, %[table], c2, c0, 0" + : + : [table] "r" (l1table.desc) + : "memory" + ); + asm volatile( // enable mmu + "mrc p15, 0, r0, c1, c0, 0\n" + "orr r0, r0, #0x1\n" + "mcr p15, 0, r0, c1, c0, 0\n" + : : : "r0", "memory" + ); +} \ No newline at end of file diff --git a/boards/portux/drivers/mmu.h b/boards/portux/drivers/mmu.h new file mode 100644 index 0000000..67fe7c7 --- /dev/null +++ b/boards/portux/drivers/mmu.h @@ -0,0 +1,16 @@ + + +#include "default.h" + +#define AP_NONE_NONE 0b00 +#define AP_RW_NONE 0b01 +#define AP_RW_R 0b10 +#define AP_RW_RW 0b11 + +typedef struct { + u32 desc[4096]; +} first_level_pagetable __attribute__ ((aligned (16384))); + +void init_first_level_pagetable(); + +void init_mmu(); diff --git a/boards/portux/kernel.lds b/boards/portux/kernel.lds index 8a6f676..f86e1ef 100644 --- a/boards/portux/kernel.lds +++ b/boards/portux/kernel.lds @@ -15,6 +15,9 @@ SECTIONS .bss : { *(.bss)} + . = 0x20000000; + .usertext : { *(.usertext*) } + /* debug stuffs, copied from ld -verbose */ /* DWARF debug sections. Symbols in the DWARF debugging sections are relative to the beginning diff --git a/boards/portux/startup.c b/boards/portux/startup.c index 3dbacfb..1fa418f 100644 --- a/boards/portux/startup.c +++ b/boards/portux/startup.c @@ -13,7 +13,8 @@ #include "kernel/syscalls.h" #include "apps/u5_demo.h" #include "kernel/config.h" - +#include "drivers/mmu.h" +#include "apps/u6_demo.h" // needed to prevent gcc from optimizing c_entry out. #pragma GCC push_options @@ -69,10 +70,14 @@ void c_entry(void) { //dbgu_write_async(17, "async writing!\r\n"); //dbgu_async_write_flush(); + init_first_level_pagetable(); + init_mmu(); + init_thread_state_args reader_t = default_init_thread_state_args; - reader_t.start = &reader; + reader_t.start = &brick_it; new_thread("reader", &reader_t); + /* interrupt tst loop*/ while (42) { asm volatile("nop":::); diff --git a/kernel/process_mgmt.c b/kernel/process_mgmt.c index 70e4f1b..8629fea 100644 --- a/kernel/process_mgmt.c +++ b/kernel/process_mgmt.c @@ -103,7 +103,7 @@ int new_thread(char* name, init_thread_state_args* args) { int id = get_tcb_slot(&tcbq); if (id < 0) return -1; if (!args->stack) - args->stack = (void*) (PROCESS_STACKS - (id - 1) * 0x5000); + args->stack = (void*) (PROCESS_STACKS - (id - 1) * 0x100000); cpu_context_init(&processes[id].context, args); return internal_new_thread_finalizer(name, id); } diff --git a/kernel/syscalls.c b/kernel/syscalls.c index abbcd79..73ba90a 100644 --- a/kernel/syscalls.c +++ b/kernel/syscalls.c @@ -53,31 +53,36 @@ int impl_get_char(u32* hw_context) { } __attribute__ ((noinline)) -void sys_exit() { +__attribute__ ((section (".usertext"))) void sys_exit() { do_syscall(0); } __attribute__ ((noinline)) +__attribute__ ((section (".usertext"))) void sys_new_thread(char* name, void* args) { do_syscall(1); } __attribute__ ((noinline)) +__attribute__ ((section (".usertext"))) void sys_restore_thread(char* name, void* context) { do_syscall(2); } __attribute__ ((noinline)) +__attribute__ ((section (".usertext"))) int sys_debug_put_char(char c) { do_syscall(3); } __attribute__ ((noinline)) +__attribute__ ((section (".usertext"))) int sys_debug_get_char() { do_syscall(4); } __attribute__ ((noinline)) +__attribute__ ((section (".usertext"))) void sys_sleep(u32 _ignore, u32 delay) { do_syscall(5); } diff --git a/libs/hardware.c b/libs/hardware.c index 647d454..a53349d 100644 --- a/libs/hardware.c +++ b/libs/hardware.c @@ -43,6 +43,7 @@ static const char* exception_fmt[] = { __attribute__((weak)) void exception_handler(int type, void* instruction, void* data) { printf(exception_fmt[type], instruction, data); + while (1); } __attribute__((weak)) void syscall_handler(int syscall, void* source) { @@ -53,13 +54,17 @@ __attribute__((weak)) void timer_handler() { debug_write(3, "!\r\n"); } -__attribute__((weak)) void *memset(void *s, int c, size_t n) { +__attribute__((weak)) void +__attribute__ ((section (".usertext"))) +*memset(void *s, int c, size_t n) { for (size_t i = 0; i < n; ++i) ((byte*) s)[i] = c; return s; } -__attribute__((weak)) void *memcpy(void *dest, const void *src, size_t n) { +__attribute__((weak)) +__attribute__ ((section (".usertext"))) +void *memcpy(void *dest, const void *src, size_t n) { for (size_t i = 0; i < n; ++i) ((byte*) dest)[i] = ((byte*) src)[i]; return dest; -- GitLab