armv7_mpu.h 2.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134
  1. /* SPDX-License-Identifier: GPL-2.0+ */
  2. /*
  3. * Copyright (C) 2017, STMicroelectronics - All Rights Reserved
  4. * Author(s): Vikas Manocha, <vikas.manocha@st.com> for STMicroelectronics.
  5. */
  6. #ifndef _ASM_ARMV7_MPU_H
  7. #define _ASM_ARMV7_MPU_H
  8. #ifndef __ASSEMBLY__
  9. #include <linux/bitops.h>
  10. #endif
  11. #ifdef CONFIG_CPU_V7M
  12. #define AP_SHIFT 24
  13. #define XN_SHIFT 28
  14. #define TEX_SHIFT 19
  15. #define S_SHIFT 18
  16. #define C_SHIFT 17
  17. #define B_SHIFT 16
  18. #else /* CONFIG_CPU_V7R */
  19. #define XN_SHIFT 12
  20. #define AP_SHIFT 8
  21. #define TEX_SHIFT 3
  22. #define S_SHIFT 2
  23. #define C_SHIFT 1
  24. #define B_SHIFT 0
  25. #endif /* CONFIG_CPU_V7R */
  26. #define CACHEABLE BIT(C_SHIFT)
  27. #define BUFFERABLE BIT(B_SHIFT)
  28. #define SHAREABLE BIT(S_SHIFT)
  29. #define REGION_SIZE_SHIFT 1
  30. #define ENABLE_REGION BIT(0)
  31. #define DISABLE_REGION 0
  32. enum region_number {
  33. REGION_0 = 0,
  34. REGION_1,
  35. REGION_2,
  36. REGION_3,
  37. REGION_4,
  38. REGION_5,
  39. REGION_6,
  40. REGION_7,
  41. };
  42. enum ap {
  43. NO_ACCESS = 0,
  44. PRIV_RW_USR_NO,
  45. PRIV_RW_USR_RO,
  46. PRIV_RW_USR_RW,
  47. UNPREDICTABLE,
  48. PRIV_RO_USR_NO,
  49. PRIV_RO_USR_RO,
  50. };
  51. enum mr_attr {
  52. STRONG_ORDER = 0,
  53. SHARED_WRITE_BUFFERED,
  54. O_I_WT_NO_WR_ALLOC,
  55. O_I_WB_NO_WR_ALLOC,
  56. O_I_NON_CACHEABLE,
  57. O_I_WB_RD_WR_ALLOC,
  58. DEVICE_NON_SHARED,
  59. };
  60. enum size {
  61. REGION_8MB = 22,
  62. REGION_16MB,
  63. REGION_32MB,
  64. REGION_64MB,
  65. REGION_128MB,
  66. REGION_256MB,
  67. REGION_512MB,
  68. REGION_1GB,
  69. REGION_2GB,
  70. REGION_4GB,
  71. };
  72. enum xn {
  73. XN_DIS = 0,
  74. XN_EN,
  75. };
  76. struct mpu_region_config {
  77. uint32_t start_addr;
  78. enum region_number region_no;
  79. enum xn xn;
  80. enum ap ap;
  81. enum mr_attr mr_attr;
  82. enum size reg_size;
  83. };
  84. void disable_mpu(void);
  85. void enable_mpu(void);
  86. int mpu_enabled(void);
  87. void mpu_config(struct mpu_region_config *reg_config);
  88. void setup_mpu_regions(struct mpu_region_config *rgns, u32 num_rgns);
  89. static inline u32 get_attr_encoding(u32 mr_attr)
  90. {
  91. u32 attr;
  92. switch (mr_attr) {
  93. case STRONG_ORDER:
  94. attr = SHAREABLE;
  95. break;
  96. case SHARED_WRITE_BUFFERED:
  97. attr = BUFFERABLE;
  98. break;
  99. case O_I_WT_NO_WR_ALLOC:
  100. attr = CACHEABLE;
  101. break;
  102. case O_I_WB_NO_WR_ALLOC:
  103. attr = CACHEABLE | BUFFERABLE;
  104. break;
  105. case O_I_NON_CACHEABLE:
  106. attr = 1 << TEX_SHIFT;
  107. break;
  108. case O_I_WB_RD_WR_ALLOC:
  109. attr = (1 << TEX_SHIFT) | CACHEABLE | BUFFERABLE;
  110. break;
  111. case DEVICE_NON_SHARED:
  112. attr = (2 << TEX_SHIFT) | BUFFERABLE;
  113. break;
  114. default:
  115. attr = 0; /* strongly ordered */
  116. break;
  117. };
  118. return attr;
  119. }
  120. #endif /* _ASM_ARMV7_MPU_H */