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