blob: a3f84d0789352643eeceeff58505f154608da56f [file] [log] [blame]
Sandrine Bailleux3cd87d72018-10-09 11:12:55 +02001/*
2 * Copyright (c) 2018, Arm Limited. All rights reserved.
3 *
4 * SPDX-License-Identifier: BSD-3-Clause
5 */
6
7#include <arch.h>
8#include <arch_helpers.h>
9#include <assert.h>
10#include <debug.h>
Antonio Nino Diaz09a00ef2019-01-11 13:12:58 +000011#include <drivers/arm/gic_common.h>
12#include <drivers/arm/gic_v2.h>
13#include <drivers/arm/gic_v3.h>
Sandrine Bailleux3cd87d72018-10-09 11:12:55 +020014
15/* Record whether a GICv3 was detected on the system */
16static unsigned int gicv3_detected;
17
18void arm_gic_enable_interrupts_local(void)
19{
20 if (gicv3_detected)
21 gicv3_enable_cpuif();
22 else
23 gicv2_enable_cpuif();
24}
25
26void arm_gic_setup_local(void)
27{
28 if (gicv3_detected) {
29 gicv3_probe_redistif_addr();
30 gicv3_setup_cpuif();
31 } else {
32 gicv2_probe_gic_cpu_id();
33 gicv2_setup_cpuif();
34 }
35}
36
37void arm_gic_disable_interrupts_local(void)
38{
39 if (gicv3_detected)
40 gicv3_disable_cpuif();
41 else
42 gicv2_disable_cpuif();
43}
44
45void arm_gic_save_context_local(void)
46{
47 if (gicv3_detected)
48 gicv3_save_cpuif_context();
49 else
50 gicv2_save_cpuif_context();
51}
52
53void arm_gic_restore_context_local(void)
54{
55 if (gicv3_detected)
56 gicv3_restore_cpuif_context();
57 else
58 gicv2_restore_cpuif_context();
59}
60
61void arm_gic_save_context_global(void)
62{
63 if (gicv3_detected)
64 gicv3_save_sgi_ppi_context();
65 else
66 gicv2_save_sgi_ppi_context();
67}
68
69void arm_gic_restore_context_global(void)
70{
71 if (gicv3_detected) {
72 gicv3_setup_distif();
73 gicv3_restore_sgi_ppi_context();
74 } else {
75 gicv2_setup_distif();
76 gicv2_restore_sgi_ppi_context();
77 }
78}
79
80void arm_gic_setup_global(void)
81{
82 if (gicv3_detected)
83 gicv3_setup_distif();
84 else
85 gicv2_setup_distif();
86}
87
88unsigned int arm_gic_get_intr_priority(unsigned int num)
89{
90 if (gicv3_detected)
91 return gicv3_get_ipriorityr(num);
92 else
93 return gicv2_gicd_get_ipriorityr(num);
94}
95
96void arm_gic_set_intr_priority(unsigned int num,
97 unsigned int priority)
98{
99 if (gicv3_detected)
100 gicv3_set_ipriorityr(num, priority);
101 else
102 gicv2_gicd_set_ipriorityr(num, priority);
103}
104
105void arm_gic_send_sgi(unsigned int sgi_id, unsigned int core_pos)
106{
107 if (gicv3_detected)
108 gicv3_send_sgi(sgi_id, core_pos);
109 else
110 gicv2_send_sgi(sgi_id, core_pos);
111}
112
113void arm_gic_set_intr_target(unsigned int num, unsigned int core_pos)
114{
115 if (gicv3_detected)
116 gicv3_set_intr_route(num, core_pos);
117 else
118 gicv2_set_itargetsr(num, core_pos);
119}
120
121unsigned int arm_gic_intr_enabled(unsigned int num)
122{
123 if (gicv3_detected)
124 return gicv3_get_isenabler(num) != 0;
125 else
126 return gicv2_gicd_get_isenabler(num) != 0;
127}
128
129void arm_gic_intr_enable(unsigned int num)
130{
131 if (gicv3_detected)
132 gicv3_set_isenabler(num);
133 else
134 gicv2_gicd_set_isenabler(num);
135}
136
137void arm_gic_intr_disable(unsigned int num)
138{
139 if (gicv3_detected)
140 gicv3_set_icenabler(num);
141 else
142 gicv2_gicd_set_icenabler(num);
143}
144
145unsigned int arm_gic_intr_ack(unsigned int *raw_iar)
146{
147 assert(raw_iar);
148
149 if (gicv3_detected) {
150 *raw_iar = gicv3_acknowledge_interrupt();
151 return *raw_iar;
152 } else {
153 *raw_iar = gicv2_gicc_read_iar();
154 return get_gicc_iar_intid(*raw_iar);
155 }
156}
157
158unsigned int arm_gic_is_intr_pending(unsigned int num)
159{
160 if (gicv3_detected)
161 return gicv3_get_ispendr(num);
162 else
163 return gicv2_gicd_get_ispendr(num);
164}
165
166void arm_gic_intr_clear(unsigned int num)
167{
168 if (gicv3_detected)
169 gicv3_set_icpendr(num);
170 else
171 gicv2_gicd_set_icpendr(num);
172}
173
174void arm_gic_end_of_intr(unsigned int raw_iar)
175{
176 if (gicv3_detected)
177 gicv3_end_of_interrupt(raw_iar);
178 else
179 gicv2_gicc_write_eoir(raw_iar);
180}
181
182void arm_gic_init(uintptr_t gicc_base,
183 uintptr_t gicd_base,
184 uintptr_t gicr_base)
185{
186
187 if (is_gicv3_mode()) {
188 gicv3_detected = 1;
189 gicv3_init(gicr_base, gicd_base);
190 } else {
191 gicv2_init(gicc_base, gicd_base);
192 }
193
194 INFO("%s mode detected\n", (gicv3_detected) ?
195 "GICv3" : "GICv2");
196}