1 /*
2  * ARMv7 MMU support
3  *
4  * Private data declarations
5  *
6  * Copyright (c) 2021 Weidmueller Interface GmbH & Co. KG
7  * SPDX-License-Identifier: Apache-2.0
8  */
9 
10 #ifndef ZEPHYR_ARCH_AARCH32_ARM_MMU_PRIV_H_
11 #define ZEPHYR_ARCH_AARCH32_ARM_MMU_PRIV_H_
12 
13 /*
14  * Comp.:
15  * ARM Architecture Reference Manual, ARMv7-A and ARMv7-R edition
16  * ARM document ID DDI0406C Rev. d, March 2018
17  * L1 / L2 page table entry formats and entry type IDs:
18  * Chapter B3.5.1, fig. B3-4 and B3-5, p. B3-1323 f.
19  */
20 
21 #define ARM_MMU_PT_L1_NUM_ENTRIES		4096
22 #define ARM_MMU_PT_L2_NUM_ENTRIES		256
23 
24 #define ARM_MMU_PTE_L1_INDEX_PA_SHIFT		20
25 #define ARM_MMU_PTE_L1_INDEX_MASK		0xFFF
26 #define ARM_MMU_PTE_L2_INDEX_PA_SHIFT		12
27 #define ARM_MMU_PTE_L2_INDEX_MASK		0xFF
28 #define ARM_MMU_PT_L2_ADDR_SHIFT		10
29 #define ARM_MMU_PT_L2_ADDR_MASK			0x3FFFFF
30 #define ARM_MMU_PTE_L2_SMALL_PAGE_ADDR_SHIFT	12
31 #define ARM_MMU_PTE_L2_SMALL_PAGE_ADDR_MASK	0xFFFFF
32 #define ARM_MMU_ADDR_BELOW_PAGE_GRAN_MASK	0xFFF
33 
34 #define ARM_MMU_PTE_ID_INVALID			0x0
35 #define ARM_MMU_PTE_ID_L2_PT			0x1
36 #define ARM_MMU_PTE_ID_SECTION			0x2
37 #define ARM_MMU_PTE_ID_LARGE_PAGE		0x1
38 #define ARM_MMU_PTE_ID_SMALL_PAGE		0x2
39 
40 #define ARM_MMU_PERMS_AP2_DISABLE_WR		0x2
41 #define ARM_MMU_PERMS_AP1_ENABLE_PL0		0x1
42 #define ARM_MMU_TEX2_CACHEABLE_MEMORY		0x4
43 
44 #define ARM_MMU_TEX_CACHE_ATTRS_WB_WA		0x1
45 #define ARM_MMU_TEX_CACHE_ATTRS_WT_nWA		0x2
46 #define ARM_MMU_TEX_CACHE_ATTRS_WB_nWA		0x3
47 #define ARM_MMU_C_CACHE_ATTRS_WB_WA		0
48 #define ARM_MMU_B_CACHE_ATTRS_WB_WA		1
49 #define ARM_MMU_C_CACHE_ATTRS_WT_nWA		1
50 #define ARM_MMU_B_CACHE_ATTRS_WT_nWA		0
51 #define ARM_MMU_C_CACHE_ATTRS_WB_nWA		1
52 #define ARM_MMU_B_CACHE_ATTRS_WB_nWA		1
53 
54 /*
55  * The following defines might vary if support for CPUs without
56  * the multiprocessor extensions was to be implemented:
57  */
58 
59 #define ARM_MMU_TTBR_IRGN0_BIT_MP_EXT_ONLY	BIT(6)
60 #define ARM_MMU_TTBR_NOS_BIT			BIT(5)
61 #define ARM_MMU_TTBR_RGN_OUTER_NON_CACHEABLE	0x0
62 #define ARM_MMU_TTBR_RGN_OUTER_WB_WA_CACHEABLE	0x1
63 #define ARM_MMU_TTBR_RGN_OUTER_WT_CACHEABLE	0x2
64 #define ARM_MMU_TTBR_RGN_OUTER_WB_nWA_CACHEABLE	0x3
65 #define ARM_MMU_TTBR_RGN_SHIFT			3
66 #define ARM_MMU_TTBR_SHAREABLE_BIT		BIT(1)
67 #define ARM_MMU_TTBR_IRGN1_BIT_MP_EXT_ONLY	BIT(0)
68 #define ARM_MMU_TTBR_CACHEABLE_BIT_NON_MP_ONLY	BIT(0)
69 
70 /* <-- end MP-/non-MP-specific */
71 
72 #define ARM_MMU_DOMAIN_OS			0
73 #define ARM_MMU_DOMAIN_DEVICE			1
74 #define ARM_MMU_DACR_ALL_DOMAINS_CLIENT		0x55555555
75 
76 #define ARM_MMU_SCTLR_AFE_BIT			BIT(29)
77 #define ARM_MMU_SCTLR_TEX_REMAP_ENABLE_BIT	BIT(28)
78 #define ARM_MMU_SCTLR_HA_BIT			BIT(17)
79 #define ARM_MMU_SCTLR_ICACHE_ENABLE_BIT		BIT(12)
80 #define ARM_MMU_SCTLR_DCACHE_ENABLE_BIT		BIT(2)
81 #define ARM_MMU_SCTLR_CHK_ALIGN_ENABLE_BIT	BIT(1)
82 #define ARM_MMU_SCTLR_MMU_ENABLE_BIT		BIT(0)
83 
84 #define ARM_MMU_L2_PT_INDEX(pt) ((uint32_t)pt - (uint32_t)l2_page_tables) /\
85 				sizeof(struct arm_mmu_l2_page_table);
86 
87 union arm_mmu_l1_page_table_entry {
88 	struct {
89 		uint32_t id			: 2;  /* [00] */
90 		uint32_t bufferable		: 1;
91 		uint32_t cacheable		: 1;
92 		uint32_t exec_never		: 1;
93 		uint32_t domain			: 4;
94 		uint32_t impl_def		: 1;
95 		uint32_t acc_perms10		: 2;
96 		uint32_t tex			: 3;
97 		uint32_t acc_perms2		: 1;
98 		uint32_t shared			: 1;
99 		uint32_t not_global		: 1;
100 		uint32_t zero			: 1;
101 		uint32_t non_sec		: 1;
102 		uint32_t base_address		: 12; /* [31] */
103 	} l1_section_1m;
104 	struct {
105 		uint32_t id			: 2;  /* [00] */
106 		uint32_t zero0			: 1;  /* PXN if avail. */
107 		uint32_t non_sec		: 1;
108 		uint32_t zero1			: 1;
109 		uint32_t domain			: 4;
110 		uint32_t impl_def		: 1;
111 		uint32_t l2_page_table_address	: 22; /* [31] */
112 	} l2_page_table_ref;
113 	struct {
114 		uint32_t id			: 2;  /* [00] */
115 		uint32_t reserved		: 30; /* [31] */
116 	} undefined;
117 	uint32_t word;
118 };
119 
120 struct arm_mmu_l1_page_table {
121 	union arm_mmu_l1_page_table_entry entries[ARM_MMU_PT_L1_NUM_ENTRIES];
122 };
123 
124 union arm_mmu_l2_page_table_entry {
125 	struct {
126 		uint32_t id			: 2;  /* [00] */
127 		uint32_t bufferable		: 1;
128 		uint32_t cacheable		: 1;
129 		uint32_t acc_perms10		: 2;
130 		uint32_t tex			: 3;
131 		uint32_t acc_perms2		: 1;
132 		uint32_t shared			: 1;
133 		uint32_t not_global		: 1;
134 		uint32_t pa_base		: 20; /* [31] */
135 	} l2_page_4k;
136 	struct {
137 		uint32_t id			: 2;  /* [00] */
138 		uint32_t bufferable		: 1;
139 		uint32_t cacheable		: 1;
140 		uint32_t acc_perms10		: 2;
141 		uint32_t zero			: 3;
142 		uint32_t acc_perms2		: 1;
143 		uint32_t shared			: 1;
144 		uint32_t not_global		: 1;
145 		uint32_t tex			: 3;
146 		uint32_t exec_never		: 1;
147 		uint32_t pa_base		: 16; /* [31] */
148 	} l2_page_64k;
149 	struct {
150 		uint32_t id			: 2;  /* [00] */
151 		uint32_t reserved		: 30; /* [31] */
152 	} undefined;
153 	uint32_t word;
154 };
155 
156 struct arm_mmu_l2_page_table {
157 	union arm_mmu_l2_page_table_entry entries[ARM_MMU_PT_L2_NUM_ENTRIES];
158 };
159 
160 /*
161  * Data structure for L2 table usage tracking, contains a
162  * L1 index reference if the respective L2 table is in use.
163  */
164 
165 struct arm_mmu_l2_page_table_status {
166 	uint32_t l1_index : 12;
167 	uint32_t entries  : 9;
168 	uint32_t reserved : 11;
169 };
170 
171 /*
172  * Data structure used to describe memory areas defined by the
173  * current Zephyr image, for which an identity mapping (pa = va)
174  * will be set up. Those memory areas are processed during the
175  * MMU initialization.
176  */
177 struct arm_mmu_flat_range {
178 	const char	*name;
179 	uint32_t	start;
180 	uint32_t	end;
181 	uint32_t	attrs;
182 };
183 
184 /*
185  * Data structure containing the memory attributes and permissions
186  * data derived from a memory region's attr flags word in the format
187  * required for setting up the corresponding PTEs.
188  */
189 struct arm_mmu_perms_attrs {
190 	uint32_t acc_perms	: 2;
191 	uint32_t bufferable	: 1;
192 	uint32_t cacheable	: 1;
193 	uint32_t not_global	: 1;
194 	uint32_t non_sec	: 1;
195 	uint32_t shared		: 1;
196 	uint32_t tex		: 3;
197 	uint32_t exec_never	: 1;
198 	uint32_t id_mask	: 2;
199 	uint32_t domain		: 4;
200 	uint32_t reserved	: 15;
201 };
202 
203 #endif /* ZEPHYR_ARCH_AARCH32_ARM_MMU_PRIV_H_ */
204