1 /*
2  * ARMv7 MMU support
3  *
4  * Copyright (c) 2021 Weidmueller Interface GmbH & Co. KG
5  * SPDX-License-Identifier: Apache-2.0
6  */
7 
8 #ifndef ZEPHYR_INCLUDE_ARCH_AARCH32_ARM_MMU_H_
9 #define ZEPHYR_INCLUDE_ARCH_AARCH32_ARM_MMU_H_
10 
11 #ifndef _ASMLANGUAGE
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  * Memory type definitions:
18  * Table B3-10, chap. B3.8.2, p. B3-1363f.
19  * Outer / inner cache attributes for cacheable memory:
20  * Table B3-11, chap. B3.8.2, p. B3-1364
21  */
22 
23 /*
24  * The following definitions are used when specifying a memory
25  * range to be mapped at boot time using the MMU_REGION_ENTRY
26  * macro.
27  */
28 #define MT_STRONGLY_ORDERED		BIT(0)
29 #define MT_DEVICE			BIT(1)
30 #define MT_NORMAL			BIT(2)
31 #define MT_MASK				0x7
32 
33 #define MPERM_R				BIT(3)
34 #define MPERM_W				BIT(4)
35 #define MPERM_X				BIT(5)
36 #define MPERM_UNPRIVILEGED		BIT(6)
37 
38 #define MATTR_NON_SECURE		BIT(7)
39 #define MATTR_NON_GLOBAL		BIT(8)
40 #define MATTR_SHARED			BIT(9)
41 #define MATTR_CACHE_OUTER_WB_WA		BIT(10)
42 #define MATTR_CACHE_OUTER_WT_nWA	BIT(11)
43 #define MATTR_CACHE_OUTER_WB_nWA	BIT(12)
44 #define MATTR_CACHE_INNER_WB_WA		BIT(13)
45 #define MATTR_CACHE_INNER_WT_nWA	BIT(14)
46 #define MATTR_CACHE_INNER_WB_nWA	BIT(15)
47 
48 #define MATTR_MAY_MAP_L1_SECTION	BIT(16)
49 
50 /*
51  * The following macros are used for adding constant entries
52  * mmu_regions array of the mmu_config struct. Use MMU_REGION_ENTRY
53  * for the specification of mappings whose PA and VA differ,
54  * the use of MMU_REGION_FLAT_ENTRY always results in an identity
55  * mapping, which are used for the mappings of the Zephyr image's
56  * code and data.
57  */
58 #define MMU_REGION_ENTRY(_name, _base_pa, _base_va, _size, _attrs) \
59 	{\
60 		.name    = _name, \
61 		.base_pa = _base_pa, \
62 		.base_va = _base_va, \
63 		.size    = _size, \
64 		.attrs   = _attrs, \
65 	}
66 
67 #define MMU_REGION_FLAT_ENTRY(name, adr, sz, attrs) \
68 	MMU_REGION_ENTRY(name, adr, adr, sz, attrs)
69 
70 /*
71  * @brief Auto generate mmu region entry for node_id
72  *
73  * Example usage:
74  *
75  * @code{.c}
76  *      DT_FOREACH_STATUS_OKAY_VARGS(nxp_imx_gpio,
77  *				  MMU_REGION_DT_FLAT_ENTRY,
78  *				 (MT_DEVICE_nGnRnE | MT_P_RW_U_NA | MT_NS))
79  * @endcode
80  *
81  * @note  Since devicetree_generated.h does not include
82  *        node_id##_P_reg_FOREACH_PROP_ELEM* definitions,
83  *        we can't automate dts node with multiple reg
84  *        entries.
85  */
86 #define MMU_REGION_DT_FLAT_ENTRY(node_id, attrs)  \
87 	MMU_REGION_FLAT_ENTRY(DT_NODE_FULL_NAME(node_id), \
88 				  DT_REG_ADDR(node_id), \
89 				  DT_REG_SIZE(node_id), \
90 				  attrs),
91 
92 /*
93  * @brief Auto generate mmu region entry for status = "okay"
94  *        nodes compatible to a driver
95  *
96  * Example usage:
97  *
98  * @code{.c}
99  *      MMU_REGION_DT_COMPAT_FOREACH_FLAT_ENTRY(nxp_imx_gpio,
100  *				 (MT_DEVICE_nGnRnE | MT_P_RW_U_NA | MT_NS))
101  * @endcode
102  *
103  * @note  This is a wrapper of @ref MMU_REGION_DT_FLAT_ENTRY
104  */
105 #define MMU_REGION_DT_COMPAT_FOREACH_FLAT_ENTRY(compat, attr) \
106 	DT_FOREACH_STATUS_OKAY_VARGS(compat, \
107 	MMU_REGION_DT_FLAT_ENTRY, attr)
108 
109 /* Region definition data structure */
110 struct arm_mmu_region {
111 	/* Region Base Physical Address */
112 	uintptr_t  base_pa;
113 	/* Region Base Virtual Address */
114 	uintptr_t  base_va;
115 	/* Region size */
116 	size_t     size;
117 	/* Region Name */
118 	const char *name;
119 	/* Region Attributes */
120 	uint32_t   attrs;
121 };
122 
123 /* MMU configuration data structure */
124 struct arm_mmu_config {
125 	/* Number of regions */
126 	uint32_t		    num_regions;
127 	/* Regions */
128 	const struct arm_mmu_region *mmu_regions;
129 };
130 
131 /*
132  * Reference to the MMU configuration.
133  *
134  * This struct is defined and populated for each SoC (in the SoC definition),
135  * and holds the build-time configuration information for the fixed MMU
136  * regions enabled during kernel initialization.
137  */
138 extern const struct arm_mmu_config mmu_config;
139 
140 int z_arm_mmu_init(void);
141 
142 #endif /* _ASMLANGUAGE */
143 
144 #endif /* ZEPHYR_INCLUDE_ARCH_AARCH32_ARM_MMU_H_ */
145