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; return -1;
} }
void xics_cpu_destroy(XICSState *xics, PowerPCCPU *cpu) void xics_cpu_destroy(XICSFabric *xi, PowerPCCPU *cpu)
{ {
CPUState *cs = CPU(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); assert(cs == ss->cs);
ss->output = NULL; ss->output = NULL;
ss->cs = NULL; ss->cs = NULL;
} }
void xics_cpu_setup(XICSState *xics, PowerPCCPU *cpu) void xics_cpu_setup(XICSFabric *xi, PowerPCCPU *cpu)
{ {
CPUState *cs = CPU(cpu); CPUState *cs = CPU(cpu);
CPUPPCState *env = &cpu->env; CPUPPCState *env = &cpu->env;
ICPState *ss = &xics->ss[cs->cpu_index]; ICPState *ss = xics_icp_get(xi, cs->cpu_index);
ICPStateClass *icpc; ICPStateClass *icpc;
assert(cs->cpu_index < xics->nr_servers); assert(ss);
ss->cs = cs; 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) static void icp_irq(ICSState *ics, int server, int nr, uint8_t priority)
{ {
XICSState *xics = ics->xics; ICPState *ss = xics_icp_get(ics->xics, server);
ICPState *ss = xics->ss + server;
trace_xics_icp_irq(server, nr, priority); 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) static int ics_simple_post_load(ICSState *ics, int version_id)
{ {
int i; XICSFabric *xi = ics->xics;
XICSFabricClass *xic = XICS_FABRIC_GET_CLASS(xi);
for (i = 0; i < ics->xics->nr_servers; i++) {
icp_resend(&ics->xics->ss[i]);
}
xic->icp_resend(xi);
return 0; return 0;
} }
@ -711,7 +708,7 @@ static void ics_base_realize(DeviceState *dev, Error **errp)
__func__, error_get_pretty(err)); __func__, error_get_pretty(err));
return; return;
} }
ics->xics = XICS_COMMON(obj); ics->xics = XICS_FABRIC(obj);
if (icsc->realize) { if (icsc->realize) {
@ -756,6 +753,13 @@ qemu_irq xics_get_qirq(XICSFabric *xi, int irq)
return NULL; 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) void ics_set_irq_type(ICSState *ics, int srcno, bool lsi)
{ {
assert(!(ics->irqs[srcno].flags & XICS_FLAGS_IRQ_MASK)); 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) target_ulong opcode, target_ulong *args)
{ {
CPUState *cs = CPU(cpu); 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]; target_ulong cppr = args[0];
icp_set_cppr(icp, cppr); 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 server = xics_get_cpu_index_by_dt_id(args[0]);
target_ulong mfrr = args[1]; 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; return H_PARAMETER;
} }
icp_set_mfrr(spapr->xics->ss + server, mfrr); icp_set_mfrr(icp, mfrr);
return H_SUCCESS; return H_SUCCESS;
} }
@ -69,7 +70,7 @@ static target_ulong h_xirr(PowerPCCPU *cpu, sPAPRMachineState *spapr,
target_ulong opcode, target_ulong *args) target_ulong opcode, target_ulong *args)
{ {
CPUState *cs = CPU(cpu); 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); uint32_t xirr = icp_accept(icp);
args[0] = xirr; args[0] = xirr;
@ -80,7 +81,7 @@ static target_ulong h_xirr_x(PowerPCCPU *cpu, sPAPRMachineState *spapr,
target_ulong opcode, target_ulong *args) target_ulong opcode, target_ulong *args)
{ {
CPUState *cs = CPU(cpu); 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); uint32_t xirr = icp_accept(icp);
args[0] = xirr; args[0] = xirr;
@ -92,7 +93,7 @@ static target_ulong h_eoi(PowerPCCPU *cpu, sPAPRMachineState *spapr,
target_ulong opcode, target_ulong *args) target_ulong opcode, target_ulong *args)
{ {
CPUState *cs = CPU(cpu); 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]; target_ulong xirr = args[0];
icp_eoi(icp, xirr); icp_eoi(icp, xirr);
@ -103,7 +104,7 @@ static target_ulong h_ipoll(PowerPCCPU *cpu, sPAPRMachineState *spapr,
target_ulong opcode, target_ulong *args) target_ulong opcode, target_ulong *args)
{ {
CPUState *cs = CPU(cpu); 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 mfrr;
uint32_t xirr = icp_ipoll(icp, &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)); server = xics_get_cpu_index_by_dt_id(rtas_ld(args, 1));
priority = rtas_ld(args, 2); 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)) { || (priority > 0xff)) {
rtas_st(rets, 0, RTAS_OUT_PARAM_ERROR); rtas_st(rets, 0, RTAS_OUT_PARAM_ERROR);
return; return;

View File

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

View File

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

View File

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