2 * QEMU PowerPC pSeries Logical Partition (aka sPAPR) hardware System Emulator
4 * PAPR Virtualized Interrupt System, aka ICS/ICP aka xics
6 * Copyright (c) 2010,2011 David Gibson, IBM Corporation.
8 * Permission is hereby granted, free of charge, to any person obtaining a copy
9 * of this software and associated documentation files (the "Software"), to deal
10 * in the Software without restriction, including without limitation the rights
11 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
12 * copies of the Software, and to permit persons to whom the Software is
13 * furnished to do so, subject to the following conditions:
15 * The above copyright notice and this permission notice shall be included in
16 * all copies or substantial portions of the Software.
18 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
19 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
20 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
21 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
22 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
23 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
28 #include "qemu/osdep.h"
30 #include "qemu/timer.h"
31 #include "hw/ppc/spapr.h"
32 #include "hw/ppc/spapr_cpu_core.h"
33 #include "hw/ppc/xics.h"
34 #include "hw/ppc/xics_spapr.h"
35 #include "hw/ppc/fdt.h"
36 #include "qapi/visitor.h"
42 static bool check_emulated_xics(SpaprMachineState
*spapr
, const char *func
)
44 if (spapr_ovec_test(spapr
->ov5_cas
, OV5_XIVE_EXPLOIT
) ||
45 kvm_irqchip_in_kernel()) {
46 error_report("pseries: %s must only be called for emulated XICS",
54 #define CHECK_EMULATED_XICS_HCALL(spapr) \
56 if (!check_emulated_xics((spapr), __func__)) { \
61 static target_ulong
h_cppr(PowerPCCPU
*cpu
, SpaprMachineState
*spapr
,
62 target_ulong opcode
, target_ulong
*args
)
64 target_ulong cppr
= args
[0];
66 CHECK_EMULATED_XICS_HCALL(spapr
);
68 icp_set_cppr(spapr_cpu_state(cpu
)->icp
, cppr
);
72 static target_ulong
h_ipi(PowerPCCPU
*cpu
, SpaprMachineState
*spapr
,
73 target_ulong opcode
, target_ulong
*args
)
75 target_ulong mfrr
= args
[1];
76 ICPState
*icp
= xics_icp_get(XICS_FABRIC(spapr
), args
[0]);
78 CHECK_EMULATED_XICS_HCALL(spapr
);
84 icp_set_mfrr(icp
, mfrr
);
88 static target_ulong
h_xirr(PowerPCCPU
*cpu
, SpaprMachineState
*spapr
,
89 target_ulong opcode
, target_ulong
*args
)
91 uint32_t xirr
= icp_accept(spapr_cpu_state(cpu
)->icp
);
93 CHECK_EMULATED_XICS_HCALL(spapr
);
99 static target_ulong
h_xirr_x(PowerPCCPU
*cpu
, SpaprMachineState
*spapr
,
100 target_ulong opcode
, target_ulong
*args
)
102 uint32_t xirr
= icp_accept(spapr_cpu_state(cpu
)->icp
);
104 CHECK_EMULATED_XICS_HCALL(spapr
);
107 args
[1] = cpu_get_host_ticks();
111 static target_ulong
h_eoi(PowerPCCPU
*cpu
, SpaprMachineState
*spapr
,
112 target_ulong opcode
, target_ulong
*args
)
114 target_ulong xirr
= args
[0];
116 CHECK_EMULATED_XICS_HCALL(spapr
);
118 icp_eoi(spapr_cpu_state(cpu
)->icp
, xirr
);
122 static target_ulong
h_ipoll(PowerPCCPU
*cpu
, SpaprMachineState
*spapr
,
123 target_ulong opcode
, target_ulong
*args
)
125 ICPState
*icp
= xics_icp_get(XICS_FABRIC(spapr
), args
[0]);
129 CHECK_EMULATED_XICS_HCALL(spapr
);
135 xirr
= icp_ipoll(icp
, &mfrr
);
143 #define CHECK_EMULATED_XICS_RTAS(spapr, rets) \
145 if (!check_emulated_xics((spapr), __func__)) { \
146 rtas_st((rets), 0, RTAS_OUT_HW_ERROR); \
151 static void rtas_set_xive(PowerPCCPU
*cpu
, SpaprMachineState
*spapr
,
153 uint32_t nargs
, target_ulong args
,
154 uint32_t nret
, target_ulong rets
)
156 ICSState
*ics
= spapr
->ics
;
157 uint32_t nr
, srcno
, server
, priority
;
159 CHECK_EMULATED_XICS_RTAS(spapr
, rets
);
161 if ((nargs
!= 3) || (nret
!= 1)) {
162 rtas_st(rets
, 0, RTAS_OUT_PARAM_ERROR
);
166 rtas_st(rets
, 0, RTAS_OUT_HW_ERROR
);
170 nr
= rtas_ld(args
, 0);
171 server
= rtas_ld(args
, 1);
172 priority
= rtas_ld(args
, 2);
174 if (!ics_valid_irq(ics
, nr
) || !xics_icp_get(XICS_FABRIC(spapr
), server
)
175 || (priority
> 0xff)) {
176 rtas_st(rets
, 0, RTAS_OUT_PARAM_ERROR
);
180 srcno
= nr
- ics
->offset
;
181 ics_write_xive(ics
, srcno
, server
, priority
, priority
);
183 rtas_st(rets
, 0, RTAS_OUT_SUCCESS
);
186 static void rtas_get_xive(PowerPCCPU
*cpu
, SpaprMachineState
*spapr
,
188 uint32_t nargs
, target_ulong args
,
189 uint32_t nret
, target_ulong rets
)
191 ICSState
*ics
= spapr
->ics
;
194 CHECK_EMULATED_XICS_RTAS(spapr
, rets
);
196 if ((nargs
!= 1) || (nret
!= 3)) {
197 rtas_st(rets
, 0, RTAS_OUT_PARAM_ERROR
);
201 rtas_st(rets
, 0, RTAS_OUT_HW_ERROR
);
205 nr
= rtas_ld(args
, 0);
207 if (!ics_valid_irq(ics
, nr
)) {
208 rtas_st(rets
, 0, RTAS_OUT_PARAM_ERROR
);
212 rtas_st(rets
, 0, RTAS_OUT_SUCCESS
);
213 srcno
= nr
- ics
->offset
;
214 rtas_st(rets
, 1, ics
->irqs
[srcno
].server
);
215 rtas_st(rets
, 2, ics
->irqs
[srcno
].priority
);
218 static void rtas_int_off(PowerPCCPU
*cpu
, SpaprMachineState
*spapr
,
220 uint32_t nargs
, target_ulong args
,
221 uint32_t nret
, target_ulong rets
)
223 ICSState
*ics
= spapr
->ics
;
226 CHECK_EMULATED_XICS_RTAS(spapr
, rets
);
228 if ((nargs
!= 1) || (nret
!= 1)) {
229 rtas_st(rets
, 0, RTAS_OUT_PARAM_ERROR
);
233 rtas_st(rets
, 0, RTAS_OUT_HW_ERROR
);
237 nr
= rtas_ld(args
, 0);
239 if (!ics_valid_irq(ics
, nr
)) {
240 rtas_st(rets
, 0, RTAS_OUT_PARAM_ERROR
);
244 srcno
= nr
- ics
->offset
;
245 ics_write_xive(ics
, srcno
, ics
->irqs
[srcno
].server
, 0xff,
246 ics
->irqs
[srcno
].priority
);
248 rtas_st(rets
, 0, RTAS_OUT_SUCCESS
);
251 static void rtas_int_on(PowerPCCPU
*cpu
, SpaprMachineState
*spapr
,
253 uint32_t nargs
, target_ulong args
,
254 uint32_t nret
, target_ulong rets
)
256 ICSState
*ics
= spapr
->ics
;
259 CHECK_EMULATED_XICS_RTAS(spapr
, rets
);
261 if ((nargs
!= 1) || (nret
!= 1)) {
262 rtas_st(rets
, 0, RTAS_OUT_PARAM_ERROR
);
266 rtas_st(rets
, 0, RTAS_OUT_HW_ERROR
);
270 nr
= rtas_ld(args
, 0);
272 if (!ics_valid_irq(ics
, nr
)) {
273 rtas_st(rets
, 0, RTAS_OUT_PARAM_ERROR
);
277 srcno
= nr
- ics
->offset
;
278 ics_write_xive(ics
, srcno
, ics
->irqs
[srcno
].server
,
279 ics
->irqs
[srcno
].saved_priority
,
280 ics
->irqs
[srcno
].saved_priority
);
282 rtas_st(rets
, 0, RTAS_OUT_SUCCESS
);
285 static void ics_spapr_realize(DeviceState
*dev
, Error
**errp
)
287 ICSState
*ics
= ICS_SPAPR(dev
);
288 ICSStateClass
*icsc
= ICS_GET_CLASS(ics
);
289 Error
*local_err
= NULL
;
291 icsc
->parent_realize(dev
, &local_err
);
293 error_propagate(errp
, local_err
);
297 spapr_rtas_register(RTAS_IBM_SET_XIVE
, "ibm,set-xive", rtas_set_xive
);
298 spapr_rtas_register(RTAS_IBM_GET_XIVE
, "ibm,get-xive", rtas_get_xive
);
299 spapr_rtas_register(RTAS_IBM_INT_OFF
, "ibm,int-off", rtas_int_off
);
300 spapr_rtas_register(RTAS_IBM_INT_ON
, "ibm,int-on", rtas_int_on
);
302 spapr_register_hypercall(H_CPPR
, h_cppr
);
303 spapr_register_hypercall(H_IPI
, h_ipi
);
304 spapr_register_hypercall(H_XIRR
, h_xirr
);
305 spapr_register_hypercall(H_XIRR_X
, h_xirr_x
);
306 spapr_register_hypercall(H_EOI
, h_eoi
);
307 spapr_register_hypercall(H_IPOLL
, h_ipoll
);
310 static void xics_spapr_dt(SpaprInterruptController
*intc
, uint32_t nr_servers
,
311 void *fdt
, uint32_t phandle
)
313 uint32_t interrupt_server_ranges_prop
[] = {
314 0, cpu_to_be32(nr_servers
),
318 _FDT(node
= fdt_add_subnode(fdt
, 0, "interrupt-controller"));
320 _FDT(fdt_setprop_string(fdt
, node
, "device_type",
321 "PowerPC-External-Interrupt-Presentation"));
322 _FDT(fdt_setprop_string(fdt
, node
, "compatible", "IBM,ppc-xicp"));
323 _FDT(fdt_setprop(fdt
, node
, "interrupt-controller", NULL
, 0));
324 _FDT(fdt_setprop(fdt
, node
, "ibm,interrupt-server-ranges",
325 interrupt_server_ranges_prop
,
326 sizeof(interrupt_server_ranges_prop
)));
327 _FDT(fdt_setprop_cell(fdt
, node
, "#interrupt-cells", 2));
328 _FDT(fdt_setprop_cell(fdt
, node
, "linux,phandle", phandle
));
329 _FDT(fdt_setprop_cell(fdt
, node
, "phandle", phandle
));
332 static int xics_spapr_cpu_intc_create(SpaprInterruptController
*intc
,
333 PowerPCCPU
*cpu
, Error
**errp
)
335 ICSState
*ics
= ICS_SPAPR(intc
);
337 SpaprCpuState
*spapr_cpu
= spapr_cpu_state(cpu
);
339 obj
= icp_create(OBJECT(cpu
), TYPE_ICP
, ics
->xics
, errp
);
344 spapr_cpu
->icp
= ICP(obj
);
348 static void xics_spapr_cpu_intc_reset(SpaprInterruptController
*intc
,
351 icp_reset(spapr_cpu_state(cpu
)->icp
);
354 static void xics_spapr_cpu_intc_destroy(SpaprInterruptController
*intc
,
357 SpaprCpuState
*spapr_cpu
= spapr_cpu_state(cpu
);
359 icp_destroy(spapr_cpu
->icp
);
360 spapr_cpu
->icp
= NULL
;
363 static int xics_spapr_claim_irq(SpaprInterruptController
*intc
, int irq
,
364 bool lsi
, Error
**errp
)
366 ICSState
*ics
= ICS_SPAPR(intc
);
369 assert(ics_valid_irq(ics
, irq
));
371 if (!ics_irq_free(ics
, irq
- ics
->offset
)) {
372 error_setg(errp
, "IRQ %d is not free", irq
);
376 ics_set_irq_type(ics
, irq
- ics
->offset
, lsi
);
380 static void xics_spapr_free_irq(SpaprInterruptController
*intc
, int irq
)
382 ICSState
*ics
= ICS_SPAPR(intc
);
383 uint32_t srcno
= irq
- ics
->offset
;
385 assert(ics_valid_irq(ics
, irq
));
387 memset(&ics
->irqs
[srcno
], 0, sizeof(ICSIRQState
));
390 static void xics_spapr_set_irq(SpaprInterruptController
*intc
, int irq
, int val
)
392 ICSState
*ics
= ICS_SPAPR(intc
);
393 uint32_t srcno
= irq
- ics
->offset
;
395 ics_set_irq(ics
, srcno
, val
);
398 static void xics_spapr_print_info(SpaprInterruptController
*intc
, Monitor
*mon
)
400 ICSState
*ics
= ICS_SPAPR(intc
);
404 PowerPCCPU
*cpu
= POWERPC_CPU(cs
);
406 icp_pic_print_info(spapr_cpu_state(cpu
)->icp
, mon
);
409 ics_pic_print_info(ics
, mon
);
412 static int xics_spapr_post_load(SpaprInterruptController
*intc
, int version_id
)
414 if (!kvm_irqchip_in_kernel()) {
417 PowerPCCPU
*cpu
= POWERPC_CPU(cs
);
418 icp_resend(spapr_cpu_state(cpu
)->icp
);
424 static int xics_spapr_activate(SpaprInterruptController
*intc
,
425 uint32_t nr_servers
, Error
**errp
)
428 return spapr_irq_init_kvm(xics_kvm_connect
, intc
, nr_servers
, errp
);
433 static void xics_spapr_deactivate(SpaprInterruptController
*intc
)
435 if (kvm_irqchip_in_kernel()) {
436 xics_kvm_disconnect(intc
);
440 static void ics_spapr_class_init(ObjectClass
*klass
, void *data
)
442 DeviceClass
*dc
= DEVICE_CLASS(klass
);
443 ICSStateClass
*isc
= ICS_CLASS(klass
);
444 SpaprInterruptControllerClass
*sicc
= SPAPR_INTC_CLASS(klass
);
446 device_class_set_parent_realize(dc
, ics_spapr_realize
,
447 &isc
->parent_realize
);
448 sicc
->activate
= xics_spapr_activate
;
449 sicc
->deactivate
= xics_spapr_deactivate
;
450 sicc
->cpu_intc_create
= xics_spapr_cpu_intc_create
;
451 sicc
->cpu_intc_reset
= xics_spapr_cpu_intc_reset
;
452 sicc
->cpu_intc_destroy
= xics_spapr_cpu_intc_destroy
;
453 sicc
->claim_irq
= xics_spapr_claim_irq
;
454 sicc
->free_irq
= xics_spapr_free_irq
;
455 sicc
->set_irq
= xics_spapr_set_irq
;
456 sicc
->print_info
= xics_spapr_print_info
;
457 sicc
->dt
= xics_spapr_dt
;
458 sicc
->post_load
= xics_spapr_post_load
;
461 static const TypeInfo ics_spapr_info
= {
462 .name
= TYPE_ICS_SPAPR
,
464 .class_init
= ics_spapr_class_init
,
465 .interfaces
= (InterfaceInfo
[]) {
471 static void xics_spapr_register_types(void)
473 type_register_static(&ics_spapr_info
);
476 type_init(xics_spapr_register_types
)