diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/kern/main.c | 99 | ||||
-rw-r--r-- | src/kern/mpu/mpu_manager.c | 63 |
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; +} |