diff options
Diffstat (limited to 'src/kern/mpu/mpu_manager.c')
-rw-r--r-- | src/kern/mpu/mpu_manager.c | 103 |
1 files changed, 98 insertions, 5 deletions
diff --git a/src/kern/mpu/mpu_manager.c b/src/kern/mpu/mpu_manager.c index 614766a..0d03c39 100644 --- a/src/kern/mpu/mpu_manager.c +++ b/src/kern/mpu/mpu_manager.c @@ -1,6 +1,6 @@ -#include "arch.h" #include "kern/mpu/mpu_manager.h" +#include "arch.h" #include "arch/arm/cortex-m4/mpu.h" #include "kern/common.h" #include "kern/log.h" @@ -40,8 +40,6 @@ void mpu_configure_region(int region_number, memory_region_opts_t* opts) 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); @@ -56,8 +54,103 @@ void mpu_configure_region(int region_number, memory_region_opts_t* opts) 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; } + +static int find_unused_region_slot() +{ + // memory_region_opts_t memory_regions[8]; + + int i; + for (i = 0; i < sizeof(memory_regions) / sizeof(memory_region_opts_t); + ++i) { + if (!memory_regions[i].enable) { + return i; + } + } + + return i; +} + +void configure_peripheral_region( + void* peripheral_base, region_size_t region_size, privilege_t priv) +{ + int idx = find_unused_region_slot(); + + memory_region_opts_t memopts = {0}; + + memopts.region = peripheral_base; + memopts.bufferable = 1; + memopts.cacheable = 0; + memopts.sharable = 1; + memopts.tex = 0; + memopts.size = region_size; + switch (priv) { + case NOT_PRIVILEGED: + memopts.perms = ACCESS_PERMS_FULL; + break; + case PRIVILEGED: + memopts.perms = ACCESS_PERMS_ONLY_PRIV; + break; + } + memopts.subregion_disable = 0; + memopts.executable = 0; + memopts.enable = 1; + + mpu_configure_region(idx, &memopts); +} + +void configure_flash_region( + void* flash_base, region_size_t region_size, privilege_t priv) +{ + int idx = find_unused_region_slot(); + + memory_region_opts_t memopts = {0}; + memopts.region = flash_base; + memopts.bufferable = 0; + memopts.cacheable = 1; + memopts.sharable = 0; + memopts.tex = 0; + memopts.size = region_size; + switch (priv) { + case NOT_PRIVILEGED: + memopts.perms = ACCESS_PERMS_BOTH_RO; + break; + case PRIVILEGED: + memopts.perms = ACCESS_PERMS_ONLY_PRIV_RO; + break; + } + memopts.subregion_disable = 0; + memopts.executable = 1; + memopts.enable = 1; + + mpu_configure_region(idx, &memopts); +} + +void configure_ram_region( + void* ram_base, region_size_t region_size, privilege_t priv) +{ + int idx = find_unused_region_slot(); + + memory_region_opts_t memopts = {0}; + memopts.region = ram_base; + memopts.bufferable = 0; + memopts.cacheable = 1; + memopts.sharable = 0; + memopts.tex = 0; + memopts.size = region_size; + switch (priv) { + case NOT_PRIVILEGED: + memopts.perms = ACCESS_PERMS_FULL; + break; + case PRIVILEGED: + memopts.perms = ACCESS_PERMS_ONLY_PRIV; + break; + } + memopts.subregion_disable = 0; + memopts.executable = 0; + memopts.enable = 1; + + mpu_configure_region(idx, &memopts); +} |