1 /* SPDX-License-Identifier: GPL-2.0-only */
2 /*
3  * mpu.h: Arm Memory Protection Unit definitions.
4  */
5 
6 #ifndef __ARM_MPU_H__
7 #define __ARM_MPU_H__
8 
9 #if defined(CONFIG_ARM_64)
10 # include <asm/arm64/mpu.h>
11 #elif defined(CONFIG_ARM_32)
12 # include <asm/arm32/mpu.h>
13 #else
14 # error "unknown ARM variant"
15 #endif
16 
17 #define MPU_REGION_SHIFT  6
18 #define MPU_REGION_ALIGN  (_AC(1, UL) << MPU_REGION_SHIFT)
19 #define MPU_REGION_MASK   (~(MPU_REGION_ALIGN - 1))
20 
21 #define NUM_MPU_REGIONS_SHIFT   8
22 #define NUM_MPU_REGIONS         (_AC(1, UL) << NUM_MPU_REGIONS_SHIFT)
23 #define NUM_MPU_REGIONS_MASK    (NUM_MPU_REGIONS - 1)
24 #define MAX_MPU_REGION_NR       NUM_MPU_REGIONS_MASK
25 
26 #define PRENR_MASK  GENMASK(31, 0)
27 
28 #ifndef __ASSEMBLY__
29 
30 /*
31  * Set base address of MPU protection region.
32  *
33  * @pr: pointer to the protection region structure.
34  * @base: base address as base of the protection region.
35  */
pr_set_base(pr_t * pr,paddr_t base)36 static inline void pr_set_base(pr_t *pr, paddr_t base)
37 {
38     pr->prbar.reg.base = ((base & ~MPU_REGION_RES0) >> MPU_REGION_SHIFT);
39 }
40 
41 /*
42  * Set limit address of MPU protection region.
43  *
44  * @pr: pointer to the protection region structure.
45  * @limit: exclusive address as limit of the protection region.
46  */
pr_set_limit(pr_t * pr,paddr_t limit)47 static inline void pr_set_limit(pr_t *pr, paddr_t limit)
48 {
49     /* PRLAR_ELx.LIMIT expects inclusive limit */
50     pr->prlar.reg.limit = (((limit - 1) & ~MPU_REGION_RES0)
51                            >> MPU_REGION_SHIFT);
52 }
53 
54 /*
55  * Access to get base address of MPU protection region.
56  * The base address shall be zero extended.
57  *
58  * @pr: pointer to the protection region structure.
59  * @return: Base address configured for the passed protection region.
60  */
pr_get_base(const pr_t * pr)61 static inline paddr_t pr_get_base(const pr_t *pr)
62 {
63     return (paddr_t)(pr->prbar.reg.base << MPU_REGION_SHIFT);
64 }
65 
66 /*
67  * Access to get limit address of MPU protection region.
68  * The limit address shall be concatenated with 0x3f.
69  *
70  * @pr: pointer to the protection region structure.
71  * @return: Inclusive limit address configured for the passed protection region.
72  */
pr_get_limit(const pr_t * pr)73 static inline paddr_t pr_get_limit(const pr_t *pr)
74 {
75     return (paddr_t)((pr->prlar.reg.limit << MPU_REGION_SHIFT)
76                      | ~MPU_REGION_MASK);
77 }
78 
79 /*
80  * Check if the protection region is valid (enabled).
81  *
82  * @pr: pointer to the protection region structure.
83  * @return: True if the region is valid (enabled), false otherwise.
84  */
region_is_valid(const pr_t * pr)85 static inline bool region_is_valid(const pr_t *pr)
86 {
87     return pr->prlar.reg.en;
88 }
89 
90 #endif /* __ASSEMBLY__ */
91 
92 #endif /* __ARM_MPU_H__ */
93 
94 /*
95  * Local variables:
96  * mode: C
97  * c-file-style: "BSD"
98  * c-basic-offset: 4
99  * indent-tabs-mode: nil
100  * End:
101  */
102