ppc/xics: Split ICS into ics-base and ics class
The existing implementation remains same and ics-base is introduced. The type name "ics" is retained, and all the related functions renamed as ics_simple_* 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 <benh@kernel.crashing.org> Signed-off-by: Nikunj A Dadhania <nikunj@linux.vnet.ibm.com> Reviewed-by: David Gibson <david@gibson.dropbear.id.au> [ clg: added ICS_BASE_GET_CLASS and related fixes, based on : http://patchwork.ozlabs.org/patch/646010/ ] 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
cc706a5305
commit
d4d7a59a7a
@ -50,12 +50,12 @@ xics_icp_accept(uint32_t old_xirr, uint32_t new_xirr) "icp_accept: XIRR %#"PRIx3
|
||||
xics_icp_eoi(int server, uint32_t xirr, uint32_t new_xirr) "icp_eoi: server %d given XIRR %#"PRIx32" new XIRR %#"PRIx32
|
||||
xics_icp_irq(int server, int nr, uint8_t priority) "cpu %d trying to deliver irq %#"PRIx32" priority %#x"
|
||||
xics_icp_raise(uint32_t xirr, uint8_t pending_priority) "raising IRQ new XIRR=%#x new pending priority=%#x"
|
||||
xics_set_irq_msi(int srcno, int nr) "set_irq_msi: srcno %d [irq %#x]"
|
||||
xics_ics_simple_set_irq_msi(int srcno, int nr) "set_irq_msi: srcno %d [irq %#x]"
|
||||
xics_masked_pending(void) "set_irq_msi: masked pending"
|
||||
xics_set_irq_lsi(int srcno, int nr) "set_irq_lsi: srcno %d [irq %#x]"
|
||||
xics_ics_write_xive(int nr, int srcno, int server, uint8_t priority) "ics_write_xive: irq %#x [src %d] server %#x prio %#x"
|
||||
xics_ics_reject(int nr, int srcno) "reject irq %#x [src %d]"
|
||||
xics_ics_eoi(int nr) "ics_eoi: irq %#x"
|
||||
xics_ics_simple_set_irq_lsi(int srcno, int nr) "set_irq_lsi: srcno %d [irq %#x]"
|
||||
xics_ics_simple_write_xive(int nr, int srcno, int server, uint8_t priority) "ics_write_xive: irq %#x [src %d] server %#x prio %#x"
|
||||
xics_ics_simple_reject(int nr, int srcno) "reject irq %#x [src %d]"
|
||||
xics_ics_simple_eoi(int nr) "ics_eoi: irq %#x"
|
||||
xics_alloc(int irq) "irq %d"
|
||||
xics_alloc_block(int first, int num, bool lsi, int align) "first irq %d, %d irqs, lsi=%d, alignnum %d"
|
||||
xics_ics_free(int src, int irq, int num) "Source#%d, first irq %d, %d irqs"
|
||||
|
152
hw/intc/xics.c
152
hw/intc/xics.c
@ -213,9 +213,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_reject(ICSState *ics, uint32_t nr)
|
||||
{
|
||||
ICSStateClass *k = ICS_BASE_GET_CLASS(ics);
|
||||
|
||||
if (k->reject) {
|
||||
k->reject(ics, nr);
|
||||
}
|
||||
}
|
||||
|
||||
static void ics_resend(ICSState *ics)
|
||||
{
|
||||
ICSStateClass *k = ICS_BASE_GET_CLASS(ics);
|
||||
|
||||
if (k->resend) {
|
||||
k->resend(ics);
|
||||
}
|
||||
}
|
||||
|
||||
static void ics_eoi(ICSState *ics, int nr)
|
||||
{
|
||||
ICSStateClass *k = ICS_BASE_GET_CLASS(ics);
|
||||
|
||||
if (k->eoi) {
|
||||
k->eoi(ics, nr);
|
||||
}
|
||||
}
|
||||
|
||||
static void icp_check_ipi(ICPState *ss)
|
||||
{
|
||||
@ -418,7 +441,7 @@ static const TypeInfo icp_info = {
|
||||
/*
|
||||
* ICS: Source layer
|
||||
*/
|
||||
static void resend_msi(ICSState *ics, int srcno)
|
||||
static void ics_simple_resend_msi(ICSState *ics, int srcno)
|
||||
{
|
||||
ICSIRQState *irq = ics->irqs + srcno;
|
||||
|
||||
@ -431,7 +454,7 @@ static void resend_msi(ICSState *ics, int srcno)
|
||||
}
|
||||
}
|
||||
|
||||
static void resend_lsi(ICSState *ics, int srcno)
|
||||
static void ics_simple_resend_lsi(ICSState *ics, int srcno)
|
||||
{
|
||||
ICSIRQState *irq = ics->irqs + srcno;
|
||||
|
||||
@ -443,11 +466,11 @@ static void resend_lsi(ICSState *ics, int srcno)
|
||||
}
|
||||
}
|
||||
|
||||
static void set_irq_msi(ICSState *ics, int srcno, int val)
|
||||
static void ics_simple_set_irq_msi(ICSState *ics, int srcno, int val)
|
||||
{
|
||||
ICSIRQState *irq = ics->irqs + srcno;
|
||||
|
||||
trace_xics_set_irq_msi(srcno, srcno + ics->offset);
|
||||
trace_xics_ics_simple_set_irq_msi(srcno, srcno + ics->offset);
|
||||
|
||||
if (val) {
|
||||
if (irq->priority == 0xff) {
|
||||
@ -459,31 +482,31 @@ 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_simple_set_irq_lsi(ICSState *ics, int srcno, int val)
|
||||
{
|
||||
ICSIRQState *irq = ics->irqs + srcno;
|
||||
|
||||
trace_xics_set_irq_lsi(srcno, srcno + ics->offset);
|
||||
trace_xics_ics_simple_set_irq_lsi(srcno, srcno + ics->offset);
|
||||
if (val) {
|
||||
irq->status |= XICS_STATUS_ASSERTED;
|
||||
} else {
|
||||
irq->status &= ~XICS_STATUS_ASSERTED;
|
||||
}
|
||||
resend_lsi(ics, srcno);
|
||||
ics_simple_resend_lsi(ics, srcno);
|
||||
}
|
||||
|
||||
static void ics_set_irq(void *opaque, int srcno, int val)
|
||||
static void ics_simple_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_simple_set_irq_lsi(ics, srcno, val);
|
||||
} else {
|
||||
set_irq_msi(ics, srcno, val);
|
||||
ics_simple_set_irq_msi(ics, srcno, val);
|
||||
}
|
||||
}
|
||||
|
||||
static void write_xive_msi(ICSState *ics, int srcno)
|
||||
static void ics_simple_write_xive_msi(ICSState *ics, int srcno)
|
||||
{
|
||||
ICSIRQState *irq = ics->irqs + srcno;
|
||||
|
||||
@ -496,35 +519,35 @@ 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_simple_write_xive_lsi(ICSState *ics, int srcno)
|
||||
{
|
||||
resend_lsi(ics, srcno);
|
||||
ics_simple_resend_lsi(ics, srcno);
|
||||
}
|
||||
|
||||
void ics_write_xive(ICSState *ics, int nr, int server,
|
||||
uint8_t priority, uint8_t saved_priority)
|
||||
void ics_simple_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_simple_write_xive(ics->offset + srcno, srcno, server,
|
||||
priority);
|
||||
|
||||
if (ics->irqs[srcno].flags & XICS_FLAGS_IRQ_LSI) {
|
||||
write_xive_lsi(ics, srcno);
|
||||
ics_simple_write_xive_lsi(ics, srcno);
|
||||
} else {
|
||||
write_xive_msi(ics, srcno);
|
||||
ics_simple_write_xive_msi(ics, srcno);
|
||||
}
|
||||
}
|
||||
|
||||
static void ics_reject(ICSState *ics, int nr)
|
||||
static void ics_simple_reject(ICSState *ics, uint32_t nr)
|
||||
{
|
||||
ICSIRQState *irq = ics->irqs + nr - ics->offset;
|
||||
|
||||
trace_xics_ics_reject(nr, nr - ics->offset);
|
||||
trace_xics_ics_simple_reject(nr, nr - ics->offset);
|
||||
if (irq->flags & XICS_FLAGS_IRQ_MSI) {
|
||||
irq->status |= XICS_STATUS_REJECTED;
|
||||
} else if (irq->flags & XICS_FLAGS_IRQ_LSI) {
|
||||
@ -532,35 +555,35 @@ static void ics_reject(ICSState *ics, int nr)
|
||||
}
|
||||
}
|
||||
|
||||
static void ics_resend(ICSState *ics)
|
||||
static void ics_simple_resend(ICSState *ics)
|
||||
{
|
||||
int i;
|
||||
|
||||
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_simple_resend_lsi(ics, i);
|
||||
} else {
|
||||
resend_msi(ics, i);
|
||||
ics_simple_resend_msi(ics, i);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void ics_eoi(ICSState *ics, int nr)
|
||||
static void ics_simple_eoi(ICSState *ics, uint32_t nr)
|
||||
{
|
||||
int srcno = nr - ics->offset;
|
||||
ICSIRQState *irq = ics->irqs + srcno;
|
||||
|
||||
trace_xics_ics_eoi(nr);
|
||||
trace_xics_ics_simple_eoi(nr);
|
||||
|
||||
if (ics->irqs[srcno].flags & XICS_FLAGS_IRQ_LSI) {
|
||||
irq->status &= ~XICS_STATUS_SENT;
|
||||
}
|
||||
}
|
||||
|
||||
static void ics_reset(DeviceState *dev)
|
||||
static void ics_simple_reset(DeviceState *dev)
|
||||
{
|
||||
ICSState *ics = ICS(dev);
|
||||
ICSState *ics = ICS_SIMPLE(dev);
|
||||
int i;
|
||||
uint8_t flags[ics->nr_irqs];
|
||||
|
||||
@ -577,7 +600,7 @@ static void ics_reset(DeviceState *dev)
|
||||
}
|
||||
}
|
||||
|
||||
static int ics_post_load(ICSState *ics, int version_id)
|
||||
static int ics_simple_post_load(ICSState *ics, int version_id)
|
||||
{
|
||||
int i;
|
||||
|
||||
@ -588,20 +611,20 @@ static int ics_post_load(ICSState *ics, int version_id)
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void ics_dispatch_pre_save(void *opaque)
|
||||
static void ics_simple_dispatch_pre_save(void *opaque)
|
||||
{
|
||||
ICSState *ics = opaque;
|
||||
ICSStateClass *info = ICS_GET_CLASS(ics);
|
||||
ICSStateClass *info = ICS_BASE_GET_CLASS(ics);
|
||||
|
||||
if (info->pre_save) {
|
||||
info->pre_save(ics);
|
||||
}
|
||||
}
|
||||
|
||||
static int ics_dispatch_post_load(void *opaque, int version_id)
|
||||
static int ics_simple_dispatch_post_load(void *opaque, int version_id)
|
||||
{
|
||||
ICSState *ics = opaque;
|
||||
ICSStateClass *info = ICS_GET_CLASS(ics);
|
||||
ICSStateClass *info = ICS_BASE_GET_CLASS(ics);
|
||||
|
||||
if (info->post_load) {
|
||||
return info->post_load(ics, version_id);
|
||||
@ -610,7 +633,7 @@ static int ics_dispatch_post_load(void *opaque, int version_id)
|
||||
return 0;
|
||||
}
|
||||
|
||||
static const VMStateDescription vmstate_ics_irq = {
|
||||
static const VMStateDescription vmstate_ics_simple_irq = {
|
||||
.name = "ics/irq",
|
||||
.version_id = 2,
|
||||
.minimum_version_id = 1,
|
||||
@ -624,59 +647,71 @@ static const VMStateDescription vmstate_ics_irq = {
|
||||
},
|
||||
};
|
||||
|
||||
static const VMStateDescription vmstate_ics = {
|
||||
static const VMStateDescription vmstate_ics_simple = {
|
||||
.name = "ics",
|
||||
.version_id = 1,
|
||||
.minimum_version_id = 1,
|
||||
.pre_save = ics_dispatch_pre_save,
|
||||
.post_load = ics_dispatch_post_load,
|
||||
.pre_save = ics_simple_dispatch_pre_save,
|
||||
.post_load = ics_simple_dispatch_post_load,
|
||||
.fields = (VMStateField[]) {
|
||||
/* Sanity check */
|
||||
VMSTATE_UINT32_EQUAL(nr_irqs, ICSState),
|
||||
|
||||
VMSTATE_STRUCT_VARRAY_POINTER_UINT32(irqs, ICSState, nr_irqs,
|
||||
vmstate_ics_irq, ICSIRQState),
|
||||
vmstate_ics_simple_irq,
|
||||
ICSIRQState),
|
||||
VMSTATE_END_OF_LIST()
|
||||
},
|
||||
};
|
||||
|
||||
static void ics_initfn(Object *obj)
|
||||
static void ics_simple_initfn(Object *obj)
|
||||
{
|
||||
ICSState *ics = ICS(obj);
|
||||
ICSState *ics = ICS_SIMPLE(obj);
|
||||
|
||||
ics->offset = XICS_IRQ_BASE;
|
||||
}
|
||||
|
||||
static void ics_realize(DeviceState *dev, Error **errp)
|
||||
static void ics_simple_realize(DeviceState *dev, Error **errp)
|
||||
{
|
||||
ICSState *ics = ICS(dev);
|
||||
ICSState *ics = ICS_SIMPLE(dev);
|
||||
|
||||
if (!ics->nr_irqs) {
|
||||
error_setg(errp, "Number of interrupts needs to be greater 0");
|
||||
return;
|
||||
}
|
||||
ics->irqs = g_malloc0(ics->nr_irqs * sizeof(ICSIRQState));
|
||||
ics->qirqs = qemu_allocate_irqs(ics_set_irq, ics, ics->nr_irqs);
|
||||
ics->qirqs = qemu_allocate_irqs(ics_simple_set_irq, ics, ics->nr_irqs);
|
||||
}
|
||||
|
||||
static void ics_class_init(ObjectClass *klass, void *data)
|
||||
static void ics_simple_class_init(ObjectClass *klass, void *data)
|
||||
{
|
||||
DeviceClass *dc = DEVICE_CLASS(klass);
|
||||
ICSStateClass *isc = ICS_CLASS(klass);
|
||||
ICSStateClass *isc = ICS_BASE_CLASS(klass);
|
||||
|
||||
dc->realize = ics_realize;
|
||||
dc->vmsd = &vmstate_ics;
|
||||
dc->reset = ics_reset;
|
||||
isc->post_load = ics_post_load;
|
||||
dc->realize = ics_simple_realize;
|
||||
dc->vmsd = &vmstate_ics_simple;
|
||||
dc->reset = ics_simple_reset;
|
||||
isc->post_load = ics_simple_post_load;
|
||||
isc->reject = ics_simple_reject;
|
||||
isc->resend = ics_simple_resend;
|
||||
isc->eoi = ics_simple_eoi;
|
||||
}
|
||||
|
||||
static const TypeInfo ics_info = {
|
||||
.name = TYPE_ICS,
|
||||
.parent = TYPE_DEVICE,
|
||||
static const TypeInfo ics_simple_info = {
|
||||
.name = TYPE_ICS_SIMPLE,
|
||||
.parent = TYPE_ICS_BASE,
|
||||
.instance_size = sizeof(ICSState),
|
||||
.class_init = ics_simple_class_init,
|
||||
.class_size = sizeof(ICSStateClass),
|
||||
.instance_init = ics_simple_initfn,
|
||||
};
|
||||
|
||||
static const TypeInfo ics_base_info = {
|
||||
.name = TYPE_ICS_BASE,
|
||||
.parent = TYPE_DEVICE,
|
||||
.abstract = true,
|
||||
.instance_size = sizeof(ICSState),
|
||||
.class_init = ics_class_init,
|
||||
.class_size = sizeof(ICSStateClass),
|
||||
.instance_init = ics_initfn,
|
||||
};
|
||||
|
||||
/*
|
||||
@ -716,7 +751,8 @@ void ics_set_irq_type(ICSState *ics, int srcno, bool lsi)
|
||||
static void xics_register_types(void)
|
||||
{
|
||||
type_register_static(&xics_common_info);
|
||||
type_register_static(&ics_info);
|
||||
type_register_static(&ics_simple_info);
|
||||
type_register_static(&ics_base_info);
|
||||
type_register_static(&icp_info);
|
||||
}
|
||||
|
||||
|
@ -272,7 +272,7 @@ static void ics_kvm_set_irq(void *opaque, int srcno, int val)
|
||||
|
||||
static void ics_kvm_reset(DeviceState *dev)
|
||||
{
|
||||
ICSState *ics = ICS(dev);
|
||||
ICSState *ics = ICS_SIMPLE(dev);
|
||||
int i;
|
||||
uint8_t flags[ics->nr_irqs];
|
||||
|
||||
@ -293,7 +293,7 @@ static void ics_kvm_reset(DeviceState *dev)
|
||||
|
||||
static void ics_kvm_realize(DeviceState *dev, Error **errp)
|
||||
{
|
||||
ICSState *ics = ICS(dev);
|
||||
ICSState *ics = ICS_SIMPLE(dev);
|
||||
|
||||
if (!ics->nr_irqs) {
|
||||
error_setg(errp, "Number of interrupts needs to be greater 0");
|
||||
@ -306,7 +306,7 @@ static void ics_kvm_realize(DeviceState *dev, Error **errp)
|
||||
static void ics_kvm_class_init(ObjectClass *klass, void *data)
|
||||
{
|
||||
DeviceClass *dc = DEVICE_CLASS(klass);
|
||||
ICSStateClass *icsc = ICS_CLASS(klass);
|
||||
ICSStateClass *icsc = ICS_BASE_CLASS(klass);
|
||||
|
||||
dc->realize = ics_kvm_realize;
|
||||
dc->reset = ics_kvm_reset;
|
||||
@ -315,8 +315,8 @@ static void ics_kvm_class_init(ObjectClass *klass, void *data)
|
||||
}
|
||||
|
||||
static const TypeInfo ics_kvm_info = {
|
||||
.name = TYPE_KVM_ICS,
|
||||
.parent = TYPE_ICS,
|
||||
.name = TYPE_ICS_KVM,
|
||||
.parent = TYPE_ICS_SIMPLE,
|
||||
.instance_size = sizeof(ICSState),
|
||||
.class_init = ics_kvm_class_init,
|
||||
};
|
||||
@ -488,7 +488,7 @@ static void xics_kvm_initfn(Object *obj)
|
||||
XICSState *xics = XICS_COMMON(obj);
|
||||
ICSState *ics;
|
||||
|
||||
ics = ICS(object_new(TYPE_KVM_ICS));
|
||||
ics = ICS_SIMPLE(object_new(TYPE_ICS_KVM));
|
||||
object_property_add_child(obj, "ics", OBJECT(ics), NULL);
|
||||
ics->xics = xics;
|
||||
QLIST_INSERT_HEAD(&xics->ics, ics, list);
|
||||
|
@ -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)) {
|
||||
rtas_st(rets, 0, RTAS_OUT_PARAM_ERROR);
|
||||
@ -135,7 +135,8 @@ static void rtas_set_xive(PowerPCCPU *cpu, sPAPRMachineState *spapr,
|
||||
return;
|
||||
}
|
||||
|
||||
ics_write_xive(ics, nr, server, priority, priority);
|
||||
srcno = nr - ics->offset;
|
||||
ics_simple_write_xive(ics, srcno, server, priority, priority);
|
||||
|
||||
rtas_st(rets, 0, RTAS_OUT_SUCCESS);
|
||||
}
|
||||
@ -146,7 +147,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)) {
|
||||
rtas_st(rets, 0, RTAS_OUT_PARAM_ERROR);
|
||||
@ -165,8 +166,9 @@ static void rtas_get_xive(PowerPCCPU *cpu, sPAPRMachineState *spapr,
|
||||
}
|
||||
|
||||
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,
|
||||
@ -175,7 +177,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)) {
|
||||
rtas_st(rets, 0, RTAS_OUT_PARAM_ERROR);
|
||||
@ -193,8 +195,9 @@ static void rtas_int_off(PowerPCCPU *cpu, sPAPRMachineState *spapr,
|
||||
return;
|
||||
}
|
||||
|
||||
ics_write_xive(ics, nr, ics->irqs[nr - ics->offset].server, 0xff,
|
||||
ics->irqs[nr - ics->offset].priority);
|
||||
srcno = nr - ics->offset;
|
||||
ics_simple_write_xive(ics, srcno, ics->irqs[srcno].server, 0xff,
|
||||
ics->irqs[srcno].priority);
|
||||
|
||||
rtas_st(rets, 0, RTAS_OUT_SUCCESS);
|
||||
}
|
||||
@ -205,7 +208,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)) {
|
||||
rtas_st(rets, 0, RTAS_OUT_PARAM_ERROR);
|
||||
@ -223,9 +226,10 @@ static void rtas_int_on(PowerPCCPU *cpu, sPAPRMachineState *spapr,
|
||||
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_simple_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);
|
||||
}
|
||||
@ -307,7 +311,7 @@ static void xics_spapr_initfn(Object *obj)
|
||||
XICSState *xics = XICS_SPAPR(obj);
|
||||
ICSState *ics;
|
||||
|
||||
ics = ICS(object_new(TYPE_ICS));
|
||||
ics = ICS_SIMPLE(object_new(TYPE_ICS_SIMPLE));
|
||||
object_property_add_child(obj, "ics", OBJECT(ics), NULL);
|
||||
ics->xics = xics;
|
||||
QLIST_INSERT_HEAD(&xics->ics, ics, list);
|
||||
|
@ -119,22 +119,29 @@ struct ICPState {
|
||||
bool cap_irq_xics_enabled;
|
||||
};
|
||||
|
||||
#define TYPE_ICS "ics"
|
||||
#define ICS(obj) OBJECT_CHECK(ICSState, (obj), TYPE_ICS)
|
||||
#define TYPE_ICS_BASE "ics-base"
|
||||
#define ICS_BASE(obj) OBJECT_CHECK(ICSState, (obj), TYPE_ICS_BASE)
|
||||
|
||||
#define TYPE_KVM_ICS "icskvm"
|
||||
#define KVM_ICS(obj) OBJECT_CHECK(ICSState, (obj), TYPE_KVM_ICS)
|
||||
/* Retain ics for sPAPR for migration from existing sPAPR guests */
|
||||
#define TYPE_ICS_SIMPLE "ics"
|
||||
#define ICS_SIMPLE(obj) OBJECT_CHECK(ICSState, (obj), TYPE_ICS_SIMPLE)
|
||||
|
||||
#define ICS_CLASS(klass) \
|
||||
OBJECT_CLASS_CHECK(ICSStateClass, (klass), TYPE_ICS)
|
||||
#define ICS_GET_CLASS(obj) \
|
||||
OBJECT_GET_CLASS(ICSStateClass, (obj), TYPE_ICS)
|
||||
#define TYPE_ICS_KVM "icskvm"
|
||||
#define ICS_KVM(obj) OBJECT_CHECK(ICSState, (obj), TYPE_ICS_KVM)
|
||||
|
||||
#define ICS_BASE_CLASS(klass) \
|
||||
OBJECT_CLASS_CHECK(ICSStateClass, (klass), TYPE_ICS_BASE)
|
||||
#define ICS_BASE_GET_CLASS(obj) \
|
||||
OBJECT_GET_CLASS(ICSStateClass, (obj), TYPE_ICS_BASE)
|
||||
|
||||
struct ICSStateClass {
|
||||
DeviceClass parent_class;
|
||||
|
||||
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 {
|
||||
@ -191,8 +198,8 @@ uint32_t icp_accept(ICPState *ss);
|
||||
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);
|
||||
void ics_simple_write_xive(ICSState *ics, int nr, int server,
|
||||
uint8_t priority, uint8_t saved_priority);
|
||||
|
||||
void ics_set_irq_type(ICSState *ics, int srcno, bool lsi);
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user