furi_hal_mpu.c 2.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566
  1. #include <furi_hal_mpu.h>
  2. #include <stm32wbxx_ll_cortex.h>
  3. #define FURI_HAL_MPU_ATTRIBUTES \
  4. (LL_MPU_ACCESS_BUFFERABLE | LL_MPU_ACCESS_CACHEABLE | LL_MPU_ACCESS_SHAREABLE | \
  5. LL_MPU_TEX_LEVEL1 | LL_MPU_INSTRUCTION_ACCESS_ENABLE)
  6. #define FURI_HAL_MPU_STACK_PROTECT_REGION FuriHalMPURegionSize32B
  7. void furi_hal_mpu_init() {
  8. furi_hal_mpu_enable();
  9. // NULL pointer dereference protection
  10. furi_hal_mpu_protect_no_access(FuriHalMpuRegionNULL, 0x00, FuriHalMPURegionSize1MB);
  11. }
  12. void furi_hal_mpu_enable() {
  13. LL_MPU_Enable(LL_MPU_CTRL_PRIVILEGED_DEFAULT);
  14. }
  15. void furi_hal_mpu_disable() {
  16. LL_MPU_Disable();
  17. }
  18. void furi_hal_mpu_protect_no_access(
  19. FuriHalMpuRegion region,
  20. uint32_t address,
  21. FuriHalMPURegionSize size) {
  22. uint32_t size_ll = size;
  23. size_ll = size_ll << MPU_RASR_SIZE_Pos;
  24. furi_hal_mpu_disable();
  25. LL_MPU_ConfigRegion(
  26. region, 0x00, address, FURI_HAL_MPU_ATTRIBUTES | LL_MPU_REGION_NO_ACCESS | size_ll);
  27. furi_hal_mpu_enable();
  28. }
  29. void furi_hal_mpu_protect_read_only(
  30. FuriHalMpuRegion region,
  31. uint32_t address,
  32. FuriHalMPURegionSize size) {
  33. uint32_t size_ll = size;
  34. size_ll = size_ll << MPU_RASR_SIZE_Pos;
  35. furi_hal_mpu_disable();
  36. LL_MPU_ConfigRegion(
  37. region, 0x00, address, FURI_HAL_MPU_ATTRIBUTES | LL_MPU_REGION_PRIV_RO_URO | size_ll);
  38. furi_hal_mpu_enable();
  39. }
  40. void furi_hal_mpu_protect_disable(FuriHalMpuRegion region) {
  41. furi_hal_mpu_disable();
  42. LL_MPU_DisableRegion(region);
  43. furi_hal_mpu_enable();
  44. }
  45. void furi_hal_mpu_set_stack_protection(uint32_t* stack) {
  46. // Protection area address must be aligned to region size
  47. uint32_t stack_ptr = (uint32_t)stack;
  48. uint32_t mask = ((1 << (FURI_HAL_MPU_STACK_PROTECT_REGION + 2)) - 1);
  49. stack_ptr &= ~mask;
  50. if(stack_ptr < (uint32_t)stack) stack_ptr += (mask + 1);
  51. furi_hal_mpu_protect_read_only(
  52. FuriHalMpuRegionStack, stack_ptr, FURI_HAL_MPU_STACK_PROTECT_REGION);
  53. }