From patchwork Thu Jun 23 17:47:28 2016 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Nikunj A Dadhania X-Patchwork-Id: 639820 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Received: from lists.gnu.org (lists.gnu.org [IPv6:2001:4830:134:3::11]) (using TLSv1 with cipher AES256-SHA (256/256 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 3rb8hl6nt7z9s9d for ; Fri, 24 Jun 2016 04:13:11 +1000 (AEST) Received: from localhost ([::1]:38551 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1bG97l-0002tf-HP for incoming@patchwork.ozlabs.org; Thu, 23 Jun 2016 14:13:09 -0400 Received: from eggs.gnu.org ([2001:4830:134:3::10]:36079) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1bG8kZ-0000jL-HI for qemu-devel@nongnu.org; Thu, 23 Jun 2016 13:49:16 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1bG8kQ-0004om-Ai for qemu-devel@nongnu.org; Thu, 23 Jun 2016 13:49:10 -0400 Received: from mx0b-001b2d01.pphosted.com ([148.163.158.5]:59666 helo=mx0a-001b2d01.pphosted.com) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1bG8kQ-0004of-4u for qemu-devel@nongnu.org; Thu, 23 Jun 2016 13:49:02 -0400 Received: from pps.filterd (m0098413.ppops.net [127.0.0.1]) by mx0b-001b2d01.pphosted.com (8.16.0.11/8.16.0.11) with SMTP id u5NHiAP3121808 for ; Thu, 23 Jun 2016 13:49:01 -0400 Received: from e23smtp08.au.ibm.com (e23smtp08.au.ibm.com [202.81.31.141]) by mx0b-001b2d01.pphosted.com with ESMTP id 23rj7h5d9m-1 (version=TLSv1.2 cipher=AES256-SHA bits=256 verify=NOT) for ; Thu, 23 Jun 2016 13:49:01 -0400 Received: from localhost by e23smtp08.au.ibm.com with IBM ESMTP SMTP Gateway: Authorized Use Only! Violators will be prosecuted for from ; Fri, 24 Jun 2016 03:48:58 +1000 Received: from d23dlp01.au.ibm.com (202.81.31.203) by e23smtp08.au.ibm.com (202.81.31.205) with IBM ESMTP SMTP Gateway: Authorized Use Only! Violators will be prosecuted; Fri, 24 Jun 2016 03:48:55 +1000 X-IBM-Helo: d23dlp01.au.ibm.com X-IBM-MailFrom: nikunj@linux.vnet.ibm.com X-IBM-RcptTo: qemu-devel@nongnu.org;qemu-ppc@nongnu.org Received: from d23relay06.au.ibm.com (d23relay06.au.ibm.com [9.185.63.219]) by d23dlp01.au.ibm.com (Postfix) with ESMTP id 34F342CE8054; Fri, 24 Jun 2016 03:48:55 +1000 (EST) Received: from d23av05.au.ibm.com (d23av05.au.ibm.com [9.190.234.119]) by d23relay06.au.ibm.com (8.14.9/8.14.9/NCO v10.0) with ESMTP id u5NHmtrO12845482; Fri, 24 Jun 2016 03:48:55 +1000 Received: from d23av05.au.ibm.com (localhost [127.0.0.1]) by d23av05.au.ibm.com (8.14.4/8.14.4/NCO v10.0 AVout) with ESMTP id u5NHmsD8010720; Fri, 24 Jun 2016 03:48:55 +1000 Received: from abhimanyu.in.ibm.com ([9.77.204.240]) by d23av05.au.ibm.com (8.14.4/8.14.4/NCO v10.0 AVin) with ESMTP id u5NHluPC009735; Fri, 24 Jun 2016 03:48:52 +1000 From: Nikunj A Dadhania To: qemu-ppc@nongnu.org, david@gibson.dropbear.id.au Date: Thu, 23 Jun 2016 23:17:28 +0530 X-Mailer: git-send-email 2.7.4 In-Reply-To: <1466704050-15108-1-git-send-email-nikunj@linux.vnet.ibm.com> References: <1466704050-15108-1-git-send-email-nikunj@linux.vnet.ibm.com> X-TM-AS-MML: disable X-Content-Scanned: Fidelis XPS MAILER x-cbid: 16062317-0048-0000-0000-000001974866 X-IBM-AV-DETECTION: SAVI=unused REMOTE=unused XFE=unused x-cbparentid: 16062317-0049-0000-0000-00004601ACD2 Message-Id: <1466704050-15108-10-git-send-email-nikunj@linux.vnet.ibm.com> X-Proofpoint-Virus-Version: vendor=fsecure engine=2.50.10432:, , definitions=2016-06-23_08:, , signatures=0 X-Proofpoint-Spam-Details: rule=outbound_notspam policy=outbound score=0 spamscore=0 suspectscore=0 malwarescore=0 phishscore=0 adultscore=0 bulkscore=0 classifier=spam adjust=0 reason=mlx scancount=1 engine=8.0.1-1604210000 definitions=main-1606230185 X-detected-operating-system: by eggs.gnu.org: GNU/Linux 3.x [generic] X-Received-From: 148.163.158.5 Subject: [Qemu-devel] [PATCH v1 09/11] ppc/xics: Split ICS into ics-base and ics class X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.21 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: qemu-devel@nongnu.org, nikunj@linux.vnet.ibm.com, clg@kaod.org Errors-To: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org Sender: "Qemu-devel" From: Benjamin Herrenschmidt 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 Signed-off-by: Nikunj A Dadhania --- 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);