master
h 113 lines 3.71 KB
Raw
1 /*
2 * QEMU Arm software mmu index internal definitions
3 * SPDX-License-Identifier: GPL-2.0-or-later
4 */
5
6 #ifndef TARGET_ARM_MMUIDX_INTERNAL_H
7 #define TARGET_ARM_MMUIDX_INTERNAL_H
8
9 #include "mmuidx.h"
10 #include "tcg/debug-assert.h"
11 #include "hw/core/registerfields.h"
12
13
14 FIELD(MMUIDXINFO, EL, 0, 2)
15 FIELD(MMUIDXINFO, ELVALID, 2, 1)
16 FIELD(MMUIDXINFO, REL, 3, 2)
17 FIELD(MMUIDXINFO, RELVALID, 5, 1)
18 FIELD(MMUIDXINFO, 2RANGES, 6, 1)
19 FIELD(MMUIDXINFO, PAN, 7, 1)
20 FIELD(MMUIDXINFO, USER, 8, 1)
21 FIELD(MMUIDXINFO, STAGE1, 9, 1)
22 FIELD(MMUIDXINFO, STAGE2, 10, 1)
23 FIELD(MMUIDXINFO, GCS, 11, 1)
24 FIELD(MMUIDXINFO, TG, 12, 5)
25
26 extern const uint32_t arm_mmuidx_table[ARM_MMU_IDX_M + 8];
27
28 #define arm_mmuidx_is_valid(x) ((unsigned)(x) < ARRAY_SIZE(arm_mmuidx_table))
29
30 /* Return the exception level associated with this mmu index. */
31 static inline int arm_mmu_idx_to_el(ARMMMUIdx idx)
32 {
33 tcg_debug_assert(arm_mmuidx_is_valid(idx));
34 tcg_debug_assert(FIELD_EX32(arm_mmuidx_table[idx], MMUIDXINFO, ELVALID));
35 return FIELD_EX32(arm_mmuidx_table[idx], MMUIDXINFO, EL);
36 }
37
38 /*
39 * Return the exception level for the address translation regime
40 * associated with this mmu index.
41 */
42 static inline uint32_t regime_el(ARMMMUIdx idx)
43 {
44 tcg_debug_assert(arm_mmuidx_is_valid(idx));
45 tcg_debug_assert(FIELD_EX32(arm_mmuidx_table[idx], MMUIDXINFO, RELVALID));
46 return FIELD_EX32(arm_mmuidx_table[idx], MMUIDXINFO, REL);
47 }
48
49 /*
50 * Return true if this address translation regime has two ranges.
51 * Note that this will not return the correct answer for AArch32
52 * Secure PL1&0 (i.e. mmu indexes E3, E30_0, E30_3_PAN), but it is
53 * never called from a context where EL3 can be AArch32. (The
54 * correct return value for ARMMMUIdx_E3 would be different for
55 * that case, so we can't just make the function return the
56 * correct value anyway; we would need an extra "bool e3_is_aarch32"
57 * argument which all the current callsites would pass as 'false'.)
58 */
59 static inline bool regime_has_2_ranges(ARMMMUIdx idx)
60 {
61 tcg_debug_assert(arm_mmuidx_is_valid(idx));
62 return FIELD_EX32(arm_mmuidx_table[idx], MMUIDXINFO, 2RANGES);
63 }
64
65 /* Return true if Privileged Access Never is enabled for this mmu index. */
66 static inline bool regime_is_pan(ARMMMUIdx idx)
67 {
68 tcg_debug_assert(arm_mmuidx_is_valid(idx));
69 return FIELD_EX32(arm_mmuidx_table[idx], MMUIDXINFO, PAN);
70 }
71
72 /*
73 * Return true if the exception level associated with this mmu index is 0.
74 * Differs from arm_mmu_idx_to_el(idx) == 0 in that this allows querying
75 * Stage1 and Stage2 mmu indexes.
76 */
77 static inline bool regime_is_user(ARMMMUIdx idx)
78 {
79 tcg_debug_assert(arm_mmuidx_is_valid(idx));
80 return FIELD_EX32(arm_mmuidx_table[idx], MMUIDXINFO, USER);
81 }
82
83 /* Return true if this mmu index is stage 1 of a 2-stage translation. */
84 static inline bool arm_mmu_idx_is_stage1_of_2(ARMMMUIdx idx)
85 {
86 tcg_debug_assert(arm_mmuidx_is_valid(idx));
87 return FIELD_EX32(arm_mmuidx_table[idx], MMUIDXINFO, STAGE1);
88 }
89
90 /* Return true if this mmu index is stage 2 of a 2-stage translation. */
91 static inline bool regime_is_stage2(ARMMMUIdx idx)
92 {
93 tcg_debug_assert(arm_mmuidx_is_valid(idx));
94 return FIELD_EX32(arm_mmuidx_table[idx], MMUIDXINFO, STAGE2);
95 }
96
97 /* Return true if this mmu index implies AccessType_GCS. */
98 static inline bool regime_is_gcs(ARMMMUIdx idx)
99 {
100 tcg_debug_assert(arm_mmuidx_is_valid(idx));
101 return FIELD_EX32(arm_mmuidx_table[idx], MMUIDXINFO, GCS);
102 }
103
104 /* Return the GCS MMUIdx for a given regime. */
105 static inline ARMMMUIdx regime_to_gcs(ARMMMUIdx idx)
106 {
107 tcg_debug_assert(arm_mmuidx_is_valid(idx));
108 uint32_t core = FIELD_EX32(arm_mmuidx_table[idx], MMUIDXINFO, TG);
109 tcg_debug_assert(core != 0); /* core 0 is E10_0, not a GCS index */
110 return core | ARM_MMU_IDX_A;
111 }
112
113 #endif /* TARGET_ARM_MMUIDX_INTERNAL_H */