ppc/xics: use the QOM interface to grab an ICP

Also introduce a xics_icp_get() helper to simplify the changes.

Signed-off-by: Cédric Le Goater <clg@kaod.org>
Signed-off-by: David Gibson <david@gibson.dropbear.id.au>
This commit is contained in:
Cédric Le Goater 2017-02-27 15:29:25 +01:00 committed by David Gibson
parent f023243432
commit b4f27d71e3
5 changed files with 35 additions and 30 deletions

View File

@ -49,26 +49,26 @@ int xics_get_cpu_index_by_dt_id(int cpu_dt_id)
return -1;
}
void xics_cpu_destroy(XICSState *xics, PowerPCCPU *cpu)
void xics_cpu_destroy(XICSFabric *xi, PowerPCCPU *cpu)
{
CPUState *cs = CPU(cpu);
ICPState *ss = &xics->ss[cs->cpu_index];
ICPState *ss = xics_icp_get(xi, cs->cpu_index);
assert(cs->cpu_index < xics->nr_servers);
assert(ss);
assert(cs == ss->cs);
ss->output = NULL;
ss->cs = NULL;
}
void xics_cpu_setup(XICSState *xics, PowerPCCPU *cpu)
void xics_cpu_setup(XICSFabric *xi, PowerPCCPU *cpu)
{
CPUState *cs = CPU(cpu);
CPUPPCState *env = &cpu->env;
ICPState *ss = &xics->ss[cs->cpu_index];
ICPState *ss = xics_icp_get(xi, cs->cpu_index);
ICPStateClass *icpc;
assert(cs->cpu_index < xics->nr_servers);
assert(ss);
ss->cs = cs;
@ -308,8 +308,7 @@ void icp_eoi(ICPState *ss, uint32_t xirr)
static void icp_irq(ICSState *ics, int server, int nr, uint8_t priority)
{
XICSState *xics = ics->xics;
ICPState *ss = xics->ss + server;
ICPState *ss = xics_icp_get(ics->xics, server);
trace_xics_icp_irq(server, nr, priority);
@ -582,12 +581,10 @@ static void ics_simple_reset(DeviceState *dev)
static int ics_simple_post_load(ICSState *ics, int version_id)
{
int i;
for (i = 0; i < ics->xics->nr_servers; i++) {
icp_resend(&ics->xics->ss[i]);
}
XICSFabric *xi = ics->xics;
XICSFabricClass *xic = XICS_FABRIC_GET_CLASS(xi);
xic->icp_resend(xi);
return 0;
}
@ -711,7 +708,7 @@ static void ics_base_realize(DeviceState *dev, Error **errp)
__func__, error_get_pretty(err));
return;
}
ics->xics = XICS_COMMON(obj);
ics->xics = XICS_FABRIC(obj);
if (icsc->realize) {
@ -756,6 +753,13 @@ qemu_irq xics_get_qirq(XICSFabric *xi, int irq)
return NULL;
}
ICPState *xics_icp_get(XICSFabric *xi, int server)
{
XICSFabricClass *xic = XICS_FABRIC_GET_CLASS(xi);
return xic->icp_get(xi, server);
}
void ics_set_irq_type(ICSState *ics, int srcno, bool lsi)
{
assert(!(ics->irqs[srcno].flags & XICS_FLAGS_IRQ_MASK));

View File

@ -44,7 +44,7 @@ static target_ulong h_cppr(PowerPCCPU *cpu, sPAPRMachineState *spapr,
target_ulong opcode, target_ulong *args)
{
CPUState *cs = CPU(cpu);
ICPState *icp = &spapr->xics->ss[cs->cpu_index];
ICPState *icp = xics_icp_get(XICS_FABRIC(spapr), cs->cpu_index);
target_ulong cppr = args[0];
icp_set_cppr(icp, cppr);
@ -56,12 +56,13 @@ static target_ulong h_ipi(PowerPCCPU *cpu, sPAPRMachineState *spapr,
{
target_ulong server = xics_get_cpu_index_by_dt_id(args[0]);
target_ulong mfrr = args[1];
ICPState *icp = xics_icp_get(XICS_FABRIC(spapr), server);
if (server >= spapr->xics->nr_servers) {
if (!icp) {
return H_PARAMETER;
}
icp_set_mfrr(spapr->xics->ss + server, mfrr);
icp_set_mfrr(icp, mfrr);
return H_SUCCESS;
}
@ -69,7 +70,7 @@ static target_ulong h_xirr(PowerPCCPU *cpu, sPAPRMachineState *spapr,
target_ulong opcode, target_ulong *args)
{
CPUState *cs = CPU(cpu);
ICPState *icp = &spapr->xics->ss[cs->cpu_index];
ICPState *icp = xics_icp_get(XICS_FABRIC(spapr), cs->cpu_index);
uint32_t xirr = icp_accept(icp);
args[0] = xirr;
@ -80,7 +81,7 @@ static target_ulong h_xirr_x(PowerPCCPU *cpu, sPAPRMachineState *spapr,
target_ulong opcode, target_ulong *args)
{
CPUState *cs = CPU(cpu);
ICPState *icp = &spapr->xics->ss[cs->cpu_index];
ICPState *icp = xics_icp_get(XICS_FABRIC(spapr), cs->cpu_index);
uint32_t xirr = icp_accept(icp);
args[0] = xirr;
@ -92,7 +93,7 @@ static target_ulong h_eoi(PowerPCCPU *cpu, sPAPRMachineState *spapr,
target_ulong opcode, target_ulong *args)
{
CPUState *cs = CPU(cpu);
ICPState *icp = &spapr->xics->ss[cs->cpu_index];
ICPState *icp = xics_icp_get(XICS_FABRIC(spapr), cs->cpu_index);
target_ulong xirr = args[0];
icp_eoi(icp, xirr);
@ -103,7 +104,7 @@ static target_ulong h_ipoll(PowerPCCPU *cpu, sPAPRMachineState *spapr,
target_ulong opcode, target_ulong *args)
{
CPUState *cs = CPU(cpu);
ICPState *icp = &spapr->xics->ss[cs->cpu_index];
ICPState *icp = xics_icp_get(XICS_FABRIC(spapr), cs->cpu_index);
uint32_t mfrr;
uint32_t xirr = icp_ipoll(icp, &mfrr);
@ -134,7 +135,7 @@ static void rtas_set_xive(PowerPCCPU *cpu, sPAPRMachineState *spapr,
server = xics_get_cpu_index_by_dt_id(rtas_ld(args, 1));
priority = rtas_ld(args, 2);
if (!ics_valid_irq(ics, nr) || (server >= ics->xics->nr_servers)
if (!ics_valid_irq(ics, nr) || !xics_icp_get(XICS_FABRIC(spapr), server)
|| (priority > 0xff)) {
rtas_st(rets, 0, RTAS_OUT_PARAM_ERROR);
return;

View File

@ -117,7 +117,7 @@ static XICSState *try_create_xics(sPAPRMachineState *spapr,
qdev_set_parent_bus(DEVICE(ics), sysbus_get_default());
object_property_add_child(OBJECT(spapr), "ics", OBJECT(ics), NULL);
object_property_set_int(OBJECT(ics), nr_irqs, "nr-irqs", &err);
object_property_add_const_link(OBJECT(ics), "xics", OBJECT(xics), NULL);
object_property_add_const_link(OBJECT(ics), "xics", OBJECT(xi), NULL);
object_property_set_bool(OBJECT(ics), true, "realized", &local_err);
error_propagate(&err, local_err);
if (err) {

View File

@ -55,7 +55,7 @@ static void spapr_cpu_destroy(PowerPCCPU *cpu)
{
sPAPRMachineState *spapr = SPAPR_MACHINE(qdev_get_machine());
xics_cpu_destroy(spapr->xics, cpu);
xics_cpu_destroy(XICS_FABRIC(spapr), cpu);
qemu_unregister_reset(spapr_cpu_reset, cpu);
}
@ -88,7 +88,7 @@ static void spapr_cpu_init(sPAPRMachineState *spapr, PowerPCCPU *cpu,
cs->numa_node = i;
}
xics_cpu_setup(spapr->xics, cpu);
xics_cpu_setup(XICS_FABRIC(spapr), cpu);
qemu_register_reset(spapr_cpu_reset, cpu);
spapr_cpu_reset(cpu);

View File

@ -151,7 +151,7 @@ struct ICSState {
uint32_t offset;
qemu_irq *qirqs;
ICSIRQState *irqs;
XICSState *xics;
XICSFabric *xics;
};
static inline bool ics_valid_irq(ICSState *ics, uint32_t nr)
@ -198,16 +198,16 @@ typedef struct XICSFabricClass {
#define XICS_IRQS_SPAPR 1024
qemu_irq xics_get_qirq(XICSFabric *xi, int irq);
int spapr_ics_alloc(ICSState *ics, int irq_hint, bool lsi, Error **errp);
int spapr_ics_alloc_block(ICSState *ics, int num, bool lsi, bool align,
Error **errp);
void spapr_ics_free(ICSState *ics, int irq, int num);
void spapr_dt_xics(XICSState *xics, void *fdt, uint32_t phandle);
void xics_cpu_setup(XICSState *icp, PowerPCCPU *cpu);
void xics_cpu_destroy(XICSState *icp, PowerPCCPU *cpu);
qemu_irq xics_get_qirq(XICSFabric *xi, int irq);
ICPState *xics_icp_get(XICSFabric *xi, int server);
void xics_cpu_setup(XICSFabric *xi, PowerPCCPU *cpu);
void xics_cpu_destroy(XICSFabric *xi, PowerPCCPU *cpu);
/* Internal XICS interfaces */
int xics_get_cpu_index_by_dt_id(int cpu_dt_id);