blob: d9c9fcee5eff8404b24f6fc617a194aab88a0ec9 [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>
Antonio Nino Diaz09a00ef2019-01-11 13:12:58 +000010#include <drivers/arm/gic_common.h>
11#include <drivers/arm/gic_v3.h>
Sandrine Bailleux3cd87d72018-10-09 11:12:55 +020012#include <mmio.h>
13
14/*******************************************************************************
15 * GIC Distributor interface accessors for reading entire registers
16 ******************************************************************************/
17
18unsigned int gicd_read_isenabler(unsigned int base, unsigned int interrupt_id)
19{
20 unsigned int n = interrupt_id >> ISENABLER_SHIFT;
21 return mmio_read_32(base + GICD_ISENABLER + (n << 2));
22}
23
24unsigned int gicd_read_icenabler(unsigned int base, unsigned int interrupt_id)
25{
26 unsigned int n = interrupt_id >> ICENABLER_SHIFT;
27 return mmio_read_32(base + GICD_ICENABLER + (n << 2));
28}
29
30unsigned int gicd_read_ispendr(unsigned int base, unsigned int interrupt_id)
31{
32 unsigned int n = interrupt_id >> ISPENDR_SHIFT;
33 return mmio_read_32(base + GICD_ISPENDR + (n << 2));
34}
35
36unsigned int gicd_read_icpendr(unsigned int base, unsigned int interrupt_id)
37{
38 unsigned int n = interrupt_id >> ICPENDR_SHIFT;
39 return mmio_read_32(base + GICD_ICPENDR + (n << 2));
40}
41
42unsigned int gicd_read_isactiver(unsigned int base, unsigned int interrupt_id)
43{
44 unsigned int n = interrupt_id >> ISACTIVER_SHIFT;
45 return mmio_read_32(base + GICD_ISACTIVER + (n << 2));
46}
47
48unsigned int gicd_read_icactiver(unsigned int base, unsigned int interrupt_id)
49{
50 unsigned int n = interrupt_id >> ICACTIVER_SHIFT;
51 return mmio_read_32(base + GICD_ICACTIVER + (n << 2));
52}
53
54unsigned int gicd_read_ipriorityr(unsigned int base, unsigned int interrupt_id)
55{
56 unsigned int n = interrupt_id >> IPRIORITYR_SHIFT;
57 return mmio_read_32(base + GICD_IPRIORITYR + (n << 2));
58}
59
60unsigned int gicd_read_icfgr(unsigned int base, unsigned int interrupt_id)
61{
62 unsigned int n = interrupt_id >> ICFGR_SHIFT;
63 return mmio_read_32(base + GICD_ICFGR + (n << 2));
64}
65
66/*******************************************************************************
67 * GIC Distributor interface accessors for writing entire registers
68 ******************************************************************************/
69
70void gicd_write_isenabler(unsigned int base,
71 unsigned int interrupt_id, unsigned int val)
72{
73 unsigned int n = interrupt_id >> ISENABLER_SHIFT;
74 mmio_write_32(base + GICD_ISENABLER + (n << 2), val);
75}
76
77void gicd_write_icenabler(unsigned int base,
78 unsigned int interrupt_id, unsigned int val)
79{
80 unsigned int n = interrupt_id >> ICENABLER_SHIFT;
81 mmio_write_32(base + GICD_ICENABLER + (n << 2), val);
82}
83
84void gicd_write_ispendr(unsigned int base,
85 unsigned int interrupt_id, unsigned int val)
86{
87 unsigned int n = interrupt_id >> ISPENDR_SHIFT;
88 mmio_write_32(base + GICD_ISPENDR + (n << 2), val);
89}
90
91void gicd_write_icpendr(unsigned int base,
92 unsigned int interrupt_id, unsigned int val)
93{
94 unsigned int n = interrupt_id >> ICPENDR_SHIFT;
95 mmio_write_32(base + GICD_ICPENDR + (n << 2), val);
96}
97
98void gicd_write_isactiver(unsigned int base,
99 unsigned int interrupt_id, unsigned int val)
100{
101 unsigned int n = interrupt_id >> ISACTIVER_SHIFT;
102 mmio_write_32(base + GICD_ISACTIVER + (n << 2), val);
103}
104
105void gicd_write_icactiver(unsigned int base,
106 unsigned int interrupt_id, unsigned int val)
107{
108 unsigned int n = interrupt_id >> ICACTIVER_SHIFT;
109 mmio_write_32(base + GICD_ICACTIVER + (n << 2), val);
110}
111
112void gicd_write_ipriorityr(unsigned int base,
113 unsigned int interrupt_id, unsigned int val)
114{
115 unsigned int n = interrupt_id >> IPRIORITYR_SHIFT;
116 mmio_write_32(base + GICD_IPRIORITYR + (n << 2), val);
117}
118
119void gicd_write_icfgr(unsigned int base,
120 unsigned int interrupt_id, unsigned int val)
121{
122 unsigned int n = interrupt_id >> ICFGR_SHIFT;
123 mmio_write_32(base + GICD_ICFGR + (n << 2), val);
124}
125
126/*******************************************************************************
127 * GIC Distributor interface accessors for individual interrupt manipulation
128 ******************************************************************************/
129unsigned int gicd_get_isenabler(unsigned int base, unsigned int interrupt_id)
130{
131 unsigned int bit_num = interrupt_id & ((1 << ISENABLER_SHIFT) - 1);
132
133 return gicd_read_isenabler(base, interrupt_id) & (1 << bit_num);
134}
135
136void gicd_set_isenabler(unsigned int base, unsigned int interrupt_id)
137{
138 unsigned int bit_num = interrupt_id & ((1 << ISENABLER_SHIFT) - 1);
139
140 gicd_write_isenabler(base, interrupt_id, (1 << bit_num));
141}
142
143void gicd_set_icenabler(unsigned int base, unsigned int interrupt_id)
144{
145 unsigned int bit_num = interrupt_id & ((1 << ICENABLER_SHIFT) - 1);
146
147 gicd_write_icenabler(base, interrupt_id, (1 << bit_num));
148}
149
150void gicd_set_ispendr(unsigned int base, unsigned int interrupt_id)
151{
152 unsigned int bit_num = interrupt_id & ((1 << ISPENDR_SHIFT) - 1);
153
154 gicd_write_ispendr(base, interrupt_id, (1 << bit_num));
155}
156
157void gicd_set_icpendr(unsigned int base, unsigned int interrupt_id)
158{
159 unsigned int bit_num = interrupt_id & ((1 << ICPENDR_SHIFT) - 1);
160
161 gicd_write_icpendr(base, interrupt_id, (1 << bit_num));
162}
163
164void gicd_set_isactiver(unsigned int base, unsigned int interrupt_id)
165{
166 unsigned int bit_num = interrupt_id & ((1 << ISACTIVER_SHIFT) - 1);
167
168 gicd_write_isactiver(base, interrupt_id, (1 << bit_num));
169}
170
171void gicd_set_icactiver(unsigned int base, unsigned int interrupt_id)
172{
173 unsigned int bit_num = interrupt_id & ((1 << ICACTIVER_SHIFT) - 1);
174
175 gicd_write_icactiver(base, interrupt_id, (1 << bit_num));
176}
177
178unsigned int gicd_get_ipriorityr(unsigned int base, unsigned int interrupt_id)
179{
180 return gicd_read_ipriorityr(base, interrupt_id) & GIC_PRI_MASK;
181}
182
183void gicd_set_ipriorityr(unsigned int base, unsigned int interrupt_id,
184 unsigned int priority)
185{
186 mmio_write_8(base + GICD_IPRIORITYR + interrupt_id,
187 priority & GIC_PRI_MASK);
188}
189
190unsigned int is_gicv3_mode(void)
191{
192 /* Check if GICv3 system register available */
193#ifndef AARCH32
194 if (!(read_id_aa64pfr0_el1() & (ID_AA64PFR0_GIC_MASK << ID_AA64PFR0_GIC_SHIFT)))
195 return 0;
196#else
197 if (!(read_id_pfr1() & (ID_PFR1_GIC_MASK << ID_PFR1_GIC_SHIFT)))
198 return 0;
199#endif
200
201 /* Check whether the system register interface is enabled */
202 return !!is_sre_enabled();
203}