[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[Qemu-ppc] [PATCH v1 09/11] ppc/xics: Split ICS into ics-base and ics cl
From: |
Nikunj A Dadhania |
Subject: |
[Qemu-ppc] [PATCH v1 09/11] ppc/xics: Split ICS into ics-base and ics class |
Date: |
Thu, 23 Jun 2016 23:17:28 +0530 |
From: Benjamin Herrenschmidt <address@hidden>
The existing implementation remains same and ics-base is introduced.
This will allow different implementations for the source controllers
such as the MSI support of PHB3 on Power8 which uses in-memory state
tables for example.
Signed-off-by: Benjamin Herrenschmidt <address@hidden>
Signed-off-by: Nikunj A Dadhania <address@hidden>
---
hw/intc/xics.c | 101 +++++++++++++++++++++++++++++++++-----------------
hw/intc/xics_spapr.c | 36 ++++++++++--------
include/hw/ppc/xics.h | 11 +++++-
3 files changed, 97 insertions(+), 51 deletions(-)
diff --git a/hw/intc/xics.c b/hw/intc/xics.c
index 326d21f..e2aa48d 100644
--- a/hw/intc/xics.c
+++ b/hw/intc/xics.c
@@ -220,9 +220,32 @@ static const TypeInfo xics_common_info = {
#define XISR(ss) (((ss)->xirr) & XISR_MASK)
#define CPPR(ss) (((ss)->xirr) >> 24)
-static void ics_reject(ICSState *ics, int nr);
-static void ics_resend(ICSState *ics);
-static void ics_eoi(ICSState *ics, int nr);
+static void ics_base_reject(ICSState *ics, uint32_t nr)
+{
+ ICSStateClass *k = ICS_GET_CLASS(ics);
+
+ if (k->reject) {
+ k->reject(ics, nr);
+ }
+}
+
+static void ics_base_resend(ICSState *ics)
+{
+ ICSStateClass *k = ICS_GET_CLASS(ics);
+
+ if (k->resend) {
+ k->resend(ics);
+ }
+}
+
+static void ics_base_eoi(ICSState *ics, int nr)
+{
+ ICSStateClass *k = ICS_GET_CLASS(ics);
+
+ if (k->eoi) {
+ k->eoi(ics, nr);
+ }
+}
static void icp_check_ipi(ICPState *ss, int server)
{
@@ -233,7 +256,7 @@ static void icp_check_ipi(ICPState *ss, int server)
trace_xics_icp_check_ipi(server, ss->mfrr);
if (XISR(ss) && ss->xirr_owner) {
- ics_reject(ss->xirr_owner, XISR(ss));
+ ics_base_reject(ss->xirr_owner, XISR(ss));
}
ss->xirr = (ss->xirr & ~XISR_MASK) | XICS_IPI;
@@ -251,7 +274,7 @@ static void icp_resend(XICSState *xics, int server)
icp_check_ipi(ss, server);
}
QLIST_FOREACH(ics, &xics->ics, list) {
- ics_resend(ics);
+ ics_base_resend(ics);
}
}
@@ -271,7 +294,7 @@ void icp_set_cppr(XICSState *xics, int server, uint8_t cppr)
ss->pending_priority = 0xff;
qemu_irq_lower(ss->output);
if (ss->xirr_owner) {
- ics_reject(ss->xirr_owner, old_xisr);
+ ics_base_reject(ss->xirr_owner, old_xisr);
ss->xirr_owner = NULL;
}
}
@@ -325,8 +348,8 @@ void icp_eoi(XICSState *xics, int server, uint32_t xirr)
trace_xics_icp_eoi(server, xirr, ss->xirr);
irq = xirr & XISR_MASK;
QLIST_FOREACH(ics, &xics->ics, list) {
- if (ics_valid_irq(ics, irq)) {
- ics_eoi(ics, irq);
+ if (ics_base_valid_irq(ics, irq)) {
+ ics_base_eoi(ics, irq);
}
}
if (!XISR(ss)) {
@@ -343,10 +366,10 @@ static void icp_irq(ICSState *ics, int server, int nr,
uint8_t priority)
if ((priority >= CPPR(ss))
|| (XISR(ss) && (ss->pending_priority <= priority))) {
- ics_reject(ics, nr);
+ ics_base_reject(ics, nr);
} else {
if (XISR(ss) && ss->xirr_owner) {
- ics_reject(ss->xirr_owner, XISR(ss));
+ ics_base_reject(ss->xirr_owner, XISR(ss));
ss->xirr_owner = NULL;
}
ss->xirr = (ss->xirr & ~XISR_MASK) | (nr & XISR_MASK);
@@ -425,7 +448,7 @@ static const TypeInfo icp_info = {
/*
* ICS: Source layer
*/
-static void resend_msi(ICSState *ics, int srcno)
+static void ics_resend_msi(ICSState *ics, int srcno)
{
ICSIRQState *irq = ics->irqs + srcno;
@@ -438,7 +461,7 @@ static void resend_msi(ICSState *ics, int srcno)
}
}
-static void resend_lsi(ICSState *ics, int srcno)
+static void ics_resend_lsi(ICSState *ics, int srcno)
{
ICSIRQState *irq = ics->irqs + srcno;
@@ -450,7 +473,7 @@ static void resend_lsi(ICSState *ics, int srcno)
}
}
-static void set_irq_msi(ICSState *ics, int srcno, int val)
+static void ics_set_irq_msi(ICSState *ics, int srcno, int val)
{
ICSIRQState *irq = ics->irqs + srcno;
@@ -466,7 +489,7 @@ static void set_irq_msi(ICSState *ics, int srcno, int val)
}
}
-static void set_irq_lsi(ICSState *ics, int srcno, int val)
+static void ics_set_irq_lsi(ICSState *ics, int srcno, int val)
{
ICSIRQState *irq = ics->irqs + srcno;
@@ -476,7 +499,7 @@ static void set_irq_lsi(ICSState *ics, int srcno, int val)
} else {
irq->status &= ~XICS_STATUS_ASSERTED;
}
- resend_lsi(ics, srcno);
+ ics_resend_lsi(ics, srcno);
}
static void ics_set_irq(void *opaque, int srcno, int val)
@@ -484,13 +507,13 @@ static void ics_set_irq(void *opaque, int srcno, int val)
ICSState *ics = (ICSState *)opaque;
if (ics->irqs[srcno].flags & XICS_FLAGS_IRQ_LSI) {
- set_irq_lsi(ics, srcno, val);
+ ics_set_irq_lsi(ics, srcno, val);
} else {
- set_irq_msi(ics, srcno, val);
+ ics_set_irq_msi(ics, srcno, val);
}
}
-static void write_xive_msi(ICSState *ics, int srcno)
+static void ics_write_xive_msi(ICSState *ics, int srcno)
{
ICSIRQState *irq = ics->irqs + srcno;
@@ -503,31 +526,30 @@ static void write_xive_msi(ICSState *ics, int srcno)
icp_irq(ics, irq->server, srcno + ics->offset, irq->priority);
}
-static void write_xive_lsi(ICSState *ics, int srcno)
+static void ics_write_xive_lsi(ICSState *ics, int srcno)
{
- resend_lsi(ics, srcno);
+ ics_resend_lsi(ics, srcno);
}
-void ics_write_xive(ICSState *ics, int nr, int server,
- uint8_t priority, uint8_t saved_priority)
+void ics_write_xive(ICSState *ics, int srcno, int server,
+ uint8_t priority, uint8_t saved_priority)
{
- int srcno = nr - ics->offset;
ICSIRQState *irq = ics->irqs + srcno;
irq->server = server;
irq->priority = priority;
irq->saved_priority = saved_priority;
- trace_xics_ics_write_xive(nr, srcno, server, priority);
+ trace_xics_ics_write_xive(ics->offset + srcno, srcno, server, priority);
if (ics->irqs[srcno].flags & XICS_FLAGS_IRQ_LSI) {
- write_xive_lsi(ics, srcno);
+ ics_write_xive_lsi(ics, srcno);
} else {
- write_xive_msi(ics, srcno);
+ ics_write_xive_msi(ics, srcno);
}
}
-static void ics_reject(ICSState *ics, int nr)
+static void ics_reject(ICSState *ics, uint32_t nr)
{
ICSIRQState *irq = ics->irqs + nr - ics->offset;
@@ -543,14 +565,14 @@ static void ics_resend(ICSState *ics)
for (i = 0; i < ics->nr_irqs; i++) {
/* FIXME: filter by server#? */
if (ics->irqs[i].flags & XICS_FLAGS_IRQ_LSI) {
- resend_lsi(ics, i);
+ ics_resend_lsi(ics, i);
} else {
- resend_msi(ics, i);
+ ics_resend_msi(ics, i);
}
}
}
-static void ics_eoi(ICSState *ics, int nr)
+static void ics_eoi(ICSState *ics, uint32_t nr)
{
int srcno = nr - ics->offset;
ICSIRQState *irq = ics->irqs + srcno;
@@ -639,7 +661,8 @@ static const VMStateDescription vmstate_ics = {
VMSTATE_UINT32_EQUAL(nr_irqs, ICSState),
VMSTATE_STRUCT_VARRAY_POINTER_UINT32(irqs, ICSState, nr_irqs,
- vmstate_ics_irq, ICSIRQState),
+ vmstate_ics_irq,
+ ICSIRQState),
VMSTATE_END_OF_LIST()
},
};
@@ -672,17 +695,28 @@ static void ics_class_init(ObjectClass *klass, void *data)
dc->vmsd = &vmstate_ics;
dc->reset = ics_reset;
isc->post_load = ics_post_load;
+ isc->reject = ics_reject;
+ isc->resend = ics_resend;
+ isc->eoi = ics_eoi;
}
static const TypeInfo ics_info = {
.name = TYPE_ICS,
- .parent = TYPE_DEVICE,
+ .parent = TYPE_ICS_BASE,
.instance_size = sizeof(ICSState),
.class_init = ics_class_init,
.class_size = sizeof(ICSStateClass),
.instance_init = ics_initfn,
};
+static const TypeInfo ics_base_info = {
+ .name = TYPE_ICS_BASE,
+ .parent = TYPE_DEVICE,
+ .abstract = true,
+ .instance_size = sizeof(ICSState),
+ .class_size = sizeof(ICSStateClass),
+};
+
/*
* Exported functions
*/
@@ -691,7 +725,7 @@ ICSState *xics_find_source(XICSState *xics, int irq)
ICSState *ics;
QLIST_FOREACH(ics, &xics->ics, list) {
- if (ics_valid_irq(ics, irq)) {
+ if (ics_base_valid_irq(ics, irq)) {
return ics;
}
}
@@ -721,6 +755,7 @@ static void xics_register_types(void)
{
type_register_static(&xics_common_info);
type_register_static(&ics_info);
+ type_register_static(&ics_base_info);
type_register_static(&icp_info);
}
diff --git a/hw/intc/xics_spapr.c b/hw/intc/xics_spapr.c
index 8acafd9..113b067 100644
--- a/hw/intc/xics_spapr.c
+++ b/hw/intc/xics_spapr.c
@@ -114,7 +114,7 @@ static void rtas_set_xive(PowerPCCPU *cpu,
sPAPRMachineState *spapr,
uint32_t nret, target_ulong rets)
{
ICSState *ics = QLIST_FIRST(&spapr->xics->ics);
- uint32_t nr, server, priority;
+ uint32_t nr, srcno, server, priority;
if ((nargs != 3) || (nret != 1) || !ics) {
rtas_st(rets, 0, RTAS_OUT_PARAM_ERROR);
@@ -125,13 +125,14 @@ static void rtas_set_xive(PowerPCCPU *cpu,
sPAPRMachineState *spapr,
server = 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_base_valid_irq(ics, nr) || (server >= ics->xics->nr_servers)
|| (priority > 0xff)) {
rtas_st(rets, 0, RTAS_OUT_PARAM_ERROR);
return;
}
- ics_write_xive(ics, nr, server, priority, priority);
+ srcno = nr - ics->offset;
+ ics_write_xive(ics, srcno, server, priority, priority);
rtas_st(rets, 0, RTAS_OUT_SUCCESS);
}
@@ -142,7 +143,7 @@ static void rtas_get_xive(PowerPCCPU *cpu,
sPAPRMachineState *spapr,
uint32_t nret, target_ulong rets)
{
ICSState *ics = QLIST_FIRST(&spapr->xics->ics);
- uint32_t nr;
+ uint32_t nr, srcno;
if ((nargs != 1) || (nret != 3) || !ics) {
rtas_st(rets, 0, RTAS_OUT_PARAM_ERROR);
@@ -151,14 +152,15 @@ static void rtas_get_xive(PowerPCCPU *cpu,
sPAPRMachineState *spapr,
nr = rtas_ld(args, 0);
- if (!ics_valid_irq(ics, nr)) {
+ if (!ics_base_valid_irq(ics, nr)) {
rtas_st(rets, 0, RTAS_OUT_PARAM_ERROR);
return;
}
rtas_st(rets, 0, RTAS_OUT_SUCCESS);
- rtas_st(rets, 1, ics->irqs[nr - ics->offset].server);
- rtas_st(rets, 2, ics->irqs[nr - ics->offset].priority);
+ srcno = nr - ics->offset;
+ rtas_st(rets, 1, ics->irqs[srcno].server);
+ rtas_st(rets, 2, ics->irqs[srcno].priority);
}
static void rtas_int_off(PowerPCCPU *cpu, sPAPRMachineState *spapr,
@@ -167,7 +169,7 @@ static void rtas_int_off(PowerPCCPU *cpu, sPAPRMachineState
*spapr,
uint32_t nret, target_ulong rets)
{
ICSState *ics = QLIST_FIRST(&spapr->xics->ics);
- uint32_t nr;
+ uint32_t nr, srcno;
if ((nargs != 1) || (nret != 1) || !ics) {
rtas_st(rets, 0, RTAS_OUT_PARAM_ERROR);
@@ -176,13 +178,14 @@ static void rtas_int_off(PowerPCCPU *cpu,
sPAPRMachineState *spapr,
nr = rtas_ld(args, 0);
- if (!ics_valid_irq(ics, nr)) {
+ if (!ics_base_valid_irq(ics, nr)) {
rtas_st(rets, 0, RTAS_OUT_PARAM_ERROR);
return;
}
- ics_write_xive(ics, nr, ics->irqs[nr - ics->offset].server, 0xff,
- ics->irqs[nr - ics->offset].priority);
+ srcno = nr - ics->offset;
+ ics_write_xive(ics, srcno, ics->irqs[srcno].server, 0xff,
+ ics->irqs[srcno].priority);
rtas_st(rets, 0, RTAS_OUT_SUCCESS);
}
@@ -193,7 +196,7 @@ static void rtas_int_on(PowerPCCPU *cpu, sPAPRMachineState
*spapr,
uint32_t nret, target_ulong rets)
{
ICSState *ics = QLIST_FIRST(&spapr->xics->ics);
- uint32_t nr;
+ uint32_t nr, srcno;
if ((nargs != 1) || (nret != 1) || !ics) {
rtas_st(rets, 0, RTAS_OUT_PARAM_ERROR);
@@ -202,14 +205,15 @@ static void rtas_int_on(PowerPCCPU *cpu,
sPAPRMachineState *spapr,
nr = rtas_ld(args, 0);
- if (!ics_valid_irq(ics, nr)) {
+ if (!ics_base_valid_irq(ics, nr)) {
rtas_st(rets, 0, RTAS_OUT_PARAM_ERROR);
return;
}
- ics_write_xive(ics, nr, ics->irqs[nr - ics->offset].server,
- ics->irqs[nr - ics->offset].saved_priority,
- ics->irqs[nr - ics->offset].saved_priority);
+ srcno = nr - ics->offset;
+ ics_write_xive(ics, srcno, ics->irqs[srcno].server,
+ ics->irqs[srcno].saved_priority,
+ ics->irqs[srcno].saved_priority);
rtas_st(rets, 0, RTAS_OUT_SUCCESS);
}
diff --git a/include/hw/ppc/xics.h b/include/hw/ppc/xics.h
index ee0fce2..6fb1cb4 100644
--- a/include/hw/ppc/xics.h
+++ b/include/hw/ppc/xics.h
@@ -117,6 +117,10 @@ struct ICPState {
bool cap_irq_xics_enabled;
};
+#define TYPE_ICS_BASE "ics-base"
+#define ICS_BASE(obj) OBJECT_CHECK(ICSState, (obj), TYPE_ICS_SIMPLE)
+
+/* Retain ics for sPAPR for migration from existing sPAPR guests */
#define TYPE_ICS "ics"
#define ICS(obj) OBJECT_CHECK(ICSState, (obj), TYPE_ICS)
@@ -133,6 +137,9 @@ struct ICSStateClass {
void (*pre_save)(ICSState *s);
int (*post_load)(ICSState *s, int version_id);
+ void (*reject)(ICSState *s, uint32_t irq);
+ void (*resend)(ICSState *s);
+ void (*eoi)(ICSState *s, uint32_t irq);
};
struct ICSState {
@@ -147,7 +154,7 @@ struct ICSState {
QLIST_ENTRY(ICSState) list;
};
-static inline bool ics_valid_irq(ICSState *ics, uint32_t nr)
+static inline bool ics_base_valid_irq(ICSState *ics, uint32_t nr)
{
return (ics->offset != 0) && (nr >= ics->offset)
&& (nr < (ics->offset + ics->nr_irqs));
@@ -190,7 +197,7 @@ uint32_t icp_ipoll(ICPState *ss, uint32_t *mfrr);
void icp_eoi(XICSState *icp, int server, uint32_t xirr);
void ics_write_xive(ICSState *ics, int nr, int server,
- uint8_t priority, uint8_t saved_priority);
+ uint8_t priority, uint8_t saved_priority);
void ics_set_irq_type(ICSState *ics, int srcno, bool lsi);
--
2.7.4
- [Qemu-ppc] [PATCH v1 07/11] ppc/xics: An ICS with offset 0 is assumed to be uninitialized, (continued)
- [Qemu-ppc] [PATCH v1 09/11] ppc/xics: Split ICS into ics-base and ics class,
Nikunj A Dadhania <=
- Re: [Qemu-ppc] [PATCH v1 09/11] ppc/xics: Split ICS into ics-base and ics class, David Gibson, 2016/06/27
- Re: [Qemu-ppc] [PATCH v1 09/11] ppc/xics: Split ICS into ics-base and ics class, Nikunj A Dadhania, 2016/06/27
- Re: [Qemu-ppc] [PATCH v1 09/11] ppc/xics: Split ICS into ics-base and ics class, Nikunj A Dadhania, 2016/06/27
- Re: [Qemu-ppc] [PATCH v1 09/11] ppc/xics: Split ICS into ics-base and ics class, David Gibson, 2016/06/27
- Re: [Qemu-ppc] [PATCH v1 09/11] ppc/xics: Split ICS into ics-base and ics class, Nikunj A Dadhania, 2016/06/28
- Re: [Qemu-ppc] [PATCH v1 09/11] ppc/xics: Split ICS into ics-base and ics class, David Gibson, 2016/06/28