1 /*
2 * Copyright (c) 2009-2022 Huawei Technologies Co., Ltd. All rights reserved.
3 *
4 * UniProton is licensed under Mulan PSL v2.
5 * You can use this software according to the terms and conditions of the Mulan PSL v2.
6 * You may obtain a copy of Mulan PSL v2 at:
7 * http://license.coscl.org.cn/MulanPSL2
8 * THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
9 * EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
10 * MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
11 * See the Mulan PSL v2 for more details.
12 * Create: 2009-12-22
13 * Description: UniProton hi3093 demo
14 */
15 #ifndef __MMU_H__
16 #define __MMU_H__
17
18 #include "prt_typedef.h"
19
20 #define CACHE_POS 0x2
21 #define CACHE_ENABLE 0x4
22 #define CACHE_MASK 0x7
23
24 #define MT_DEVICE_NGNRNE 0
25 #define MT_DEVICE_NGNRE 1
26 #define MT_DEVICE_GRE 2
27 #define MT_NORMAL_NC 3
28 #define MT_NORMAL 4
29
30 #define MEMORY_ATTRIBUTES ((0x00 << (MT_DEVICE_NGNRNE * 8)) | \
31 (0x04 << (MT_DEVICE_NGNRE * 8)) | \
32 (0x0c << (MT_DEVICE_GRE * 8)) | \
33 (0x44 << (MT_NORMAL_NC * 8)) | \
34 (0xffUL << (MT_NORMAL * 8)))
35
36 #define PTE_TYPE_FAULT (0 << 0)
37 #define PTE_TYPE_BLOCK (1 << 0)
38 #define PTE_TYPE_VALID (1 << 0)
39 #define PTE_TYPE_MASK (3 << 0)
40 #define PTE_TYPE_PAGE (3 << 0)
41 #define PTE_TYPE_TABLE (3 << 0)
42
43 #define PTE_TABLE_PXN (1UL << 59)
44 #define PTE_TABLE_XN (1UL << 60)
45 #define PTE_TABLE_AP (1UL << 61)
46 #define PTE_TABLE_NS (1UL << 63)
47
48 #define PTE_BLOCK_MEMTYPE(x) ((x) << 2)
49 #define PTE_BLOCK_NS (1 << 5)
50 #define PTE_BLOCK_AP_R (2 << 6)
51 #define PTE_BLOCK_AP_RW (0 << 6)
52 #define PTE_BLOCK_NON_SHARE (0 << 8)
53 #define PTE_BLOCK_OUTER_SHARE (2 << 8)
54 #define PTE_BLOCK_INNER_SHARE (3 << 8)
55 #define PTE_BLOCK_AF (1 << 10)
56 #define PTE_BLOCK_NG (1 << 11)
57 #define PTE_BLOCK_PXN (1UL << 53)
58 #define PTE_BLOCK_UXN (1UL << 54)
59
60 #define PMD_ATTRINDX(t) ((t) << 2)
61 #define PMD_ATTRINDX_MASK (7 << 2)
62 #define PMD_ATTRMASK (PTE_BLOCK_PXN | \
63 PTE_BLOCK_UXN | \
64 PMD_ATTRINDX_MASK | \
65 PTE_TYPE_VALID)
66
67 #define TCR_IPS(x) ((x) << 32)
68 #define TCR_T0SZ(x) ((64 - (x)) << 0)
69 #define TCR_IRGN_NC (0 << 8)
70 #define TCR_IRGN_WBWA (1 << 8)
71 #define TCR_IRGN_WT (2 << 8)
72 #define TCR_IRGN_WBNWA (3 << 8)
73 #define TCR_IRGN_MASK (3 << 8)
74 #define TCR_ORGN_NC (0 << 10)
75 #define TCR_ORGN_WBWA (1 << 10)
76 #define TCR_ORGN_WT (2 << 10)
77 #define TCR_ORGN_WBNWA (3 << 10)
78 #define TCR_ORGN_MASK (3 << 10)
79 #define TCR_SHARED_NON (0 << 12)
80 #define TCR_SHARED_OUTER (2 << 12)
81 #define TCR_SHARED_INNER (3 << 12)
82 #define TCR_TG0_4K (0 << 14)
83 #define TCR_TG0_64K (1 << 14)
84 #define TCR_TG0_16K (2 << 14)
85 #define TCR_EPD1_DISABLE (1 << 23)
86
87 #define TCR_EL1_RSVD (1UL << 31)
88 #define TCR_EL2_RSVD (1UL << 31 | 1UL << 23)
89 #define TCR_EL3_RSVD (1UL << 31 | 1UL << 23)
90
91 #define MAX_PTE_ENTRIES_4K 512
92 #define MAX_PTE_ENTRIES_64K 8192
93
94 #define PTE_TABLE_ADDR_MARK_4K 0x0000FFFFFFFFF000ULL
95 #define PTE_TABLE_ADDR_MARK_64K 0x0000FFFFFFFF0000ULL
96
97
98 #define MMU_ATTR_DEVICE_NGNRNE (PTE_BLOCK_MEMTYPE(MT_DEVICE_NGNRNE))
99 #define MMU_ATTR_DEVICE (PTE_BLOCK_MEMTYPE(MT_DEVICE_NGNRE))
100 #define MMU_ATTR_UNCACHE_UNSHARE (PTE_BLOCK_MEMTYPE(MT_NORMAL_NC) | PTE_BLOCK_NON_SHARE)
101 #define MMU_ATTR_UNCACHE_SHARE (PTE_BLOCK_MEMTYPE(MT_NORMAL_NC) | PTE_BLOCK_INNER_SHARE)
102 #define MMU_ATTR_CACHE_UNSHARE (PTE_BLOCK_MEMTYPE(MT_NORMAL) | PTE_BLOCK_NON_SHARE)
103 #define MMU_ATTR_CACHE_SHARE (PTE_BLOCK_MEMTYPE(MT_NORMAL) | PTE_BLOCK_INNER_SHARE)
104 #define MMU_ATTR_MASK 0X31CULL
105
106 #define MMU_ACCESS_NONE (PTE_BLOCK_AP_RW)
107 #define MMU_ACCESS_R (PTE_BLOCK_AF | PTE_BLOCK_UXN | PTE_BLOCK_PXN | PTE_BLOCK_AP_R)
108 #define MMU_ACCESS_RW (PTE_BLOCK_AF | PTE_BLOCK_UXN | PTE_BLOCK_PXN | PTE_BLOCK_AP_RW)
109 #define MMU_ACCESS_RWX (PTE_BLOCK_AF | PTE_BLOCK_AP_RW)
110 #define MMU_ACCESS_RX (PTE_BLOCK_AF | PTE_BLOCK_AP_R)
111 #define MMU_ACCESS_MASK 0X600000000004C0ULL
112
113 #define MMU_GRANULE_4K 0
114 #define MMU_GRANULE_64K 1
115
116 #define MAX(a, b) (((a) > (b)) ? (a) : (b))
117 #define MIN(a, b) (((a) < (b)) ? (a) : (b))
118
119 #define CR_M (1 << 0)
120 #define CR_A (1 << 1)
121 #define CR_C (1 << 2)
122 #define CR_SA (1 << 3)
123 #define CR_I (1 << 12)
124 #define CR_WXN (1 << 19)
125 #define CR_EE (1 << 25)
126
127 #define SPSR_EL_END_LE (0 << 9)
128 #define SPSR_EL_DEBUG_MASK (1 << 9)
129 #define SPSR_EL_ASYN_MASK (1 << 8)
130 #define SPSR_EL_SERR_MASK (1 << 8)
131 #define SPSR_EL_IRQ_MASK (1 << 7)
132 #define SPSR_EL_FIQ_MASK (1 << 6)
133 #define SPSR_EL_T_A32 (0 << 5)
134 #define SPSR_EL_M_AARCH64 (0 << 4)
135 #define SPSR_EL_M_AARCH32 (1 << 4)
136 #define SPSR_EL_M_SVC (0x3)
137 #define SPSR_EL_M_HYP (0xa)
138 #define SPSR_EL_M_EL1H (5)
139 #define SPSR_EL_M_EL2H (9)
140
141 #define CPUECTLR_EL1_L1PCTL_MASK (7 << 13)
142 #define CPUECTLR_EL1_L3PCTL_MASK (7 << 10)
143
144 typedef enum {
145 MMU_LEVEL_0 = 0,
146 MMU_LEVEL_1,
147 MMU_LEVEL_2,
148 MMU_LEVEL_3,
149 MMU_LEVEL_MAX
150 } mmu_level_e;
151
152 typedef enum {
153 MMU_PHY_ADDR_LEVEL_0 = 0,
154 MMU_PHY_ADDR_LEVEL_1,
155 MMU_PHY_ADDR_LEVEL_2,
156 MMU_PHY_ADDR_LEVEL_3,
157 MMU_PHY_ADDR_LEVEL_4,
158 MMU_PHY_ADDR_LEVEL_5
159 } mmu_physical_addr_size_e;
160
161 typedef enum {
162 MMU_BITS_9 = 9,
163 MMU_BITS_12 = 12,
164 MMU_BITS_13 = 13,
165 MMU_BITS_16 = 16,
166 MMU_BITS_32 = 32,
167 MMU_BITS_36 = 36,
168 MMU_BITS_39 = 39,
169 MMU_BITS_40 = 40,
170 MMU_BITS_42 = 42,
171 MMU_BITS_44 = 44,
172 MMU_BITS_48 = 48,
173 } mmu_bits_e;
174
175 typedef struct {
176 U64 tlb_addr;
177 U64 tlb_size;
178 U64 tlb_fillptr;
179 U32 granule;
180 U32 start_level;
181 U32 va_bits;
182 } mmu_ctrl_s;
183
184 typedef struct {
185 U64 virt;
186 U64 phys;
187 U64 size;
188 U64 max_level;
189 U64 attrs;
190 } mmu_mmap_region_s;
191
get_sctlr(void)192 static inline unsigned long get_sctlr(void)
193 {
194 unsigned long val;
195
196 __asm__ __volatile__("mrs %0, sctlr_el1" : "=r" (val) : : "cc");
197
198 return val;
199 }
200
get_cpuectr(void)201 static inline unsigned long get_cpuectr(void)
202 {
203 unsigned long val;
204
205 __asm__ __volatile__("mrs %0, S3_1_C15_C2_1" : "=r" (val) : : "cc");
206
207 return val;
208 }
209
set_sctlr(unsigned long val)210 static inline void set_sctlr(unsigned long val)
211 {
212 __asm__ __volatile__("dsb sy");
213 __asm__ __volatile__("msr sctlr_el1, %0" : : "r" (val) : "cc");
214 __asm__ __volatile__("dsb sy");
215 __asm__ __volatile__("isb");
216 }
217
218 extern S32 mmu_init(void);
219
220 #endif
221