From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from eggs.gnu.org ([208.118.235.92]:60377) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1TBzc2-0000iX-1S for qemu-devel@nongnu.org; Wed, 12 Sep 2012 22:57:07 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1TBzc0-00006a-24 for qemu-devel@nongnu.org; Wed, 12 Sep 2012 22:57:05 -0400 From: David Gibson Date: Thu, 13 Sep 2012 12:57:15 +1000 Message-Id: <1347505041-27411-8-git-send-email-david@gibson.dropbear.id.au> In-Reply-To: <1347505041-27411-1-git-send-email-david@gibson.dropbear.id.au> References: <1347505041-27411-1-git-send-email-david@gibson.dropbear.id.au> Subject: [Qemu-devel] [PATCH 07/13] pseries: Fix XICS reset List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , To: agraf@suse.de Cc: qemu-ppc@nongnu.org, qemu-devel@nongnu.org, David Gibson The XICS interrupt controller used on the pseries machine currently has no reset handler. We can get away with this under some circumstances, but it's not correct, and can cause failures if the XICS happens to be in the wrong state at the time of reset. This patch adds a hook to properly reset the XICS state. Signed-off-by: David Gibson --- hw/xics.c | 38 ++++++++++++++++++++++++++++---------- 1 file changed, 28 insertions(+), 10 deletions(-) diff --git a/hw/xics.c b/hw/xics.c index b674771..a8a08ce 100644 --- a/hw/xics.c +++ b/hw/xics.c @@ -489,11 +489,36 @@ static void rtas_int_on(sPAPREnvironment *spapr, uint32_t token, rtas_st(rets, 0, 0); /* Success */ } +static void xics_reset(void *opaque) +{ + struct icp_state *icp = (struct icp_state *)opaque; + struct ics_state *ics = icp->ics; + int i; + + for (i = 0; i < icp->nr_servers; i++) { + icp->ss[i].xirr = 0; + icp->ss[i].pending_priority = 0; + icp->ss[i].mfrr = 0xff; + /* Make all outputs are deasserted */ + qemu_set_irq(icp->ss[i].output, 0); + } + + for (i = 0; i < ics->nr_irqs; i++) { + /* Reset everything *except* the type */ + ics->irqs[i].server = 0; + ics->irqs[i].asserted = 0; + ics->irqs[i].sent = 0; + ics->irqs[i].rejected = 0; + ics->irqs[i].masked_pending = 0; + ics->irqs[i].priority = 0xff; + ics->irqs[i].saved_priority = 0xff; + } +} + struct icp_state *xics_system_init(int nr_irqs) { CPUPPCState *env; int max_server_num; - int i; struct icp_state *icp; struct ics_state *ics; @@ -508,10 +533,6 @@ struct icp_state *xics_system_init(int nr_irqs) icp->nr_servers = max_server_num + 1; icp->ss = g_malloc0(icp->nr_servers*sizeof(struct icp_server_state)); - for (i = 0; i < icp->nr_servers; i++) { - icp->ss[i].mfrr = 0xff; - } - for (env = first_cpu; env != NULL; env = env->next_cpu) { struct icp_server_state *ss = &icp->ss[env->cpu_index]; @@ -539,11 +560,6 @@ struct icp_state *xics_system_init(int nr_irqs) icp->ics = ics; ics->icp = icp; - for (i = 0; i < nr_irqs; i++) { - ics->irqs[i].priority = 0xff; - ics->irqs[i].saved_priority = 0xff; - } - ics->qirqs = qemu_allocate_irqs(ics_set_irq, ics, nr_irqs); spapr_register_hypercall(H_CPPR, h_cppr); @@ -556,5 +572,7 @@ struct icp_state *xics_system_init(int nr_irqs) spapr_rtas_register("ibm,int-off", rtas_int_off); spapr_rtas_register("ibm,int-on", rtas_int_on); + qemu_register_reset(xics_reset, icp); + return icp; } -- 1.7.10.4