mirror of
https://github.com/qemu/qemu.git
synced 2025-08-09 19:15:32 +00:00
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:
parent
f023243432
commit
b4f27d71e3
@ -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));
|
||||||
|
@ -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;
|
||||||
|
@ -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) {
|
||||||
|
@ -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);
|
||||||
|
@ -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);
|
||||||
|
Loading…
Reference in New Issue
Block a user