1 /* SPDX-License-Identifier: GPL-2.0-only */
2
3 #ifndef __ARM_MPU_MM_H__
4 #define __ARM_MPU_MM_H__
5
6 #include <xen/bug.h>
7 #include <xen/macros.h>
8 #include <xen/page-size.h>
9 #include <xen/types.h>
10 #include <asm/mm.h>
11 #include <asm/mpu.h>
12
13 #define MPUMAP_REGION_OVERLAP -1
14 #define MPUMAP_REGION_NOTFOUND 0
15 #define MPUMAP_REGION_FOUND 1
16 #define MPUMAP_REGION_INCLUSIVE 2
17
18 #define INVALID_REGION_IDX 0xFFU
19
20 extern struct page_info *frame_table;
21
22 extern uint8_t max_mpu_regions;
23
24 extern DECLARE_BITMAP(xen_mpumap_mask, MAX_MPU_REGION_NR);
25
26 extern pr_t xen_mpumap[MAX_MPU_REGION_NR];
27
28 #define virt_to_maddr(va) ((paddr_t)((vaddr_t)(va) & PADDR_MASK))
29
30 #ifdef CONFIG_ARM_32
31 #define is_xen_heap_page(page) ({ BUG_ON("unimplemented"); false; })
32 #define is_xen_heap_mfn(mfn) ({ BUG_ON("unimplemented"); false; })
33 #endif
34
35 /* On MPU systems there is no translation, ma == va. */
maddr_to_virt(paddr_t ma)36 static inline void *maddr_to_virt(paddr_t ma)
37 {
38 return _p(ma);
39 }
40
41 /* Convert between virtual address to page-info structure. */
virt_to_page(const void * v)42 static inline struct page_info *virt_to_page(const void *v)
43 {
44 mfn_t mfn = _mfn(virt_to_mfn(v));
45
46 ASSERT(mfn_valid(mfn));
47
48 return mfn_to_page(mfn);
49 }
50
51 /* Utility function to be used whenever MPU regions are modified */
context_sync_mpu(void)52 static inline void context_sync_mpu(void)
53 {
54 /*
55 * ARM DDI 0600B.a, C1.7.1
56 * Writes to MPU registers are only guaranteed to be visible following a
57 * Context synchronization event and DSB operation.
58 */
59 dsb(sy);
60 isb();
61 }
62
63 /*
64 * The following API requires context_sync_mpu() after being used to modify MPU
65 * regions:
66 * - write_protection_region
67 * - xen_mpumap_update
68 */
69
70 /* Reads the MPU region (into @pr_read) with index @sel from the HW */
71 void read_protection_region(pr_t *pr_read, uint8_t sel);
72
73 /* Writes the MPU region (from @pr_write) with index @sel to the HW */
74 void write_protection_region(const pr_t *pr_write, uint8_t sel);
75
76 /*
77 * Maps an address range into the MPU data structure and updates the HW.
78 * Equivalent to xen_pt_update in an MMU system.
79 *
80 * @param base Base address of the range to map (inclusive).
81 * @param limit Limit address of the range to map (exclusive).
82 * @param flags Flags for the memory range to map.
83 * @return 0 on success, negative on error.
84 */
85 int xen_mpumap_update(paddr_t base, paddr_t limit, unsigned int flags);
86
87 /*
88 * Creates a pr_t structure describing a protection region.
89 *
90 * @base: base address as base of the protection region.
91 * @limit: exclusive address as limit of the protection region.
92 * @flags: memory flags for the mapping.
93 * @return: pr_t structure describing a protection region.
94 */
95 pr_t pr_of_addr(paddr_t base, paddr_t limit, unsigned int flags);
96
97 /*
98 * Checks whether a given memory range is present in the provided table of
99 * MPU protection regions.
100 *
101 * @param table Array of pr_t protection regions.
102 * @param r_regions Number of elements in `table`.
103 * @param base Start of the memory region to be checked (inclusive).
104 * @param limit End of the memory region to be checked (exclusive).
105 * @param index Set to the index of the region if an exact or inclusive
106 * match is found, and INVALID_REGION otherwise.
107 * @return: Return code indicating the result of the search:
108 * MPUMAP_REGION_NOTFOUND: no part of the range is present in `table`
109 * MPUMAP_REGION_FOUND: found an exact match in `table`
110 * MPUMAP_REGION_INCLUSIVE: found an inclusive match in `table`
111 * MPUMAP_REGION_OVERLAP: found an overlap with a mapping in `table`
112 *
113 * Note: make sure that the range [`base`, `limit`) refers to the memory region
114 * inclusive of `base` and exclusive of `limit`.
115 */
116 int mpumap_contains_region(pr_t *table, uint8_t nr_regions, paddr_t base,
117 paddr_t limit, uint8_t *index);
118
119 #endif /* __ARM_MPU_MM_H__ */
120
121 /*
122 * Local variables:
123 * mode: C
124 * c-file-style: "BSD"
125 * c-basic-offset: 4
126 * indent-tabs-mode: nil
127 * End:
128 */
129