m4u_pgtable.h 5.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144
  1. #ifndef __M4U_PGTABLE_H__
  2. #define __M4U_PGTABLE_H__
  3. #include "m4u_reg.h"
  4. /* ================================================================= */
  5. /* 2 level pagetable: pgd -> pte */
  6. #define F_PTE_TYPE_MSK F_MSK(1, 0)
  7. #define F_PTE_TYPE_SET(val) F_VAL(val, 1, 0)
  8. #define F_PTE_TYPE_GET(regval) F_MSK_SHIFT(regval, 1, 0)
  9. #define F_PTE_TYPE_LARGE (0x1)
  10. #define F_PTE_TYPE_SMALL (0x2)
  11. #define F_PTE_B_BIT F_BIT_SET(2)
  12. #define F_PTE_C_BIT F_BIT_SET(3)
  13. #define F_PTE_AP_MSK F_MSK(5, 4)
  14. #define F_PTE_AP_SET(val) F_VAL(val, 5, 4)
  15. #define F_PTE_AP_GET(regval) F_MSK_SHIFT(regval, 5, 4)
  16. #define F_PTE_TEX_MSK F_MSK(8, 6)
  17. #define F_PTE_TEX_SET(val) F_VAL(val, 8, 6)
  18. #define F_PTE_TEX_GET(regval) F_MSK_SHIFT(regval, 8, 6)
  19. #define F_PTE_BIT32_BIT F_BIT_SET(9)
  20. #define F_PTE_S_BIT F_BIT_SET(10)
  21. #define F_PTE_NG_BIT F_BIT_SET(11)
  22. #define F_PTE_PA_LARGE_MSK F_MSK(31, 16)
  23. #define F_PTE_PA_LARGE_SET(val) F_VAL(val, 31, 16)
  24. #define F_PTE_PA_LARGE_GET(regval) F_MSK_SHIFT(regval, 31, 16)
  25. #define F_PTE_PA_SMALL_MSK F_MSK(31, 12)
  26. #define F_PTE_PA_SMALL_SET(val) F_VAL(val, 31, 12)
  27. #define F_PTE_PA_SMALL_GET(regval) F_MSK_SHIFT(regval, 31, 12)
  28. #define F_PTE_TYPE_IS_LARGE_PAGE(pte) ((imu_pte_val(pte)&0x3) == F_PTE_TYPE_LARGE)
  29. #define F_PTE_TYPE_IS_SMALL_PAGE(pte) ((imu_pte_val(pte)&0x3) == F_PTE_TYPE_SMALL)
  30. #define F_PGD_TYPE_PAGE (0x1)
  31. #define F_PGD_TYPE_PAGE_MSK (0x3)
  32. #define F_PGD_TYPE_SECTION (0x2)
  33. #define F_PGD_TYPE_SUPERSECTION (0x2|(1<<18))
  34. #define F_PGD_TYPE_SECTION_MSK (0x3|(1<<18))
  35. #define F_PGD_TYPE_IS_PAGE(pgd) ((imu_pgd_val(pgd)&3) == 1)
  36. #define F_PGD_TYPE_IS_SECTION(pgd) \
  37. (F_PGD_TYPE_IS_PAGE(pgd) ? 0 : ((imu_pgd_val(pgd)&F_PGD_TYPE_SECTION_MSK) == F_PGD_TYPE_SECTION))
  38. #define F_PGD_TYPE_IS_SUPERSECTION(pgd) \
  39. (F_PGD_TYPE_IS_PAGE(pgd) ? 0 : ((imu_pgd_val(pgd)&F_PGD_TYPE_SECTION_MSK) == F_PGD_TYPE_SUPERSECTION))
  40. #define F_PGD_B_BIT F_BIT_SET(2)
  41. #define F_PGD_C_BIT F_BIT_SET(3)
  42. #define F_PGD_AP_MSK F_MSK(11, 10)
  43. #define F_PGD_AP_SET(val) F_VAL(val, 11, 10)
  44. #define F_PGD_AP_GET(regval) F_MSK_SHIFT(regval, 11, 10)
  45. #define F_PGD_TEX_MSK F_MSK(14, 12)
  46. #define F_PGD_TEX_SET(val) F_VAL(val, 14, 12)
  47. #define F_PGD_TEX_GET(regval) F_MSK_SHIFT(regval, 14, 12)
  48. #define F_PGD_BIT32_BIT F_BIT_SET(9)
  49. #define F_PGD_S_BIT F_BIT_SET(16)
  50. #define F_PGD_NG_BIT F_BIT_SET(17)
  51. #define F_PGD_NS_BIT_PAGE(ns) F_BIT_VAL(ns, 3)
  52. #define F_PGD_NS_BIT_SECTION(ns) F_BIT_VAL(ns, 19)
  53. #define F_PGD_NS_BIT_SUPERSECTION(ns) F_BIT_VAL(ns, 19)
  54. #define F_PGD_PA_PAGETABLE_MSK F_MSK(31, 10)
  55. #define F_PGD_PA_PAGETABLE_SET(val) F_VAL(val, 31, 10)
  56. #define F_PGD_PA_SECTION_MSK F_MSK(31, 20)
  57. #define F_PGD_PA_SECTION_SET(val) F_VAL(val, 31, 20)
  58. #define F_PGD_PA_SUPERSECTION_MSK F_MSK(31, 24)
  59. #define F_PGD_PA_SUPERSECTION_SET(val) F_VAL(val, 31, 24)
  60. /* pagetable walk */
  61. #define IMU_PGDIR_SHIFT 20
  62. #define IMU_PAGE_SHIFT 12
  63. #define IMU_PTRS_PER_PGD 4096
  64. #define IMU_PTRS_PER_PTE 256
  65. #define IMU_BYTES_PER_PTE (IMU_PTRS_PER_PTE*sizeof(imu_pteval_t))
  66. #define MMU_PT_TYPE_SUPERSECTION (1<<4)
  67. #define MMU_PT_TYPE_SECTION (1<<3)
  68. #define MMU_PT_TYPE_LARGE_PAGE (1<<2)
  69. #define MMU_PT_TYPE_SMALL_PAGE (1<<1)
  70. #define MMU_SMALL_PAGE_SIZE (SZ_4K)
  71. #define MMU_LARGE_PAGE_SIZE (SZ_64K)
  72. #define MMU_SECTION_SIZE (SZ_1M)
  73. #define MMU_SUPERSECTION_SIZE (SZ_16M)
  74. typedef unsigned int imu_pteval_t;
  75. typedef struct {imu_pteval_t imu_pte; } imu_pte_t;
  76. typedef struct {imu_pteval_t imu_pgd; } imu_pgd_t;
  77. #define imu_pte_val(x) ((x).imu_pte)
  78. #define imu_pgd_val(x) ((x).imu_pgd)
  79. #define __imu_pte(x) ((imu_pte_t){(x)})
  80. #define __imu_pgd(x) ((imu_pgd_t){(x)})
  81. #define imu_pte_none(pte) (!imu_pte_val(pte))
  82. #define imu_pte_type(pte) (imu_pte_val(pte)&0x3)
  83. #define imu_pgd_index(addr) ((addr) >> IMU_PGDIR_SHIFT)
  84. #define imu_pgd_offset(domain, addr) ((domain)->pgd + imu_pgd_index(addr))
  85. #define imu_pte_index(addr) (((addr)>>IMU_PAGE_SHIFT)&(IMU_PTRS_PER_PTE - 1))
  86. #define imu_pte_offset_map(pgd, addr) (imu_pte_map(pgd) + imu_pte_index(addr))
  87. static inline imu_pte_t *imu_pte_map(imu_pgd_t *pgd)
  88. {
  89. return (imu_pte_t *) __va(imu_pgd_val(*pgd) & F_PGD_PA_PAGETABLE_MSK);
  90. }
  91. static inline int imu_pte_unmap(imu_pte_t *pte)
  92. {
  93. return 0;
  94. }
  95. static inline unsigned int imu_pgd_entry_pa(imu_pgd_t pgd)
  96. {
  97. if (F_PGD_TYPE_IS_PAGE(pgd))
  98. return imu_pgd_val(pgd) & F_PGD_PA_PAGETABLE_MSK;
  99. else if (F_PGD_TYPE_IS_SECTION(pgd))
  100. return imu_pgd_val(pgd) & F_PGD_PA_SECTION_MSK;
  101. else if (F_PGD_TYPE_IS_SUPERSECTION(pgd))
  102. return imu_pgd_val(pgd) & F_PGD_PA_SUPERSECTION_MSK;
  103. else
  104. return 0;
  105. }
  106. static inline imu_pgd_t *imu_supersection_start(imu_pgd_t *pgd)
  107. {
  108. return (imu_pgd_t *) (round_down((unsigned long)pgd, (16 * 4)));
  109. }
  110. static inline imu_pte_t *imu_largepage_start(imu_pte_t *pte)
  111. {
  112. return (imu_pte_t *) (round_down((unsigned long)pte, (16 * 4)));
  113. }
  114. static inline unsigned long long m4u_calc_next_mva(unsigned long long addr, unsigned long long end, unsigned int size)
  115. {
  116. /* addr + size may equal 0x100000000*/
  117. unsigned long long __boundary = (addr + (unsigned long long)size) & (~((unsigned long long)size-1));
  118. unsigned long long min = min_t(unsigned long long, __boundary, end);
  119. return min;
  120. }
  121. #endif