1 /*
2  * Copyright (c) 2015-2020, ARM Limited and Contributors. All rights reserved.
3  *
4  * SPDX-License-Identifier: BSD-3-Clause
5  */
6 
7 #include <stdint.h>
8 
9 #include "gicv3_private.h"
10 
11 /*******************************************************************************
12  * GIC Distributor functions for accessing the GIC registers
13  * corresponding to a single interrupt ID. These functions use bitwise
14  * operations or appropriate register accesses to modify or return
15  * the bit-field corresponding the single interrupt ID.
16  ******************************************************************************/
17 
18 /*
19  * Accessors to set the bits corresponding to interrupt ID
20  * in GIC Distributor ICFGR and ICFGRE.
21  */
gicd_set_icfgr(uintptr_t base,unsigned int id,unsigned int cfg)22 void gicd_set_icfgr(uintptr_t base, unsigned int id, unsigned int cfg)
23 {
24 	/* Interrupt configuration is a 2-bit field */
25 	unsigned int bit_shift = BIT_NUM(ICFG, id) << 1U;
26 
27 	/* Clear the field, and insert required configuration */
28 	mmio_clrsetbits_32(base + GICD_OFFSET(ICFG, id),
29 				(uint32_t)GIC_CFG_MASK << bit_shift,
30 				(cfg & GIC_CFG_MASK) << bit_shift);
31 }
32 
33 /*
34  * Accessors to get/set/clear the bit corresponding to interrupt ID
35  * in GIC Distributor IGROUPR and IGROUPRE.
36  */
gicd_get_igroupr(uintptr_t base,unsigned int id)37 unsigned int gicd_get_igroupr(uintptr_t base, unsigned int id)
38 {
39 	return GICD_GET_BIT(IGROUP, base, id);
40 }
41 
gicd_set_igroupr(uintptr_t base,unsigned int id)42 void gicd_set_igroupr(uintptr_t base, unsigned int id)
43 {
44 	GICD_SET_BIT(IGROUP, base, id);
45 }
46 
gicd_clr_igroupr(uintptr_t base,unsigned int id)47 void gicd_clr_igroupr(uintptr_t base, unsigned int id)
48 {
49 	GICD_CLR_BIT(IGROUP, base, id);
50 }
51 
52 /*
53  * Accessors to get/set/clear the bit corresponding to interrupt ID
54  * in GIC Distributor IGRPMODR and IGRPMODRE.
55  */
gicd_get_igrpmodr(uintptr_t base,unsigned int id)56 unsigned int gicd_get_igrpmodr(uintptr_t base, unsigned int id)
57 {
58 	return GICD_GET_BIT(IGRPMOD, base, id);
59 }
60 
gicd_set_igrpmodr(uintptr_t base,unsigned int id)61 void gicd_set_igrpmodr(uintptr_t base, unsigned int id)
62 {
63 	GICD_SET_BIT(IGRPMOD, base, id);
64 }
65 
gicd_clr_igrpmodr(uintptr_t base,unsigned int id)66 void gicd_clr_igrpmodr(uintptr_t base, unsigned int id)
67 {
68 	GICD_CLR_BIT(IGRPMOD, base, id);
69 }
70 
71 /*
72  * Accessors to set the bit corresponding to interrupt ID
73  * in GIC Distributor ICENABLER and ICENABLERE.
74  */
gicd_set_icenabler(uintptr_t base,unsigned int id)75 void gicd_set_icenabler(uintptr_t base, unsigned int id)
76 {
77 	GICD_WRITE_BIT(ICENABLE, base, id);
78 }
79 
80 /*
81  * Accessors to set the bit corresponding to interrupt ID
82  * in GIC Distributor ICPENDR and ICPENDRE.
83  */
gicd_set_icpendr(uintptr_t base,unsigned int id)84 void gicd_set_icpendr(uintptr_t base, unsigned int id)
85 {
86 	GICD_WRITE_BIT(ICPEND, base, id);
87 }
88 
89 /*
90  * Accessors to get/set the bit corresponding to interrupt ID
91  * in GIC Distributor ISACTIVER and ISACTIVERE.
92  */
gicd_get_isactiver(uintptr_t base,unsigned int id)93 unsigned int gicd_get_isactiver(uintptr_t base, unsigned int id)
94 {
95 	return GICD_GET_BIT(ISACTIVE, base, id);
96 }
97 
gicd_set_isactiver(uintptr_t base,unsigned int id)98 void gicd_set_isactiver(uintptr_t base, unsigned int id)
99 {
100 	GICD_WRITE_BIT(ISACTIVE, base, id);
101 }
102 
103 /*
104  * Accessors to set the bit corresponding to interrupt ID
105  * in GIC Distributor ISENABLER and ISENABLERE.
106  */
gicd_set_isenabler(uintptr_t base,unsigned int id)107 void gicd_set_isenabler(uintptr_t base, unsigned int id)
108 {
109 	GICD_WRITE_BIT(ISENABLE, base, id);
110 }
111 
112 /*
113  * Accessors to set the bit corresponding to interrupt ID
114  * in GIC Distributor ISPENDR and ISPENDRE.
115  */
gicd_set_ispendr(uintptr_t base,unsigned int id)116 void gicd_set_ispendr(uintptr_t base, unsigned int id)
117 {
118 	GICD_WRITE_BIT(ISPEND, base, id);
119 }
120 
121 /*
122  * Accessors to set the bit corresponding to interrupt ID
123  * in GIC Distributor IPRIORITYR and IPRIORITYRE.
124  */
gicd_set_ipriorityr(uintptr_t base,unsigned int id,unsigned int pri)125 void gicd_set_ipriorityr(uintptr_t base, unsigned int id, unsigned int pri)
126 {
127 	GICD_WRITE_8(IPRIORITY, base, id, (uint8_t)(pri & GIC_PRI_MASK));
128 }
129 
130 /*******************************************************************************
131  * GIC Distributor interface accessors for reading/writing entire registers
132  ******************************************************************************/
133 
134 /*
135  * Accessors to read/write the GIC Distributor ICGFR and ICGFRE
136  * corresponding to the interrupt ID, 16 interrupt IDs at a time.
137  */
gicd_read_icfgr(uintptr_t base,unsigned int id)138 unsigned int gicd_read_icfgr(uintptr_t base, unsigned int id)
139 {
140 	return GICD_READ(ICFG, base, id);
141 }
142 
gicd_write_icfgr(uintptr_t base,unsigned int id,unsigned int val)143 void gicd_write_icfgr(uintptr_t base, unsigned int id, unsigned int val)
144 {
145 	GICD_WRITE(ICFG, base, id, val);
146 }
147 
148 /*
149  * Accessors to read/write the GIC Distributor IGROUPR and IGROUPRE
150  * corresponding to the interrupt ID, 32 interrupt IDs at a time.
151  */
gicd_read_igroupr(uintptr_t base,unsigned int id)152 unsigned int gicd_read_igroupr(uintptr_t base, unsigned int id)
153 {
154 	return GICD_READ(IGROUP, base, id);
155 }
156 
gicd_write_igroupr(uintptr_t base,unsigned int id,unsigned int val)157 void gicd_write_igroupr(uintptr_t base, unsigned int id, unsigned int val)
158 {
159 	GICD_WRITE(IGROUP, base, id, val);
160 }
161 
162 /*
163  * Accessors to read/write the GIC Distributor IGRPMODR and IGRPMODRE
164  * corresponding to the interrupt ID, 32 interrupt IDs at a time.
165  */
gicd_read_igrpmodr(uintptr_t base,unsigned int id)166 unsigned int gicd_read_igrpmodr(uintptr_t base, unsigned int id)
167 {
168 	return GICD_READ(IGRPMOD, base, id);
169 }
170 
gicd_write_igrpmodr(uintptr_t base,unsigned int id,unsigned int val)171 void gicd_write_igrpmodr(uintptr_t base, unsigned int id, unsigned int val)
172 {
173 	GICD_WRITE(IGRPMOD, base, id, val);
174 }
175 
176 /*
177  * Accessors to read/write the GIC Distributor IPRIORITYR and IPRIORITYRE
178  * corresponding to the interrupt ID, 4 interrupt IDs at a time.
179  */
gicd_read_ipriorityr(uintptr_t base,unsigned int id)180 unsigned int gicd_read_ipriorityr(uintptr_t base, unsigned int id)
181 {
182 	return GICD_READ(IPRIORITY, base, id);
183 }
184 
gicd_write_ipriorityr(uintptr_t base,unsigned int id,unsigned int val)185 void gicd_write_ipriorityr(uintptr_t base, unsigned int id, unsigned int val)
186 {
187 	GICD_WRITE(IPRIORITY, base, id, val);
188 }
189 
190 /*
191  * Accessors to read/write the GIC Distributor ISACTIVER and ISACTIVERE
192  * corresponding to the interrupt ID, 32 interrupt IDs at a time.
193  */
gicd_read_isactiver(uintptr_t base,unsigned int id)194 unsigned int gicd_read_isactiver(uintptr_t base, unsigned int id)
195 {
196 	return GICD_READ(ISACTIVE, base, id);
197 }
198 
gicd_write_isactiver(uintptr_t base,unsigned int id,unsigned int val)199 void gicd_write_isactiver(uintptr_t base, unsigned int id, unsigned int val)
200 {
201 	GICD_WRITE(ISACTIVE, base, id, val);
202 }
203 
204 /*
205  * Accessors to read/write the GIC Distributor ISENABLER and ISENABLERE
206  * corresponding to the interrupt ID, 32 interrupt IDs at a time.
207  */
gicd_read_isenabler(uintptr_t base,unsigned int id)208 unsigned int gicd_read_isenabler(uintptr_t base, unsigned int id)
209 {
210 	return GICD_READ(ISENABLE, base, id);
211 }
212 
gicd_write_isenabler(uintptr_t base,unsigned int id,unsigned int val)213 void gicd_write_isenabler(uintptr_t base, unsigned int id, unsigned int val)
214 {
215 	GICD_WRITE(ISENABLE, base, id, val);
216 }
217 
218 /*
219  * Accessors to read/write the GIC Distributor ISPENDR and ISPENDRE
220  * corresponding to the interrupt ID, 32 interrupt IDs at a time.
221  */
gicd_read_ispendr(uintptr_t base,unsigned int id)222 unsigned int gicd_read_ispendr(uintptr_t base, unsigned int id)
223 {
224 	return GICD_READ(ISPEND, base, id);
225 }
226 
gicd_write_ispendr(uintptr_t base,unsigned int id,unsigned int val)227 void gicd_write_ispendr(uintptr_t base, unsigned int id, unsigned int val)
228 {
229 	GICD_WRITE(ISPEND, base, id, val);
230 }
231 
232 /*
233  * Accessors to read/write the GIC Distributor NSACR and NSACRE
234  * corresponding to the interrupt ID, 16 interrupt IDs at a time.
235  */
gicd_read_nsacr(uintptr_t base,unsigned int id)236 unsigned int gicd_read_nsacr(uintptr_t base, unsigned int id)
237 {
238 	return GICD_READ(NSAC, base, id);
239 }
240 
gicd_write_nsacr(uintptr_t base,unsigned int id,unsigned int val)241 void gicd_write_nsacr(uintptr_t base, unsigned int id, unsigned int val)
242 {
243 	GICD_WRITE(NSAC, base, id, val);
244 }
245