blob: ff51420e835f0445672d8084a6d725439c60e91e [file] [log] [blame]
Sandrine Bailleux3cd87d72018-10-09 11:12:55 +02001/*
Boyan Karatoteva4b33342025-06-19 16:24:29 +01002 * Copyright (c) 2018-2025, Arm Limited. All rights reserved.
Sandrine Bailleux3cd87d72018-10-09 11:12:55 +02003 *
4 * SPDX-License-Identifier: BSD-3-Clause
5 */
6
Boyan Karatoteve5629bd2025-06-16 11:45:34 +01007#include <stdbool.h>
8
Sandrine Bailleux3cd87d72018-10-09 11:12:55 +02009#include <arch.h>
10#include <arch_helpers.h>
11#include <assert.h>
12#include <debug.h>
Boyan Karatoteva4b33342025-06-19 16:24:29 +010013#include <drivers/arm/gic_v2v3_common.h>
Antonio Nino Diaz09a00ef2019-01-11 13:12:58 +000014#include <drivers/arm/gic_v2.h>
15#include <drivers/arm/gic_v3.h>
Boyan Karatoteve5629bd2025-06-16 11:45:34 +010016#include <drivers/arm/gic_v5.h>
Sandrine Bailleux3cd87d72018-10-09 11:12:55 +020017
18/* Record whether a GICv3 was detected on the system */
19static unsigned int gicv3_detected;
Boyan Karatoteve5629bd2025-06-16 11:45:34 +010020static unsigned int gicv5_detected;
21static bool gic_done_init;
22
23int arm_gic_get_version(void)
24{
25 assert(gic_done_init);
26
27 if (gicv3_detected) {
28 return 3;
29 } else if (gicv5_detected) {
30 return 5;
31 } else {
32 return 2;
33 }
34}
Sandrine Bailleux3cd87d72018-10-09 11:12:55 +020035
36void arm_gic_enable_interrupts_local(void)
37{
38 if (gicv3_detected)
39 gicv3_enable_cpuif();
Boyan Karatoteve5629bd2025-06-16 11:45:34 +010040 else if (gicv5_detected)
41 gicv5_enable_cpuif();
Sandrine Bailleux3cd87d72018-10-09 11:12:55 +020042 else
43 gicv2_enable_cpuif();
44}
45
46void arm_gic_setup_local(void)
47{
48 if (gicv3_detected) {
49 gicv3_probe_redistif_addr();
50 gicv3_setup_cpuif();
Boyan Karatoteve5629bd2025-06-16 11:45:34 +010051 } else if (gicv5_detected) {
52 gicv5_setup_cpuif();
Sandrine Bailleux3cd87d72018-10-09 11:12:55 +020053 } else {
54 gicv2_probe_gic_cpu_id();
55 gicv2_setup_cpuif();
56 }
57}
58
59void arm_gic_disable_interrupts_local(void)
60{
61 if (gicv3_detected)
62 gicv3_disable_cpuif();
Boyan Karatoteve5629bd2025-06-16 11:45:34 +010063 else if (gicv5_detected)
64 gicv5_disable_cpuif();
Sandrine Bailleux3cd87d72018-10-09 11:12:55 +020065 else
66 gicv2_disable_cpuif();
67}
68
69void arm_gic_save_context_local(void)
70{
71 if (gicv3_detected)
72 gicv3_save_cpuif_context();
Boyan Karatoteve5629bd2025-06-16 11:45:34 +010073 else if (gicv5_detected)
74 gicv5_save_cpuif_context();
Sandrine Bailleux3cd87d72018-10-09 11:12:55 +020075 else
76 gicv2_save_cpuif_context();
77}
78
79void arm_gic_restore_context_local(void)
80{
81 if (gicv3_detected)
82 gicv3_restore_cpuif_context();
Boyan Karatoteve5629bd2025-06-16 11:45:34 +010083 else if (gicv5_detected)
84 gicv5_restore_cpuif_context();
Sandrine Bailleux3cd87d72018-10-09 11:12:55 +020085 else
86 gicv2_restore_cpuif_context();
87}
88
89void arm_gic_save_context_global(void)
90{
Boyan Karatoteve5629bd2025-06-16 11:45:34 +010091 if (gicv3_detected) {
Sandrine Bailleux3cd87d72018-10-09 11:12:55 +020092 gicv3_save_sgi_ppi_context();
Boyan Karatoteve5629bd2025-06-16 11:45:34 +010093 } else if (gicv5_detected) {
94 /* NOP, done by EL3 */
95 } else {
Sandrine Bailleux3cd87d72018-10-09 11:12:55 +020096 gicv2_save_sgi_ppi_context();
Boyan Karatoteve5629bd2025-06-16 11:45:34 +010097 }
Sandrine Bailleux3cd87d72018-10-09 11:12:55 +020098}
99
100void arm_gic_restore_context_global(void)
101{
102 if (gicv3_detected) {
103 gicv3_setup_distif();
104 gicv3_restore_sgi_ppi_context();
Boyan Karatoteve5629bd2025-06-16 11:45:34 +0100105 } else if (gicv5_detected) {
106 /* NOP, done by EL3 */
Sandrine Bailleux3cd87d72018-10-09 11:12:55 +0200107 } else {
108 gicv2_setup_distif();
109 gicv2_restore_sgi_ppi_context();
110 }
111}
112
113void arm_gic_setup_global(void)
114{
115 if (gicv3_detected)
116 gicv3_setup_distif();
Boyan Karatoteve5629bd2025-06-16 11:45:34 +0100117 else if (gicv5_detected)
118 gicv5_setup();
Sandrine Bailleux3cd87d72018-10-09 11:12:55 +0200119 else
120 gicv2_setup_distif();
121}
122
123unsigned int arm_gic_get_intr_priority(unsigned int num)
124{
125 if (gicv3_detected)
126 return gicv3_get_ipriorityr(num);
Boyan Karatoteve5629bd2025-06-16 11:45:34 +0100127 /* TODO only used for SDEI, currently not supported/ported */
128 else if (gicv5_detected) {
129 assert(0);
130 return 0;
131 } else
Sandrine Bailleux3cd87d72018-10-09 11:12:55 +0200132 return gicv2_gicd_get_ipriorityr(num);
133}
134
135void arm_gic_set_intr_priority(unsigned int num,
136 unsigned int priority)
137{
138 if (gicv3_detected)
139 gicv3_set_ipriorityr(num, priority);
Boyan Karatoteve5629bd2025-06-16 11:45:34 +0100140 else if (gicv5_detected)
141 gicv5_set_priority(num, priority);
Sandrine Bailleux3cd87d72018-10-09 11:12:55 +0200142 else
143 gicv2_gicd_set_ipriorityr(num, priority);
144}
145
Boyan Karatotev6d144db2025-06-23 15:04:53 +0100146uint32_t arm_gic_get_sgi_num(uint32_t seq_id, unsigned int core_pos)
147{
148 if (gicv5_detected) {
149 return gicv5_get_sgi_num(seq_id, core_pos);
150 } else {
151 return gicv2v3_get_sgi_num(seq_id, core_pos);
152 }
153}
154
Sandrine Bailleux3cd87d72018-10-09 11:12:55 +0200155void arm_gic_send_sgi(unsigned int sgi_id, unsigned int core_pos)
156{
157 if (gicv3_detected)
158 gicv3_send_sgi(sgi_id, core_pos);
Boyan Karatoteve5629bd2025-06-16 11:45:34 +0100159 else if (gicv5_detected)
160 gicv5_send_sgi(sgi_id, core_pos);
Sandrine Bailleux3cd87d72018-10-09 11:12:55 +0200161 else
162 gicv2_send_sgi(sgi_id, core_pos);
163}
164
165void arm_gic_set_intr_target(unsigned int num, unsigned int core_pos)
166{
167 if (gicv3_detected)
168 gicv3_set_intr_route(num, core_pos);
Boyan Karatoteve5629bd2025-06-16 11:45:34 +0100169 else if (gicv5_detected)
170 gicv5_set_intr_route(num, core_pos);
Sandrine Bailleux3cd87d72018-10-09 11:12:55 +0200171 else
172 gicv2_set_itargetsr(num, core_pos);
173}
174
175unsigned int arm_gic_intr_enabled(unsigned int num)
176{
177 if (gicv3_detected)
178 return gicv3_get_isenabler(num) != 0;
Boyan Karatoteve5629bd2025-06-16 11:45:34 +0100179 /* TODO only used for SDEI, currently not supported/ported */
180 else if (gicv5_detected) {
181 assert(0);
182 return 0;
183 } else
Sandrine Bailleux3cd87d72018-10-09 11:12:55 +0200184 return gicv2_gicd_get_isenabler(num) != 0;
185}
186
187void arm_gic_intr_enable(unsigned int num)
188{
189 if (gicv3_detected)
190 gicv3_set_isenabler(num);
Boyan Karatoteve5629bd2025-06-16 11:45:34 +0100191 else if (gicv5_detected)
192 gicv5_intr_enable(num);
Sandrine Bailleux3cd87d72018-10-09 11:12:55 +0200193 else
194 gicv2_gicd_set_isenabler(num);
195}
196
197void arm_gic_intr_disable(unsigned int num)
198{
199 if (gicv3_detected)
200 gicv3_set_icenabler(num);
Boyan Karatoteve5629bd2025-06-16 11:45:34 +0100201 else if (gicv5_detected)
202 gicv5_intr_disable(num);
Sandrine Bailleux3cd87d72018-10-09 11:12:55 +0200203 else
204 gicv2_gicd_set_icenabler(num);
205}
206
207unsigned int arm_gic_intr_ack(unsigned int *raw_iar)
208{
209 assert(raw_iar);
210
211 if (gicv3_detected) {
212 *raw_iar = gicv3_acknowledge_interrupt();
213 return *raw_iar;
Boyan Karatoteve5629bd2025-06-16 11:45:34 +0100214 } else if (gicv5_detected) {
215 *raw_iar = gicv5_acknowledge_interrupt();
216 return *raw_iar;
Sandrine Bailleux3cd87d72018-10-09 11:12:55 +0200217 } else {
218 *raw_iar = gicv2_gicc_read_iar();
219 return get_gicc_iar_intid(*raw_iar);
220 }
221}
222
223unsigned int arm_gic_is_intr_pending(unsigned int num)
224{
225 if (gicv3_detected)
226 return gicv3_get_ispendr(num);
Boyan Karatoteve5629bd2025-06-16 11:45:34 +0100227 else if (gicv5_detected)
228 return gicv5_is_intr_pending(num);
Sandrine Bailleux3cd87d72018-10-09 11:12:55 +0200229 else
230 return gicv2_gicd_get_ispendr(num);
231}
232
233void arm_gic_intr_clear(unsigned int num)
234{
235 if (gicv3_detected)
236 gicv3_set_icpendr(num);
Boyan Karatoteve5629bd2025-06-16 11:45:34 +0100237 else if (gicv5_detected)
238 gicv5_intr_clear(num);
Sandrine Bailleux3cd87d72018-10-09 11:12:55 +0200239 else
240 gicv2_gicd_set_icpendr(num);
241}
242
243void arm_gic_end_of_intr(unsigned int raw_iar)
244{
245 if (gicv3_detected)
246 gicv3_end_of_interrupt(raw_iar);
Boyan Karatoteve5629bd2025-06-16 11:45:34 +0100247 else if (gicv5_detected)
248 gicv5_end_of_interrupt(raw_iar);
Sandrine Bailleux3cd87d72018-10-09 11:12:55 +0200249 else
250 gicv2_gicc_write_eoir(raw_iar);
251}
252
Boyan Karatoteve5629bd2025-06-16 11:45:34 +0100253void arm_gic_probe(void)
254{
255 if (is_gicv3_mode()) {
256 gicv3_detected = 1;
257 INFO("GICv3 mode detected\n");
258 } else if (is_gicv5_mode()) {
259 gicv5_detected = 1;
260 INFO("GICv5 mode detected\n");
261 } else {
262 INFO("GICv2 mode detected\n");
263 }
264
265 gic_done_init = true;
266}
267
268/* to not change the API, pretend the IRS is a distributor */
Sandrine Bailleux3cd87d72018-10-09 11:12:55 +0200269void arm_gic_init(uintptr_t gicc_base,
270 uintptr_t gicd_base,
271 uintptr_t gicr_base)
272{
Boyan Karatoteve5629bd2025-06-16 11:45:34 +0100273 if (gicv3_detected) {
Sandrine Bailleux3cd87d72018-10-09 11:12:55 +0200274 gicv3_init(gicr_base, gicd_base);
Boyan Karatoteve5629bd2025-06-16 11:45:34 +0100275 } else if (gicv5_detected) {
276 gicv5_init(gicd_base);
Sandrine Bailleux3cd87d72018-10-09 11:12:55 +0200277 } else {
278 gicv2_init(gicc_base, gicd_base);
279 }
Sandrine Bailleux3cd87d72018-10-09 11:12:55 +0200280}
Madhukar Pappireddyc6a3abf2023-10-25 16:47:23 -0500281
282bool arm_gic_is_espi_supported(void)
283{
Boyan Karatoteve5629bd2025-06-16 11:45:34 +0100284 /* TODO only used for FFA, currently not supported/ported on GICv5 */
Madhukar Pappireddyc6a3abf2023-10-25 16:47:23 -0500285 if (!gicv3_detected) {
286 return false;
287 }
288
289 /* Check if extended SPI range is implemented. */
Boyan Karatotevaa483582025-06-20 09:07:44 +0100290 if ((gicv3_get_gicd_typer() & TYPER_ESPI) != 0U) {
Madhukar Pappireddyc6a3abf2023-10-25 16:47:23 -0500291 return true;
292 }
293
294 return false;
295}