aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorJosh Rahm <joshuarahm@gmail.com>2020-11-25 11:27:45 -0700
committerJosh Rahm <joshuarahm@gmail.com>2020-11-25 11:32:16 -0700
commitd7d50cc81f72d1275140d7a15c52b6f9e272896f (patch)
tree875b7ed438412c3fc09ff49b58391787813e3998 /src
parentc29e0323020e0f96932d0f9b09747d5b2e28e5a6 (diff)
downloadstm32l4-d7d50cc81f72d1275140d7a15c52b6f9e272896f.tar.gz
stm32l4-d7d50cc81f72d1275140d7a15c52b6f9e272896f.tar.bz2
stm32l4-d7d50cc81f72d1275140d7a15c52b6f9e272896f.zip
Add module for controlling the MPU.
The MPU is a module in arm chips which allow for memory access protection. They are more primitive than full MMUs, but can still provide at least basic access control between different process controls.
Diffstat (limited to 'src')
-rw-r--r--src/kern/main.c99
-rw-r--r--src/kern/mpu/mpu_manager.c63
2 files changed, 156 insertions, 6 deletions
diff --git a/src/kern/main.c b/src/kern/main.c
index c85decb..e3995b1 100644
--- a/src/kern/main.c
+++ b/src/kern/main.c
@@ -1,10 +1,17 @@
#include "arch.h"
+#include "arch/arm/cortex-m4/mpu.h"
#include "arch/stm32l4xxx/peripherals/clock.h"
#include "arch/stm32l4xxx/peripherals/system.h"
-#include "kern/log.h"
-#include "kern/panic.h"
#include "kern/init.h"
+#include "kern/log.h"
#include "kern/mem.h"
+#include "kern/mpu/mpu_manager.h"
+#include "kern/panic.h"
+
+void on_hard_fault()
+{
+ panic("Hard fault encountered!\n");
+}
void on_systick() /* Overrides weak-symbol on_systick. */
{
@@ -13,6 +20,8 @@ void on_systick() /* Overrides weak-symbol on_systick. */
#ifdef ARCH_STM32L4
+int thing_in_sram_1;
+
/* Main function. This gets executed from the interrupt vector defined above. */
int main()
{
@@ -20,18 +29,96 @@ int main()
klogf("Heap Start: %p\n", &HEAP_START);
klogf("Heap End : %p\n", &HEAP_STOP);
+ klogf("mpu: %p\n", &MPU);
+ klogf("mpu.type_r: %p\n", MPU.type_r);
+ klogf("mpu.ctrl_r: %p\n", MPU.ctrl_r);
+ klogf("mpu.rn_r: %p\n", MPU.rn_r);
+
+ thing_in_sram_1 = 0xdeadbeef;
+
+ uint32_t control;
+ asm volatile("mrs %0, control" : "=r"(control) :);
+
/* Set the countdown to start from 10,000,0000. */
SCB.strv_r = 10000000 / 20;
/* Enable interrupts. */
- regset(SCB.stcs_r, scb_tickint, 1);
+ // regset(SCB.stcs_r, scb_tickint, 1);
/* Start the systick. */
regset(SCB.stcs_r, scb_enable, 1);
- void* hunk = kalloc(25);
- kfree(hunk);
- kfree(hunk); /* Invalid free. */
+
+ klogf("&thing_in_sram_1: %p\n", &thing_in_sram_1);
+ klogf(" thing_in_sram_1: %p\n", thing_in_sram_1);
+ mpu_set_enabled(0);
+
+ memory_region_opts_t memopts = { 0 };
+ memopts.region = (void*) 0x08000000 /* Flash base */ ;
+ memopts.bufferable = 0;
+ memopts.cacheable = 1;
+ memopts.sharable = 0;
+ memopts.tex = 0;
+ memopts.size = REGION_SIZE_256Kb;
+ memopts.perms = ACCESS_PERMS_BOTH_RO;
+ memopts.subregion_disable = 0;
+ memopts.executable = 1;
+ memopts.enable = 1;
+
+ mpu_configure_region(0, &memopts);
+
+ memopts.region = (void*) SRAM1_BASE;
+ memopts.bufferable = 0;
+ memopts.cacheable = 1;
+ memopts.sharable = 0;
+ memopts.tex = 0;
+ memopts.size = REGION_SIZE_32Kb;
+ memopts.perms = ACCESS_PERMS_FULL;
+ memopts.subregion_disable = 0;
+ memopts.executable = 1;
+ memopts.enable = 1;
+
+ mpu_configure_region(1, &memopts);
+
+ memopts.region = (void*) SRAM2_BASE;
+ memopts.bufferable = 0;
+ memopts.cacheable = 1;
+ memopts.sharable = 0;
+ memopts.tex = 0;
+ memopts.size = REGION_SIZE_16Kb;
+ memopts.perms = ACCESS_PERMS_FULL;
+ memopts.subregion_disable = 0;
+ memopts.executable = 1;
+ memopts.enable = 1;
+
+ mpu_configure_region(2, &memopts);
+
+ for (uint32_t i = 0; i < 8; ++ i) {
+ MPU.rn_r = i;
+ klogf("--- %d ---\n", i);
+ klogf("mpu: %p\n", &MPU);
+ klogf("mpu.type_r: %p\n", MPU.type_r);
+ klogf("mpu.ctrl_r: %p\n", MPU.ctrl_r);
+ klogf("mpu.rn_r: %p\n", MPU.rn_r);
+ klogf("mpu.ras_r: %p\n", MPU.ras_r);
+ klogf("mpu.rba_r: %p\n", MPU.rba_r);
+ }
+
+ // memopts.region = (void*) (SRAM1_BASE);
+ // memopts.bufferable = 0;
+ // memopts.cacheable = 1;
+ // memopts.sharable = 1;
+ // memopts.tex = 0;
+ // memopts.size = REGION_SIZE_16Kb;
+ // memopts.perms = ACCESS_PERMS_NO_ACCESS;
+
+ klogf("MPU not enabled\n");
+ mpu_set_enabled(1);
+ for(;;);
+ // klogf("MPU enabled\n");
+
+ // klogf("&thing_in_sram_1: %p\n", &thing_in_sram_1);
+ // klogf(" thing_in_sram_1: %p\n", thing_in_sram_1);
}
#endif
diff --git a/src/kern/mpu/mpu_manager.c b/src/kern/mpu/mpu_manager.c
new file mode 100644
index 0000000..614766a
--- /dev/null
+++ b/src/kern/mpu/mpu_manager.c
@@ -0,0 +1,63 @@
+#include "arch.h"
+#include "kern/mpu/mpu_manager.h"
+
+#include "arch/arm/cortex-m4/mpu.h"
+#include "kern/common.h"
+#include "kern/log.h"
+#include "kern/panic.h"
+
+memory_region_opts_t memory_regions[8];
+
+void mpu_set_enabled(bool enabled)
+{
+ if (enabled) {
+ regset(MPU.ctrl_r, mpu_en, 1);
+ __isb();
+ __dsb();
+ } else {
+ regset(MPU.ctrl_r, mpu_en, 0);
+ }
+}
+
+void mpu_configure_region(int region_number, memory_region_opts_t* opts)
+{
+ if (region_number >= 8) {
+ panic("MPU can only handle 8 regions.");
+ }
+
+ memory_regions[region_number] = *opts;
+
+ uint32_t region = ptr2reg(opts->region);
+
+ if (opts->size == REGION_SIZE_4Gb && region != 0) {
+ panic("Region pointer must be 0 for region size of 4Gb");
+ } else if ((region & region_size_mask(opts->size))) {
+ panic("Memory region MUST be aligned with given size.");
+ }
+
+ MPU.rn_r = region_number;
+
+ uint32_t rbar = region;
+ regset(rbar, mpu_region, region_number);
+ regset(rbar, mpu_valid, 1);
+
+ klogf("Writing RBAR: %p\n", rbar);
+
+ uint32_t rasr = 0;
+ regset(rasr, mpu_en, opts->enable);
+ regset(rasr, mpu_size, opts->size);
+ regset(rasr, mpu_srd, opts->subregion_disable);
+
+ regset(rasr, mpu_b, opts->bufferable);
+ regset(rasr, mpu_c, opts->cacheable);
+ regset(rasr, mpu_s, opts->sharable);
+
+ regset(rasr, mpu_tex, opts->tex);
+ regset(rasr, mpu_ap, opts->perms);
+ regset(rasr, mpu_xn, !opts->executable);
+
+ klogf("Writing RASR: %p\n", rasr);
+
+ MPU.rba_r = rbar;
+ MPU.ras_r = rasr;
+}