master
h 228 lines 8.15 KB
Raw
1 /*
2 * Interface between GICv5 CPU interface and GICv5 IRS
3 * Loosely modelled on the GICv5 Stream Protocol interface documented
4 * in the GICv5 specification.
5 *
6 * Copyright (c) 2025 Linaro Limited
7 *
8 * SPDX-License-Identifier: GPL-2.0-or-later
9 */
10
11 #ifndef HW_INTC_ARM_GICV5_STREAM_H
12 #define HW_INTC_ARM_GICV5_STREAM_H
13
14 #include "target/arm/cpu-qom.h"
15 #include "hw/intc/arm_gicv5_types.h"
16
17 typedef struct GICv5Common GICv5Common;
18
19 /**
20 * gicv5_set_gicv5state
21 * @cpu: CPU object to tell about its IRS
22 * @cs: the GIC IRS it is connected to
23 * @iaffid: the IAFFID of this CPU
24 *
25 * Set the CPU object's GICv5 pointer to point to this GIC IRS. The
26 * IRS must call this when it is realized, for each CPU it is
27 * connected to.
28 *
29 * Returns true on success, false if the CPU doesn't implement the
30 * GICv5 CPU interface.
31 */
32 bool gicv5_set_gicv5state(ARMCPU *cpu, GICv5Common *cs, uint32_t iaffid);
33
34 /*
35 * The architected Stream Protocol is asynchronous; commands can be
36 * initiated both from the IRS and from the CPU interface, and some
37 * require acknowledgement. For QEMU, we simplify this because we know
38 * that in the CPU interface code we hold the BQL and so our IRS model
39 * is not going to be busy; when we send commands from the CPUIF
40 * ("upstream commands") we can model this as a synchronous function
41 * call whose return corresponds to the acknowledgement of a completed
42 * command.
43 */
44
45 /**
46 * gicv5_set_priority
47 * @cs: GIC IRS to send command to
48 * @id: interrupt ID
49 * @priority: priority to set
50 * @domain: interrupt Domain to act on
51 * @type: interrupt type (LPI or SPI)
52 * @virtual: true if this is a virtual interrupt
53 *
54 * Set priority of an interrupt; matches stream interface SetPriority
55 * command from CPUIF to IRS. There is no report back of
56 * success/failure to the CPUIF in the protocol.
57 */
58 void gicv5_set_priority(GICv5Common *cs, uint32_t id,
59 uint8_t priority, GICv5Domain domain,
60 GICv5IntType type, bool virtual);
61
62 /**
63 * gicv5_set_enabled
64 * @cs: GIC IRS to send command to
65 * @id: interrupt ID
66 * @enabled: new enabled state
67 * @domain: interrupt Domain to act on
68 * @type: interrupt type (LPI or SPI)
69 * @virtual: true if this is a virtual interrupt
70 *
71 * Set enabled state of an interrupt; matches stream interface
72 * SetEnabled command from CPUIF to IRS. There is no report back of
73 * success/failure to the CPUIF in the protocol.
74 */
75 void gicv5_set_enabled(GICv5Common *cs, uint32_t id,
76 bool enabled, GICv5Domain domain,
77 GICv5IntType type, bool virtual);
78
79 /**
80 * gicv5_set_pending
81 * @cs: GIC IRS to send command to
82 * @id: interrupt ID
83 * @pending: new pending state
84 * @domain: interrupt Domain to act on
85 * @type: interrupt type (LPI or SPI)
86 * @virtual: true if this is a virtual interrupt
87 *
88 * Set pending state of an interrupt; matches stream interface
89 * SetPending command from CPUIF to IRS. There is no report back of
90 * success/failure to the CPUIF in the protocol.
91 */
92 void gicv5_set_pending(GICv5Common *cs, uint32_t id,
93 bool pending, GICv5Domain domain,
94 GICv5IntType type, bool virtual);
95
96 /**
97 * gicv5_set_handling
98 * @cs: GIC IRS to send command to
99 * @id: interrupt ID
100 * @handling: new handling mode
101 * @domain: interrupt Domain to act on
102 * @type: interrupt type (LPI or SPI)
103 * @virtual: true if this is a virtual interrupt
104 *
105 * Set handling mode of an interrupt (edge/level); matches stream
106 * interface SetHandling command from CPUIF to IRS. There is no report
107 * back of success/failure to the CPUIF in the protocol.
108 */
109 void gicv5_set_handling(GICv5Common *cs, uint32_t id,
110 GICv5HandlingMode handling, GICv5Domain domain,
111 GICv5IntType type, bool virtual);
112
113 /**
114 * gicv5_set_target
115 * @cs: GIC IRS to send command to
116 * @id: interrupt ID
117 * @iaffid: new target PE's interrupt affinity
118 * @irm: interrupt routing mode (targeted vs 1-of-N)
119 * @domain: interrupt Domain to act on
120 * @type: interrupt type (LPI or SPI)
121 * @virtual: true if this is a virtual interrupt
122 *
123 * Set handling mode of an interrupt (edge/level); matches stream
124 * interface SetHandling command from CPUIF to IRS. There is no report
125 * back of success/failure to the CPUIF in the protocol.
126 */
127 void gicv5_set_target(GICv5Common *cs, uint32_t id, uint32_t iaffid,
128 GICv5RoutingMode irm, GICv5Domain domain,
129 GICv5IntType type, bool virtual);
130
131 /**
132 * gicv5_request_config
133 * @cs: GIC IRS to send command to
134 * @id: interrupt ID
135 * @domain: interrupt domain to act on
136 * @type: interrupt type (LPI or SPI)
137 * @virtual: true if this is a virtual interrupt
138 *
139 * Query the current configuration of an interrupt; matches stream
140 * interface RequestConfig command from CPUIF to IRS and the
141 * RequestConfigAck reply to it.
142 *
143 * In the real stream protocol, the RequestConfigAck packet has the
144 * same information as the register but in a different order; we use
145 * the register order, not the packet order, so we don't need to
146 * unpack and repack in the cpuif.
147 *
148 * Returns: the config of the interrupt, in the format used by
149 * ICC_ICSR_EL1.
150 */
151 uint64_t gicv5_request_config(GICv5Common *cs, uint32_t id, GICv5Domain domain,
152 GICv5IntType type, bool virtual);
153
154 /**
155 * gicv5_activate
156 * @cs: GIC IRS to send command to
157 * @id: interrupt ID
158 * @domain: interrupt domain to act on
159 * @type: interrupt type (LPI or SPI)
160 * @virtual: true if this is a virtual interrupt
161 *
162 * Activate the IRS's highest priority pending interrupt; matches the
163 * stream interface's Activate command.
164 *
165 * In the stream interface, the command has only the domain and
166 * virtual fields, because both the IRS and the CPUIF keep track of
167 * the IRS's current HPPI. In QEMU, we also have arguments here for
168 * @id and @type which are telling the IRS something that in hardware
169 * it already knows. This is because we have them to hand in the cpuif
170 * code, and it means we don't need to pass in an iaffid argument to
171 * tell the IRS which CPU we are so it can find the right element in
172 * its hppi[][] array.
173 */
174 void gicv5_activate(GICv5Common *cs, uint32_t id, GICv5Domain domain,
175 GICv5IntType type, bool virtual);
176
177 /**
178 * gicv5_forward_interrupt
179 * @cpu: CPU interface to forward interrupt to
180 * @domain: domain this interrupt is for
181 *
182 * Tell the CPU interface that the highest priority pending interrupt
183 * that the IRS has available for it has changed. This is the
184 * equivalent of the stream protocol's Forward packet, and also of its
185 * Recall packet.
186 *
187 * The stream protocol makes this asynchronous, allowing two Forward
188 * packets to be in flight and requiring an acknowledge, because the
189 * cpuif might be about to activate the previous forwarded interrupt
190 * while we are trying to tell it about a new one. But for QEMU we
191 * hold the BQL, so we know the vcpu might be executing guest code but
192 * it cannot be in the middle of changing cpuif state. So we can just
193 * synchronously tell it that a new HPPI exists (which might cause it
194 * to assert IRQ or FIQ to itself); this works as if the cpuif gave us
195 * a Release for the old HPPI. The cpuif will ask the IRS for the
196 * HPPI info via a function call, so we do not need to pass it across
197 * here.
198 */
199 void gicv5_forward_interrupt(ARMCPU *cpu, GICv5Domain domain);
200
201 /**
202 * gicv5_get_hppi
203 * @cs: GIC IRS to query
204 * @domain: interrupt domain to act on
205 * @iaffid: IAFFID of this CPU interface
206 *
207 * Ask the IRS for the highest priority pending interrupt that it has
208 * for this CPU. This returns the equivalent of what in the stream
209 * protocol is the outstanding interrupt sent with a Forward packet.
210 */
211 GICv5PendingIrq gicv5_get_hppi(GICv5Common *cs, GICv5Domain domain,
212 uint32_t iaffid);
213
214 /**
215 * gicv5_deactivate
216 * @cs: GIC IRS to send command to
217 * @id: interrupt ID
218 * @domain: interrupt Domain to act on
219 * @type: interrupt type (LPI or SPI)
220 * @virtual: true if this is a virtual interrupt
221 *
222 * Deactivate the specified interrupt. There is no report back of
223 * success/failure to the CPUIF in the protocol.
224 */
225 void gicv5_deactivate(GICv5Common *cs, uint32_t id, GICv5Domain domain,
226 GICv5IntType type, bool virtual);
227
228 #endif