diff options
-rw-r--r-- | include/kern/mpu/mpu_manager.h | 4 | ||||
-rw-r--r-- | include/kern/priv.h | 14 | ||||
-rw-r--r-- | src/kern/main.c | 37 | ||||
-rw-r--r-- | src/kern/priv.c | 24 |
4 files changed, 75 insertions, 4 deletions
diff --git a/include/kern/mpu/mpu_manager.h b/include/kern/mpu/mpu_manager.h index 5e0bc7b..7c47722 100644 --- a/include/kern/mpu/mpu_manager.h +++ b/include/kern/mpu/mpu_manager.h @@ -34,14 +34,14 @@ typedef enum { REGION_SIZE_4Gb = 31, } region_size_t; -#define region_size_mask(region_size) ((1 << (region_size)) - 1) +#define region_size_mask(region_size) ((1 << (region_size + 1)) - 1) typedef enum { /* Neither Privileged nor non-Privileged code cannnot access this region */ ACCESS_PERMS_NO_ACCESS = 0, /* Only privileged users can access this memory. */ - ACCESS_PERMS_ONLY_PERMS = 1, + ACCESS_PERMS_ONLY_PRIV = 1, /* Privileged code can access fully, but non-privilege only has Read-only access.*/ diff --git a/include/kern/priv.h b/include/kern/priv.h new file mode 100644 index 0000000..8940b23 --- /dev/null +++ b/include/kern/priv.h @@ -0,0 +1,14 @@ +#ifndef _KERN_PRIV_H_ +#define _KERN_PRIV_H_ + +#include "kern/common.h" + +uint32_t get_control_register(); + +void set_control_register(uint32_t reg); + +/* Enters user mode from privilieged mode. */ +void enter_user_mode(); + + +#endif /* _KERN_PRIV_H_ */ diff --git a/src/kern/main.c b/src/kern/main.c index e3995b1..df2f0bf 100644 --- a/src/kern/main.c +++ b/src/kern/main.c @@ -7,6 +7,7 @@ #include "kern/mem.h" #include "kern/mpu/mpu_manager.h" #include "kern/panic.h" +#include "kern/priv.h" void on_hard_fault() { @@ -60,7 +61,7 @@ int main() memopts.sharable = 0; memopts.tex = 0; memopts.size = REGION_SIZE_256Kb; - memopts.perms = ACCESS_PERMS_BOTH_RO; + memopts.perms = ACCESS_PERMS_ONLY_PRIV_RO; memopts.subregion_disable = 0; memopts.executable = 1; memopts.enable = 1; @@ -72,7 +73,7 @@ int main() memopts.cacheable = 1; memopts.sharable = 0; memopts.tex = 0; - memopts.size = REGION_SIZE_32Kb; + memopts.size = REGION_SIZE_64Kb; memopts.perms = ACCESS_PERMS_FULL; memopts.subregion_disable = 0; memopts.executable = 1; @@ -93,6 +94,19 @@ int main() mpu_configure_region(2, &memopts); + memopts.region = (void*) 0x40000000 /* Peripheral base. */; + memopts.bufferable = 1; + memopts.cacheable = 0; + memopts.sharable = 1; + memopts.tex = 0; + memopts.size = REGION_SIZE_512Mb; + memopts.perms = ACCESS_PERMS_ONLY_PRIV; + memopts.subregion_disable = 0; + memopts.executable = 0; + memopts.enable = 1; + + mpu_configure_region(3, &memopts); + for (uint32_t i = 0; i < 8; ++ i) { MPU.rn_r = i; klogf("--- %d ---\n", i); @@ -112,8 +126,27 @@ int main() // memopts.size = REGION_SIZE_16Kb; // memopts.perms = ACCESS_PERMS_NO_ACCESS; + klogf("CONTROL: %p\n", get_control_register()); + klogf("CONTROL: %p\n", get_control_register()); klogf("MPU not enabled\n"); + + volatile int x; + klogf("x location: %p\n", &x); + mpu_set_enabled(1); + + x = 5; + klogf("Still alive?\n"); + + klogf("Entering User Mode\n"); + enter_user_mode(); + + asm volatile ( + "svc #4\n" + ); + + klogf("Should Kernel Panic\n"); + for(;;); // klogf("MPU enabled\n"); diff --git a/src/kern/priv.c b/src/kern/priv.c new file mode 100644 index 0000000..9d64005 --- /dev/null +++ b/src/kern/priv.c @@ -0,0 +1,24 @@ +#include "kern/priv.h" + +void set_control_register(uint32_t reg) +{ + asm volatile("msr control, %0" : "=r"(reg) :); +} + +uint32_t get_control_register() +{ + uint32_t control; + asm volatile("mrs %0, control" : "=r"(control) :); + return control; +} + +void enter_user_mode() +{ + asm volatile ( + "mov r0, #1\n\t" + "msr control, r0\n\t" + ); + + // uint32_t creg = get_control_register(); + // set_control_register(creg | 1); +} |