File indexing completed on 2025-05-11 08:23:05
0001
0002
0003
0004
0005
0006
0007
0008
0009
0010 #include <libcpu/mmu.h>
0011 #include <libcpu/arm-cp15.h>
0012
0013 typedef uint32_t mmu_lvl1_t;
0014
0015 extern uint32_t _ttbl_base;
0016
0017 static void mmu_set_map_inval(mmu_lvl1_t *base);
0018
0019 #define MMU_CTRL_MMU_EN (1 << 0)
0020 #define MMU_CTRL_ALIGN_FAULT_EN (1 << 1)
0021 #define MMU_CTRL_D_CACHE_EN (1 << 2)
0022 #define MMU_CTRL_DEFAULT (0xf << 3)
0023 #define MMU_CTRL_LITTLE_ENDIAN (0 << 7)
0024 #define MMU_CTRL_BIG_ENDIAN (1 << 7)
0025 #define MMU_CTRL_SYS_PROT (1 << 8)
0026 #define MMU_CTRL_ROM_PROT (1 << 9)
0027 #define MMU_CTRL_I_CACHE_EN (1 << 12)
0028 #define MMU_CTRL_LOW_VECT (0 << 13)
0029 #define MMU_CTRL_HIGH_VECT (1 << 13)
0030
0031
0032 #define MMU_SET_LVL1_SECT(addr, ap, dom, ce, be) \
0033 (((addr) & 0xfff00000) | \
0034 (ap) | \
0035 (dom) | \
0036 ((ce) << 3) | \
0037 ((be) << 2) | \
0038 0x12)
0039
0040 #define MMU_SET_LVL1_INVAL (0x0)
0041
0042 #define MMU_SECT_AP_ALL (0x3 << 10)
0043
0044 void mmu_init(mmu_sect_map_t *map)
0045 {
0046 mmu_lvl1_t *lvl1_base;
0047 int i;
0048
0049
0050 arm_cp15_cache_invalidate();
0051 arm_cp15_tlb_invalidate();
0052
0053
0054 arm_cp15_set_domain_access_control(0xffffffff);
0055
0056 lvl1_base = (mmu_lvl1_t *)&_ttbl_base;
0057
0058
0059 mmu_set_map_inval(lvl1_base);
0060 arm_cp15_set_translation_table_base(lvl1_base);
0061
0062
0063 i = 0;
0064 while(map[i].size != 0) {
0065 int c = 0;
0066 int b = 0;
0067 int pbase;
0068 int vbase;
0069 int sects;
0070
0071 switch (map[i].cache_flags) {
0072 case MMU_CACHE_NONE:
0073 c = 0;
0074 b = 0;
0075 break;
0076 case MMU_CACHE_BUFFERED:
0077 c = 0;
0078 b = 1;
0079 break;
0080 case MMU_CACHE_WTHROUGH:
0081 c = 1;
0082 b = 0;
0083 break;
0084 case MMU_CACHE_WBACK:
0085 c = 1;
0086 b = 1;
0087 break;
0088 }
0089
0090 pbase = (map[i].paddr & 0xfff00000) >> 20;
0091 vbase = (map[i].vaddr & 0xfff00000) >> 20;
0092 sects = map[i].size;
0093
0094 while (sects > 0) {
0095 lvl1_base[vbase] = MMU_SET_LVL1_SECT(pbase << 20,
0096 MMU_SECT_AP_ALL,
0097 0,
0098 c,
0099 b);
0100 pbase++;
0101 vbase++;
0102 sects--;
0103 }
0104 i++;
0105 }
0106
0107
0108 arm_cp15_cache_invalidate();
0109 arm_cp15_tlb_invalidate();
0110
0111
0112 arm_cp15_set_control(MMU_CTRL_DEFAULT |
0113 MMU_CTRL_D_CACHE_EN |
0114 MMU_CTRL_I_CACHE_EN |
0115 MMU_CTRL_ALIGN_FAULT_EN |
0116 MMU_CTRL_LITTLE_ENDIAN |
0117 MMU_CTRL_MMU_EN);
0118
0119 return;
0120 }
0121
0122
0123 static void mmu_set_map_inval(mmu_lvl1_t *base)
0124 {
0125 int i;
0126 for (i = 0; i < (0x4000 / 4); i++) {
0127 base[i] = MMU_SET_LVL1_INVAL;
0128 }
0129 }
0130
0131 void mmu_set_cpu_async_mode(void)
0132 {
0133 uint32_t reg;
0134 reg = arm_cp15_get_control();
0135 reg |= 0xc0000000;
0136 arm_cp15_set_control(reg);
0137 }