blob: 294acda5a2da388b80e6d6dd3360ea8765ee3b37 [file] [log] [blame]
Alexei Fedorov2f13d6c2020-02-21 10:17:26 +00001/*
2 * Copyright (c) 2015-2020, Arm Limited and Contributors. All rights reserved.
3 *
4 * SPDX-License-Identifier: BSD-3-Clause
5 */
6
7#include <arch.h>
8#include <arch_helpers.h>
9#include <common/debug.h>
10#include <common/interrupt_props.h>
11#include <drivers/arm/gicv3.h>
12#include "gicv3_private.h"
13
14/*******************************************************************************
15 * GIC Redistributor functions
16 * Note: The raw register values correspond to multiple interrupt IDs and
17 * the number of interrupt IDs involved depends on the register accessed.
18 ******************************************************************************/
19
20/*
21 * Accessor to read the GIC Redistributor IPRIORITYR corresponding to the
22 * interrupt `id`, 4 interrupts IDs at a time.
23 */
24unsigned int gicr_read_ipriorityr(uintptr_t base, unsigned int id)
25{
26 unsigned int n = id >> IPRIORITYR_SHIFT;
27
28 return mmio_read_32(base + GICR_IPRIORITYR + (n << 2));
29}
30
31/*
32 * Accessor to write the GIC Redistributor IPRIORITYR corresponding to the
33 * interrupt `id`, 4 interrupts IDs at a time.
34 */
35void gicr_write_ipriorityr(uintptr_t base, unsigned int id, unsigned int val)
36{
37 unsigned int n = id >> IPRIORITYR_SHIFT;
38
39 mmio_write_32(base + GICR_IPRIORITYR + (n << 2), val);
40}
41
42/*
43 * Accessor to set the byte corresponding to interrupt ID
44 * in GIC Redistributor IPRIORITYR.
45 */
46void gicr_set_ipriorityr(uintptr_t base, unsigned int id, unsigned int pri)
47{
48 GICR_WRITE_8(IPRIORITYR, base, id, pri & GIC_PRI_MASK);
49}
50
51/*
52 * Accessor to get the bit corresponding to interrupt ID
53 * from GIC Redistributor IGROUPR0.
54 */
55unsigned int gicr_get_igroupr0(uintptr_t base, unsigned int id)
56{
57 unsigned int bit_num = id & ((1U << IGROUPR_SHIFT) - 1U);
58 unsigned int reg_val = gicr_read_igroupr0(base);
59
60 return (reg_val >> bit_num) & 0x1U;
61}
62
63/*
64 * Accessor to set the bit corresponding to interrupt ID
65 * in GIC Redistributor IGROUPR0.
66 */
67void gicr_set_igroupr0(uintptr_t base, unsigned int id)
68{
69 unsigned int bit_num = id & ((1U << IGROUPR_SHIFT) - 1U);
70 unsigned int reg_val = gicr_read_igroupr0(base);
71
72 gicr_write_igroupr0(base, reg_val | (1U << bit_num));
73}
74
75/*
76 * Accessor to clear the bit corresponding to interrupt ID
77 * in GIC Redistributor IGROUPR0.
78 */
79void gicr_clr_igroupr0(uintptr_t base, unsigned int id)
80{
81 unsigned int bit_num = id & ((1U << IGROUPR_SHIFT) - 1U);
82 unsigned int reg_val = gicr_read_igroupr0(base);
83
84 gicr_write_igroupr0(base, reg_val & ~(1U << bit_num));
85}
86
87/*
88 * Accessor to get the bit corresponding to interrupt ID
89 * from GIC Redistributor IGRPMODR0.
90 */
91unsigned int gicr_get_igrpmodr0(uintptr_t base, unsigned int id)
92{
93 unsigned int bit_num = id & ((1U << IGRPMODR_SHIFT) - 1U);
94 unsigned int reg_val = gicr_read_igrpmodr0(base);
95
96 return (reg_val >> bit_num) & 0x1U;
97}
98
99/*
100 * Accessor to set the bit corresponding to interrupt ID
101 * in GIC Redistributor IGRPMODR0.
102 */
103void gicr_set_igrpmodr0(uintptr_t base, unsigned int id)
104{
105 unsigned int bit_num = id & ((1U << IGRPMODR_SHIFT) - 1U);
106 unsigned int reg_val = gicr_read_igrpmodr0(base);
107
108 gicr_write_igrpmodr0(base, reg_val | (1U << bit_num));
109}
110
111/*
112 * Accessor to clear the bit corresponding to interrupt ID
113 * in GIC Redistributor IGRPMODR0.
114 */
115void gicr_clr_igrpmodr0(uintptr_t base, unsigned int id)
116{
117 unsigned int bit_num = id & ((1U << IGRPMODR_SHIFT) - 1U);
118 unsigned int reg_val = gicr_read_igrpmodr0(base);
119
120 gicr_write_igrpmodr0(base, reg_val & ~(1U << bit_num));
121}
122
123/*
124 * Accessor to set the bit corresponding to interrupt ID
125 * in GIC Redistributor ISENABLER0.
126 */
127void gicr_set_isenabler0(uintptr_t base, unsigned int id)
128{
129 unsigned int bit_num = id & ((1U << ISENABLER_SHIFT) - 1U);
130
131 gicr_write_isenabler0(base, (1U << bit_num));
132}
133
134/*
135 * Accessor to set the bit corresponding to interrupt ID in GIC Redistributor
136 * ICENABLER0.
137 */
138void gicr_set_icenabler0(uintptr_t base, unsigned int id)
139{
140 unsigned int bit_num = id & ((1U << ICENABLER_SHIFT) - 1U);
141
142 gicr_write_icenabler0(base, (1U << bit_num));
143}
144
145/*
146 * Accessor to set the bit corresponding to interrupt ID in GIC Redistributor
147 * ISACTIVER0.
148 */
149unsigned int gicr_get_isactiver0(uintptr_t base, unsigned int id)
150{
151 unsigned int bit_num = id & ((1U << ISACTIVER_SHIFT) - 1U);
152 unsigned int reg_val = gicr_read_isactiver0(base);
153
154 return (reg_val >> bit_num) & 0x1U;
155}
156
157/*
158 * Accessor to clear the bit corresponding to interrupt ID in GIC Redistributor
159 * ICPENDRR0.
160 */
161void gicr_set_icpendr0(uintptr_t base, unsigned int id)
162{
163 unsigned int bit_num = id & ((1U << ICPENDR_SHIFT) - 1U);
164
165 gicr_write_icpendr0(base, (1U << bit_num));
166}
167
168/*
169 * Accessor to set the bit corresponding to interrupt ID in GIC Redistributor
170 * ISPENDR0.
171 */
172void gicr_set_ispendr0(uintptr_t base, unsigned int id)
173{
174 unsigned int bit_num = id & ((1U << ISPENDR_SHIFT) - 1U);
175
176 gicr_write_ispendr0(base, (1U << bit_num));
177}
178
179/*
180 * Accessor to set the bit fields corresponding to interrupt ID
181 * in GIC Redistributor ICFGR0.
182 */
183void gicr_set_icfgr0(uintptr_t base, unsigned int id, unsigned int cfg)
184{
185 /* Interrupt configuration is a 2-bit field */
186 unsigned int bit_num = id & ((1U << ICFGR_SHIFT) - 1U);
187 unsigned int bit_shift = bit_num << 1U;
188
189 uint32_t reg_val = gicr_read_icfgr0(base);
190
191 /* Clear the field, and insert required configuration */
192 reg_val &= ~(GIC_CFG_MASK << bit_shift);
193 reg_val |= ((cfg & GIC_CFG_MASK) << bit_shift);
194
195 gicr_write_icfgr0(base, reg_val);
196}
197
198/*
199 * Accessor to set the bit fields corresponding to interrupt ID
200 * in GIC Redistributor ICFGR1.
201 */
202void gicr_set_icfgr1(uintptr_t base, unsigned int id, unsigned int cfg)
203{
204 /* Interrupt configuration is a 2-bit field */
205 unsigned int bit_num = id & ((1U << ICFGR_SHIFT) - 1U);
206 unsigned int bit_shift = bit_num << 1U;
207
208 uint32_t reg_val = gicr_read_icfgr1(base);
209
210 /* Clear the field, and insert required configuration */
211 reg_val &= ~(GIC_CFG_MASK << bit_shift);
212 reg_val |= ((cfg & GIC_CFG_MASK) << bit_shift);
213
214 gicr_write_icfgr1(base, reg_val);
215}