mpu.c 3.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113
  1. /*
  2. * Copyright (C) 2023 Daniele Lacamera <root@danielinux.net>
  3. *
  4. * This program is free software: you can redistribute it and/or modify
  5. * it under the terms of the GNU Lesser General Public License as published by
  6. * the Free Software Foundation, either version 3 of the License, or
  7. * (at your option) any later version.
  8. *
  9. * This program is distributed in the hope that it will be useful,
  10. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  11. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  12. * GNU Lesser General Public License for more details.
  13. *
  14. * You should have received a copy of the GNU Lesser General Public License
  15. * along with this program. If not, see <http://www.gnu.org/licenses/>.
  16. */
  17. /*
  18. *
  19. * Author: Daniele Lacamera <root@danielinux.net>
  20. */
  21. #include <stdint.h>
  22. #define MPU_BASE (0xE000ED90)
  23. extern uint32_t _end_stack;
  24. /* FAULT enable register SHCSR */
  25. #define SHCSR (*(volatile uint32_t *)(0xE000ED24))
  26. /* Bit to enable memory fault handler */
  27. #define MEMFAULT_ENABLE (1 << 16)
  28. /* MPU Registers */
  29. #define MPU_TYPE (*(volatile uint32_t *)(MPU_BASE + 0x00))
  30. #define MPU_CTRL (*(volatile uint32_t *)(MPU_BASE + 0x04))
  31. #define MPU_RNR (*(volatile uint32_t *)(MPU_BASE + 0x08))
  32. #define MPU_RBAR (*(volatile uint32_t *)(MPU_BASE + 0x0c))
  33. #define MPU_RASR (*(volatile uint32_t *)(MPU_BASE + 0x10))
  34. /* Some use-case specific values for RASR */
  35. #define RASR_ENABLED (1)
  36. #define RASR_RW (1 << 24)
  37. #define RASR_RDONLY (5 << 24)
  38. #define RASR_NOACCESS (0 << 24)
  39. #define RASR_SCB (7 << 16)
  40. #define RASR_SB (5 << 16)
  41. #define RASR_NOEXEC (1 << 28)
  42. /* Size */
  43. #define MPUSIZE_1K (0x09 << 1)
  44. #define MPUSIZE_2K (0x0a << 1)
  45. #define MPUSIZE_4K (0x0b << 1)
  46. #define MPUSIZE_8K (0x0c << 1)
  47. #define MPUSIZE_16K (0x0d << 1)
  48. #define MPUSIZE_32K (0x0e << 1)
  49. #define MPUSIZE_64K (0x0f << 1)
  50. #define MPUSIZE_128K (0x10 << 1)
  51. #define MPUSIZE_256K (0x11 << 1)
  52. #define MPUSIZE_512K (0x12 << 1)
  53. #define MPUSIZE_1M (0x13 << 1)
  54. #define MPUSIZE_2M (0x14 << 1)
  55. #define MPUSIZE_4M (0x15 << 1)
  56. #define MPUSIZE_8M (0x16 << 1)
  57. #define MPUSIZE_16M (0x17 << 1)
  58. #define MPUSIZE_32M (0x18 << 1)
  59. #define MPUSIZE_64M (0x19 << 1)
  60. #define MPUSIZE_128M (0x1a << 1)
  61. #define MPUSIZE_256M (0x1b << 1)
  62. #define MPUSIZE_512M (0x1c << 1)
  63. #define MPUSIZE_1G (0x1d << 1)
  64. #define MPUSIZE_2G (0x1e << 1)
  65. #define MPUSIZE_4G (0x1f << 1)
  66. #define STACK_SIZE (4 * 1024)
  67. static void mpu_set_region(int region, uint32_t start, uint32_t attr)
  68. {
  69. MPU_RNR = region;
  70. MPU_RBAR = start;
  71. MPU_RNR = region;
  72. MPU_RASR = attr;
  73. }
  74. int f7_mpu_enable(void)
  75. {
  76. volatile uint32_t type;
  77. volatile uint32_t start;
  78. volatile uint32_t attr;
  79. type = MPU_TYPE;
  80. if (type == 0) {
  81. /* MPU not present! */
  82. return -1;
  83. }
  84. /* Disable MPU to reconfigure regions */
  85. MPU_CTRL = 0;
  86. /* Set flash area as read-only, executable */
  87. start = 0;
  88. attr = RASR_ENABLED | MPUSIZE_4G | RASR_SCB | RASR_RW;
  89. mpu_set_region(0, start, attr);
  90. /* Enable the MPU, no background region */
  91. MPU_CTRL = 1;
  92. return 0;
  93. }