]>
Commit | Line | Data |
---|---|---|
02e3ff54 CLG |
1 | /* |
2 | * QEMU PowerPC XIVE interrupt controller model | |
3 | * | |
4 | * | |
5 | * The POWER9 processor comes with a new interrupt controller, called | |
6 | * XIVE as "eXternal Interrupt Virtualization Engine". | |
7 | * | |
8 | * = Overall architecture | |
9 | * | |
10 | * | |
11 | * XIVE Interrupt Controller | |
12 | * +------------------------------------+ IPIs | |
13 | * | +---------+ +---------+ +--------+ | +-------+ | |
14 | * | |VC | |CQ | |PC |----> | CORES | | |
15 | * | | esb | | | | |----> | | | |
16 | * | | eas | | Bridge | | tctx |----> | | | |
17 | * | |SC end | | | | nvt | | | | | |
18 | * +------+ | +---------+ +----+----+ +--------+ | +-+-+-+-+ | |
19 | * | RAM | +------------------|-----------------+ | | | | |
20 | * | | | | | | | |
21 | * | | | | | | | |
22 | * | | +--------------------v------------------------v-v-v--+ other | |
23 | * | <--+ Power Bus +--> chips | |
24 | * | esb | +---------+-----------------------+------------------+ | |
25 | * | eas | | | | |
26 | * | end | +--|------+ | | |
27 | * | nvt | +----+----+ | +----+----+ | |
28 | * +------+ |SC | | |SC | | |
29 | * | | | | | | |
30 | * | PQ-bits | | | PQ-bits | | |
31 | * | local |-+ | in VC | | |
32 | * +---------+ +---------+ | |
33 | * PCIe NX,NPU,CAPI | |
34 | * | |
35 | * SC: Source Controller (aka. IVSE) | |
36 | * VC: Virtualization Controller (aka. IVRE) | |
37 | * PC: Presentation Controller (aka. IVPE) | |
38 | * CQ: Common Queue (Bridge) | |
39 | * | |
40 | * PQ-bits: 2 bits source state machine (P:pending Q:queued) | |
41 | * esb: Event State Buffer (Array of PQ bits in an IVSE) | |
42 | * eas: Event Assignment Structure | |
43 | * end: Event Notification Descriptor | |
44 | * nvt: Notification Virtual Target | |
45 | * tctx: Thread interrupt Context | |
46 | * | |
47 | * | |
48 | * The XIVE IC is composed of three sub-engines : | |
49 | * | |
50 | * - Interrupt Virtualization Source Engine (IVSE), or Source | |
51 | * Controller (SC). These are found in PCI PHBs, in the PSI host | |
52 | * bridge controller, but also inside the main controller for the | |
53 | * core IPIs and other sub-chips (NX, CAP, NPU) of the | |
54 | * chip/processor. They are configured to feed the IVRE with events. | |
55 | * | |
56 | * - Interrupt Virtualization Routing Engine (IVRE) or Virtualization | |
57 | * Controller (VC). Its job is to match an event source with an | |
58 | * Event Notification Descriptor (END). | |
59 | * | |
60 | * - Interrupt Virtualization Presentation Engine (IVPE) or | |
61 | * Presentation Controller (PC). It maintains the interrupt context | |
62 | * state of each thread and handles the delivery of the external | |
63 | * exception to the thread. | |
64 | * | |
65 | * In XIVE 1.0, the sub-engines used to be referred as: | |
66 | * | |
67 | * SC Source Controller | |
68 | * VC Virtualization Controller | |
69 | * PC Presentation Controller | |
70 | * CQ Common Queue (PowerBUS Bridge) | |
71 | * | |
72 | * | |
73 | * = XIVE internal tables | |
74 | * | |
75 | * Each of the sub-engines uses a set of tables to redirect exceptions | |
76 | * from event sources to CPU threads. | |
77 | * | |
78 | * +-------+ | |
79 | * User or OS | EQ | | |
80 | * or +------>|entries| | |
81 | * Hypervisor | | .. | | |
82 | * Memory | +-------+ | |
83 | * | ^ | |
84 | * | | | |
85 | * +-------------------------------------------------+ | |
86 | * | | | |
87 | * Hypervisor +------+ +---+--+ +---+--+ +------+ | |
88 | * Memory | ESB | | EAT | | ENDT | | NVTT | | |
89 | * (skiboot) +----+-+ +----+-+ +----+-+ +------+ | |
90 | * ^ | ^ | ^ | ^ | |
91 | * | | | | | | | | |
92 | * +-------------------------------------------------+ | |
93 | * | | | | | | | | |
94 | * | | | | | | | | |
95 | * +----|--|--------|--|--------|--|-+ +-|-----+ +------+ | |
96 | * | | | | | | | | | | tctx| |Thread| | |
97 | * IPI or --> | + v + v + v |---| + .. |-----> | | |
98 | * HW events --> | | | | | | | |
99 | * IVSE | IVRE | | IVPE | +------+ | |
100 | * +---------------------------------+ +-------+ | |
101 | * | |
102 | * | |
103 | * | |
104 | * The IVSE have a 2-bits state machine, P for pending and Q for queued, | |
105 | * for each source that allows events to be triggered. They are stored in | |
106 | * an Event State Buffer (ESB) array and can be controlled by MMIOs. | |
107 | * | |
108 | * If the event is let through, the IVRE looks up in the Event Assignment | |
109 | * Structure (EAS) table for an Event Notification Descriptor (END) | |
110 | * configured for the source. Each Event Notification Descriptor defines | |
111 | * a notification path to a CPU and an in-memory Event Queue, in which | |
112 | * will be enqueued an EQ data for the OS to pull. | |
113 | * | |
114 | * The IVPE determines if a Notification Virtual Target (NVT) can | |
115 | * handle the event by scanning the thread contexts of the VCPUs | |
116 | * dispatched on the processor HW threads. It maintains the state of | |
117 | * the thread interrupt context (TCTX) of each thread in a NVT table. | |
118 | * | |
119 | * = Acronyms | |
120 | * | |
121 | * Description In XIVE 1.0, used to be referred as | |
122 | * | |
123 | * EAS Event Assignment Structure IVE Interrupt Virt. Entry | |
124 | * EAT Event Assignment Table IVT Interrupt Virt. Table | |
125 | * ENDT Event Notif. Descriptor Table EQDT Event Queue Desc. Table | |
126 | * EQ Event Queue same | |
127 | * ESB Event State Buffer SBE State Bit Entry | |
128 | * NVT Notif. Virtual Target VPD Virtual Processor Desc. | |
129 | * NVTT Notif. Virtual Target Table VPDT Virtual Processor Desc. Table | |
130 | * TCTX Thread interrupt Context | |
131 | * | |
132 | * | |
133 | * Copyright (c) 2017-2018, IBM Corporation. | |
134 | * | |
135 | * This code is licensed under the GPL version 2 or later. See the | |
136 | * COPYING file in the top-level directory. | |
137 | * | |
138 | */ | |
139 | ||
140 | #ifndef PPC_XIVE_H | |
141 | #define PPC_XIVE_H | |
142 | ||
38afd772 | 143 | #include "sysemu/kvm.h" |
02e3ff54 | 144 | #include "hw/qdev-core.h" |
7ff7ea92 CLG |
145 | #include "hw/sysbus.h" |
146 | #include "hw/ppc/xive_regs.h" | |
02e3ff54 | 147 | |
5e79b155 | 148 | /* |
6bf6f3a1 | 149 | * XIVE Notifier (Interface between Source and Router) |
5e79b155 CLG |
150 | */ |
151 | ||
152 | typedef struct XiveNotifier { | |
153 | Object parent; | |
154 | } XiveNotifier; | |
155 | ||
156 | #define TYPE_XIVE_NOTIFIER "xive-notifier" | |
157 | #define XIVE_NOTIFIER(obj) \ | |
158 | OBJECT_CHECK(XiveNotifier, (obj), TYPE_XIVE_NOTIFIER) | |
159 | #define XIVE_NOTIFIER_CLASS(klass) \ | |
160 | OBJECT_CLASS_CHECK(XiveNotifierClass, (klass), TYPE_XIVE_NOTIFIER) | |
161 | #define XIVE_NOTIFIER_GET_CLASS(obj) \ | |
162 | OBJECT_GET_CLASS(XiveNotifierClass, (obj), TYPE_XIVE_NOTIFIER) | |
163 | ||
164 | typedef struct XiveNotifierClass { | |
165 | InterfaceClass parent; | |
166 | void (*notify)(XiveNotifier *xn, uint32_t lisn); | |
167 | } XiveNotifierClass; | |
168 | ||
02e3ff54 CLG |
169 | /* |
170 | * XIVE Interrupt Source | |
171 | */ | |
172 | ||
173 | #define TYPE_XIVE_SOURCE "xive-source" | |
174 | #define XIVE_SOURCE(obj) OBJECT_CHECK(XiveSource, (obj), TYPE_XIVE_SOURCE) | |
175 | ||
176 | /* | |
177 | * XIVE Interrupt Source characteristics, which define how the ESB are | |
178 | * controlled. | |
179 | */ | |
180 | #define XIVE_SRC_H_INT_ESB 0x1 /* ESB managed with hcall H_INT_ESB */ | |
181 | #define XIVE_SRC_STORE_EOI 0x2 /* Store EOI supported */ | |
182 | ||
183 | typedef struct XiveSource { | |
184 | DeviceState parent; | |
185 | ||
186 | /* IRQs */ | |
187 | uint32_t nr_irqs; | |
5fd9ef18 | 188 | unsigned long *lsi_map; |
02e3ff54 | 189 | |
5fd9ef18 | 190 | /* PQ bits and LSI assertion bit */ |
02e3ff54 CLG |
191 | uint8_t *status; |
192 | ||
193 | /* ESB memory region */ | |
194 | uint64_t esb_flags; | |
195 | uint32_t esb_shift; | |
196 | MemoryRegion esb_mmio; | |
5e79b155 | 197 | |
38afd772 CLG |
198 | /* KVM support */ |
199 | void *esb_mmap; | |
981b1c62 | 200 | MemoryRegion esb_mmio_kvm; |
38afd772 | 201 | |
5e79b155 | 202 | XiveNotifier *xive; |
02e3ff54 CLG |
203 | } XiveSource; |
204 | ||
205 | /* | |
206 | * ESB MMIO setting. Can be one page, for both source triggering and | |
207 | * source management, or two different pages. See below for magic | |
208 | * values. | |
209 | */ | |
210 | #define XIVE_ESB_4K 12 /* PSI HB only */ | |
211 | #define XIVE_ESB_4K_2PAGE 13 | |
212 | #define XIVE_ESB_64K 16 | |
213 | #define XIVE_ESB_64K_2PAGE 17 | |
214 | ||
215 | static inline bool xive_source_esb_has_2page(XiveSource *xsrc) | |
216 | { | |
217 | return xsrc->esb_shift == XIVE_ESB_64K_2PAGE || | |
218 | xsrc->esb_shift == XIVE_ESB_4K_2PAGE; | |
219 | } | |
220 | ||
221 | /* The trigger page is always the first/even page */ | |
222 | static inline hwaddr xive_source_esb_page(XiveSource *xsrc, uint32_t srcno) | |
223 | { | |
224 | assert(srcno < xsrc->nr_irqs); | |
225 | return (1ull << xsrc->esb_shift) * srcno; | |
226 | } | |
227 | ||
228 | /* In a two pages ESB MMIO setting, the odd page is for management */ | |
229 | static inline hwaddr xive_source_esb_mgmt(XiveSource *xsrc, int srcno) | |
230 | { | |
231 | hwaddr addr = xive_source_esb_page(xsrc, srcno); | |
232 | ||
233 | if (xive_source_esb_has_2page(xsrc)) { | |
234 | addr += (1 << (xsrc->esb_shift - 1)); | |
235 | } | |
236 | ||
237 | return addr; | |
238 | } | |
239 | ||
240 | /* | |
241 | * Each interrupt source has a 2-bit state machine which can be | |
242 | * controlled by MMIO. P indicates that an interrupt is pending (has | |
243 | * been sent to a queue and is waiting for an EOI). Q indicates that | |
244 | * the interrupt has been triggered while pending. | |
245 | * | |
246 | * This acts as a coalescing mechanism in order to guarantee that a | |
247 | * given interrupt only occurs at most once in a queue. | |
248 | * | |
249 | * When doing an EOI, the Q bit will indicate if the interrupt | |
250 | * needs to be re-triggered. | |
251 | */ | |
5fd9ef18 | 252 | #define XIVE_STATUS_ASSERTED 0x4 /* Extra bit for LSI */ |
02e3ff54 CLG |
253 | #define XIVE_ESB_VAL_P 0x2 |
254 | #define XIVE_ESB_VAL_Q 0x1 | |
255 | ||
256 | #define XIVE_ESB_RESET 0x0 | |
257 | #define XIVE_ESB_PENDING XIVE_ESB_VAL_P | |
258 | #define XIVE_ESB_QUEUED (XIVE_ESB_VAL_P | XIVE_ESB_VAL_Q) | |
259 | #define XIVE_ESB_OFF XIVE_ESB_VAL_Q | |
260 | ||
261 | /* | |
262 | * "magic" Event State Buffer (ESB) MMIO offsets. | |
263 | * | |
264 | * The following offsets into the ESB MMIO allow to read or manipulate | |
265 | * the PQ bits. They must be used with an 8-byte load instruction. | |
266 | * They all return the previous state of the interrupt (atomically). | |
267 | * | |
268 | * Additionally, some ESB pages support doing an EOI via a store and | |
269 | * some ESBs support doing a trigger via a separate trigger page. | |
270 | */ | |
271 | #define XIVE_ESB_STORE_EOI 0x400 /* Store */ | |
272 | #define XIVE_ESB_LOAD_EOI 0x000 /* Load */ | |
273 | #define XIVE_ESB_GET 0x800 /* Load */ | |
274 | #define XIVE_ESB_SET_PQ_00 0xc00 /* Load */ | |
275 | #define XIVE_ESB_SET_PQ_01 0xd00 /* Load */ | |
276 | #define XIVE_ESB_SET_PQ_10 0xe00 /* Load */ | |
277 | #define XIVE_ESB_SET_PQ_11 0xf00 /* Load */ | |
278 | ||
279 | uint8_t xive_source_esb_get(XiveSource *xsrc, uint32_t srcno); | |
280 | uint8_t xive_source_esb_set(XiveSource *xsrc, uint32_t srcno, uint8_t pq); | |
281 | ||
282 | void xive_source_pic_print_info(XiveSource *xsrc, uint32_t offset, | |
283 | Monitor *mon); | |
284 | ||
5fd9ef18 CLG |
285 | static inline bool xive_source_irq_is_lsi(XiveSource *xsrc, uint32_t srcno) |
286 | { | |
287 | assert(srcno < xsrc->nr_irqs); | |
288 | return test_bit(srcno, xsrc->lsi_map); | |
289 | } | |
290 | ||
0afed8c8 | 291 | static inline void xive_source_irq_set_lsi(XiveSource *xsrc, uint32_t srcno) |
5fd9ef18 CLG |
292 | { |
293 | assert(srcno < xsrc->nr_irqs); | |
0afed8c8 | 294 | bitmap_set(xsrc->lsi_map, srcno, 1); |
5fd9ef18 CLG |
295 | } |
296 | ||
734d9c89 CLG |
297 | void xive_source_set_irq(void *opaque, int srcno, int val); |
298 | ||
40a5056c CLG |
299 | /* |
300 | * XIVE Thread interrupt Management (TM) context | |
301 | */ | |
302 | ||
303 | #define TYPE_XIVE_TCTX "xive-tctx" | |
304 | #define XIVE_TCTX(obj) OBJECT_CHECK(XiveTCTX, (obj), TYPE_XIVE_TCTX) | |
305 | ||
306 | /* | |
307 | * XIVE Thread interrupt Management register rings : | |
308 | * | |
309 | * QW-0 User event-based exception state | |
310 | * QW-1 O/S OS context for priority management, interrupt acks | |
311 | * QW-2 Pool hypervisor pool context for virtual processors dispatched | |
312 | * QW-3 Physical physical thread context and security context | |
313 | */ | |
314 | #define XIVE_TM_RING_COUNT 4 | |
315 | #define XIVE_TM_RING_SIZE 0x10 | |
316 | ||
317 | typedef struct XiveTCTX { | |
318 | DeviceState parent_obj; | |
319 | ||
320 | CPUState *cs; | |
4aca9786 BH |
321 | qemu_irq hv_output; |
322 | qemu_irq os_output; | |
40a5056c CLG |
323 | |
324 | uint8_t regs[XIVE_TM_RING_COUNT * XIVE_TM_RING_SIZE]; | |
325 | } XiveTCTX; | |
326 | ||
7ff7ea92 CLG |
327 | /* |
328 | * XIVE Router | |
329 | */ | |
330 | ||
331 | typedef struct XiveRouter { | |
332 | SysBusDevice parent; | |
333 | } XiveRouter; | |
334 | ||
335 | #define TYPE_XIVE_ROUTER "xive-router" | |
336 | #define XIVE_ROUTER(obj) \ | |
337 | OBJECT_CHECK(XiveRouter, (obj), TYPE_XIVE_ROUTER) | |
338 | #define XIVE_ROUTER_CLASS(klass) \ | |
339 | OBJECT_CLASS_CHECK(XiveRouterClass, (klass), TYPE_XIVE_ROUTER) | |
340 | #define XIVE_ROUTER_GET_CLASS(obj) \ | |
341 | OBJECT_GET_CLASS(XiveRouterClass, (obj), TYPE_XIVE_ROUTER) | |
342 | ||
343 | typedef struct XiveRouterClass { | |
344 | SysBusDeviceClass parent; | |
345 | ||
346 | /* XIVE table accessors */ | |
347 | int (*get_eas)(XiveRouter *xrtr, uint8_t eas_blk, uint32_t eas_idx, | |
348 | XiveEAS *eas); | |
e4ddaac6 CLG |
349 | int (*get_end)(XiveRouter *xrtr, uint8_t end_blk, uint32_t end_idx, |
350 | XiveEND *end); | |
351 | int (*write_end)(XiveRouter *xrtr, uint8_t end_blk, uint32_t end_idx, | |
352 | XiveEND *end, uint8_t word_number); | |
af53dbf6 CLG |
353 | int (*get_nvt)(XiveRouter *xrtr, uint8_t nvt_blk, uint32_t nvt_idx, |
354 | XiveNVT *nvt); | |
355 | int (*write_nvt)(XiveRouter *xrtr, uint8_t nvt_blk, uint32_t nvt_idx, | |
356 | XiveNVT *nvt, uint8_t word_number); | |
40a5056c | 357 | XiveTCTX *(*get_tctx)(XiveRouter *xrtr, CPUState *cs); |
7ff7ea92 CLG |
358 | } XiveRouterClass; |
359 | ||
360 | void xive_eas_pic_print_info(XiveEAS *eas, uint32_t lisn, Monitor *mon); | |
361 | ||
362 | int xive_router_get_eas(XiveRouter *xrtr, uint8_t eas_blk, uint32_t eas_idx, | |
363 | XiveEAS *eas); | |
e4ddaac6 CLG |
364 | int xive_router_get_end(XiveRouter *xrtr, uint8_t end_blk, uint32_t end_idx, |
365 | XiveEND *end); | |
366 | int xive_router_write_end(XiveRouter *xrtr, uint8_t end_blk, uint32_t end_idx, | |
367 | XiveEND *end, uint8_t word_number); | |
af53dbf6 CLG |
368 | int xive_router_get_nvt(XiveRouter *xrtr, uint8_t nvt_blk, uint32_t nvt_idx, |
369 | XiveNVT *nvt); | |
370 | int xive_router_write_nvt(XiveRouter *xrtr, uint8_t nvt_blk, uint32_t nvt_idx, | |
371 | XiveNVT *nvt, uint8_t word_number); | |
40a5056c | 372 | XiveTCTX *xive_router_get_tctx(XiveRouter *xrtr, CPUState *cs); |
a58a18ad | 373 | void xive_router_notify(XiveNotifier *xn, uint32_t lisn); |
e4ddaac6 | 374 | |
002686be CLG |
375 | /* |
376 | * XIVE END ESBs | |
377 | */ | |
378 | ||
379 | #define TYPE_XIVE_END_SOURCE "xive-end-source" | |
380 | #define XIVE_END_SOURCE(obj) \ | |
381 | OBJECT_CHECK(XiveENDSource, (obj), TYPE_XIVE_END_SOURCE) | |
382 | ||
383 | typedef struct XiveENDSource { | |
384 | DeviceState parent; | |
385 | ||
386 | uint32_t nr_ends; | |
387 | uint8_t block_id; | |
388 | ||
389 | /* ESB memory region */ | |
390 | uint32_t esb_shift; | |
391 | MemoryRegion esb_mmio; | |
392 | ||
393 | XiveRouter *xrtr; | |
394 | } XiveENDSource; | |
395 | ||
e4ddaac6 CLG |
396 | /* |
397 | * For legacy compatibility, the exceptions define up to 256 different | |
398 | * priorities. P9 implements only 9 levels : 8 active levels [0 - 7] | |
399 | * and the least favored level 0xFF. | |
400 | */ | |
401 | #define XIVE_PRIORITY_MAX 7 | |
402 | ||
403 | void xive_end_pic_print_info(XiveEND *end, uint32_t end_idx, Monitor *mon); | |
404 | void xive_end_queue_pic_print_info(XiveEND *end, uint32_t width, Monitor *mon); | |
7ff7ea92 | 405 | |
207d9fe9 CLG |
406 | /* |
407 | * XIVE Thread Interrupt Management Aera (TIMA) | |
408 | * | |
409 | * This region gives access to the registers of the thread interrupt | |
410 | * management context. It is four page wide, each page providing a | |
411 | * different view of the registers. The page with the lower offset is | |
412 | * the most privileged and gives access to the entire context. | |
413 | */ | |
414 | #define XIVE_TM_HW_PAGE 0x0 | |
415 | #define XIVE_TM_HV_PAGE 0x1 | |
416 | #define XIVE_TM_OS_PAGE 0x2 | |
417 | #define XIVE_TM_USER_PAGE 0x3 | |
418 | ||
419 | extern const MemoryRegionOps xive_tm_ops; | |
f9b9db38 CLG |
420 | void xive_tctx_tm_write(XiveTCTX *tctx, hwaddr offset, uint64_t value, |
421 | unsigned size); | |
422 | uint64_t xive_tctx_tm_read(XiveTCTX *tctx, hwaddr offset, unsigned size); | |
207d9fe9 CLG |
423 | |
424 | void xive_tctx_pic_print_info(XiveTCTX *tctx, Monitor *mon); | |
1a937ad7 | 425 | Object *xive_tctx_create(Object *cpu, XiveRouter *xrtr, Error **errp); |
207d9fe9 | 426 | |
af53dbf6 CLG |
427 | static inline uint32_t xive_nvt_cam_line(uint8_t nvt_blk, uint32_t nvt_idx) |
428 | { | |
429 | return (nvt_blk << 19) | nvt_idx; | |
430 | } | |
431 | ||
38afd772 CLG |
432 | /* |
433 | * KVM XIVE device helpers | |
434 | */ | |
435 | ||
436 | void kvmppc_xive_source_reset_one(XiveSource *xsrc, int srcno, Error **errp); | |
38afd772 CLG |
437 | void kvmppc_xive_source_set_irq(void *opaque, int srcno, int val); |
438 | void kvmppc_xive_cpu_connect(XiveTCTX *tctx, Error **errp); | |
7bfc759c | 439 | void kvmppc_xive_cpu_synchronize_state(XiveTCTX *tctx, Error **errp); |
277dd3d7 | 440 | void kvmppc_xive_cpu_get_state(XiveTCTX *tctx, Error **errp); |
38afd772 | 441 | |
02e3ff54 | 442 | #endif /* PPC_XIVE_H */ |