diff options
author | Josh Rahm <joshuarahm@gmail.com> | 2020-11-25 11:27:45 -0700 |
---|---|---|
committer | Josh Rahm <joshuarahm@gmail.com> | 2020-11-25 11:32:16 -0700 |
commit | d7d50cc81f72d1275140d7a15c52b6f9e272896f (patch) | |
tree | 875b7ed438412c3fc09ff49b58391787813e3998 /src/kern/mpu/mpu_manager.c | |
parent | c29e0323020e0f96932d0f9b09747d5b2e28e5a6 (diff) | |
download | stm32l4-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/kern/mpu/mpu_manager.c')
-rw-r--r-- | src/kern/mpu/mpu_manager.c | 63 |
1 files changed, 63 insertions, 0 deletions
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; +} |