Commit | Line | Data |
---|---|---|
caab277b | 1 | /* SPDX-License-Identifier: GPL-2.0-only */ |
7936e914 JPB |
2 | /* |
3 | * arch/arm64/include/asm/arch_gicv3.h | |
4 | * | |
5 | * Copyright (C) 2015 ARM Ltd. | |
7936e914 JPB |
6 | */ |
7 | #ifndef __ASM_ARCH_GICV3_H | |
8 | #define __ASM_ARCH_GICV3_H | |
9 | ||
10 | #include <asm/sysreg.h> | |
11 | ||
7936e914 JPB |
12 | #ifndef __ASSEMBLY__ |
13 | ||
b334481a | 14 | #include <linux/irqchip/arm-gic-common.h> |
7936e914 | 15 | #include <linux/stringify.h> |
8e31ed9c | 16 | #include <asm/barrier.h> |
328191c0 | 17 | #include <asm/cacheflush.h> |
7936e914 | 18 | |
0e9884fe MR |
19 | #define read_gicreg(r) read_sysreg_s(SYS_ ## r) |
20 | #define write_gicreg(v, r) write_sysreg_s(v, SYS_ ## r) | |
b5525ce8 | 21 | |
f6c86a41 JPB |
22 | /* |
23 | * Low-level accessors | |
24 | * | |
25 | * These system registers are 32 bits, but we make sure that the compiler | |
26 | * sets the GP register's most significant bits to 0 with an explicit cast. | |
27 | */ | |
7936e914 | 28 | |
f6c86a41 | 29 | static inline void gic_write_eoir(u32 irq) |
7936e914 | 30 | { |
0e9884fe | 31 | write_sysreg_s(irq, SYS_ICC_EOIR1_EL1); |
7936e914 JPB |
32 | isb(); |
33 | } | |
34 | ||
5c37f1ae | 35 | static __always_inline void gic_write_dir(u32 irq) |
7936e914 | 36 | { |
0e9884fe | 37 | write_sysreg_s(irq, SYS_ICC_DIR_EL1); |
7936e914 JPB |
38 | isb(); |
39 | } | |
40 | ||
41 | static inline u64 gic_read_iar_common(void) | |
42 | { | |
43 | u64 irqstat; | |
44 | ||
0e9884fe | 45 | irqstat = read_sysreg_s(SYS_ICC_IAR1_EL1); |
1a1ebd5f | 46 | dsb(sy); |
7936e914 JPB |
47 | return irqstat; |
48 | } | |
49 | ||
50 | /* | |
51 | * Cavium ThunderX erratum 23154 | |
52 | * | |
53 | * The gicv3 of ThunderX requires a modified version for reading the | |
54 | * IAR status to ensure data synchronization (access to icc_iar1_el1 | |
55 | * is not sync'ed before and after). | |
56 | */ | |
57 | static inline u64 gic_read_iar_cavium_thunderx(void) | |
58 | { | |
59 | u64 irqstat; | |
60 | ||
016f98af | 61 | nops(8); |
0e9884fe | 62 | irqstat = read_sysreg_s(SYS_ICC_IAR1_EL1); |
016f98af | 63 | nops(4); |
7936e914 JPB |
64 | mb(); |
65 | ||
66 | return irqstat; | |
67 | } | |
68 | ||
f6c86a41 | 69 | static inline void gic_write_ctlr(u32 val) |
7936e914 | 70 | { |
0e9884fe | 71 | write_sysreg_s(val, SYS_ICC_CTLR_EL1); |
7936e914 JPB |
72 | isb(); |
73 | } | |
74 | ||
eda0d04a SD |
75 | static inline u32 gic_read_ctlr(void) |
76 | { | |
77 | return read_sysreg_s(SYS_ICC_CTLR_EL1); | |
78 | } | |
79 | ||
f6c86a41 | 80 | static inline void gic_write_grpen1(u32 val) |
7936e914 | 81 | { |
21bc5281 | 82 | write_sysreg_s(val, SYS_ICC_IGRPEN1_EL1); |
7936e914 JPB |
83 | isb(); |
84 | } | |
85 | ||
86 | static inline void gic_write_sgi1r(u64 val) | |
87 | { | |
0e9884fe | 88 | write_sysreg_s(val, SYS_ICC_SGI1R_EL1); |
7936e914 JPB |
89 | } |
90 | ||
f6c86a41 | 91 | static inline u32 gic_read_sre(void) |
7936e914 | 92 | { |
0e9884fe | 93 | return read_sysreg_s(SYS_ICC_SRE_EL1); |
7936e914 JPB |
94 | } |
95 | ||
f6c86a41 | 96 | static inline void gic_write_sre(u32 val) |
7936e914 | 97 | { |
0e9884fe | 98 | write_sysreg_s(val, SYS_ICC_SRE_EL1); |
7936e914 JPB |
99 | isb(); |
100 | } | |
101 | ||
91ef8442 DT |
102 | static inline void gic_write_bpr1(u32 val) |
103 | { | |
0e9884fe | 104 | write_sysreg_s(val, SYS_ICC_BPR1_EL1); |
91ef8442 DT |
105 | } |
106 | ||
e99da7c6 JT |
107 | static inline u32 gic_read_pmr(void) |
108 | { | |
109 | return read_sysreg_s(SYS_ICC_PMR_EL1); | |
110 | } | |
111 | ||
7733306b | 112 | static __always_inline void gic_write_pmr(u32 val) |
e99da7c6 JT |
113 | { |
114 | write_sysreg_s(val, SYS_ICC_PMR_EL1); | |
115 | } | |
116 | ||
117 | static inline u32 gic_read_rpr(void) | |
118 | { | |
119 | return read_sysreg_s(SYS_ICC_RPR_EL1); | |
120 | } | |
121 | ||
72c97126 JPB |
122 | #define gic_read_typer(c) readq_relaxed(c) |
123 | #define gic_write_irouter(v, c) writeq_relaxed(v, c) | |
f6a91da7 MZ |
124 | #define gic_read_lpir(c) readq_relaxed(c) |
125 | #define gic_write_lpir(v, c) writeq_relaxed(v, c) | |
72c97126 | 126 | |
328191c0 VM |
127 | #define gic_flush_dcache_to_poc(a,l) __flush_dcache_area((a), (l)) |
128 | ||
0968a619 VM |
129 | #define gits_read_baser(c) readq_relaxed(c) |
130 | #define gits_write_baser(v, c) writeq_relaxed(v, c) | |
131 | ||
132 | #define gits_read_cbaser(c) readq_relaxed(c) | |
133 | #define gits_write_cbaser(v, c) writeq_relaxed(v, c) | |
134 | ||
135 | #define gits_write_cwriter(v, c) writeq_relaxed(v, c) | |
136 | ||
137 | #define gicr_read_propbaser(c) readq_relaxed(c) | |
138 | #define gicr_write_propbaser(v, c) writeq_relaxed(v, c) | |
139 | ||
140 | #define gicr_write_pendbaser(v, c) writeq_relaxed(v, c) | |
141 | #define gicr_read_pendbaser(c) readq_relaxed(c) | |
142 | ||
5186a6cc ZY |
143 | #define gicr_write_vpropbaser(v, c) writeq_relaxed(v, c) |
144 | #define gicr_read_vpropbaser(c) readq_relaxed(c) | |
3ca63f36 | 145 | |
5186a6cc ZY |
146 | #define gicr_write_vpendbaser(v, c) writeq_relaxed(v, c) |
147 | #define gicr_read_vpendbaser(c) readq_relaxed(c) | |
3ca63f36 | 148 | |
3f1f3234 JT |
149 | static inline bool gic_prio_masking_enabled(void) |
150 | { | |
151 | return system_uses_irq_prio_masking(); | |
152 | } | |
153 | ||
154 | static inline void gic_pmr_mask_irqs(void) | |
155 | { | |
33678059 | 156 | BUILD_BUG_ON(GICD_INT_DEF_PRI < (__GIC_PRIO_IRQOFF | |
bd82d4bd JT |
157 | GIC_PRIO_PSR_I_SET)); |
158 | BUILD_BUG_ON(GICD_INT_DEF_PRI >= GIC_PRIO_IRQON); | |
677379bc JT |
159 | /* |
160 | * Need to make sure IRQON allows IRQs when SCR_EL3.FIQ is cleared | |
161 | * and non-secure PMR accesses are not subject to the shifts that | |
162 | * are applied to IRQ priorities | |
163 | */ | |
164 | BUILD_BUG_ON((0x80 | (GICD_INT_DEF_PRI >> 1)) >= GIC_PRIO_IRQON); | |
33678059 AE |
165 | /* |
166 | * Same situation as above, but now we make sure that we can mask | |
167 | * regular interrupts. | |
168 | */ | |
169 | BUILD_BUG_ON((0x80 | (GICD_INT_DEF_PRI >> 1)) < (__GIC_PRIO_IRQOFF_NS | | |
170 | GIC_PRIO_PSR_I_SET)); | |
b334481a | 171 | gic_write_pmr(GIC_PRIO_IRQOFF); |
3f1f3234 JT |
172 | } |
173 | ||
174 | static inline void gic_arch_enable_irqs(void) | |
175 | { | |
b334481a | 176 | asm volatile ("msr daifclr, #2" : : : "memory"); |
3f1f3234 JT |
177 | } |
178 | ||
7936e914 JPB |
179 | #endif /* __ASSEMBLY__ */ |
180 | #endif /* __ASM_ARCH_GICV3_H */ |