From patchwork Mon Dec 20 18:18:52 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: Fabiano Rosas X-Patchwork-Id: 12688453 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.lore.kernel.org (Postfix) with ESMTPS id DD953C433EF for ; Mon, 20 Dec 2021 19:43:27 +0000 (UTC) Received: from localhost ([::1]:35058 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1mzOZD-0002LE-0u for qemu-devel@archiver.kernel.org; Mon, 20 Dec 2021 14:43:27 -0500 Received: from eggs.gnu.org ([209.51.188.92]:35662) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1mzNFw-0002Kq-Dv; Mon, 20 Dec 2021 13:19:28 -0500 Received: from mx0a-001b2d01.pphosted.com ([148.163.156.1]:42366) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1mzNFt-0006hL-LX; Mon, 20 Dec 2021 13:19:28 -0500 Received: from pps.filterd (m0098393.ppops.net [127.0.0.1]) by mx0a-001b2d01.pphosted.com (8.16.1.2/8.16.1.2) with SMTP id 1BKGSsOv016600; Mon, 20 Dec 2021 18:19:16 GMT DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=ibm.com; h=from : to : cc : subject : date : message-id : in-reply-to : references : mime-version : content-transfer-encoding; s=pp1; bh=KtbHT4QTwfKxNs817/JaNt30QmSy7sTqRZQ8+ABAh6I=; b=dpV8WBTH+45okmROBHZA46Xb3tftVV7wov/V/OSDK2y4aROS+ZHcWfKkkI1rI+fAOtBQ ji6O7QCdXwX5FopZayiyqeYdMjZehYgO9YWsknCEkzodnVm8/ra2yP63lgM3MQ5sRrIv QU55DhmsUiTeNwl6mn3iyQevQ4l41azecQYJBuMjuZ2yHROMhU5HbU/gWFrT0tLpm0k6 2cAwva+WkCijKRb5enOGZQULAD8S+8bGnfVZQ86r4yZTqQytJLKWhGTqoZ+Cen6B39Ua Abe0y4LTBTgoDG06XCyVktT0WLogMy3vlgOvrFhF/p7Hvwazcis4nhpPwLyFiyJO3vc1 YQ== Received: from pps.reinject (localhost [127.0.0.1]) by mx0a-001b2d01.pphosted.com with ESMTP id 3d1sqn9bp8-1 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NOT); Mon, 20 Dec 2021 18:19:16 +0000 Received: from m0098393.ppops.net (m0098393.ppops.net [127.0.0.1]) by pps.reinject (8.16.0.43/8.16.0.43) with SMTP id 1BKHnOSJ014757; Mon, 20 Dec 2021 18:19:16 GMT Received: from ppma03dal.us.ibm.com (b.bd.3ea9.ip4.static.sl-reverse.com [169.62.189.11]) by mx0a-001b2d01.pphosted.com with ESMTP id 3d1sqn9bnn-1 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NOT); Mon, 20 Dec 2021 18:19:16 +0000 Received: from pps.filterd (ppma03dal.us.ibm.com [127.0.0.1]) by ppma03dal.us.ibm.com (8.16.1.2/8.16.1.2) with SMTP id 1BKIDRXb016516; Mon, 20 Dec 2021 18:19:15 GMT Received: from b03cxnp07028.gho.boulder.ibm.com (b03cxnp07028.gho.boulder.ibm.com [9.17.130.15]) by ppma03dal.us.ibm.com with ESMTP id 3d179aa9jy-1 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NOT); Mon, 20 Dec 2021 18:19:15 +0000 Received: from b03ledav006.gho.boulder.ibm.com (b03ledav006.gho.boulder.ibm.com [9.17.130.237]) by b03cxnp07028.gho.boulder.ibm.com (8.14.9/8.14.9/NCO v10.0) with ESMTP id 1BKIJEMe23134684 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-GCM-SHA384 bits=256 verify=OK); Mon, 20 Dec 2021 18:19:14 GMT Received: from b03ledav006.gho.boulder.ibm.com (unknown [127.0.0.1]) by IMSVA (Postfix) with ESMTP id 207B8C605D; Mon, 20 Dec 2021 18:19:14 +0000 (GMT) Received: from b03ledav006.gho.boulder.ibm.com (unknown [127.0.0.1]) by IMSVA (Postfix) with ESMTP id 913D5C605F; Mon, 20 Dec 2021 18:19:12 +0000 (GMT) Received: from farosas.linux.ibm.com.com (unknown [9.211.60.53]) by b03ledav006.gho.boulder.ibm.com (Postfix) with ESMTP; Mon, 20 Dec 2021 18:19:12 +0000 (GMT) From: Fabiano Rosas To: qemu-devel@nongnu.org Subject: [RFC v2 01/12] target/ppc: powerpc_excp: Set alternate SRRs directly Date: Mon, 20 Dec 2021 15:18:52 -0300 Message-Id: <20211220181903.3456898-2-farosas@linux.ibm.com> X-Mailer: git-send-email 2.33.1 In-Reply-To: <20211220181903.3456898-1-farosas@linux.ibm.com> References: <20211220181903.3456898-1-farosas@linux.ibm.com> MIME-Version: 1.0 X-TM-AS-GCONF: 00 X-Proofpoint-ORIG-GUID: 2q2Lhn_nd9QDTMM5tv4tvudmOrx5Yv60 X-Proofpoint-GUID: mS2ttPVYUzDdbeHyYTTjKOJPbCWFRGPY X-Proofpoint-Virus-Version: vendor=baseguard engine=ICAP:2.0.205,Aquarius:18.0.790,Hydra:6.0.425,FMLib:17.11.62.513 definitions=2021-12-20_08,2021-12-20_01,2021-12-02_01 X-Proofpoint-Spam-Details: rule=outbound_notspam policy=outbound score=0 phishscore=0 priorityscore=1501 mlxlogscore=625 spamscore=0 clxscore=1015 bulkscore=0 mlxscore=0 impostorscore=0 lowpriorityscore=0 malwarescore=0 adultscore=0 suspectscore=0 classifier=spam adjust=0 reason=mlx scancount=1 engine=8.12.0-2110150000 definitions=main-2112200101 Received-SPF: pass client-ip=148.163.156.1; envelope-from=farosas@linux.ibm.com; helo=mx0a-001b2d01.pphosted.com X-Spam_score_int: -19 X-Spam_score: -2.0 X-Spam_bar: -- X-Spam_report: (-2.0 / 5.0 requ) BAYES_00=-1.9, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_EF=-0.1, RCVD_IN_MSPIKE_H2=-0.001, SPF_HELO_NONE=0.001, SPF_PASS=-0.001 autolearn=ham autolearn_force=no X-Spam_action: no action X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: danielhb413@gmail.com, qemu-ppc@nongnu.org, clg@kaod.org, david@gibson.dropbear.id.au Errors-To: qemu-devel-bounces+qemu-devel=archiver.kernel.org@nongnu.org Sender: "Qemu-devel" There are currently only two interrupts that use alternate SRRs, so let them write to them directly during the setup code. No functional change intented. Signed-off-by: Fabiano Rosas Reviewed-by: Richard Henderson Reviewed-by: Cédric Le Goater Reviewed-by: David Gibson --- target/ppc/excp_helper.c | 23 ++++++++--------------- 1 file changed, 8 insertions(+), 15 deletions(-) diff --git a/target/ppc/excp_helper.c b/target/ppc/excp_helper.c index f90e616aac..8b9c6bc5a8 100644 --- a/target/ppc/excp_helper.c +++ b/target/ppc/excp_helper.c @@ -298,7 +298,7 @@ static inline void powerpc_excp(PowerPCCPU *cpu, int excp_model, int excp) CPUState *cs = CPU(cpu); CPUPPCState *env = &cpu->env; target_ulong msr, new_msr, vector; - int srr0, srr1, asrr0, asrr1, lev = -1; + int srr0, srr1, lev = -1; qemu_log_mask(CPU_LOG_INT, "Raise exception at " TARGET_FMT_lx " => %08x (%02x)\n", env->nip, excp, env->error_code); @@ -319,8 +319,6 @@ static inline void powerpc_excp(PowerPCCPU *cpu, int excp_model, int excp) /* target registers */ srr0 = SPR_SRR0; srr1 = SPR_SRR1; - asrr0 = -1; - asrr1 = -1; /* * check for special resume at 0x100 from doze/nap/sleep/winkle on @@ -410,8 +408,9 @@ static inline void powerpc_excp(PowerPCCPU *cpu, int excp_model, int excp) /* FIXME: choose one or the other based on CPU type */ srr0 = SPR_BOOKE_MCSRR0; srr1 = SPR_BOOKE_MCSRR1; - asrr0 = SPR_BOOKE_CSRR0; - asrr1 = SPR_BOOKE_CSRR1; + + env->spr[SPR_BOOKE_CSRR0] = env->nip; + env->spr[SPR_BOOKE_CSRR1] = msr; break; default: break; @@ -570,8 +569,10 @@ static inline void powerpc_excp(PowerPCCPU *cpu, int excp_model, int excp) /* FIXME: choose one or the other based on CPU type */ srr0 = SPR_BOOKE_DSRR0; srr1 = SPR_BOOKE_DSRR1; - asrr0 = SPR_BOOKE_CSRR0; - asrr1 = SPR_BOOKE_CSRR1; + + env->spr[SPR_BOOKE_CSRR0] = env->nip; + env->spr[SPR_BOOKE_CSRR1] = msr; + /* DBSR already modified by caller */ } else { cpu_abort(cs, "Debug exception triggered on unsupported model\n"); @@ -838,14 +839,6 @@ static inline void powerpc_excp(PowerPCCPU *cpu, int excp_model, int excp) vector |= env->excp_prefix; - /* If any alternate SRR register are defined, duplicate saved values */ - if (asrr0 != -1) { - env->spr[asrr0] = env->nip; - } - if (asrr1 != -1) { - env->spr[asrr1] = msr; - } - #if defined(TARGET_PPC64) if (excp_model == POWERPC_EXCP_BOOKE) { if (env->spr[SPR_BOOKE_EPCR] & EPCR_ICM) { From patchwork Mon Dec 20 18:18:53 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: Fabiano Rosas X-Patchwork-Id: 12688391 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.lore.kernel.org (Postfix) with ESMTPS id AD45DC433F5 for ; Mon, 20 Dec 2021 18:54:04 +0000 (UTC) Received: from localhost ([::1]:44064 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1mzNnP-0007SR-K7 for qemu-devel@archiver.kernel.org; Mon, 20 Dec 2021 13:54:03 -0500 Received: from eggs.gnu.org ([209.51.188.92]:35624) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1mzNFv-0002GC-3j; Mon, 20 Dec 2021 13:19:27 -0500 Received: from mx0a-001b2d01.pphosted.com ([148.163.156.1]:43840) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1mzNFt-0006hO-85; Mon, 20 Dec 2021 13:19:26 -0500 Received: from pps.filterd (m0098410.ppops.net [127.0.0.1]) by mx0a-001b2d01.pphosted.com (8.16.1.2/8.16.1.2) with SMTP id 1BKGjJBT029724; Mon, 20 Dec 2021 18:19:18 GMT DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=ibm.com; h=from : to : cc : subject : date : message-id : in-reply-to : references : mime-version : content-transfer-encoding; s=pp1; bh=MBaI6jL64OdNT0oUQwYQInrDNvJFooTTbui+6Yr8NkE=; b=hF9oBS5c4aYdgG8njlBooZX512e+YU8WXnSAH2QFh5croh2C4tsZY9ESzFw8vJ0+k4wT mmWNsjq2UWAkbxuSmGL1gqLTCgAXmeCrlcogQfxL4z5aBn6opJvtxVkbOzpNuB5xl9Lr T/jY/XIK3cMkUOvSH2TDyP+vEgnAENhGg520c5KqWCHg/4MjjjgyYwGSkp6cBC80o9yl h4wZ15rQlgiVcbQK9W6TxNVdyvP1dtDjpVkw2QGiVklAyQH8j35BCwtY8Y093y7/cp2c y6hJtVWONSuuQBnn7JpqOiyN+dHAMpOpp5dwpgLHxD1pr0M3y7My0h+3t8WLfgGFiNqN rg== Received: from pps.reinject (localhost [127.0.0.1]) by mx0a-001b2d01.pphosted.com with ESMTP id 3d1s4e2nt7-1 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NOT); Mon, 20 Dec 2021 18:19:18 +0000 Received: from m0098410.ppops.net (m0098410.ppops.net [127.0.0.1]) by pps.reinject (8.16.0.43/8.16.0.43) with SMTP id 1BKIFWU0007316; Mon, 20 Dec 2021 18:19:18 GMT Received: from ppma02wdc.us.ibm.com (aa.5b.37a9.ip4.static.sl-reverse.com [169.55.91.170]) by mx0a-001b2d01.pphosted.com with ESMTP id 3d1s4e2nsw-1 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NOT); Mon, 20 Dec 2021 18:19:18 +0000 Received: from pps.filterd (ppma02wdc.us.ibm.com [127.0.0.1]) by ppma02wdc.us.ibm.com (8.16.1.2/8.16.1.2) with SMTP id 1BKIE7Ta014694; Mon, 20 Dec 2021 18:19:16 GMT Received: from b03cxnp08026.gho.boulder.ibm.com (b03cxnp08026.gho.boulder.ibm.com [9.17.130.18]) by ppma02wdc.us.ibm.com with ESMTP id 3d179a2116-1 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NOT); Mon, 20 Dec 2021 18:19:16 +0000 Received: from b03ledav006.gho.boulder.ibm.com (b03ledav006.gho.boulder.ibm.com [9.17.130.237]) by b03cxnp08026.gho.boulder.ibm.com (8.14.9/8.14.9/NCO v10.0) with ESMTP id 1BKIJGZD33423850 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-GCM-SHA384 bits=256 verify=OK); Mon, 20 Dec 2021 18:19:16 GMT Received: from b03ledav006.gho.boulder.ibm.com (unknown [127.0.0.1]) by IMSVA (Postfix) with ESMTP id 0A88EC6062; Mon, 20 Dec 2021 18:19:16 +0000 (GMT) Received: from b03ledav006.gho.boulder.ibm.com (unknown [127.0.0.1]) by IMSVA (Postfix) with ESMTP id 83C91C6055; Mon, 20 Dec 2021 18:19:14 +0000 (GMT) Received: from farosas.linux.ibm.com.com (unknown [9.211.60.53]) by b03ledav006.gho.boulder.ibm.com (Postfix) with ESMTP; Mon, 20 Dec 2021 18:19:14 +0000 (GMT) From: Fabiano Rosas To: qemu-devel@nongnu.org Subject: [RFC v2 02/12] target/ppc: powerpc_excp: Set vector earlier Date: Mon, 20 Dec 2021 15:18:53 -0300 Message-Id: <20211220181903.3456898-3-farosas@linux.ibm.com> X-Mailer: git-send-email 2.33.1 In-Reply-To: <20211220181903.3456898-1-farosas@linux.ibm.com> References: <20211220181903.3456898-1-farosas@linux.ibm.com> MIME-Version: 1.0 X-TM-AS-GCONF: 00 X-Proofpoint-ORIG-GUID: VWFaBSPmVpFr-qcNcT2w9YbMnJahNvCk X-Proofpoint-GUID: emhG-Y7sh1dKrWDVBpCHNj32EkHAmfga X-Proofpoint-Virus-Version: vendor=baseguard engine=ICAP:2.0.205,Aquarius:18.0.790,Hydra:6.0.425,FMLib:17.11.62.513 definitions=2021-12-20_08,2021-12-20_01,2021-12-02_01 X-Proofpoint-Spam-Details: rule=outbound_notspam policy=outbound score=0 priorityscore=1501 phishscore=0 impostorscore=0 mlxlogscore=775 clxscore=1015 mlxscore=0 suspectscore=0 adultscore=0 lowpriorityscore=0 bulkscore=0 malwarescore=0 spamscore=0 classifier=spam adjust=0 reason=mlx scancount=1 engine=8.12.0-2110150000 definitions=main-2112200101 Received-SPF: pass client-ip=148.163.156.1; envelope-from=farosas@linux.ibm.com; helo=mx0a-001b2d01.pphosted.com X-Spam_score_int: -19 X-Spam_score: -2.0 X-Spam_bar: -- X-Spam_report: (-2.0 / 5.0 requ) BAYES_00=-1.9, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_EF=-0.1, RCVD_IN_MSPIKE_H2=-0.001, SPF_HELO_NONE=0.001, SPF_PASS=-0.001 autolearn=ham autolearn_force=no X-Spam_action: no action X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: danielhb413@gmail.com, qemu-ppc@nongnu.org, clg@kaod.org, david@gibson.dropbear.id.au Errors-To: qemu-devel-bounces+qemu-devel=archiver.kernel.org@nongnu.org Sender: "Qemu-devel" None of the interrupt setup code touches 'vector', so we can move it earlier in the function. This will allow us to later move the System Call Vectored setup that is on the top level into the POWERPC_EXCP_SYSCALL_VECTORED code block. This patch also moves the verification for when 'excp' does not have an address associated with it. We now bail a little earlier when that is the case. This should not cause any visible effects. Signed-off-by: Fabiano Rosas Reviewed-by: Cédric Le Goater --- target/ppc/excp_helper.c | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/target/ppc/excp_helper.c b/target/ppc/excp_helper.c index 8b9c6bc5a8..14fd0213a0 100644 --- a/target/ppc/excp_helper.c +++ b/target/ppc/excp_helper.c @@ -352,6 +352,14 @@ static inline void powerpc_excp(PowerPCCPU *cpu, int excp_model, int excp) } #endif + vector = env->excp_vectors[excp]; + if (vector == (target_ulong)-1ULL) { + cpu_abort(cs, "Raised an exception without defined vector %d\n", + excp); + } + + vector |= env->excp_prefix; + switch (excp) { case POWERPC_EXCP_NONE: /* Should never happen */ @@ -831,14 +839,6 @@ static inline void powerpc_excp(PowerPCCPU *cpu, int excp_model, int excp) } #endif - vector = env->excp_vectors[excp]; - if (vector == (target_ulong)-1ULL) { - cpu_abort(cs, "Raised an exception without defined vector %d\n", - excp); - } - - vector |= env->excp_prefix; - #if defined(TARGET_PPC64) if (excp_model == POWERPC_EXCP_BOOKE) { if (env->spr[SPR_BOOKE_EPCR] & EPCR_ICM) { From patchwork Mon Dec 20 18:18:54 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: Fabiano Rosas X-Patchwork-Id: 12688397 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.lore.kernel.org (Postfix) with ESMTPS id 5880EC433F5 for ; Mon, 20 Dec 2021 19:05:08 +0000 (UTC) Received: from localhost ([::1]:37312 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1mzNy7-0005nD-FT for qemu-devel@archiver.kernel.org; Mon, 20 Dec 2021 14:05:07 -0500 Received: from eggs.gnu.org ([209.51.188.92]:35724) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1mzNG1-0002f3-Ms; Mon, 20 Dec 2021 13:19:33 -0500 Received: from mx0a-001b2d01.pphosted.com ([148.163.156.1]:50126) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1mzNG0-0006k4-2F; Mon, 20 Dec 2021 13:19:33 -0500 Received: from pps.filterd (m0098410.ppops.net [127.0.0.1]) by mx0a-001b2d01.pphosted.com (8.16.1.2/8.16.1.2) with SMTP id 1BKHAPBq029785; Mon, 20 Dec 2021 18:19:20 GMT DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=ibm.com; h=from : to : cc : subject : date : message-id : in-reply-to : references : mime-version : content-transfer-encoding; s=pp1; bh=Q8GOAC5RpdMCQcaxSJFvSaUEui3vOUTP85nCqDD9wlE=; b=f5H/RDebq7qGJ+9UK8gqv7wbKMHKwV/srMCIeemDCfedtIaWlXqomTgOluIjmp2VOJ4x J3dFVgtl81o9w6g6kR16Y6cJN/nFNS6Kj+qOgDXX88EUBBRJwtVC+e9HdiXFdebPfMPb maMXmW0vrmfonunS4J0cOvQLRCY29Nsn+Do4WHgN9s3msaKnsOraEwJ153ENpU6kQveC H1hhXFJoOOI8PWiHw9VZ+OUvPw/x6f0p9bkTA5HbMdiBX8NoUglMf/eis7Hh4sHEXRAw e1jSLRjRMhpNnIOxezUzl04bShgWmLaveJxgoxcktLCxOiz5DCmzQ1qCnUGnUqvLswaL 3A== Received: from pps.reinject (localhost [127.0.0.1]) by mx0a-001b2d01.pphosted.com with ESMTP id 3d1s4e2ntr-1 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NOT); Mon, 20 Dec 2021 18:19:20 +0000 Received: from m0098410.ppops.net (m0098410.ppops.net [127.0.0.1]) by pps.reinject (8.16.0.43/8.16.0.43) with SMTP id 1BKHZThG008760; Mon, 20 Dec 2021 18:19:20 GMT Received: from ppma03wdc.us.ibm.com (ba.79.3fa9.ip4.static.sl-reverse.com [169.63.121.186]) by mx0a-001b2d01.pphosted.com with ESMTP id 3d1s4e2ntg-1 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NOT); Mon, 20 Dec 2021 18:19:19 +0000 Received: from pps.filterd (ppma03wdc.us.ibm.com [127.0.0.1]) by ppma03wdc.us.ibm.com (8.16.1.2/8.16.1.2) with SMTP id 1BKIHuRa011746; Mon, 20 Dec 2021 18:19:18 GMT Received: from b03cxnp08027.gho.boulder.ibm.com (b03cxnp08027.gho.boulder.ibm.com [9.17.130.19]) by ppma03wdc.us.ibm.com with ESMTP id 3d1799hwyw-1 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NOT); Mon, 20 Dec 2021 18:19:18 +0000 Received: from b03ledav006.gho.boulder.ibm.com (b03ledav006.gho.boulder.ibm.com [9.17.130.237]) by b03cxnp08027.gho.boulder.ibm.com (8.14.9/8.14.9/NCO v10.0) with ESMTP id 1BKIJIvs14352756 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-GCM-SHA384 bits=256 verify=OK); Mon, 20 Dec 2021 18:19:18 GMT Received: from b03ledav006.gho.boulder.ibm.com (unknown [127.0.0.1]) by IMSVA (Postfix) with ESMTP id E6C52C6061; Mon, 20 Dec 2021 18:19:17 +0000 (GMT) Received: from b03ledav006.gho.boulder.ibm.com (unknown [127.0.0.1]) by IMSVA (Postfix) with ESMTP id 76CFCC6063; Mon, 20 Dec 2021 18:19:16 +0000 (GMT) Received: from farosas.linux.ibm.com.com (unknown [9.211.60.53]) by b03ledav006.gho.boulder.ibm.com (Postfix) with ESMTP; Mon, 20 Dec 2021 18:19:16 +0000 (GMT) From: Fabiano Rosas To: qemu-devel@nongnu.org Subject: [RFC v2 03/12] target/ppc: powerpc_excp: Move system call vectored code together Date: Mon, 20 Dec 2021 15:18:54 -0300 Message-Id: <20211220181903.3456898-4-farosas@linux.ibm.com> X-Mailer: git-send-email 2.33.1 In-Reply-To: <20211220181903.3456898-1-farosas@linux.ibm.com> References: <20211220181903.3456898-1-farosas@linux.ibm.com> MIME-Version: 1.0 X-TM-AS-GCONF: 00 X-Proofpoint-ORIG-GUID: Yuh6EiOE_nqhwRDDWUjfm5dWi-TWBKhI X-Proofpoint-GUID: zRV--_Dg_PDdLtGSV_dnHH9qSUGCHAxz X-Proofpoint-Virus-Version: vendor=baseguard engine=ICAP:2.0.205,Aquarius:18.0.790,Hydra:6.0.425,FMLib:17.11.62.513 definitions=2021-12-20_08,2021-12-20_01,2021-12-02_01 X-Proofpoint-Spam-Details: rule=outbound_notspam policy=outbound score=0 priorityscore=1501 phishscore=0 impostorscore=0 mlxlogscore=726 clxscore=1015 mlxscore=0 suspectscore=0 adultscore=0 lowpriorityscore=0 bulkscore=0 malwarescore=0 spamscore=0 classifier=spam adjust=0 reason=mlx scancount=1 engine=8.12.0-2110150000 definitions=main-2112200101 Received-SPF: pass client-ip=148.163.156.1; envelope-from=farosas@linux.ibm.com; helo=mx0a-001b2d01.pphosted.com X-Spam_score_int: -19 X-Spam_score: -2.0 X-Spam_bar: -- X-Spam_report: (-2.0 / 5.0 requ) BAYES_00=-1.9, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_EF=-0.1, RCVD_IN_MSPIKE_H2=-0.001, SPF_HELO_NONE=0.001, SPF_PASS=-0.001 autolearn=ham autolearn_force=no X-Spam_action: no action X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: danielhb413@gmail.com, qemu-ppc@nongnu.org, clg@kaod.org, david@gibson.dropbear.id.au Errors-To: qemu-devel-bounces+qemu-devel=archiver.kernel.org@nongnu.org Sender: "Qemu-devel" Now that 'vector' is known before calling the interrupt-specific setup code, we can move all of the scv setup into one place. No functional change intended. Signed-off-by: Fabiano Rosas Reviewed-by: Cédric Le Goater Reviewed-by: Richard Henderson --- target/ppc/excp_helper.c | 13 +++++-------- 1 file changed, 5 insertions(+), 8 deletions(-) diff --git a/target/ppc/excp_helper.c b/target/ppc/excp_helper.c index 14fd0213a0..7bdc1e8410 100644 --- a/target/ppc/excp_helper.c +++ b/target/ppc/excp_helper.c @@ -549,6 +549,11 @@ static inline void powerpc_excp(PowerPCCPU *cpu, int excp_model, int excp) env->nip += 4; new_msr |= env->msr & ((target_ulong)1 << MSR_EE); new_msr |= env->msr & ((target_ulong)1 << MSR_RI); + + vector += lev * 0x20; + + env->lr = env->nip; + env->ctr = msr; break; case POWERPC_EXCP_FPU: /* Floating-point unavailable exception */ case POWERPC_EXCP_APU: /* Auxiliary processor unavailable */ @@ -862,14 +867,6 @@ static inline void powerpc_excp(PowerPCCPU *cpu, int excp_model, int excp) /* Save MSR */ env->spr[srr1] = msr; - -#if defined(TARGET_PPC64) - } else { - vector += lev * 0x20; - - env->lr = env->nip; - env->ctr = msr; -#endif } /* This can update new_msr and vector if AIL applies */ From patchwork Mon Dec 20 18:18:55 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: Fabiano Rosas X-Patchwork-Id: 12688455 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.lore.kernel.org (Postfix) with ESMTPS id CD9AEC433EF for ; Mon, 20 Dec 2021 19:46:21 +0000 (UTC) Received: from localhost ([::1]:38876 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1mzOc0-00052X-Rp for qemu-devel@archiver.kernel.org; Mon, 20 Dec 2021 14:46:20 -0500 Received: from eggs.gnu.org ([209.51.188.92]:35690) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1mzNFy-0002Ut-VS; Mon, 20 Dec 2021 13:19:30 -0500 Received: from mx0a-001b2d01.pphosted.com ([148.163.156.1]:21448) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1mzNFw-0006iz-VS; Mon, 20 Dec 2021 13:19:30 -0500 Received: from pps.filterd (m0098410.ppops.net [127.0.0.1]) by mx0a-001b2d01.pphosted.com (8.16.1.2/8.16.1.2) with SMTP id 1BKGEfbU029771; Mon, 20 Dec 2021 18:19:23 GMT DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=ibm.com; h=from : to : cc : subject : date : message-id : in-reply-to : references : mime-version : content-transfer-encoding; s=pp1; bh=uRgoLBW6Fxrg8Vr+xFTdA9KIg/grbpnLZwCJZyWXafo=; b=CWHxzpzZsuN0r0CvhOBmwctvmaDqADSPr2rxasPskzIyUSNZU5BFmhFT5+M7XWktYgyT rej0rUdxlgoQ0s4lx7v+c6F3ys9lD2SxowbFsgnN4S359anFK0x4Zose5yLI+7UdIAq4 0h2DAkwse/gwhTS6mICspq+RJN/du2utkn1oVE5Mm1H4hljOd24rIRc11T4Fe+GTqioo PS0yj2LOClXT94O7ts0csryc14mYdzXbrQGvfHxp2OjC9lnuTGFppAoHOo1Q9pfKS7/c jwHOcYbQlCjbBo1HyRoBRLV/6THv+4U0B2tdcI4kF20kcJhj7PKHczpYan4h+OfkWuGJ vg== Received: from pps.reinject (localhost [127.0.0.1]) by mx0a-001b2d01.pphosted.com with ESMTP id 3d1s4e2nue-1 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NOT); Mon, 20 Dec 2021 18:19:22 +0000 Received: from m0098410.ppops.net (m0098410.ppops.net [127.0.0.1]) by pps.reinject (8.16.0.43/8.16.0.43) with SMTP id 1BKIFWU2007316; Mon, 20 Dec 2021 18:19:22 GMT Received: from ppma03dal.us.ibm.com (b.bd.3ea9.ip4.static.sl-reverse.com [169.62.189.11]) by mx0a-001b2d01.pphosted.com with ESMTP id 3d1s4e2nu6-1 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NOT); Mon, 20 Dec 2021 18:19:22 +0000 Received: from pps.filterd (ppma03dal.us.ibm.com [127.0.0.1]) by ppma03dal.us.ibm.com (8.16.1.2/8.16.1.2) with SMTP id 1BKIDR6j016579; Mon, 20 Dec 2021 18:19:21 GMT Received: from b03cxnp07029.gho.boulder.ibm.com (b03cxnp07029.gho.boulder.ibm.com [9.17.130.16]) by ppma03dal.us.ibm.com with ESMTP id 3d179aa9mt-1 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NOT); Mon, 20 Dec 2021 18:19:21 +0000 Received: from b03ledav006.gho.boulder.ibm.com (b03ledav006.gho.boulder.ibm.com [9.17.130.237]) by b03cxnp07029.gho.boulder.ibm.com (8.14.9/8.14.9/NCO v10.0) with ESMTP id 1BKIJKBQ33882620 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-GCM-SHA384 bits=256 verify=OK); Mon, 20 Dec 2021 18:19:20 GMT Received: from b03ledav006.gho.boulder.ibm.com (unknown [127.0.0.1]) by IMSVA (Postfix) with ESMTP id 02FC5C6062; Mon, 20 Dec 2021 18:19:20 +0000 (GMT) Received: from b03ledav006.gho.boulder.ibm.com (unknown [127.0.0.1]) by IMSVA (Postfix) with ESMTP id 6988BC605A; Mon, 20 Dec 2021 18:19:18 +0000 (GMT) Received: from farosas.linux.ibm.com.com (unknown [9.211.60.53]) by b03ledav006.gho.boulder.ibm.com (Postfix) with ESMTP; Mon, 20 Dec 2021 18:19:18 +0000 (GMT) From: Fabiano Rosas To: qemu-devel@nongnu.org Subject: [RFC v2 04/12] target/ppc: powerpc_excp: Stop passing excp_model around Date: Mon, 20 Dec 2021 15:18:55 -0300 Message-Id: <20211220181903.3456898-5-farosas@linux.ibm.com> X-Mailer: git-send-email 2.33.1 In-Reply-To: <20211220181903.3456898-1-farosas@linux.ibm.com> References: <20211220181903.3456898-1-farosas@linux.ibm.com> MIME-Version: 1.0 X-TM-AS-GCONF: 00 X-Proofpoint-ORIG-GUID: LaMR4KF7eGO32gnIVADmI7El0_DsZwuJ X-Proofpoint-GUID: wDOQhdRjFdYdsBWCCcn5ozmb7VhCEEc_ X-Proofpoint-Virus-Version: vendor=baseguard engine=ICAP:2.0.205,Aquarius:18.0.790,Hydra:6.0.425,FMLib:17.11.62.513 definitions=2021-12-20_08,2021-12-20_01,2021-12-02_01 X-Proofpoint-Spam-Details: rule=outbound_notspam policy=outbound score=0 priorityscore=1501 phishscore=0 impostorscore=0 mlxlogscore=999 clxscore=1015 mlxscore=0 suspectscore=0 adultscore=0 lowpriorityscore=0 bulkscore=0 malwarescore=0 spamscore=0 classifier=spam adjust=0 reason=mlx scancount=1 engine=8.12.0-2110150000 definitions=main-2112200101 Received-SPF: pass client-ip=148.163.156.1; envelope-from=farosas@linux.ibm.com; helo=mx0a-001b2d01.pphosted.com X-Spam_score_int: -19 X-Spam_score: -2.0 X-Spam_bar: -- X-Spam_report: (-2.0 / 5.0 requ) BAYES_00=-1.9, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_EF=-0.1, RCVD_IN_MSPIKE_H2=-0.001, SPF_HELO_NONE=0.001, SPF_PASS=-0.001 autolearn=ham autolearn_force=no X-Spam_action: no action X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: danielhb413@gmail.com, qemu-ppc@nongnu.org, clg@kaod.org, david@gibson.dropbear.id.au Errors-To: qemu-devel-bounces+qemu-devel=archiver.kernel.org@nongnu.org Sender: "Qemu-devel" We can just access it directly in powerpc_excp. Signed-off-by: Fabiano Rosas Reviewed-by: Cédric Le Goater Reviewed-by: Richard Henderson Reviewed-by: David Gibson --- target/ppc/excp_helper.c | 43 ++++++++++++++++++++-------------------- 1 file changed, 21 insertions(+), 22 deletions(-) diff --git a/target/ppc/excp_helper.c b/target/ppc/excp_helper.c index 7bdc1e8410..45641f6d1d 100644 --- a/target/ppc/excp_helper.c +++ b/target/ppc/excp_helper.c @@ -293,10 +293,11 @@ static inline void powerpc_set_excp_state(PowerPCCPU *cpu, * Note that this function should be greatly optimized when called * with a constant excp, from ppc_hw_interrupt */ -static inline void powerpc_excp(PowerPCCPU *cpu, int excp_model, int excp) +static inline void powerpc_excp(PowerPCCPU *cpu, int excp) { CPUState *cs = CPU(cpu); CPUPPCState *env = &cpu->env; + int excp_model = env->excp_model; target_ulong msr, new_msr, vector; int srr0, srr1, lev = -1; @@ -878,9 +879,8 @@ static inline void powerpc_excp(PowerPCCPU *cpu, int excp_model, int excp) void ppc_cpu_do_interrupt(CPUState *cs) { PowerPCCPU *cpu = POWERPC_CPU(cs); - CPUPPCState *env = &cpu->env; - powerpc_excp(cpu, env->excp_model, cs->exception_index); + powerpc_excp(cpu, cs->exception_index); } static void ppc_hw_interrupt(CPUPPCState *env) @@ -891,20 +891,20 @@ static void ppc_hw_interrupt(CPUPPCState *env) /* External reset */ if (env->pending_interrupts & (1 << PPC_INTERRUPT_RESET)) { env->pending_interrupts &= ~(1 << PPC_INTERRUPT_RESET); - powerpc_excp(cpu, env->excp_model, POWERPC_EXCP_RESET); + powerpc_excp(cpu, POWERPC_EXCP_RESET); return; } /* Machine check exception */ if (env->pending_interrupts & (1 << PPC_INTERRUPT_MCK)) { env->pending_interrupts &= ~(1 << PPC_INTERRUPT_MCK); - powerpc_excp(cpu, env->excp_model, POWERPC_EXCP_MCHECK); + powerpc_excp(cpu, POWERPC_EXCP_MCHECK); return; } #if 0 /* TODO */ /* External debug exception */ if (env->pending_interrupts & (1 << PPC_INTERRUPT_DEBUG)) { env->pending_interrupts &= ~(1 << PPC_INTERRUPT_DEBUG); - powerpc_excp(cpu, env->excp_model, POWERPC_EXCP_DEBUG); + powerpc_excp(cpu, POWERPC_EXCP_DEBUG); return; } #endif @@ -924,7 +924,7 @@ static void ppc_hw_interrupt(CPUPPCState *env) if ((async_deliver || msr_hv == 0) && hdice) { /* HDEC clears on delivery */ env->pending_interrupts &= ~(1 << PPC_INTERRUPT_HDECR); - powerpc_excp(cpu, env->excp_model, POWERPC_EXCP_HDECR); + powerpc_excp(cpu, POWERPC_EXCP_HDECR); return; } } @@ -934,7 +934,7 @@ static void ppc_hw_interrupt(CPUPPCState *env) /* LPCR will be clear when not supported so this will work */ bool hvice = !!(env->spr[SPR_LPCR] & LPCR_HVICE); if ((async_deliver || msr_hv == 0) && hvice) { - powerpc_excp(cpu, env->excp_model, POWERPC_EXCP_HVIRT); + powerpc_excp(cpu, POWERPC_EXCP_HVIRT); return; } } @@ -946,14 +946,14 @@ static void ppc_hw_interrupt(CPUPPCState *env) /* HEIC blocks delivery to the hypervisor */ if ((async_deliver && !(heic && msr_hv && !msr_pr)) || (env->has_hv_mode && msr_hv == 0 && !lpes0)) { - powerpc_excp(cpu, env->excp_model, POWERPC_EXCP_EXTERNAL); + powerpc_excp(cpu, POWERPC_EXCP_EXTERNAL); return; } } if (msr_ce != 0) { /* External critical interrupt */ if (env->pending_interrupts & (1 << PPC_INTERRUPT_CEXT)) { - powerpc_excp(cpu, env->excp_model, POWERPC_EXCP_CRITICAL); + powerpc_excp(cpu, POWERPC_EXCP_CRITICAL); return; } } @@ -961,24 +961,24 @@ static void ppc_hw_interrupt(CPUPPCState *env) /* Watchdog timer on embedded PowerPC */ if (env->pending_interrupts & (1 << PPC_INTERRUPT_WDT)) { env->pending_interrupts &= ~(1 << PPC_INTERRUPT_WDT); - powerpc_excp(cpu, env->excp_model, POWERPC_EXCP_WDT); + powerpc_excp(cpu, POWERPC_EXCP_WDT); return; } if (env->pending_interrupts & (1 << PPC_INTERRUPT_CDOORBELL)) { env->pending_interrupts &= ~(1 << PPC_INTERRUPT_CDOORBELL); - powerpc_excp(cpu, env->excp_model, POWERPC_EXCP_DOORCI); + powerpc_excp(cpu, POWERPC_EXCP_DOORCI); return; } /* Fixed interval timer on embedded PowerPC */ if (env->pending_interrupts & (1 << PPC_INTERRUPT_FIT)) { env->pending_interrupts &= ~(1 << PPC_INTERRUPT_FIT); - powerpc_excp(cpu, env->excp_model, POWERPC_EXCP_FIT); + powerpc_excp(cpu, POWERPC_EXCP_FIT); return; } /* Programmable interval timer on embedded PowerPC */ if (env->pending_interrupts & (1 << PPC_INTERRUPT_PIT)) { env->pending_interrupts &= ~(1 << PPC_INTERRUPT_PIT); - powerpc_excp(cpu, env->excp_model, POWERPC_EXCP_PIT); + powerpc_excp(cpu, POWERPC_EXCP_PIT); return; } /* Decrementer exception */ @@ -986,32 +986,32 @@ static void ppc_hw_interrupt(CPUPPCState *env) if (ppc_decr_clear_on_delivery(env)) { env->pending_interrupts &= ~(1 << PPC_INTERRUPT_DECR); } - powerpc_excp(cpu, env->excp_model, POWERPC_EXCP_DECR); + powerpc_excp(cpu, POWERPC_EXCP_DECR); return; } if (env->pending_interrupts & (1 << PPC_INTERRUPT_DOORBELL)) { env->pending_interrupts &= ~(1 << PPC_INTERRUPT_DOORBELL); if (is_book3s_arch2x(env)) { - powerpc_excp(cpu, env->excp_model, POWERPC_EXCP_SDOOR); + powerpc_excp(cpu, POWERPC_EXCP_SDOOR); } else { - powerpc_excp(cpu, env->excp_model, POWERPC_EXCP_DOORI); + powerpc_excp(cpu, POWERPC_EXCP_DOORI); } return; } if (env->pending_interrupts & (1 << PPC_INTERRUPT_HDOORBELL)) { env->pending_interrupts &= ~(1 << PPC_INTERRUPT_HDOORBELL); - powerpc_excp(cpu, env->excp_model, POWERPC_EXCP_SDOOR_HV); + powerpc_excp(cpu, POWERPC_EXCP_SDOOR_HV); return; } if (env->pending_interrupts & (1 << PPC_INTERRUPT_PERFM)) { env->pending_interrupts &= ~(1 << PPC_INTERRUPT_PERFM); - powerpc_excp(cpu, env->excp_model, POWERPC_EXCP_PERFM); + powerpc_excp(cpu, POWERPC_EXCP_PERFM); return; } /* Thermal interrupt */ if (env->pending_interrupts & (1 << PPC_INTERRUPT_THERM)) { env->pending_interrupts &= ~(1 << PPC_INTERRUPT_THERM); - powerpc_excp(cpu, env->excp_model, POWERPC_EXCP_THERM); + powerpc_excp(cpu, POWERPC_EXCP_THERM); return; } } @@ -1036,9 +1036,8 @@ static void ppc_hw_interrupt(CPUPPCState *env) void ppc_cpu_do_system_reset(CPUState *cs) { PowerPCCPU *cpu = POWERPC_CPU(cs); - CPUPPCState *env = &cpu->env; - powerpc_excp(cpu, env->excp_model, POWERPC_EXCP_RESET); + powerpc_excp(cpu, POWERPC_EXCP_RESET); } void ppc_cpu_do_fwnmi_machine_check(CPUState *cs, target_ulong vector) From patchwork Mon Dec 20 18:18:56 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Fabiano Rosas X-Patchwork-Id: 12688401 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.lore.kernel.org (Postfix) with ESMTPS id B70EBC433F5 for ; Mon, 20 Dec 2021 19:09:38 +0000 (UTC) Received: from localhost ([::1]:43890 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1mzO2T-0001wJ-LV for qemu-devel@archiver.kernel.org; Mon, 20 Dec 2021 14:09:37 -0500 Received: from eggs.gnu.org ([209.51.188.92]:35806) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1mzNG8-0002w7-3X; Mon, 20 Dec 2021 13:19:40 -0500 Received: from mx0a-001b2d01.pphosted.com ([148.163.156.1]:46932) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1mzNG4-0006kh-Pe; Mon, 20 Dec 2021 13:19:39 -0500 Received: from pps.filterd (m0098394.ppops.net [127.0.0.1]) by mx0a-001b2d01.pphosted.com (8.16.1.2/8.16.1.2) with SMTP id 1BKGSAwr013992; Mon, 20 Dec 2021 18:19:25 GMT DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=ibm.com; h=from : to : cc : subject : date : message-id : in-reply-to : references : mime-version : content-transfer-encoding; s=pp1; bh=YK+PBR7lcRHGIWWc5NuByntqZRVK5PLWrAD32WYqXkw=; b=CaWEpWLFxhRfnt2chkZg9R8ZoLz2tJcY2MFJFodVtfxq1EMlnOeatZwZUAujLYMabqZB ujm4bbz2gALmPZBoOXaKKaNSUitXENgVfFKGEzus8DXU8O8P1gE3tAfGUOhkEZBEM5/m o2/zO+j3YPA9yRTjpdQ/k7wK7FpqlK1yvMtd2o4wjCu/WoDRMe0FDEpcbZr4wlKqT24m CXdySkAC7empqtbb66NpAxcWviZ1MQ1hHSMs/L4IrtA3pIdow5MHaQbDE3onegYFNm00 HLDbJwuq3QR7T8UIyMip+wHTj1gmuvnVOlxXdycXzvKLw5D2Nq1h3NopB7/w2XyobuoG Gw== Received: from pps.reinject (localhost [127.0.0.1]) by mx0a-001b2d01.pphosted.com with ESMTP id 3d1s4wt2y4-1 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NOT); Mon, 20 Dec 2021 18:19:25 +0000 Received: from m0098394.ppops.net (m0098394.ppops.net [127.0.0.1]) by pps.reinject (8.16.0.43/8.16.0.43) with SMTP id 1BKIIwW0024628; Mon, 20 Dec 2021 18:19:24 GMT Received: from ppma03wdc.us.ibm.com (ba.79.3fa9.ip4.static.sl-reverse.com [169.63.121.186]) by mx0a-001b2d01.pphosted.com with ESMTP id 3d1s4wt2xp-1 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NOT); Mon, 20 Dec 2021 18:19:24 +0000 Received: from pps.filterd (ppma03wdc.us.ibm.com [127.0.0.1]) by ppma03wdc.us.ibm.com (8.16.1.2/8.16.1.2) with SMTP id 1BKIHvcq011786; Mon, 20 Dec 2021 18:19:23 GMT Received: from b03cxnp08025.gho.boulder.ibm.com (b03cxnp08025.gho.boulder.ibm.com [9.17.130.17]) by ppma03wdc.us.ibm.com with ESMTP id 3d1799hx17-1 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NOT); Mon, 20 Dec 2021 18:19:23 +0000 Received: from b03ledav006.gho.boulder.ibm.com (b03ledav006.gho.boulder.ibm.com [9.17.130.237]) by b03cxnp08025.gho.boulder.ibm.com (8.14.9/8.14.9/NCO v10.0) with ESMTP id 1BKIJMbA28377420 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-GCM-SHA384 bits=256 verify=OK); Mon, 20 Dec 2021 18:19:22 GMT Received: from b03ledav006.gho.boulder.ibm.com (unknown [127.0.0.1]) by IMSVA (Postfix) with ESMTP id 5EEA2C6069; Mon, 20 Dec 2021 18:19:22 +0000 (GMT) Received: from b03ledav006.gho.boulder.ibm.com (unknown [127.0.0.1]) by IMSVA (Postfix) with ESMTP id 75E24C6067; Mon, 20 Dec 2021 18:19:20 +0000 (GMT) Received: from farosas.linux.ibm.com.com (unknown [9.211.60.53]) by b03ledav006.gho.boulder.ibm.com (Postfix) with ESMTP; Mon, 20 Dec 2021 18:19:20 +0000 (GMT) From: Fabiano Rosas To: qemu-devel@nongnu.org Subject: [RFC v2 05/12] target/ppc: powerpc_excp: Standardize arguments to interrupt code Date: Mon, 20 Dec 2021 15:18:56 -0300 Message-Id: <20211220181903.3456898-6-farosas@linux.ibm.com> X-Mailer: git-send-email 2.33.1 In-Reply-To: <20211220181903.3456898-1-farosas@linux.ibm.com> References: <20211220181903.3456898-1-farosas@linux.ibm.com> MIME-Version: 1.0 X-TM-AS-GCONF: 00 X-Proofpoint-ORIG-GUID: FIuNCMkUa9imRZjNDjd4Ue4JzUpbwqr1 X-Proofpoint-GUID: xEC3y_NWZFmLsdet4juhZ2PzEALAT3mQ X-Proofpoint-Virus-Version: vendor=baseguard engine=ICAP:2.0.205,Aquarius:18.0.790,Hydra:6.0.425,FMLib:17.11.62.513 definitions=2021-12-20_08,2021-12-20_01,2021-12-02_01 X-Proofpoint-Spam-Details: rule=outbound_notspam policy=outbound score=0 malwarescore=0 clxscore=1015 mlxscore=0 bulkscore=0 lowpriorityscore=0 priorityscore=1501 mlxlogscore=999 spamscore=0 impostorscore=0 suspectscore=0 phishscore=0 adultscore=0 classifier=spam adjust=0 reason=mlx scancount=1 engine=8.12.0-2110150000 definitions=main-2112200101 Received-SPF: pass client-ip=148.163.156.1; envelope-from=farosas@linux.ibm.com; helo=mx0a-001b2d01.pphosted.com X-Spam_score_int: -19 X-Spam_score: -2.0 X-Spam_bar: -- X-Spam_report: (-2.0 / 5.0 requ) BAYES_00=-1.9, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_EF=-0.1, RCVD_IN_MSPIKE_H2=-0.001, SPF_HELO_NONE=0.001, SPF_PASS=-0.001 autolearn=ham autolearn_force=no X-Spam_action: no action X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: danielhb413@gmail.com, qemu-ppc@nongnu.org, clg@kaod.org, david@gibson.dropbear.id.au Errors-To: qemu-devel-bounces+qemu-devel=archiver.kernel.org@nongnu.org Sender: "Qemu-devel" In preparation to moving the interrupt code into separate functions, create a PPCIntrArgs structure to serve as a consistent API. No functional change intended. Signed-off-by: Fabiano Rosas --- target/ppc/excp_helper.c | 213 +++++++++++++++++++++------------------ 1 file changed, 113 insertions(+), 100 deletions(-) diff --git a/target/ppc/excp_helper.c b/target/ppc/excp_helper.c index 45641f6d1d..f478ff8a87 100644 --- a/target/ppc/excp_helper.c +++ b/target/ppc/excp_helper.c @@ -164,7 +164,7 @@ static int powerpc_reset_wakeup(CPUState *cs, CPUPPCState *env, int excp, static inline void ppc_excp_apply_ail(PowerPCCPU *cpu, int excp_model, int excp, target_ulong msr, target_ulong *new_msr, - target_ulong *vector) + target_ulong *new_nip) { #if defined(TARGET_PPC64) CPUPPCState *env = &cpu->env; @@ -241,9 +241,9 @@ static inline void ppc_excp_apply_ail(PowerPCCPU *cpu, int excp_model, int excp, if (excp != POWERPC_EXCP_SYSCALL_VECTORED) { if (ail == 2) { - *vector |= 0x0000000000018000ull; + *new_nip |= 0x0000000000018000ull; } else if (ail == 3) { - *vector |= 0xc000000000004000ull; + *new_nip |= 0xc000000000004000ull; } } else { /* @@ -251,15 +251,15 @@ static inline void ppc_excp_apply_ail(PowerPCCPU *cpu, int excp_model, int excp, * only the MSR. AIL=3 replaces the 0x17000 base with 0xc...3000. */ if (ail == 3) { - *vector &= ~0x0000000000017000ull; /* Un-apply the base offset */ - *vector |= 0xc000000000003000ull; /* Apply scv's AIL=3 offset */ + *new_nip &= ~0x0000000000017000ull; /* Un-apply the base offset */ + *new_nip |= 0xc000000000003000ull; /* Apply scv's AIL=3 offset */ } } #endif } -static inline void powerpc_set_excp_state(PowerPCCPU *cpu, - target_ulong vector, target_ulong msr) +static inline void powerpc_set_excp_state(PowerPCCPU *cpu, target_ulong new_nip, + target_ulong new_msr) { CPUState *cs = CPU(cpu); CPUPPCState *env = &cpu->env; @@ -272,9 +272,9 @@ static inline void powerpc_set_excp_state(PowerPCCPU *cpu, * will prevent setting of the HV bit which some exceptions might need * to do. */ - env->msr = msr & env->msr_mask; + env->msr = new_msr & env->msr_mask; hreg_compute_hflags(env); - env->nip = vector; + env->nip = new_nip; /* Reset exception state */ cs->exception_index = POWERPC_EXCP_NONE; env->error_code = 0; @@ -289,6 +289,15 @@ static inline void powerpc_set_excp_state(PowerPCCPU *cpu, check_tlb_flush(env, false); } +typedef struct PPCIntrArgs { + target_ulong nip; + target_ulong msr; + target_ulong new_nip; + target_ulong new_msr; + int sprn_srr0; + int sprn_srr1; +} PPCIntrArgs; + /* * Note that this function should be greatly optimized when called * with a constant excp, from ppc_hw_interrupt @@ -298,35 +307,35 @@ static inline void powerpc_excp(PowerPCCPU *cpu, int excp) CPUState *cs = CPU(cpu); CPUPPCState *env = &cpu->env; int excp_model = env->excp_model; - target_ulong msr, new_msr, vector; - int srr0, srr1, lev = -1; + PPCIntrArgs regs; + int lev = -1; qemu_log_mask(CPU_LOG_INT, "Raise exception at " TARGET_FMT_lx " => %08x (%02x)\n", env->nip, excp, env->error_code); /* new srr1 value excluding must-be-zero bits */ if (excp_model == POWERPC_EXCP_BOOKE) { - msr = env->msr; + regs.msr = env->msr; } else { - msr = env->msr & ~0x783f0000ULL; + regs.msr = env->msr & ~0x783f0000ULL; } + regs.nip = env->nip; /* * new interrupt handler msr preserves existing HV and ME unless * explicitly overriden */ - new_msr = env->msr & (((target_ulong)1 << MSR_ME) | MSR_HVB); + regs.new_msr = env->msr & (((target_ulong)1 << MSR_ME) | MSR_HVB); - /* target registers */ - srr0 = SPR_SRR0; - srr1 = SPR_SRR1; + regs.sprn_srr0 = SPR_SRR0; + regs.sprn_srr1 = SPR_SRR1; /* * check for special resume at 0x100 from doze/nap/sleep/winkle on * P7/P8/P9 */ if (env->resume_as_sreset) { - excp = powerpc_reset_wakeup(cs, env, excp, &msr); + excp = powerpc_reset_wakeup(cs, env, excp, ®s.msr); } /* @@ -353,13 +362,13 @@ static inline void powerpc_excp(PowerPCCPU *cpu, int excp) } #endif - vector = env->excp_vectors[excp]; - if (vector == (target_ulong)-1ULL) { + regs.new_nip = env->excp_vectors[excp]; + if (regs.new_nip == (target_ulong)-1ULL) { cpu_abort(cs, "Raised an exception without defined vector %d\n", excp); } - vector |= env->excp_prefix; + regs.new_nip |= env->excp_prefix; switch (excp) { case POWERPC_EXCP_NONE: @@ -368,12 +377,12 @@ static inline void powerpc_excp(PowerPCCPU *cpu, int excp) case POWERPC_EXCP_CRITICAL: /* Critical input */ switch (excp_model) { case POWERPC_EXCP_40x: - srr0 = SPR_40x_SRR2; - srr1 = SPR_40x_SRR3; + regs.sprn_srr0 = SPR_40x_SRR2; + regs.sprn_srr1 = SPR_40x_SRR3; break; case POWERPC_EXCP_BOOKE: - srr0 = SPR_BOOKE_CSRR0; - srr1 = SPR_BOOKE_CSRR1; + regs.sprn_srr0 = SPR_BOOKE_CSRR0; + regs.sprn_srr1 = SPR_BOOKE_CSRR1; break; case POWERPC_EXCP_G2: break; @@ -401,25 +410,25 @@ static inline void powerpc_excp(PowerPCCPU *cpu, int excp) * ISA specifies HV, but can be delivered to guest with HV * clear (e.g., see FWNMI in PAPR). */ - new_msr |= (target_ulong)MSR_HVB; + regs.new_msr |= (target_ulong)MSR_HVB; } /* machine check exceptions don't have ME set */ - new_msr &= ~((target_ulong)1 << MSR_ME); + regs.new_msr &= ~((target_ulong)1 << MSR_ME); /* XXX: should also have something loaded in DAR / DSISR */ switch (excp_model) { case POWERPC_EXCP_40x: - srr0 = SPR_40x_SRR2; - srr1 = SPR_40x_SRR3; + regs.sprn_srr0 = SPR_40x_SRR2; + regs.sprn_srr1 = SPR_40x_SRR3; break; case POWERPC_EXCP_BOOKE: /* FIXME: choose one or the other based on CPU type */ - srr0 = SPR_BOOKE_MCSRR0; - srr1 = SPR_BOOKE_MCSRR1; + regs.sprn_srr0 = SPR_BOOKE_MCSRR0; + regs.sprn_srr1 = SPR_BOOKE_MCSRR1; - env->spr[SPR_BOOKE_CSRR0] = env->nip; - env->spr[SPR_BOOKE_CSRR1] = msr; + env->spr[SPR_BOOKE_CSRR0] = regs.nip; + env->spr[SPR_BOOKE_CSRR1] = regs.msr; break; default: break; @@ -429,8 +438,8 @@ static inline void powerpc_excp(PowerPCCPU *cpu, int excp) trace_ppc_excp_dsi(env->spr[SPR_DSISR], env->spr[SPR_DAR]); break; case POWERPC_EXCP_ISI: /* Instruction storage exception */ - trace_ppc_excp_isi(msr, env->nip); - msr |= env->error_code; + trace_ppc_excp_isi(regs.msr, regs.nip); + regs.msr |= env->error_code; break; case POWERPC_EXCP_EXTERNAL: /* External input */ { @@ -460,10 +469,10 @@ static inline void powerpc_excp(PowerPCCPU *cpu, int excp) } if (!lpes0) { - new_msr |= (target_ulong)MSR_HVB; - new_msr |= env->msr & ((target_ulong)1 << MSR_RI); - srr0 = SPR_HSRR0; - srr1 = SPR_HSRR1; + regs.new_msr |= (target_ulong)MSR_HVB; + regs.new_msr |= env->msr & ((target_ulong)1 << MSR_RI); + regs.sprn_srr0 = SPR_HSRR0; + regs.sprn_srr1 = SPR_HSRR1; } if (env->mpic_proxy) { /* IACK the IRQ on delivery */ @@ -495,20 +504,20 @@ static inline void powerpc_excp(PowerPCCPU *cpu, int excp) * instruction, so always use store_next and claim we are * precise in the MSR. */ - msr |= 0x00100000; + regs.msr |= 0x00100000; env->spr[SPR_BOOKE_ESR] = ESR_FP; break; case POWERPC_EXCP_INVAL: - trace_ppc_excp_inval(env->nip); - msr |= 0x00080000; + trace_ppc_excp_inval(regs.nip); + regs.msr |= 0x00080000; env->spr[SPR_BOOKE_ESR] = ESR_PIL; break; case POWERPC_EXCP_PRIV: - msr |= 0x00040000; + regs.msr |= 0x00040000; env->spr[SPR_BOOKE_ESR] = ESR_PPR; break; case POWERPC_EXCP_TRAP: - msr |= 0x00020000; + regs.msr |= 0x00020000; env->spr[SPR_BOOKE_ESR] = ESR_PTR; break; default: @@ -529,9 +538,12 @@ static inline void powerpc_excp(PowerPCCPU *cpu, int excp) /* * We need to correct the NIP which in this case is supposed - * to point to the next instruction + * to point to the next instruction. We also set env->nip here + * because the modification needs to be accessible by the + * virtual hypervisor code below. */ - env->nip += 4; + regs.nip += 4; + env->nip = regs.nip; /* "PAPR mode" built-in hypercall emulation */ if ((lev == 1) && cpu->vhyp) { @@ -540,21 +552,22 @@ static inline void powerpc_excp(PowerPCCPU *cpu, int excp) vhc->hypercall(cpu->vhyp, cpu); return; } + if (lev == 1) { - new_msr |= (target_ulong)MSR_HVB; + regs.new_msr |= (target_ulong)MSR_HVB; } break; case POWERPC_EXCP_SYSCALL_VECTORED: /* scv exception */ lev = env->error_code; dump_syscall(env); - env->nip += 4; - new_msr |= env->msr & ((target_ulong)1 << MSR_EE); - new_msr |= env->msr & ((target_ulong)1 << MSR_RI); + regs.nip += 4; + regs.new_msr |= env->msr & ((target_ulong)1 << MSR_EE); + regs.new_msr |= env->msr & ((target_ulong)1 << MSR_RI); - vector += lev * 0x20; + regs.new_nip += lev * 0x20; - env->lr = env->nip; - env->ctr = msr; + env->lr = regs.nip; + env->ctr = regs.msr; break; case POWERPC_EXCP_FPU: /* Floating-point unavailable exception */ case POWERPC_EXCP_APU: /* Auxiliary processor unavailable */ @@ -568,8 +581,8 @@ static inline void powerpc_excp(PowerPCCPU *cpu, int excp) trace_ppc_excp_print("WDT"); switch (excp_model) { case POWERPC_EXCP_BOOKE: - srr0 = SPR_BOOKE_CSRR0; - srr1 = SPR_BOOKE_CSRR1; + regs.sprn_srr0 = SPR_BOOKE_CSRR0; + regs.sprn_srr1 = SPR_BOOKE_CSRR1; break; default: break; @@ -581,12 +594,11 @@ static inline void powerpc_excp(PowerPCCPU *cpu, int excp) case POWERPC_EXCP_DEBUG: /* Debug interrupt */ if (env->flags & POWERPC_FLAG_DE) { /* FIXME: choose one or the other based on CPU type */ - srr0 = SPR_BOOKE_DSRR0; - srr1 = SPR_BOOKE_DSRR1; - - env->spr[SPR_BOOKE_CSRR0] = env->nip; - env->spr[SPR_BOOKE_CSRR1] = msr; + regs.sprn_srr0 = SPR_BOOKE_DSRR0; + regs.sprn_srr1 = SPR_BOOKE_DSRR1; + env->spr[SPR_BOOKE_CSRR0] = regs.nip; + env->spr[SPR_BOOKE_CSRR1] = regs.msr; /* DBSR already modified by caller */ } else { cpu_abort(cs, "Debug exception triggered on unsupported model\n"); @@ -615,22 +627,22 @@ static inline void powerpc_excp(PowerPCCPU *cpu, int excp) case POWERPC_EXCP_DOORI: /* Embedded doorbell interrupt */ break; case POWERPC_EXCP_DOORCI: /* Embedded doorbell critical interrupt */ - srr0 = SPR_BOOKE_CSRR0; - srr1 = SPR_BOOKE_CSRR1; + regs.sprn_srr0 = SPR_BOOKE_CSRR0; + regs.sprn_srr1 = SPR_BOOKE_CSRR1; break; case POWERPC_EXCP_RESET: /* System reset exception */ /* A power-saving exception sets ME, otherwise it is unchanged */ if (msr_pow) { /* indicate that we resumed from power save mode */ - msr |= 0x10000; - new_msr |= ((target_ulong)1 << MSR_ME); + regs.msr |= 0x10000; + regs.new_msr |= ((target_ulong)1 << MSR_ME); } if (env->msr_mask & MSR_HVB) { /* * ISA specifies HV, but can be delivered to guest with HV * clear (e.g., see FWNMI in PAPR, NMI injection in QEMU). */ - new_msr |= (target_ulong)MSR_HVB; + regs.new_msr |= (target_ulong)MSR_HVB; } else { if (msr_pow) { cpu_abort(cs, "Trying to deliver power-saving system reset " @@ -643,7 +655,7 @@ static inline void powerpc_excp(PowerPCCPU *cpu, int excp) case POWERPC_EXCP_TRACE: /* Trace exception */ break; case POWERPC_EXCP_HISI: /* Hypervisor instruction storage exception */ - msr |= env->error_code; + regs.msr |= env->error_code; /* fall through */ case POWERPC_EXCP_HDECR: /* Hypervisor decrementer exception */ case POWERPC_EXCP_HDSI: /* Hypervisor data storage exception */ @@ -652,10 +664,10 @@ static inline void powerpc_excp(PowerPCCPU *cpu, int excp) case POWERPC_EXCP_SDOOR_HV: /* Hypervisor Doorbell interrupt */ case POWERPC_EXCP_HV_EMU: case POWERPC_EXCP_HVIRT: /* Hypervisor virtualization */ - srr0 = SPR_HSRR0; - srr1 = SPR_HSRR1; - new_msr |= (target_ulong)MSR_HVB; - new_msr |= env->msr & ((target_ulong)1 << MSR_RI); + regs.sprn_srr0 = SPR_HSRR0; + regs.sprn_srr1 = SPR_HSRR1; + regs.new_msr |= (target_ulong)MSR_HVB; + regs.new_msr |= env->msr & ((target_ulong)1 << MSR_RI); break; case POWERPC_EXCP_VPU: /* Vector unavailable exception */ case POWERPC_EXCP_VSXU: /* VSX unavailable exception */ @@ -667,10 +679,10 @@ static inline void powerpc_excp(PowerPCCPU *cpu, int excp) case POWERPC_EXCP_HV_FU: /* Hypervisor Facility Unavailable Exception */ #ifdef TARGET_PPC64 env->spr[SPR_HFSCR] |= ((target_ulong)env->error_code << FSCR_IC_POS); - srr0 = SPR_HSRR0; - srr1 = SPR_HSRR1; - new_msr |= (target_ulong)MSR_HVB; - new_msr |= env->msr & ((target_ulong)1 << MSR_RI); + regs.sprn_srr0 = SPR_HSRR0; + regs.sprn_srr1 = SPR_HSRR1; + regs.new_msr |= (target_ulong)MSR_HVB; + regs.new_msr |= env->msr & ((target_ulong)1 << MSR_RI); #endif break; case POWERPC_EXCP_PIT: /* Programmable interval timer interrupt */ @@ -697,8 +709,8 @@ static inline void powerpc_excp(PowerPCCPU *cpu, int excp) case POWERPC_EXCP_603: case POWERPC_EXCP_G2: /* Swap temporary saved registers with GPRs */ - if (!(new_msr & ((target_ulong)1 << MSR_TGPR))) { - new_msr |= (target_ulong)1 << MSR_TGPR; + if (!(regs.new_msr & ((target_ulong)1 << MSR_TGPR))) { + regs.new_msr |= (target_ulong)1 << MSR_TGPR; hreg_swap_gpr_tgpr(env); } /* fall through */ @@ -731,10 +743,10 @@ static inline void powerpc_excp(PowerPCCPU *cpu, int excp) env->error_code); } #endif - msr |= env->crf[0] << 28; - msr |= env->error_code; /* key, D/I, S/L bits */ + regs.msr |= env->crf[0] << 28; + regs.msr |= env->error_code; /* key, D/I, S/L bits */ /* Set way using a LRU mechanism */ - msr |= ((env->last_way + 1) & (env->nb_ways - 1)) << 17; + regs.msr |= ((env->last_way + 1) & (env->nb_ways - 1)) << 17; break; default: cpu_abort(cs, "Invalid TLB miss exception\n"); @@ -800,11 +812,11 @@ static inline void powerpc_excp(PowerPCCPU *cpu, int excp) /* Sanity check */ if (!(env->msr_mask & MSR_HVB)) { - if (new_msr & MSR_HVB) { + if (regs.new_msr & MSR_HVB) { cpu_abort(cs, "Trying to deliver HV exception (MSR) %d with " "no HV support\n", excp); } - if (srr0 == SPR_HSRR0) { + if (regs.sprn_srr0 == SPR_HSRR0) { cpu_abort(cs, "Trying to deliver HV exception (HSRR) %d with " "no HV support\n", excp); } @@ -816,32 +828,32 @@ static inline void powerpc_excp(PowerPCCPU *cpu, int excp) */ #ifdef TARGET_PPC64 if (excp_model == POWERPC_EXCP_POWER7) { - if (!(new_msr & MSR_HVB) && (env->spr[SPR_LPCR] & LPCR_ILE)) { - new_msr |= (target_ulong)1 << MSR_LE; + if (!(regs.new_msr & MSR_HVB) && (env->spr[SPR_LPCR] & LPCR_ILE)) { + regs.new_msr |= (target_ulong)1 << MSR_LE; } } else if (excp_model == POWERPC_EXCP_POWER8) { - if (new_msr & MSR_HVB) { + if (regs.new_msr & MSR_HVB) { if (env->spr[SPR_HID0] & HID0_HILE) { - new_msr |= (target_ulong)1 << MSR_LE; + regs.new_msr |= (target_ulong)1 << MSR_LE; } } else if (env->spr[SPR_LPCR] & LPCR_ILE) { - new_msr |= (target_ulong)1 << MSR_LE; + regs.new_msr |= (target_ulong)1 << MSR_LE; } } else if (excp_model == POWERPC_EXCP_POWER9 || excp_model == POWERPC_EXCP_POWER10) { - if (new_msr & MSR_HVB) { + if (regs.new_msr & MSR_HVB) { if (env->spr[SPR_HID0] & HID0_POWER9_HILE) { - new_msr |= (target_ulong)1 << MSR_LE; + regs.new_msr |= (target_ulong)1 << MSR_LE; } } else if (env->spr[SPR_LPCR] & LPCR_ILE) { - new_msr |= (target_ulong)1 << MSR_LE; + regs.new_msr |= (target_ulong)1 << MSR_LE; } } else if (msr_ile) { - new_msr |= (target_ulong)1 << MSR_LE; + regs.new_msr |= (target_ulong)1 << MSR_LE; } #else if (msr_ile) { - new_msr |= (target_ulong)1 << MSR_LE; + regs.new_msr |= (target_ulong)1 << MSR_LE; } #endif @@ -849,31 +861,32 @@ static inline void powerpc_excp(PowerPCCPU *cpu, int excp) if (excp_model == POWERPC_EXCP_BOOKE) { if (env->spr[SPR_BOOKE_EPCR] & EPCR_ICM) { /* Cat.64-bit: EPCR.ICM is copied to MSR.CM */ - new_msr |= (target_ulong)1 << MSR_CM; + regs.new_msr |= (target_ulong)1 << MSR_CM; } else { - vector = (uint32_t)vector; + regs.new_nip = (uint32_t)regs.new_nip; } } else { if (!msr_isf && !mmu_is_64bit(env->mmu_model)) { - vector = (uint32_t)vector; + regs.new_nip = (uint32_t)regs.new_nip; } else { - new_msr |= (target_ulong)1 << MSR_SF; + regs.new_msr |= (target_ulong)1 << MSR_SF; } } #endif if (excp != POWERPC_EXCP_SYSCALL_VECTORED) { /* Save PC */ - env->spr[srr0] = env->nip; + env->spr[regs.sprn_srr0] = regs.nip; /* Save MSR */ - env->spr[srr1] = msr; + env->spr[regs.sprn_srr1] = regs.msr; } - /* This can update new_msr and vector if AIL applies */ - ppc_excp_apply_ail(cpu, excp_model, excp, msr, &new_msr, &vector); + /* This can update regs.new_msr and regs.new_nip if AIL applies */ + ppc_excp_apply_ail(cpu, excp_model, excp, regs.msr, ®s.new_msr, + ®s.new_nip); - powerpc_set_excp_state(cpu, vector, new_msr); + powerpc_set_excp_state(cpu, regs.new_nip, regs.new_msr); } void ppc_cpu_do_interrupt(CPUState *cs) From patchwork Mon Dec 20 18:18:57 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Fabiano Rosas X-Patchwork-Id: 12688399 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.lore.kernel.org (Postfix) with ESMTPS id 58E11C433FE for ; Mon, 20 Dec 2021 19:07:06 +0000 (UTC) Received: from localhost ([::1]:39332 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1mzO00-0007Gb-09 for qemu-devel@archiver.kernel.org; Mon, 20 Dec 2021 14:07:04 -0500 Received: from eggs.gnu.org ([209.51.188.92]:35900) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1mzNGD-00031G-G1; Mon, 20 Dec 2021 13:19:45 -0500 Received: from mx0a-001b2d01.pphosted.com ([148.163.156.1]:20792) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1mzNG8-0006mQ-Em; Mon, 20 Dec 2021 13:19:45 -0500 Received: from pps.filterd (m0098409.ppops.net [127.0.0.1]) by mx0a-001b2d01.pphosted.com (8.16.1.2/8.16.1.2) with SMTP id 1BKI6aBn005671; Mon, 20 Dec 2021 18:19:28 GMT DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=ibm.com; h=from : to : cc : subject : date : message-id : in-reply-to : references : mime-version : content-transfer-encoding; s=pp1; bh=ST7YdzWAL4N187OmUdDhi/AnB/ulQ74+anXZaWJvrTc=; b=AapkZ7T1zzkpIRMRwAtHjTnKoApdvCTHmpTZb0SJNkQokSPw3JpYyvPv24XikN1zuj1p EsJSuysTahXSmRBTAaQ5uPR5eh5PHzLutikzYS5k+o+6+WdYFhMbEuPTc79FuvcKroaH o2V5ZDqoJYylELL9wfXn9ZbfTf9oNA14+Ap1aPyLhBIjP849I8Gvo3eF7V2Mxknm/Dhc 1UYvJSG4cSVmMVlvHd5EnLtF1EW1Avlk094pPNUi2ALpVSe7PM5AsJQ2hkqXwb2y2AbY l/ChrZRXM14zHQffIz10VXOFkE3yvqKhPg0FYjCYRcZ9apqY4aVS5AclKpeoaBb50DnX Bg== Received: from pps.reinject (localhost [127.0.0.1]) by mx0a-001b2d01.pphosted.com with ESMTP id 3d2q0jtp5s-1 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NOT); Mon, 20 Dec 2021 18:19:28 +0000 Received: from m0098409.ppops.net (m0098409.ppops.net [127.0.0.1]) by pps.reinject (8.16.0.43/8.16.0.43) with SMTP id 1BKIAnV6012556; Mon, 20 Dec 2021 18:19:27 GMT Received: from ppma01dal.us.ibm.com (83.d6.3fa9.ip4.static.sl-reverse.com [169.63.214.131]) by mx0a-001b2d01.pphosted.com with ESMTP id 3d2q0jtp5c-1 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NOT); Mon, 20 Dec 2021 18:19:27 +0000 Received: from pps.filterd (ppma01dal.us.ibm.com [127.0.0.1]) by ppma01dal.us.ibm.com (8.16.1.2/8.16.1.2) with SMTP id 1BKIEub6007232; Mon, 20 Dec 2021 18:19:26 GMT Received: from b03cxnp07027.gho.boulder.ibm.com (b03cxnp07027.gho.boulder.ibm.com [9.17.130.14]) by ppma01dal.us.ibm.com with ESMTP id 3d179aj88c-1 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NOT); Mon, 20 Dec 2021 18:19:26 +0000 Received: from b03ledav006.gho.boulder.ibm.com (b03ledav006.gho.boulder.ibm.com [9.17.130.237]) by b03cxnp07027.gho.boulder.ibm.com (8.14.9/8.14.9/NCO v10.0) with ESMTP id 1BKIJOMm31850754 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-GCM-SHA384 bits=256 verify=OK); Mon, 20 Dec 2021 18:19:24 GMT Received: from b03ledav006.gho.boulder.ibm.com (unknown [127.0.0.1]) by IMSVA (Postfix) with ESMTP id A95CBC6059; Mon, 20 Dec 2021 18:19:24 +0000 (GMT) Received: from b03ledav006.gho.boulder.ibm.com (unknown [127.0.0.1]) by IMSVA (Postfix) with ESMTP id E59B3C606C; Mon, 20 Dec 2021 18:19:22 +0000 (GMT) Received: from farosas.linux.ibm.com.com (unknown [9.211.60.53]) by b03ledav006.gho.boulder.ibm.com (Postfix) with ESMTP; Mon, 20 Dec 2021 18:19:22 +0000 (GMT) From: Fabiano Rosas To: qemu-devel@nongnu.org Subject: [RFC v2 06/12] target/ppc: Extract interrupt routines into a new file Date: Mon, 20 Dec 2021 15:18:57 -0300 Message-Id: <20211220181903.3456898-7-farosas@linux.ibm.com> X-Mailer: git-send-email 2.33.1 In-Reply-To: <20211220181903.3456898-1-farosas@linux.ibm.com> References: <20211220181903.3456898-1-farosas@linux.ibm.com> MIME-Version: 1.0 X-TM-AS-GCONF: 00 X-Proofpoint-GUID: BMF_B9sBc4ymCIuwVKLssCVUoA-Q6noQ X-Proofpoint-ORIG-GUID: KbGt_LHUDxADC0hJHF-e5i_488wd4qL9 X-Proofpoint-Virus-Version: vendor=baseguard engine=ICAP:2.0.205,Aquarius:18.0.790,Hydra:6.0.425,FMLib:17.11.62.513 definitions=2021-12-20_08,2021-12-20_01,2021-12-02_01 X-Proofpoint-Spam-Details: rule=outbound_notspam policy=outbound score=0 malwarescore=0 spamscore=0 impostorscore=0 bulkscore=0 clxscore=1015 mlxlogscore=999 phishscore=0 adultscore=0 suspectscore=0 priorityscore=1501 mlxscore=0 lowpriorityscore=0 classifier=spam adjust=0 reason=mlx scancount=1 engine=8.12.0-2110150000 definitions=main-2112200101 Received-SPF: pass client-ip=148.163.156.1; envelope-from=farosas@linux.ibm.com; helo=mx0a-001b2d01.pphosted.com X-Spam_score_int: -19 X-Spam_score: -2.0 X-Spam_bar: -- X-Spam_report: (-2.0 / 5.0 requ) BAYES_00=-1.9, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_EF=-0.1, RCVD_IN_MSPIKE_H2=-0.001, SPF_HELO_NONE=0.001, SPF_PASS=-0.001 autolearn=ham autolearn_force=no X-Spam_action: no action X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: danielhb413@gmail.com, qemu-ppc@nongnu.org, clg@kaod.org, david@gibson.dropbear.id.au Errors-To: qemu-devel-bounces+qemu-devel=archiver.kernel.org@nongnu.org Sender: "Qemu-devel" Extract the interrupt setup routines into their own functions and put everything in a separate file. These routines will be made independent of exception model in the following patches. This change is just to facilitate the review. No funcional change intended. Signed-off-by: Fabiano Rosas --- target/ppc/excp_helper.c | 434 ++++---------------------- target/ppc/interrupts.c | 645 +++++++++++++++++++++++++++++++++++++++ target/ppc/meson.build | 1 + target/ppc/ppc_intr.h | 61 ++++ 4 files changed, 769 insertions(+), 372 deletions(-) create mode 100644 target/ppc/interrupts.c create mode 100644 target/ppc/ppc_intr.h diff --git a/target/ppc/excp_helper.c b/target/ppc/excp_helper.c index f478ff8a87..bc20499b6c 100644 --- a/target/ppc/excp_helper.c +++ b/target/ppc/excp_helper.c @@ -23,6 +23,10 @@ #include "internal.h" #include "helper_regs.h" +#if !defined(CONFIG_USER_ONLY) +#include "ppc_intr.h" +#endif + #include "trace.h" #ifdef CONFIG_TCG @@ -30,39 +34,10 @@ #include "exec/cpu_ldst.h" #endif -/* #define DEBUG_SOFTWARE_TLB */ - /*****************************************************************************/ /* Exception processing */ #if !defined(CONFIG_USER_ONLY) -static inline void dump_syscall(CPUPPCState *env) -{ - qemu_log_mask(CPU_LOG_INT, "syscall r0=%016" PRIx64 - " r3=%016" PRIx64 " r4=%016" PRIx64 " r5=%016" PRIx64 - " r6=%016" PRIx64 " r7=%016" PRIx64 " r8=%016" PRIx64 - " nip=" TARGET_FMT_lx "\n", - ppc_dump_gpr(env, 0), ppc_dump_gpr(env, 3), - ppc_dump_gpr(env, 4), ppc_dump_gpr(env, 5), - ppc_dump_gpr(env, 6), ppc_dump_gpr(env, 7), - ppc_dump_gpr(env, 8), env->nip); -} - -static inline void dump_hcall(CPUPPCState *env) -{ - qemu_log_mask(CPU_LOG_INT, "hypercall r3=%016" PRIx64 - " r4=%016" PRIx64 " r5=%016" PRIx64 " r6=%016" PRIx64 - " r7=%016" PRIx64 " r8=%016" PRIx64 " r9=%016" PRIx64 - " r10=%016" PRIx64 " r11=%016" PRIx64 " r12=%016" PRIx64 - " nip=" TARGET_FMT_lx "\n", - ppc_dump_gpr(env, 3), ppc_dump_gpr(env, 4), - ppc_dump_gpr(env, 5), ppc_dump_gpr(env, 6), - ppc_dump_gpr(env, 7), ppc_dump_gpr(env, 8), - ppc_dump_gpr(env, 9), ppc_dump_gpr(env, 10), - ppc_dump_gpr(env, 11), ppc_dump_gpr(env, 12), - env->nip); -} - static int powerpc_reset_wakeup(CPUState *cs, CPUPPCState *env, int excp, target_ulong *msr) { @@ -289,15 +264,6 @@ static inline void powerpc_set_excp_state(PowerPCCPU *cpu, target_ulong new_nip, check_tlb_flush(env, false); } -typedef struct PPCIntrArgs { - target_ulong nip; - target_ulong msr; - target_ulong new_nip; - target_ulong new_msr; - int sprn_srr0; - int sprn_srr1; -} PPCIntrArgs; - /* * Note that this function should be greatly optimized when called * with a constant excp, from ppc_hw_interrupt @@ -308,7 +274,7 @@ static inline void powerpc_excp(PowerPCCPU *cpu, int excp) CPUPPCState *env = &cpu->env; int excp_model = env->excp_model; PPCIntrArgs regs; - int lev = -1; + bool ignore = false; qemu_log_mask(CPU_LOG_INT, "Raise exception at " TARGET_FMT_lx " => %08x (%02x)\n", env->nip, excp, env->error_code); @@ -374,442 +340,166 @@ static inline void powerpc_excp(PowerPCCPU *cpu, int excp) case POWERPC_EXCP_NONE: /* Should never happen */ return; + case POWERPC_EXCP_CRITICAL: /* Critical input */ - switch (excp_model) { - case POWERPC_EXCP_40x: - regs.sprn_srr0 = SPR_40x_SRR2; - regs.sprn_srr1 = SPR_40x_SRR3; - break; - case POWERPC_EXCP_BOOKE: - regs.sprn_srr0 = SPR_BOOKE_CSRR0; - regs.sprn_srr1 = SPR_BOOKE_CSRR1; - break; - case POWERPC_EXCP_G2: - break; - default: - goto excp_invalid; - } + ppc_intr_critical(cpu, ®s, &ignore); break; case POWERPC_EXCP_MCHECK: /* Machine check exception */ - if (msr_me == 0) { - /* - * Machine check exception is not enabled. Enter - * checkstop state. - */ - fprintf(stderr, "Machine check while not allowed. " - "Entering checkstop state\n"); - if (qemu_log_separate()) { - qemu_log("Machine check while not allowed. " - "Entering checkstop state\n"); - } - cs->halted = 1; - cpu_interrupt_exittb(cs); - } - if (env->msr_mask & MSR_HVB) { - /* - * ISA specifies HV, but can be delivered to guest with HV - * clear (e.g., see FWNMI in PAPR). - */ - regs.new_msr |= (target_ulong)MSR_HVB; - } - - /* machine check exceptions don't have ME set */ - regs.new_msr &= ~((target_ulong)1 << MSR_ME); - - /* XXX: should also have something loaded in DAR / DSISR */ - switch (excp_model) { - case POWERPC_EXCP_40x: - regs.sprn_srr0 = SPR_40x_SRR2; - regs.sprn_srr1 = SPR_40x_SRR3; - break; - case POWERPC_EXCP_BOOKE: - /* FIXME: choose one or the other based on CPU type */ - regs.sprn_srr0 = SPR_BOOKE_MCSRR0; - regs.sprn_srr1 = SPR_BOOKE_MCSRR1; - - env->spr[SPR_BOOKE_CSRR0] = regs.nip; - env->spr[SPR_BOOKE_CSRR1] = regs.msr; - break; - default: - break; - } + ppc_intr_machine_check(cpu, ®s, &ignore); break; case POWERPC_EXCP_DSI: /* Data storage exception */ - trace_ppc_excp_dsi(env->spr[SPR_DSISR], env->spr[SPR_DAR]); + ppc_intr_data_storage(cpu, ®s, &ignore); break; case POWERPC_EXCP_ISI: /* Instruction storage exception */ - trace_ppc_excp_isi(regs.msr, regs.nip); - regs.msr |= env->error_code; + ppc_intr_insn_storage(cpu, ®s, &ignore); break; case POWERPC_EXCP_EXTERNAL: /* External input */ - { - bool lpes0; - - cs = CPU(cpu); - - /* - * Exception targeting modifiers - * - * LPES0 is supported on POWER7/8/9 - * LPES1 is not supported (old iSeries mode) - * - * On anything else, we behave as if LPES0 is 1 - * (externals don't alter MSR:HV) - */ -#if defined(TARGET_PPC64) - if (excp_model == POWERPC_EXCP_POWER7 || - excp_model == POWERPC_EXCP_POWER8 || - excp_model == POWERPC_EXCP_POWER9 || - excp_model == POWERPC_EXCP_POWER10) { - lpes0 = !!(env->spr[SPR_LPCR] & LPCR_LPES0); - } else -#endif /* defined(TARGET_PPC64) */ - { - lpes0 = true; - } - - if (!lpes0) { - regs.new_msr |= (target_ulong)MSR_HVB; - regs.new_msr |= env->msr & ((target_ulong)1 << MSR_RI); - regs.sprn_srr0 = SPR_HSRR0; - regs.sprn_srr1 = SPR_HSRR1; - } - if (env->mpic_proxy) { - /* IACK the IRQ on delivery */ - env->spr[SPR_BOOKE_EPR] = ldl_phys(cs->as, env->mpic_iack); - } + ppc_intr_external(cpu, ®s, &ignore); break; - } case POWERPC_EXCP_ALIGN: /* Alignment exception */ - /* Get rS/rD and rA from faulting opcode */ - /* - * Note: the opcode fields will not be set properly for a - * direct store load/store, but nobody cares as nobody - * actually uses direct store segments. - */ - env->spr[SPR_DSISR] |= (env->error_code & 0x03FF0000) >> 16; + ppc_intr_alignment(cpu, ®s, &ignore); break; case POWERPC_EXCP_PROGRAM: /* Program exception */ - switch (env->error_code & ~0xF) { - case POWERPC_EXCP_FP: - if ((msr_fe0 == 0 && msr_fe1 == 0) || msr_fp == 0) { - trace_ppc_excp_fp_ignore(); - cs->exception_index = POWERPC_EXCP_NONE; - env->error_code = 0; - return; - } - - /* - * FP exceptions always have NIP pointing to the faulting - * instruction, so always use store_next and claim we are - * precise in the MSR. - */ - regs.msr |= 0x00100000; - env->spr[SPR_BOOKE_ESR] = ESR_FP; - break; - case POWERPC_EXCP_INVAL: - trace_ppc_excp_inval(regs.nip); - regs.msr |= 0x00080000; - env->spr[SPR_BOOKE_ESR] = ESR_PIL; - break; - case POWERPC_EXCP_PRIV: - regs.msr |= 0x00040000; - env->spr[SPR_BOOKE_ESR] = ESR_PPR; - break; - case POWERPC_EXCP_TRAP: - regs.msr |= 0x00020000; - env->spr[SPR_BOOKE_ESR] = ESR_PTR; - break; - default: - /* Should never occur */ - cpu_abort(cs, "Invalid program exception %d. Aborting\n", - env->error_code); - break; - } + ppc_intr_program(cpu, ®s, &ignore); break; case POWERPC_EXCP_SYSCALL: /* System call exception */ - lev = env->error_code; - - if ((lev == 1) && cpu->vhyp) { - dump_hcall(env); - } else { - dump_syscall(env); - } - - /* - * We need to correct the NIP which in this case is supposed - * to point to the next instruction. We also set env->nip here - * because the modification needs to be accessible by the - * virtual hypervisor code below. - */ - regs.nip += 4; - env->nip = regs.nip; - - /* "PAPR mode" built-in hypercall emulation */ - if ((lev == 1) && cpu->vhyp) { - PPCVirtualHypervisorClass *vhc = - PPC_VIRTUAL_HYPERVISOR_GET_CLASS(cpu->vhyp); - vhc->hypercall(cpu->vhyp, cpu); - return; - } - - if (lev == 1) { - regs.new_msr |= (target_ulong)MSR_HVB; - } + ppc_intr_system_call(cpu, ®s, &ignore); break; case POWERPC_EXCP_SYSCALL_VECTORED: /* scv exception */ - lev = env->error_code; - dump_syscall(env); - regs.nip += 4; - regs.new_msr |= env->msr & ((target_ulong)1 << MSR_EE); - regs.new_msr |= env->msr & ((target_ulong)1 << MSR_RI); - - regs.new_nip += lev * 0x20; - - env->lr = regs.nip; - env->ctr = regs.msr; + ppc_intr_system_call_vectored(cpu, ®s, &ignore); break; case POWERPC_EXCP_FPU: /* Floating-point unavailable exception */ case POWERPC_EXCP_APU: /* Auxiliary processor unavailable */ case POWERPC_EXCP_DECR: /* Decrementer exception */ break; case POWERPC_EXCP_FIT: /* Fixed-interval timer interrupt */ - /* FIT on 4xx */ - trace_ppc_excp_print("FIT"); + ppc_intr_fit(cpu, ®s, &ignore); break; case POWERPC_EXCP_WDT: /* Watchdog timer interrupt */ - trace_ppc_excp_print("WDT"); - switch (excp_model) { - case POWERPC_EXCP_BOOKE: - regs.sprn_srr0 = SPR_BOOKE_CSRR0; - regs.sprn_srr1 = SPR_BOOKE_CSRR1; - break; - default: - break; - } + ppc_intr_watchdog(cpu, ®s, &ignore); break; case POWERPC_EXCP_DTLB: /* Data TLB error */ case POWERPC_EXCP_ITLB: /* Instruction TLB error */ break; case POWERPC_EXCP_DEBUG: /* Debug interrupt */ - if (env->flags & POWERPC_FLAG_DE) { - /* FIXME: choose one or the other based on CPU type */ - regs.sprn_srr0 = SPR_BOOKE_DSRR0; - regs.sprn_srr1 = SPR_BOOKE_DSRR1; - - env->spr[SPR_BOOKE_CSRR0] = regs.nip; - env->spr[SPR_BOOKE_CSRR1] = regs.msr; - /* DBSR already modified by caller */ - } else { - cpu_abort(cs, "Debug exception triggered on unsupported model\n"); - } + ppc_intr_debug(cpu, ®s, &ignore); break; case POWERPC_EXCP_SPEU: /* SPE/embedded floating-point unavailable/VPU */ - env->spr[SPR_BOOKE_ESR] = ESR_SPV; + ppc_intr_spe_unavailable(cpu, ®s, &ignore); break; case POWERPC_EXCP_EFPDI: /* Embedded floating-point data interrupt */ - /* XXX: TODO */ - cpu_abort(cs, "Embedded floating point data exception " - "is not implemented yet !\n"); - env->spr[SPR_BOOKE_ESR] = ESR_SPV; + ppc_intr_embedded_fp_data(cpu, ®s, &ignore); break; case POWERPC_EXCP_EFPRI: /* Embedded floating-point round interrupt */ - /* XXX: TODO */ - cpu_abort(cs, "Embedded floating point round exception " - "is not implemented yet !\n"); - env->spr[SPR_BOOKE_ESR] = ESR_SPV; + ppc_intr_embedded_fp_round(cpu, ®s, &ignore); break; case POWERPC_EXCP_EPERFM: /* Embedded performance monitor interrupt */ - /* XXX: TODO */ - cpu_abort(cs, - "Performance counter exception is not implemented yet !\n"); + ppc_intr_embedded_perf_monitor(cpu, ®s, &ignore); break; case POWERPC_EXCP_DOORI: /* Embedded doorbell interrupt */ break; case POWERPC_EXCP_DOORCI: /* Embedded doorbell critical interrupt */ - regs.sprn_srr0 = SPR_BOOKE_CSRR0; - regs.sprn_srr1 = SPR_BOOKE_CSRR1; + ppc_intr_embedded_doorbell_crit(cpu, ®s, &ignore); break; case POWERPC_EXCP_RESET: /* System reset exception */ - /* A power-saving exception sets ME, otherwise it is unchanged */ - if (msr_pow) { - /* indicate that we resumed from power save mode */ - regs.msr |= 0x10000; - regs.new_msr |= ((target_ulong)1 << MSR_ME); - } - if (env->msr_mask & MSR_HVB) { - /* - * ISA specifies HV, but can be delivered to guest with HV - * clear (e.g., see FWNMI in PAPR, NMI injection in QEMU). - */ - regs.new_msr |= (target_ulong)MSR_HVB; - } else { - if (msr_pow) { - cpu_abort(cs, "Trying to deliver power-saving system reset " - "exception %d with no HV support\n", excp); - } - } + ppc_intr_system_reset(cpu, ®s, &ignore); break; case POWERPC_EXCP_DSEG: /* Data segment exception */ case POWERPC_EXCP_ISEG: /* Instruction segment exception */ case POWERPC_EXCP_TRACE: /* Trace exception */ break; case POWERPC_EXCP_HISI: /* Hypervisor instruction storage exception */ - regs.msr |= env->error_code; - /* fall through */ + ppc_intr_hv_insn_storage(cpu, ®s, &ignore); + break; case POWERPC_EXCP_HDECR: /* Hypervisor decrementer exception */ + ppc_intr_hv_decrementer(cpu, ®s, &ignore); + break; case POWERPC_EXCP_HDSI: /* Hypervisor data storage exception */ + ppc_intr_hv_data_storage(cpu, ®s, &ignore); + break; case POWERPC_EXCP_HDSEG: /* Hypervisor data segment exception */ + ppc_intr_hv_data_segment(cpu, ®s, &ignore); + break; case POWERPC_EXCP_HISEG: /* Hypervisor instruction segment exception */ + ppc_intr_hv_insn_segment(cpu, ®s, &ignore); + break; case POWERPC_EXCP_SDOOR_HV: /* Hypervisor Doorbell interrupt */ + ppc_intr_hv_doorbell(cpu, ®s, &ignore); + break; case POWERPC_EXCP_HV_EMU: + ppc_intr_hv_emulation(cpu, ®s, &ignore); + break; case POWERPC_EXCP_HVIRT: /* Hypervisor virtualization */ - regs.sprn_srr0 = SPR_HSRR0; - regs.sprn_srr1 = SPR_HSRR1; - regs.new_msr |= (target_ulong)MSR_HVB; - regs.new_msr |= env->msr & ((target_ulong)1 << MSR_RI); + ppc_intr_hv_virtualization(cpu, ®s, &ignore); break; case POWERPC_EXCP_VPU: /* Vector unavailable exception */ case POWERPC_EXCP_VSXU: /* VSX unavailable exception */ case POWERPC_EXCP_FU: /* Facility unavailable exception */ -#ifdef TARGET_PPC64 - env->spr[SPR_FSCR] |= ((target_ulong)env->error_code << 56); -#endif + ppc_intr_facility_unavail(cpu, ®s, &ignore); break; case POWERPC_EXCP_HV_FU: /* Hypervisor Facility Unavailable Exception */ -#ifdef TARGET_PPC64 - env->spr[SPR_HFSCR] |= ((target_ulong)env->error_code << FSCR_IC_POS); - regs.sprn_srr0 = SPR_HSRR0; - regs.sprn_srr1 = SPR_HSRR1; - regs.new_msr |= (target_ulong)MSR_HVB; - regs.new_msr |= env->msr & ((target_ulong)1 << MSR_RI); -#endif + ppc_intr_hv_facility_unavail(cpu, ®s, &ignore); break; case POWERPC_EXCP_PIT: /* Programmable interval timer interrupt */ - trace_ppc_excp_print("PIT"); + ppc_intr_programmable_timer(cpu, ®s, &ignore); break; case POWERPC_EXCP_IO: /* IO error exception */ - /* XXX: TODO */ - cpu_abort(cs, "601 IO error exception is not implemented yet !\n"); + ppc_intr_io_error(cpu, ®s, &ignore); break; case POWERPC_EXCP_RUNM: /* Run mode exception */ - /* XXX: TODO */ - cpu_abort(cs, "601 run mode exception is not implemented yet !\n"); + ppc_intr_run_mode(cpu, ®s, &ignore); break; case POWERPC_EXCP_EMUL: /* Emulation trap exception */ - /* XXX: TODO */ - cpu_abort(cs, "602 emulation trap exception " - "is not implemented yet !\n"); + ppc_intr_emulation(cpu, ®s, &ignore); break; case POWERPC_EXCP_IFTLB: /* Instruction fetch TLB error */ case POWERPC_EXCP_DLTLB: /* Data load TLB miss */ case POWERPC_EXCP_DSTLB: /* Data store TLB miss */ - switch (excp_model) { - case POWERPC_EXCP_602: - case POWERPC_EXCP_603: - case POWERPC_EXCP_G2: - /* Swap temporary saved registers with GPRs */ - if (!(regs.new_msr & ((target_ulong)1 << MSR_TGPR))) { - regs.new_msr |= (target_ulong)1 << MSR_TGPR; - hreg_swap_gpr_tgpr(env); - } - /* fall through */ - case POWERPC_EXCP_7x5: -#if defined(DEBUG_SOFTWARE_TLB) - if (qemu_log_enabled()) { - const char *es; - target_ulong *miss, *cmp; - int en; - - if (excp == POWERPC_EXCP_IFTLB) { - es = "I"; - en = 'I'; - miss = &env->spr[SPR_IMISS]; - cmp = &env->spr[SPR_ICMP]; - } else { - if (excp == POWERPC_EXCP_DLTLB) { - es = "DL"; - } else { - es = "DS"; - } - en = 'D'; - miss = &env->spr[SPR_DMISS]; - cmp = &env->spr[SPR_DCMP]; - } - qemu_log("6xx %sTLB miss: %cM " TARGET_FMT_lx " %cC " - TARGET_FMT_lx " H1 " TARGET_FMT_lx " H2 " - TARGET_FMT_lx " %08x\n", es, en, *miss, en, *cmp, - env->spr[SPR_HASH1], env->spr[SPR_HASH2], - env->error_code); - } -#endif - regs.msr |= env->crf[0] << 28; - regs.msr |= env->error_code; /* key, D/I, S/L bits */ - /* Set way using a LRU mechanism */ - regs.msr |= ((env->last_way + 1) & (env->nb_ways - 1)) << 17; - break; - default: - cpu_abort(cs, "Invalid TLB miss exception\n"); - break; - } + ppc_intr_tlb_miss(cpu, ®s, &ignore); break; case POWERPC_EXCP_FPA: /* Floating-point assist exception */ - /* XXX: TODO */ - cpu_abort(cs, "Floating point assist exception " - "is not implemented yet !\n"); + ppc_intr_fpa(cpu, ®s, &ignore); break; case POWERPC_EXCP_DABR: /* Data address breakpoint */ - /* XXX: TODO */ - cpu_abort(cs, "DABR exception is not implemented yet !\n"); + ppc_intr_dabr(cpu, ®s, &ignore); break; case POWERPC_EXCP_IABR: /* Instruction address breakpoint */ - /* XXX: TODO */ - cpu_abort(cs, "IABR exception is not implemented yet !\n"); + ppc_intr_iabr(cpu, ®s, &ignore); break; case POWERPC_EXCP_SMI: /* System management interrupt */ - /* XXX: TODO */ - cpu_abort(cs, "SMI exception is not implemented yet !\n"); + ppc_intr_smi(cpu, ®s, &ignore); break; case POWERPC_EXCP_THERM: /* Thermal interrupt */ - /* XXX: TODO */ - cpu_abort(cs, "Thermal management exception " - "is not implemented yet !\n"); + ppc_intr_therm(cpu, ®s, &ignore); break; case POWERPC_EXCP_PERFM: /* Embedded performance monitor interrupt */ - /* XXX: TODO */ - cpu_abort(cs, - "Performance counter exception is not implemented yet !\n"); + ppc_intr_perfm(cpu, ®s, &ignore); break; case POWERPC_EXCP_VPUA: /* Vector assist exception */ - /* XXX: TODO */ - cpu_abort(cs, "VPU assist exception is not implemented yet !\n"); + ppc_intr_vpua(cpu, ®s, &ignore); break; case POWERPC_EXCP_SOFTP: /* Soft patch exception */ - /* XXX: TODO */ - cpu_abort(cs, - "970 soft-patch exception is not implemented yet !\n"); + ppc_intr_softp(cpu, ®s, &ignore); break; case POWERPC_EXCP_MAINT: /* Maintenance exception */ - /* XXX: TODO */ - cpu_abort(cs, - "970 maintenance exception is not implemented yet !\n"); + ppc_intr_maint(cpu, ®s, &ignore); break; case POWERPC_EXCP_MEXTBR: /* Maskable external breakpoint */ - /* XXX: TODO */ - cpu_abort(cs, "Maskable external exception " - "is not implemented yet !\n"); + ppc_intr_mextbr(cpu, ®s, &ignore); break; case POWERPC_EXCP_NMEXTBR: /* Non maskable external breakpoint */ - /* XXX: TODO */ - cpu_abort(cs, "Non maskable external exception " - "is not implemented yet !\n"); + ppc_intr_nmextbr(cpu, ®s, &ignore); break; default: - excp_invalid: cpu_abort(cs, "Invalid PowerPC exception %d. Aborting\n", excp); break; } + if (ignore) { + /* No further setup is needed for this interrupt */ + return; + } + /* Sanity check */ if (!(env->msr_mask & MSR_HVB)) { if (regs.new_msr & MSR_HVB) { diff --git a/target/ppc/interrupts.c b/target/ppc/interrupts.c new file mode 100644 index 0000000000..0168ce03a7 --- /dev/null +++ b/target/ppc/interrupts.c @@ -0,0 +1,645 @@ +/* + * PowerPC interrupt emulation. + * + * Copyright (C) 2021 IBM Corporation. + * + * This code is licensed under the GPL version 2 or later. See the + * COPYING file in the top-level directory. + */ +#include "qemu/osdep.h" +#include "qemu/log.h" +#include "cpu.h" +#include "ppc_intr.h" +#include "trace.h" + +/* for hreg_swap_gpr_tgpr */ +#include "helper_regs.h" + +/* #define DEBUG_SOFTWARE_TLB */ + +void ppc_intr_critical(PowerPCCPU *cpu, PPCIntrArgs *regs, bool *ignore) +{ + CPUPPCState *env = &cpu->env; + int excp_model = env->excp_model; + + switch (excp_model) { + case POWERPC_EXCP_40x: + regs->sprn_srr0 = SPR_40x_SRR2; + regs->sprn_srr1 = SPR_40x_SRR3; + break; + case POWERPC_EXCP_BOOKE: + regs->sprn_srr0 = SPR_BOOKE_CSRR0; + regs->sprn_srr1 = SPR_BOOKE_CSRR1; + break; + case POWERPC_EXCP_G2: + break; + default: + cpu_abort(CPU(cpu), "Invalid PowerPC critical exception. Aborting\n"); + break; + } +} + +void ppc_intr_machine_check(PowerPCCPU *cpu, PPCIntrArgs *regs, bool *ignore) +{ + CPUState *cs = CPU(cpu); + CPUPPCState *env = &cpu->env; + int excp_model = env->excp_model; + + if (msr_me == 0) { + /* + * Machine check exception is not enabled. Enter + * checkstop state. + */ + fprintf(stderr, "Machine check while not allowed. " + "Entering checkstop state\n"); + if (qemu_log_separate()) { + qemu_log("Machine check while not allowed. " + "Entering checkstop state\n"); + } + cs->halted = 1; + cpu_interrupt_exittb(cs); + } + if (env->msr_mask & MSR_HVB) { + /* + * ISA specifies HV, but can be delivered to guest with HV + * clear (e.g., see FWNMI in PAPR). + */ + regs->new_msr |= (target_ulong)MSR_HVB; + } + + /* machine check exceptions don't have ME set */ + regs->new_msr &= ~((target_ulong)1 << MSR_ME); + + /* XXX: should also have something loaded in DAR / DSISR */ + switch (excp_model) { + case POWERPC_EXCP_40x: + regs->sprn_srr0 = SPR_40x_SRR2; + regs->sprn_srr1 = SPR_40x_SRR3; + break; + case POWERPC_EXCP_BOOKE: + /* FIXME: choose one or the other based on CPU type */ + regs->sprn_srr0 = SPR_BOOKE_MCSRR0; + regs->sprn_srr1 = SPR_BOOKE_MCSRR1; + + env->spr[SPR_BOOKE_CSRR0] = regs->nip; + env->spr[SPR_BOOKE_CSRR1] = regs->msr; + break; + default: + break; + } +} + +void ppc_intr_data_storage(PowerPCCPU *cpu, PPCIntrArgs *regs, bool *ignore) +{ + CPUPPCState *env = &cpu->env; + + trace_ppc_excp_dsi(env->spr[SPR_DSISR], env->spr[SPR_DAR]); +} + + +void ppc_intr_insn_storage(PowerPCCPU *cpu, PPCIntrArgs *regs, bool *ignore) +{ + CPUPPCState *env = &cpu->env; + + trace_ppc_excp_isi(regs->msr, regs->nip); + + regs->msr |= env->error_code; +} + +void ppc_intr_external(PowerPCCPU *cpu, PPCIntrArgs *regs, bool *ignore) +{ + CPUState *cs = CPU(cpu); + CPUPPCState *env = &cpu->env; + bool lpes0; +#if defined(TARGET_PPC64) + int excp_model = env->excp_model; +#endif /* defined(TARGET_PPC64) */ + + /* + * Exception targeting modifiers + * + * LPES0 is supported on POWER7/8/9 + * LPES1 is not supported (old iSeries mode) + * + * On anything else, we behave as if LPES0 is 1 + * (externals don't alter MSR:HV) + */ +#if defined(TARGET_PPC64) + if (excp_model == POWERPC_EXCP_POWER7 || + excp_model == POWERPC_EXCP_POWER8 || + excp_model == POWERPC_EXCP_POWER9 || + excp_model == POWERPC_EXCP_POWER10) { + lpes0 = !!(env->spr[SPR_LPCR] & LPCR_LPES0); + } else +#endif /* defined(TARGET_PPC64) */ + { + lpes0 = true; + } + + if (!lpes0) { + regs->new_msr |= (target_ulong)MSR_HVB; + regs->new_msr |= env->msr & ((target_ulong)1 << MSR_RI); + regs->sprn_srr0 = SPR_HSRR0; + regs->sprn_srr1 = SPR_HSRR1; + } + if (env->mpic_proxy) { + /* IACK the IRQ on delivery */ + env->spr[SPR_BOOKE_EPR] = ldl_phys(cs->as, env->mpic_iack); + } +} + +void ppc_intr_alignment(PowerPCCPU *cpu, PPCIntrArgs *regs, bool *ignore) +{ + CPUPPCState *env = &cpu->env; + + /* Get rS/rD and rA from faulting opcode */ + /* + * Note: the opcode fields will not be set properly for a + * direct store load/store, but nobody cares as nobody + * actually uses direct store segments. + */ + env->spr[SPR_DSISR] |= (env->error_code & 0x03FF0000) >> 16; +} + +void ppc_intr_program(PowerPCCPU *cpu, PPCIntrArgs *regs, bool *ignore) +{ + CPUState *cs = CPU(cpu); + CPUPPCState *env = &cpu->env; + + switch (env->error_code & ~0xF) { + case POWERPC_EXCP_FP: + if ((msr_fe0 == 0 && msr_fe1 == 0) || msr_fp == 0) { + trace_ppc_excp_fp_ignore(); + cs->exception_index = POWERPC_EXCP_NONE; + env->error_code = 0; + + *ignore = true; + return; + } + + /* + * FP exceptions always have NIP pointing to the faulting + * instruction, so always use store_next and claim we are + * precise in the MSR. + */ + regs->msr |= 0x00100000; + env->spr[SPR_BOOKE_ESR] = ESR_FP; + break; + case POWERPC_EXCP_INVAL: + trace_ppc_excp_inval(regs->nip); + regs->msr |= 0x00080000; + env->spr[SPR_BOOKE_ESR] = ESR_PIL; + break; + case POWERPC_EXCP_PRIV: + regs->msr |= 0x00040000; + env->spr[SPR_BOOKE_ESR] = ESR_PPR; + break; + case POWERPC_EXCP_TRAP: + regs->msr |= 0x00020000; + env->spr[SPR_BOOKE_ESR] = ESR_PTR; + break; + default: + /* Should never occur */ + cpu_abort(cs, "Invalid program exception %d. Aborting\n", + env->error_code); + break; + } +} + +static inline void dump_syscall(CPUPPCState *env) +{ + qemu_log_mask(CPU_LOG_INT, "syscall r0=%016" PRIx64 + " r3=%016" PRIx64 " r4=%016" PRIx64 " r5=%016" PRIx64 + " r6=%016" PRIx64 " r7=%016" PRIx64 " r8=%016" PRIx64 + " nip=" TARGET_FMT_lx "\n", + ppc_dump_gpr(env, 0), ppc_dump_gpr(env, 3), + ppc_dump_gpr(env, 4), ppc_dump_gpr(env, 5), + ppc_dump_gpr(env, 6), ppc_dump_gpr(env, 7), + ppc_dump_gpr(env, 8), env->nip); +} + +static inline void dump_hcall(CPUPPCState *env) +{ + qemu_log_mask(CPU_LOG_INT, "hypercall r3=%016" PRIx64 + " r4=%016" PRIx64 " r5=%016" PRIx64 " r6=%016" PRIx64 + " r7=%016" PRIx64 " r8=%016" PRIx64 " r9=%016" PRIx64 + " r10=%016" PRIx64 " r11=%016" PRIx64 " r12=%016" PRIx64 + " nip=" TARGET_FMT_lx "\n", + ppc_dump_gpr(env, 3), ppc_dump_gpr(env, 4), + ppc_dump_gpr(env, 5), ppc_dump_gpr(env, 6), + ppc_dump_gpr(env, 7), ppc_dump_gpr(env, 8), + ppc_dump_gpr(env, 9), ppc_dump_gpr(env, 10), + ppc_dump_gpr(env, 11), ppc_dump_gpr(env, 12), + env->nip); +} + +void ppc_intr_system_call(PowerPCCPU *cpu, PPCIntrArgs *regs, bool *ignore) +{ + CPUPPCState *env = &cpu->env; + int lev = env->error_code; + + if ((lev == 1) && cpu->vhyp) { + dump_hcall(env); + } else { + dump_syscall(env); + } + + /* + * We need to correct the NIP which in this case is supposed + * to point to the next instruction. We also set env->nip here + * because the modification needs to be accessible by the + * virtual hypervisor code below. + */ + regs->nip += 4; + env->nip = regs->nip; + + /* "PAPR mode" built-in hypercall emulation */ + if ((lev == 1) && cpu->vhyp) { + PPCVirtualHypervisorClass *vhc = + PPC_VIRTUAL_HYPERVISOR_GET_CLASS(cpu->vhyp); + vhc->hypercall(cpu->vhyp, cpu); + + *ignore = true; + return; + } + + if (lev == 1) { + regs->new_msr |= (target_ulong)MSR_HVB; + } +} + +void ppc_intr_system_call_vectored(PowerPCCPU *cpu, PPCIntrArgs *regs, bool *ignore) +{ + CPUPPCState *env = &cpu->env; + int lev = env->error_code; + + dump_syscall(env); + + regs->nip += 4; + regs->new_msr |= env->msr & ((target_ulong)1 << MSR_EE); + regs->new_msr |= env->msr & ((target_ulong)1 << MSR_RI); + regs->new_nip += lev * 0x20; + + env->lr = regs->nip; + env->ctr = regs->msr; +} + +void ppc_intr_fit(PowerPCCPU *cpu, PPCIntrArgs *regs, bool *ignore) +{ + /* FIT on 4xx */ + trace_ppc_excp_print("FIT"); +}; + +void ppc_intr_watchdog(PowerPCCPU *cpu, PPCIntrArgs *regs, bool *ignore) +{ + CPUPPCState *env = &cpu->env; + int excp_model = env->excp_model; + + trace_ppc_excp_print("WDT"); + switch (excp_model) { + case POWERPC_EXCP_BOOKE: + regs->sprn_srr0 = SPR_BOOKE_CSRR0; + regs->sprn_srr1 = SPR_BOOKE_CSRR1; + break; + default: + break; + } +} + +void ppc_intr_debug(PowerPCCPU *cpu, PPCIntrArgs *regs, bool *ignore) +{ + CPUPPCState *env = &cpu->env; + + if (env->flags & POWERPC_FLAG_DE) { + /* FIXME: choose one or the other based on CPU type */ + regs->sprn_srr0 = SPR_BOOKE_DSRR0; + regs->sprn_srr1 = SPR_BOOKE_DSRR1; + + env->spr[SPR_BOOKE_CSRR0] = regs->nip; + env->spr[SPR_BOOKE_CSRR1] = regs->msr; + /* DBSR already modified by caller */ + } else { + cpu_abort(CPU(cpu), "Debug exception triggered on unsupported model\n"); + } +} + +void ppc_intr_spe_unavailable(PowerPCCPU *cpu, PPCIntrArgs *regs, bool *ignore) +{ + CPUPPCState *env = &cpu->env; + + env->spr[SPR_BOOKE_ESR] = ESR_SPV; +} + +void ppc_intr_embedded_fp_data(PowerPCCPU *cpu, PPCIntrArgs *regs, bool *ignore) +{ + CPUPPCState *env = &cpu->env; + + /* XXX: TODO */ + cpu_abort(CPU(cpu), "Embedded floating point data exception " + "is not implemented yet !\n"); + env->spr[SPR_BOOKE_ESR] = ESR_SPV; +} + +void ppc_intr_embedded_fp_round(PowerPCCPU *cpu, PPCIntrArgs *regs, bool *ignore) +{ + CPUPPCState *env = &cpu->env; + + /* XXX: TODO */ + cpu_abort(CPU(cpu), "Embedded floating point round exception " + "is not implemented yet !\n"); + env->spr[SPR_BOOKE_ESR] = ESR_SPV; +} + +void ppc_intr_embedded_perf_monitor(PowerPCCPU *cpu, PPCIntrArgs *regs, bool *ignore) +{ + /* XXX: TODO */ + cpu_abort(CPU(cpu), + "Performance counter exception is not implemented yet !\n"); +} + +void ppc_intr_embedded_doorbell_crit(PowerPCCPU *cpu, PPCIntrArgs *regs, bool *ignore) +{ + regs->sprn_srr0 = SPR_BOOKE_CSRR0; + regs->sprn_srr1 = SPR_BOOKE_CSRR1; +} + +void ppc_intr_system_reset(PowerPCCPU *cpu, PPCIntrArgs *regs, bool *ignore) +{ + CPUPPCState *env = &cpu->env; + + /* A power-saving exception sets ME, otherwise it is unchanged */ + if (msr_pow) { + /* indicate that we resumed from power save mode */ + regs->msr |= 0x10000; + regs->new_msr |= ((target_ulong)1 << MSR_ME); + } + if (env->msr_mask & MSR_HVB) { + /* + * ISA specifies HV, but can be delivered to guest with HV + * clear (e.g., see FWNMI in PAPR, NMI injection in QEMU). + */ + regs->new_msr |= (target_ulong)MSR_HVB; + } else { + if (msr_pow) { + cpu_abort(CPU(cpu), "Trying to deliver power-saving system reset " + "exception with no HV support\n"); + } + } +} + +void ppc_intr_hv_insn_storage(PowerPCCPU *cpu, PPCIntrArgs *regs, bool *ignore) +{ + CPUPPCState *env = &cpu->env; + + regs->msr |= env->error_code; + + regs->sprn_srr0 = SPR_HSRR0; + regs->sprn_srr1 = SPR_HSRR1; + regs->new_msr |= (target_ulong)MSR_HVB; + regs->new_msr |= env->msr & ((target_ulong)1 << MSR_RI); +} + +void ppc_intr_hv_decrementer(PowerPCCPU *cpu, PPCIntrArgs *regs, bool *ignore) +{ + CPUPPCState *env = &cpu->env; + + regs->sprn_srr0 = SPR_HSRR0; + regs->sprn_srr1 = SPR_HSRR1; + regs->new_msr |= (target_ulong)MSR_HVB; + regs->new_msr |= env->msr & ((target_ulong)1 << MSR_RI); +} + +void ppc_intr_hv_data_storage(PowerPCCPU *cpu, PPCIntrArgs *regs, bool *ignore) +{ + CPUPPCState *env = &cpu->env; + + regs->sprn_srr0 = SPR_HSRR0; + regs->sprn_srr1 = SPR_HSRR1; + regs->new_msr |= (target_ulong)MSR_HVB; + regs->new_msr |= env->msr & ((target_ulong)1 << MSR_RI); +} + +void ppc_intr_hv_data_segment(PowerPCCPU *cpu, PPCIntrArgs *regs, bool *ignore) +{ + CPUPPCState *env = &cpu->env; + + regs->sprn_srr0 = SPR_HSRR0; + regs->sprn_srr1 = SPR_HSRR1; + regs->new_msr |= (target_ulong)MSR_HVB; + regs->new_msr |= env->msr & ((target_ulong)1 << MSR_RI); +} + +void ppc_intr_hv_insn_segment(PowerPCCPU *cpu, PPCIntrArgs *regs, bool *ignore) +{ + CPUPPCState *env = &cpu->env; + + regs->sprn_srr0 = SPR_HSRR0; + regs->sprn_srr1 = SPR_HSRR1; + regs->new_msr |= (target_ulong)MSR_HVB; + regs->new_msr |= env->msr & ((target_ulong)1 << MSR_RI); +} + +void ppc_intr_hv_doorbell(PowerPCCPU *cpu, PPCIntrArgs *regs, bool *ignore) +{ + CPUPPCState *env = &cpu->env; + + regs->sprn_srr0 = SPR_HSRR0; + regs->sprn_srr1 = SPR_HSRR1; + regs->new_msr |= (target_ulong)MSR_HVB; + regs->new_msr |= env->msr & ((target_ulong)1 << MSR_RI); +} + +void ppc_intr_hv_emulation(PowerPCCPU *cpu, PPCIntrArgs *regs, bool *ignore) +{ + CPUPPCState *env = &cpu->env; + + regs->sprn_srr0 = SPR_HSRR0; + regs->sprn_srr1 = SPR_HSRR1; + regs->new_msr |= (target_ulong)MSR_HVB; + regs->new_msr |= env->msr & ((target_ulong)1 << MSR_RI); +} + +void ppc_intr_hv_virtualization(PowerPCCPU *cpu, PPCIntrArgs *regs, bool *ignore) +{ + CPUPPCState *env = &cpu->env; + + regs->sprn_srr0 = SPR_HSRR0; + regs->sprn_srr1 = SPR_HSRR1; + regs->new_msr |= (target_ulong)MSR_HVB; + regs->new_msr |= env->msr & ((target_ulong)1 << MSR_RI); +} + +void ppc_intr_facility_unavail(PowerPCCPU *cpu, PPCIntrArgs *regs, bool *ignore) +{ +#ifdef TARGET_PPC64 + CPUPPCState *env = &cpu->env; + env->spr[SPR_FSCR] |= ((target_ulong)env->error_code << 56); +#endif +} + +void ppc_intr_hv_facility_unavail(PowerPCCPU *cpu, PPCIntrArgs *regs, bool *ignore) +{ +#ifdef TARGET_PPC64 + CPUPPCState *env = &cpu->env; + env->spr[SPR_FSCR] |= ((target_ulong)env->error_code << FSCR_IC_POS); + + regs->sprn_srr0 = SPR_HSRR0; + regs->sprn_srr1 = SPR_HSRR1; + regs->new_msr |= (target_ulong)MSR_HVB; + regs->new_msr |= env->msr & ((target_ulong)1 << MSR_RI); +#endif +} + +void ppc_intr_programmable_timer(PowerPCCPU *cpu, PPCIntrArgs *regs, bool *ignore) +{ + trace_ppc_excp_print("PIT"); +} + +void ppc_intr_io_error(PowerPCCPU *cpu, PPCIntrArgs *regs, bool *ignore) +{ + /* XXX: TODO */ + cpu_abort(CPU(cpu), "601 IO error exception is not implemented yet !\n"); +} + +void ppc_intr_run_mode(PowerPCCPU *cpu, PPCIntrArgs *regs, bool *ignore) +{ + /* XXX: TODO */ + cpu_abort(CPU(cpu), "601 run mode exception is not implemented yet !\n"); +} + +void ppc_intr_emulation(PowerPCCPU *cpu, PPCIntrArgs *regs, bool *ignore) +{ + /* XXX: TODO */ + cpu_abort(CPU(cpu), "602 emulation trap exception is not implemented yet !\n"); +} + +void ppc_intr_tlb_miss(PowerPCCPU *cpu, PPCIntrArgs *regs, bool *ignore) +{ + CPUPPCState *env = &cpu->env; + int excp_model = env->excp_model; + + switch (excp_model) { + case POWERPC_EXCP_602: + case POWERPC_EXCP_603: + case POWERPC_EXCP_G2: + /* Swap temporary saved registers with GPRs */ + if (!(regs->new_msr & ((target_ulong)1 << MSR_TGPR))) { + regs->new_msr |= (target_ulong)1 << MSR_TGPR; + hreg_swap_gpr_tgpr(env); + } + /* fall through */ + case POWERPC_EXCP_7x5: +#if defined(DEBUG_SOFTWARE_TLB) + if (qemu_log_enabled()) { + const char *es; + target_ulong *miss, *cmp; + int en; + + if (excp == POWERPC_EXCP_IFTLB) { + es = "I"; + en = 'I'; + miss = &env->spr[imiss_sprn]; + cmp = &env->spr[icmp_sprn]; + } else { + if (excp == POWERPC_EXCP_DLTLB) { + es = "DL"; + } else { + es = "DS"; + } + en = 'D'; + miss = &env->spr[dmiss_sprn]; + cmp = &env->spr[dcmp_srpn]; + } + + qemu_log("6xx %sTLB miss: %cM " TARGET_FMT_lx " %cC " + TARGET_FMT_lx " H1 " TARGET_FMT_lx " H2 " + TARGET_FMT_lx " %08x\n", es, en, *miss, en, *cmp, + env->spr[SPR_HASH1], env->spr[SPR_HASH2], + env->error_code); + } +#endif + regs->msr |= env->crf[0] << 28; + regs->msr |= env->error_code; /* key, D/I, S/L bits */ + + /* Set way using a LRU mechanism */ + regs->msr |= ((env->last_way + 1) & (env->nb_ways - 1)) << 17; + + break; + default: + cpu_abort(CPU(cpu), "Invalid instruction TLB miss exception\n"); + break; + } +} + +void ppc_intr_fpa(PowerPCCPU *cpu, PPCIntrArgs *regs, bool *ignore) +{ + /* XXX: TODO */ + cpu_abort(CPU(cpu), "Floating point assist exception " + "is not implemented yet !\n"); +} + +void ppc_intr_dabr(PowerPCCPU *cpu, PPCIntrArgs *regs, bool *ignore) +{ + /* XXX: TODO */ + cpu_abort(CPU(cpu), "DABR exception is not implemented yet !\n"); +} + +void ppc_intr_iabr(PowerPCCPU *cpu, PPCIntrArgs *regs, bool *ignore) +{ + /* XXX: TODO */ + cpu_abort(CPU(cpu), "IABR exception is not implemented yet !\n"); +} + +void ppc_intr_smi(PowerPCCPU *cpu, PPCIntrArgs *regs, bool *ignore) +{ + /* XXX: TODO */ + cpu_abort(CPU(cpu), "SMI exception is not implemented yet !\n"); +} + +void ppc_intr_therm(PowerPCCPU *cpu, PPCIntrArgs *regs, bool *ignore) +{ + /* XXX: TODO */ + cpu_abort(CPU(cpu), "Thermal management exception " + "is not implemented yet !\n"); +} + +void ppc_intr_perfm(PowerPCCPU *cpu, PPCIntrArgs *regs, bool *ignore) +{ + /* XXX: TODO */ + cpu_abort(CPU(cpu), + "Performance counter exception is not implemented yet !\n"); +} + +void ppc_intr_vpua(PowerPCCPU *cpu, PPCIntrArgs *regs, bool *ignore) +{ + /* XXX: TODO */ + cpu_abort(CPU(cpu), "VPU assist exception is not implemented yet !\n"); +} + +void ppc_intr_softp(PowerPCCPU *cpu, PPCIntrArgs *regs, bool *ignore) +{ + /* XXX: TODO */ + cpu_abort(CPU(cpu), + "970 soft-patch exception is not implemented yet !\n"); +} + +void ppc_intr_maint(PowerPCCPU *cpu, PPCIntrArgs *regs, bool *ignore) +{ + /* XXX: TODO */ + cpu_abort(CPU(cpu), + "970 maintenance exception is not implemented yet !\n"); +} + +void ppc_intr_mextbr(PowerPCCPU *cpu, PPCIntrArgs *regs, bool *ignore) +{ + /* XXX: TODO */ + cpu_abort(CPU(cpu), "Maskable external exception " + "is not implemented yet !\n"); +} + +void ppc_intr_nmextbr(PowerPCCPU *cpu, PPCIntrArgs *regs, bool *ignore) +{ + /* XXX: TODO */ + cpu_abort(CPU(cpu), "Non maskable external exception " + "is not implemented yet !\n"); +} diff --git a/target/ppc/meson.build b/target/ppc/meson.build index a49a8911e0..53b8e0a98e 100644 --- a/target/ppc/meson.build +++ b/target/ppc/meson.build @@ -39,6 +39,7 @@ ppc_softmmu_ss.add(files( 'mmu-hash32.c', 'mmu_common.c', 'monitor.c', + 'interrupts.c', )) ppc_softmmu_ss.add(when: 'CONFIG_TCG', if_true: files( 'mmu_helper.c', diff --git a/target/ppc/ppc_intr.h b/target/ppc/ppc_intr.h new file mode 100644 index 0000000000..25c11710f9 --- /dev/null +++ b/target/ppc/ppc_intr.h @@ -0,0 +1,61 @@ +#ifndef PPC_INTR_H +#define PPC_INTR_H + +typedef struct PPCIntrArgs PPCIntrArgs; + +struct PPCIntrArgs { + target_ulong nip; + target_ulong msr; + target_ulong new_nip; + target_ulong new_msr; + int sprn_srr0; + int sprn_srr1; +}; + +void ppc_intr_alignment(PowerPCCPU *cpu, PPCIntrArgs *regs, bool *ignore); +void ppc_intr_critical(PowerPCCPU *cpu, PPCIntrArgs *regs, bool *ignore); +void ppc_intr_dabr(PowerPCCPU *cpu, PPCIntrArgs *regs, bool *ignore); +void ppc_intr_data_storage(PowerPCCPU *cpu, PPCIntrArgs *regs, bool *ignore); +void ppc_intr_debug(PowerPCCPU *cpu, PPCIntrArgs *regs, bool *ignore); +void ppc_intr_embedded_doorbell_crit(PowerPCCPU *cpu, PPCIntrArgs *regs, bool *ignore); +void ppc_intr_embedded_fp_data(PowerPCCPU *cpu, PPCIntrArgs *regs, bool *ignore); +void ppc_intr_embedded_fp_round(PowerPCCPU *cpu, PPCIntrArgs *regs, bool *ignore); +void ppc_intr_embedded_perf_monitor(PowerPCCPU *cpu, PPCIntrArgs *regs, bool *ignore); +void ppc_intr_emulation(PowerPCCPU *cpu, PPCIntrArgs *regs, bool *ignore); +void ppc_intr_external(PowerPCCPU *cpu, PPCIntrArgs *regs, bool *ignore); +void ppc_intr_facility_unavail(PowerPCCPU *cpu, PPCIntrArgs *regs, bool *ignore); +void ppc_intr_fit(PowerPCCPU *cpu, PPCIntrArgs *regs, bool *ignore); +void ppc_intr_fpa(PowerPCCPU *cpu, PPCIntrArgs *regs, bool *ignore); +void ppc_intr_hv_data_segment(PowerPCCPU *cpu, PPCIntrArgs *regs, bool *ignore); +void ppc_intr_hv_data_storage(PowerPCCPU *cpu, PPCIntrArgs *regs, bool *ignore); +void ppc_intr_hv_decrementer(PowerPCCPU *cpu, PPCIntrArgs *regs, bool *ignore); +void ppc_intr_hv_doorbell(PowerPCCPU *cpu, PPCIntrArgs *regs, bool *ignore); +void ppc_intr_hv_emulation(PowerPCCPU *cpu, PPCIntrArgs *regs, bool *ignore); +void ppc_intr_hv_facility_unavail(PowerPCCPU *cpu, PPCIntrArgs *regs, bool *ignore); +void ppc_intr_hv_insn_segment(PowerPCCPU *cpu, PPCIntrArgs *regs, bool *ignore); +void ppc_intr_hv_insn_storage(PowerPCCPU *cpu, PPCIntrArgs *regs, bool *ignore); +void ppc_intr_hv_virtualization(PowerPCCPU *cpu, PPCIntrArgs *regs, bool *ignore); +void ppc_intr_iabr(PowerPCCPU *cpu, PPCIntrArgs *regs, bool *ignore); +void ppc_intr_insn_storage(PowerPCCPU *cpu, PPCIntrArgs *regs, bool *ignore); +void ppc_intr_io_error(PowerPCCPU *cpu, PPCIntrArgs *regs, bool *ignore); +void ppc_intr_machine_check(PowerPCCPU *cpu, PPCIntrArgs *regs, bool *ignore); +void ppc_intr_maint(PowerPCCPU *cpu, PPCIntrArgs *regs, bool *ignore); +void ppc_intr_mextbr(PowerPCCPU *cpu, PPCIntrArgs *regs, bool *ignore); +void ppc_intr_nmextbr(PowerPCCPU *cpu, PPCIntrArgs *regs, bool *ignore); +void ppc_intr_noop(PowerPCCPU *cpu, PPCIntrArgs *regs, bool *ignore); +void ppc_intr_perfm(PowerPCCPU *cpu, PPCIntrArgs *regs, bool *ignore); +void ppc_intr_program(PowerPCCPU *cpu, PPCIntrArgs *regs, bool *ignore); +void ppc_intr_programmable_timer(PowerPCCPU *cpu, PPCIntrArgs *regs, bool *ignore); +void ppc_intr_run_mode(PowerPCCPU *cpu, PPCIntrArgs *regs, bool *ignore); +void ppc_intr_smi(PowerPCCPU *cpu, PPCIntrArgs *regs, bool *ignore); +void ppc_intr_softp(PowerPCCPU *cpu, PPCIntrArgs *regs, bool *ignore); +void ppc_intr_spe_unavailable(PowerPCCPU *cpu, PPCIntrArgs *regs, bool *ignore); +void ppc_intr_system_call(PowerPCCPU *cpu, PPCIntrArgs *regs, bool *ignore); +void ppc_intr_system_call_vectored(PowerPCCPU *cpu, PPCIntrArgs *regs, bool *ignore); +void ppc_intr_system_reset(PowerPCCPU *cpu, PPCIntrArgs *regs, bool *ignore); +void ppc_intr_therm(PowerPCCPU *cpu, PPCIntrArgs *regs, bool *ignore); +void ppc_intr_tlb_miss(PowerPCCPU *cpu, PPCIntrArgs *regs, bool *ignore); +void ppc_intr_vpua(PowerPCCPU *cpu, PPCIntrArgs *regs, bool *ignore); +void ppc_intr_watchdog(PowerPCCPU *cpu, PPCIntrArgs *regs, bool *ignore); + +#endif /* PPC_INTR_H */ From patchwork Mon Dec 20 18:18:58 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Fabiano Rosas X-Patchwork-Id: 12688393 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.lore.kernel.org (Postfix) with ESMTPS id B1EEBC433EF for ; Mon, 20 Dec 2021 18:57:57 +0000 (UTC) Received: from localhost ([::1]:52978 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1mzNrA-00057K-Mq for qemu-devel@archiver.kernel.org; Mon, 20 Dec 2021 13:57:56 -0500 Received: from eggs.gnu.org ([209.51.188.92]:35772) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1mzNG5-0002r5-SW; Mon, 20 Dec 2021 13:19:37 -0500 Received: from mx0a-001b2d01.pphosted.com ([148.163.156.1]:61646) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1mzNG3-0006kX-JK; Mon, 20 Dec 2021 13:19:37 -0500 Received: from pps.filterd (m0098409.ppops.net [127.0.0.1]) by mx0a-001b2d01.pphosted.com (8.16.1.2/8.16.1.2) with SMTP id 1BKI329r005406; Mon, 20 Dec 2021 18:19:30 GMT DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=ibm.com; h=from : to : cc : subject : date : message-id : in-reply-to : references : mime-version : content-transfer-encoding; s=pp1; bh=983gXqUUJJVWku1XoS5bjtmvEk8wqflKgL2VjdNaRcM=; b=BAUZV6w6wPsyUtx4nsF4xlS1f3TELNqySdAdbAWFXdGuri/BPpqJ9WP9ifZGO6guQVWj Elmfu/VSFgd6RS/fCTNMUkftGd1w8hldTU1jYLw0nvKpmDEeBy4Uz7ETPJeUcuf0LyMk xHpCvSXQkR+djqViYYyWP0EhDuqOxH6gRKo1AsmZlRPm1esrHfCTafPU0+csT0xiFXZe eUG4aVGFxtxCgGivIP/NUK7c3I18aDAhFqgFOOhAlAaZ5KoBV54gW00x7JH5W/p41IBG ZXTvE5zqjASH3mwqrNNqiyNswZ9DzMKvvibYS/2sRgBX//DYxmn4ieqCNzDq8vsK9QoJ +Q== Received: from pps.reinject (localhost [127.0.0.1]) by mx0a-001b2d01.pphosted.com with ESMTP id 3d2q0jtp6h-1 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NOT); Mon, 20 Dec 2021 18:19:29 +0000 Received: from m0098409.ppops.net (m0098409.ppops.net [127.0.0.1]) by pps.reinject (8.16.0.43/8.16.0.43) with SMTP id 1BKIF1d0029159; Mon, 20 Dec 2021 18:19:29 GMT Received: from ppma04dal.us.ibm.com (7a.29.35a9.ip4.static.sl-reverse.com [169.53.41.122]) by mx0a-001b2d01.pphosted.com with ESMTP id 3d2q0jtp5y-1 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NOT); Mon, 20 Dec 2021 18:19:29 +0000 Received: from pps.filterd (ppma04dal.us.ibm.com [127.0.0.1]) by ppma04dal.us.ibm.com (8.16.1.2/8.16.1.2) with SMTP id 1BKIEVkb022792; Mon, 20 Dec 2021 18:19:27 GMT Received: from b03cxnp08028.gho.boulder.ibm.com (b03cxnp08028.gho.boulder.ibm.com [9.17.130.20]) by ppma04dal.us.ibm.com with ESMTP id 3d179aa5nw-1 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NOT); Mon, 20 Dec 2021 18:19:27 +0000 Received: from b03ledav006.gho.boulder.ibm.com (b03ledav006.gho.boulder.ibm.com [9.17.130.237]) by b03cxnp08028.gho.boulder.ibm.com (8.14.9/8.14.9/NCO v10.0) with ESMTP id 1BKIJQK327853246 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-GCM-SHA384 bits=256 verify=OK); Mon, 20 Dec 2021 18:19:26 GMT Received: from b03ledav006.gho.boulder.ibm.com (unknown [127.0.0.1]) by IMSVA (Postfix) with ESMTP id 99D78C605D; Mon, 20 Dec 2021 18:19:26 +0000 (GMT) Received: from b03ledav006.gho.boulder.ibm.com (unknown [127.0.0.1]) by IMSVA (Postfix) with ESMTP id 15F82C6055; Mon, 20 Dec 2021 18:19:25 +0000 (GMT) Received: from farosas.linux.ibm.com.com (unknown [9.211.60.53]) by b03ledav006.gho.boulder.ibm.com (Postfix) with ESMTP; Mon, 20 Dec 2021 18:19:24 +0000 (GMT) From: Fabiano Rosas To: qemu-devel@nongnu.org Subject: [RFC v2 07/12] target/ppc: Introduce PPCInterrupt Date: Mon, 20 Dec 2021 15:18:58 -0300 Message-Id: <20211220181903.3456898-8-farosas@linux.ibm.com> X-Mailer: git-send-email 2.33.1 In-Reply-To: <20211220181903.3456898-1-farosas@linux.ibm.com> References: <20211220181903.3456898-1-farosas@linux.ibm.com> MIME-Version: 1.0 X-TM-AS-GCONF: 00 X-Proofpoint-GUID: xWRlBSBIZUS6sYUDOs9hfmA-8vXAeFng X-Proofpoint-ORIG-GUID: KA197xII_D6LiKIc670dyjce8cXjqvyy X-Proofpoint-Virus-Version: vendor=baseguard engine=ICAP:2.0.205,Aquarius:18.0.790,Hydra:6.0.425,FMLib:17.11.62.513 definitions=2021-12-20_08,2021-12-20_01,2021-12-02_01 X-Proofpoint-Spam-Details: rule=outbound_notspam policy=outbound score=0 malwarescore=0 spamscore=0 impostorscore=0 bulkscore=0 clxscore=1015 mlxlogscore=999 phishscore=0 adultscore=0 suspectscore=0 priorityscore=1501 mlxscore=0 lowpriorityscore=0 classifier=spam adjust=0 reason=mlx scancount=1 engine=8.12.0-2110150000 definitions=main-2112200101 Received-SPF: pass client-ip=148.163.156.1; envelope-from=farosas@linux.ibm.com; helo=mx0a-001b2d01.pphosted.com X-Spam_score_int: -19 X-Spam_score: -2.0 X-Spam_bar: -- X-Spam_report: (-2.0 / 5.0 requ) BAYES_00=-1.9, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_EF=-0.1, RCVD_IN_MSPIKE_H2=-0.001, SPF_HELO_NONE=0.001, SPF_PASS=-0.001 autolearn=ham autolearn_force=no X-Spam_action: no action X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: danielhb413@gmail.com, qemu-ppc@nongnu.org, clg@kaod.org, david@gibson.dropbear.id.au Errors-To: qemu-devel-bounces+qemu-devel=archiver.kernel.org@nongnu.org Sender: "Qemu-devel" Now that each interrupt has its own routine, we can have an array of interrupts and drop the big switch in powerpc_excp(). That will allow us to later split the interrupt list between the various powerpc implementations (book3s, booke, 32bit, kvm, etc). No functional change. Signed-off-by: Fabiano Rosas --- target/ppc/excp_helper.c | 172 +++---------------------------- target/ppc/interrupts.c | 212 +++++++++++++++++++++++++++++++++++++++ target/ppc/ppc_intr.h | 9 ++ 3 files changed, 236 insertions(+), 157 deletions(-) diff --git a/target/ppc/excp_helper.c b/target/ppc/excp_helper.c index bc20499b6c..4f8a6c4ec8 100644 --- a/target/ppc/excp_helper.c +++ b/target/ppc/excp_helper.c @@ -31,7 +31,6 @@ #ifdef CONFIG_TCG #include "exec/helper-proto.h" -#include "exec/cpu_ldst.h" #endif /*****************************************************************************/ @@ -274,11 +273,17 @@ static inline void powerpc_excp(PowerPCCPU *cpu, int excp) CPUPPCState *env = &cpu->env; int excp_model = env->excp_model; PPCIntrArgs regs; + PPCInterrupt *intr; bool ignore = false; qemu_log_mask(CPU_LOG_INT, "Raise exception at " TARGET_FMT_lx " => %08x (%02x)\n", env->nip, excp, env->error_code); + if (excp == POWERPC_EXCP_NONE) { + /* Should never happen */ + return; + } + /* new srr1 value excluding must-be-zero bits */ if (excp_model == POWERPC_EXCP_BOOKE) { regs.msr = env->msr; @@ -336,165 +341,18 @@ static inline void powerpc_excp(PowerPCCPU *cpu, int excp) regs.new_nip |= env->excp_prefix; - switch (excp) { - case POWERPC_EXCP_NONE: - /* Should never happen */ - return; - - case POWERPC_EXCP_CRITICAL: /* Critical input */ - ppc_intr_critical(cpu, ®s, &ignore); - break; - case POWERPC_EXCP_MCHECK: /* Machine check exception */ - ppc_intr_machine_check(cpu, ®s, &ignore); - break; - case POWERPC_EXCP_DSI: /* Data storage exception */ - ppc_intr_data_storage(cpu, ®s, &ignore); - break; - case POWERPC_EXCP_ISI: /* Instruction storage exception */ - ppc_intr_insn_storage(cpu, ®s, &ignore); - break; - case POWERPC_EXCP_EXTERNAL: /* External input */ - ppc_intr_external(cpu, ®s, &ignore); - break; - case POWERPC_EXCP_ALIGN: /* Alignment exception */ - ppc_intr_alignment(cpu, ®s, &ignore); - break; - case POWERPC_EXCP_PROGRAM: /* Program exception */ - ppc_intr_program(cpu, ®s, &ignore); - break; - case POWERPC_EXCP_SYSCALL: /* System call exception */ - ppc_intr_system_call(cpu, ®s, &ignore); - break; - case POWERPC_EXCP_SYSCALL_VECTORED: /* scv exception */ - ppc_intr_system_call_vectored(cpu, ®s, &ignore); - break; - case POWERPC_EXCP_FPU: /* Floating-point unavailable exception */ - case POWERPC_EXCP_APU: /* Auxiliary processor unavailable */ - case POWERPC_EXCP_DECR: /* Decrementer exception */ - break; - case POWERPC_EXCP_FIT: /* Fixed-interval timer interrupt */ - ppc_intr_fit(cpu, ®s, &ignore); - break; - case POWERPC_EXCP_WDT: /* Watchdog timer interrupt */ - ppc_intr_watchdog(cpu, ®s, &ignore); - break; - case POWERPC_EXCP_DTLB: /* Data TLB error */ - case POWERPC_EXCP_ITLB: /* Instruction TLB error */ - break; - case POWERPC_EXCP_DEBUG: /* Debug interrupt */ - ppc_intr_debug(cpu, ®s, &ignore); - break; - case POWERPC_EXCP_SPEU: /* SPE/embedded floating-point unavailable/VPU */ - ppc_intr_spe_unavailable(cpu, ®s, &ignore); - break; - case POWERPC_EXCP_EFPDI: /* Embedded floating-point data interrupt */ - ppc_intr_embedded_fp_data(cpu, ®s, &ignore); - break; - case POWERPC_EXCP_EFPRI: /* Embedded floating-point round interrupt */ - ppc_intr_embedded_fp_round(cpu, ®s, &ignore); - break; - case POWERPC_EXCP_EPERFM: /* Embedded performance monitor interrupt */ - ppc_intr_embedded_perf_monitor(cpu, ®s, &ignore); - break; - case POWERPC_EXCP_DOORI: /* Embedded doorbell interrupt */ - break; - case POWERPC_EXCP_DOORCI: /* Embedded doorbell critical interrupt */ - ppc_intr_embedded_doorbell_crit(cpu, ®s, &ignore); - break; - case POWERPC_EXCP_RESET: /* System reset exception */ - ppc_intr_system_reset(cpu, ®s, &ignore); - break; - case POWERPC_EXCP_DSEG: /* Data segment exception */ - case POWERPC_EXCP_ISEG: /* Instruction segment exception */ - case POWERPC_EXCP_TRACE: /* Trace exception */ - break; - case POWERPC_EXCP_HISI: /* Hypervisor instruction storage exception */ - ppc_intr_hv_insn_storage(cpu, ®s, &ignore); - break; - case POWERPC_EXCP_HDECR: /* Hypervisor decrementer exception */ - ppc_intr_hv_decrementer(cpu, ®s, &ignore); - break; - case POWERPC_EXCP_HDSI: /* Hypervisor data storage exception */ - ppc_intr_hv_data_storage(cpu, ®s, &ignore); - break; - case POWERPC_EXCP_HDSEG: /* Hypervisor data segment exception */ - ppc_intr_hv_data_segment(cpu, ®s, &ignore); - break; - case POWERPC_EXCP_HISEG: /* Hypervisor instruction segment exception */ - ppc_intr_hv_insn_segment(cpu, ®s, &ignore); - break; - case POWERPC_EXCP_SDOOR_HV: /* Hypervisor Doorbell interrupt */ - ppc_intr_hv_doorbell(cpu, ®s, &ignore); - break; - case POWERPC_EXCP_HV_EMU: - ppc_intr_hv_emulation(cpu, ®s, &ignore); - break; - case POWERPC_EXCP_HVIRT: /* Hypervisor virtualization */ - ppc_intr_hv_virtualization(cpu, ®s, &ignore); - break; - case POWERPC_EXCP_VPU: /* Vector unavailable exception */ - case POWERPC_EXCP_VSXU: /* VSX unavailable exception */ - case POWERPC_EXCP_FU: /* Facility unavailable exception */ - ppc_intr_facility_unavail(cpu, ®s, &ignore); - break; - case POWERPC_EXCP_HV_FU: /* Hypervisor Facility Unavailable Exception */ - ppc_intr_hv_facility_unavail(cpu, ®s, &ignore); - break; - case POWERPC_EXCP_PIT: /* Programmable interval timer interrupt */ - ppc_intr_programmable_timer(cpu, ®s, &ignore); - break; - case POWERPC_EXCP_IO: /* IO error exception */ - ppc_intr_io_error(cpu, ®s, &ignore); - break; - case POWERPC_EXCP_RUNM: /* Run mode exception */ - ppc_intr_run_mode(cpu, ®s, &ignore); - break; - case POWERPC_EXCP_EMUL: /* Emulation trap exception */ - ppc_intr_emulation(cpu, ®s, &ignore); - break; - case POWERPC_EXCP_IFTLB: /* Instruction fetch TLB error */ - case POWERPC_EXCP_DLTLB: /* Data load TLB miss */ - case POWERPC_EXCP_DSTLB: /* Data store TLB miss */ - ppc_intr_tlb_miss(cpu, ®s, &ignore); - break; - case POWERPC_EXCP_FPA: /* Floating-point assist exception */ - ppc_intr_fpa(cpu, ®s, &ignore); - break; - case POWERPC_EXCP_DABR: /* Data address breakpoint */ - ppc_intr_dabr(cpu, ®s, &ignore); - break; - case POWERPC_EXCP_IABR: /* Instruction address breakpoint */ - ppc_intr_iabr(cpu, ®s, &ignore); - break; - case POWERPC_EXCP_SMI: /* System management interrupt */ - ppc_intr_smi(cpu, ®s, &ignore); - break; - case POWERPC_EXCP_THERM: /* Thermal interrupt */ - ppc_intr_therm(cpu, ®s, &ignore); - break; - case POWERPC_EXCP_PERFM: /* Embedded performance monitor interrupt */ - ppc_intr_perfm(cpu, ®s, &ignore); - break; - case POWERPC_EXCP_VPUA: /* Vector assist exception */ - ppc_intr_vpua(cpu, ®s, &ignore); - break; - case POWERPC_EXCP_SOFTP: /* Soft patch exception */ - ppc_intr_softp(cpu, ®s, &ignore); - break; - case POWERPC_EXCP_MAINT: /* Maintenance exception */ - ppc_intr_maint(cpu, ®s, &ignore); - break; - case POWERPC_EXCP_MEXTBR: /* Maskable external breakpoint */ - ppc_intr_mextbr(cpu, ®s, &ignore); - break; - case POWERPC_EXCP_NMEXTBR: /* Non maskable external breakpoint */ - ppc_intr_nmextbr(cpu, ®s, &ignore); - break; - default: + intr = &interrupts[excp]; + if (!intr->name) { cpu_abort(cs, "Invalid PowerPC exception %d. Aborting\n", excp); - break; } + if (!intr->fn) { + cpu_abort(cs, "%s exception is not implemented yet !\n", intr->name); + } + + /* Setup interrupt-specific registers before dispatching */ + intr->fn(cpu, ®s, &ignore); + if (ignore) { /* No further setup is needed for this interrupt */ return; diff --git a/target/ppc/interrupts.c b/target/ppc/interrupts.c index 0168ce03a7..2dd3815167 100644 --- a/target/ppc/interrupts.c +++ b/target/ppc/interrupts.c @@ -17,6 +17,10 @@ /* #define DEBUG_SOFTWARE_TLB */ +void ppc_intr_noop(PowerPCCPU *cpu, PPCIntrArgs *regs, bool *ignore) +{ +} + void ppc_intr_critical(PowerPCCPU *cpu, PPCIntrArgs *regs, bool *ignore) { CPUPPCState *env = &cpu->env; @@ -643,3 +647,211 @@ void ppc_intr_nmextbr(PowerPCCPU *cpu, PPCIntrArgs *regs, bool *ignore) cpu_abort(CPU(cpu), "Non maskable external exception " "is not implemented yet !\n"); } + +PPCInterrupt interrupts[POWERPC_EXCP_NB] = { + [POWERPC_EXCP_ALIGN] = { + "Alignment", ppc_intr_alignment + }, + + [POWERPC_EXCP_CRITICAL] = { + "Critical input", ppc_intr_critical + }, + + [POWERPC_EXCP_DABR] = { + "Data address breakpoint", ppc_intr_dabr + }, + + [POWERPC_EXCP_DEBUG] = { + "Debug", ppc_intr_debug + }, + + [POWERPC_EXCP_DLTLB] = { + "Data load TLB error", ppc_intr_tlb_miss + }, + + [POWERPC_EXCP_DOORCI] = { + "Embedded doorbell critical", ppc_intr_embedded_doorbell_crit + }, + + [POWERPC_EXCP_DSI] = { + "Data storage", ppc_intr_data_storage + }, + + [POWERPC_EXCP_DSTLB] = { + "Data store TLB error", ppc_intr_tlb_miss + }, + + [POWERPC_EXCP_EFPDI] = { + "Embedded floating-point data", ppc_intr_embedded_fp_data + }, + + [POWERPC_EXCP_EFPRI] = { + "Embedded floating-point round", ppc_intr_embedded_fp_round + }, + + [POWERPC_EXCP_EMUL] = { + "Emulation trap", ppc_intr_emulation + }, + + [POWERPC_EXCP_EPERFM] = { + "Embedded perf. monitor", ppc_intr_embedded_perf_monitor + }, + + [POWERPC_EXCP_EXTERNAL] = { + "External", ppc_intr_external + }, + + [POWERPC_EXCP_FIT] = { + "Fixed-interval timer", ppc_intr_fit + }, + + [POWERPC_EXCP_FPA] = { + "Floating-point assist", ppc_intr_fpa + }, + + [POWERPC_EXCP_FU] = { + "Facility unavailable", ppc_intr_facility_unavail + }, + + [POWERPC_EXCP_HDECR] = { + "Hypervisor decrementer", ppc_intr_hv_decrementer + }, + + [POWERPC_EXCP_HDSEG] = { + "Hypervisor data segment", ppc_intr_hv_data_segment + }, + + [POWERPC_EXCP_HDSI] = { + "Hypervisor data storage", ppc_intr_hv_data_storage + }, + + [POWERPC_EXCP_HISEG] = { + "Hypervisor insn segment", ppc_intr_hv_insn_segment + }, + + [POWERPC_EXCP_HISI] = { + "Hypervisor instruction storage", ppc_intr_hv_insn_storage + }, + + [POWERPC_EXCP_HVIRT] = { + "Hypervisor virtualization", ppc_intr_hv_virtualization + }, + + [POWERPC_EXCP_HV_EMU] = { + "Hypervisor emulation assist", ppc_intr_hv_emulation + }, + + [POWERPC_EXCP_HV_FU] = { + "Hypervisor facility unavailable" , ppc_intr_hv_facility_unavail + }, + + [POWERPC_EXCP_IABR] = { + "Insn address breakpoint", ppc_intr_iabr + }, + + [POWERPC_EXCP_IFTLB] = { + "Insn fetch TLB error", ppc_intr_tlb_miss + }, + + [POWERPC_EXCP_IO] = { + "IO error", ppc_intr_io_error + }, + + [POWERPC_EXCP_ISI] = { + "Instruction storage", ppc_intr_insn_storage + }, + + [POWERPC_EXCP_MAINT] = { + "Maintenance", ppc_intr_maint + }, + + [POWERPC_EXCP_MCHECK] = { + "Machine check", ppc_intr_machine_check + }, + + [POWERPC_EXCP_MEXTBR] = { + "Maskable external", ppc_intr_mextbr + }, + + [POWERPC_EXCP_NMEXTBR] = { + "Non-maskable external", ppc_intr_nmextbr + }, + + [POWERPC_EXCP_PERFM] = { + "Performance counter", ppc_intr_perfm + }, + + [POWERPC_EXCP_PIT] = { + "Programmable interval timer", ppc_intr_programmable_timer + }, + + [POWERPC_EXCP_PROGRAM] = { + "Program", ppc_intr_program + }, + + [POWERPC_EXCP_RESET] = { + "System reset", ppc_intr_system_reset + }, + + [POWERPC_EXCP_RUNM] = { + "Run mode", ppc_intr_run_mode + }, + + [POWERPC_EXCP_SDOOR_HV] = { + "Hypervisor doorbell", ppc_intr_hv_doorbell + }, + + [POWERPC_EXCP_SMI] = { + "System management", ppc_intr_smi + }, + + [POWERPC_EXCP_SOFTP] = { + "Soft patch", ppc_intr_softp + }, + + [POWERPC_EXCP_SPEU] = { + "SPE/embedded FP unavailable/VPU", ppc_intr_spe_unavailable + }, + + [POWERPC_EXCP_SYSCALL] = { + "System call", ppc_intr_system_call + }, + + [POWERPC_EXCP_SYSCALL_VECTORED] = { + "System call vectored", ppc_intr_system_call_vectored + }, + + [POWERPC_EXCP_THERM] = { + "Thermal management", ppc_intr_therm + }, + + [POWERPC_EXCP_VPUA] = { + "Vector assist", ppc_intr_vpua + }, + + [POWERPC_EXCP_VPU] = { + "Vector unavailable", ppc_intr_facility_unavail + }, + + [POWERPC_EXCP_VSXU] = { + "VSX unavailable", ppc_intr_facility_unavail + }, + + [POWERPC_EXCP_WDT] = { + "Watchdog timer", ppc_intr_watchdog + }, + + [POWERPC_EXCP_APU] = { "Aux. processor unavailable", ppc_intr_noop }, + [POWERPC_EXCP_DECR] = { "Decrementer", ppc_intr_noop }, + [POWERPC_EXCP_DOORI] = { "Embedded doorbell", ppc_intr_noop }, + [POWERPC_EXCP_DSEG] = { "Data segment", ppc_intr_noop }, + [POWERPC_EXCP_DTLB] = { "Data TLB error", ppc_intr_noop }, + [POWERPC_EXCP_FPU] = { "Floating-point unavailable", ppc_intr_noop }, + [POWERPC_EXCP_ISEG] = { "Instruction segment", ppc_intr_noop }, + [POWERPC_EXCP_ITLB] = { "Instruction TLB error", ppc_intr_noop }, + [POWERPC_EXCP_TRACE] = { "Trace", ppc_intr_noop }, + +/* Not implemented */ + [POWERPC_EXCP_HV_MAINT] = { "Hypervisor maintenance" }, + [POWERPC_EXCP_SDOOR] = { "Server doorbell" }, +}; diff --git a/target/ppc/ppc_intr.h b/target/ppc/ppc_intr.h index 25c11710f9..82372ca227 100644 --- a/target/ppc/ppc_intr.h +++ b/target/ppc/ppc_intr.h @@ -2,6 +2,8 @@ #define PPC_INTR_H typedef struct PPCIntrArgs PPCIntrArgs; +typedef struct PPCInterrupt PPCInterrupt; +typedef void (*ppc_intr_fn_t)(PowerPCCPU *cpu, PPCIntrArgs *regs, bool *ignore); struct PPCIntrArgs { target_ulong nip; @@ -12,6 +14,11 @@ struct PPCIntrArgs { int sprn_srr1; }; +struct PPCInterrupt { + const char *name; + ppc_intr_fn_t fn; +}; + void ppc_intr_alignment(PowerPCCPU *cpu, PPCIntrArgs *regs, bool *ignore); void ppc_intr_critical(PowerPCCPU *cpu, PPCIntrArgs *regs, bool *ignore); void ppc_intr_dabr(PowerPCCPU *cpu, PPCIntrArgs *regs, bool *ignore); @@ -58,4 +65,6 @@ void ppc_intr_tlb_miss(PowerPCCPU *cpu, PPCIntrArgs *regs, bool *ignore); void ppc_intr_vpua(PowerPCCPU *cpu, PPCIntrArgs *regs, bool *ignore); void ppc_intr_watchdog(PowerPCCPU *cpu, PPCIntrArgs *regs, bool *ignore); +extern PPCInterrupt interrupts[POWERPC_EXCP_NB]; + #endif /* PPC_INTR_H */ From patchwork Mon Dec 20 18:18:59 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Fabiano Rosas X-Patchwork-Id: 12688457 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.lore.kernel.org (Postfix) with ESMTPS id C888CC433F5 for ; Mon, 20 Dec 2021 19:49:01 +0000 (UTC) Received: from localhost ([::1]:42376 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1mzOea-0007Ui-LI for qemu-devel@archiver.kernel.org; Mon, 20 Dec 2021 14:49:00 -0500 Received: from eggs.gnu.org ([209.51.188.92]:35878) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1mzNGC-00031E-Rp; Mon, 20 Dec 2021 13:19:45 -0500 Received: from mx0a-001b2d01.pphosted.com ([148.163.156.1]:59464) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1mzNGA-0006nc-GY; Mon, 20 Dec 2021 13:19:44 -0500 Received: from pps.filterd (m0098394.ppops.net [127.0.0.1]) by mx0a-001b2d01.pphosted.com (8.16.1.2/8.16.1.2) with SMTP id 1BKGBn6X012997; Mon, 20 Dec 2021 18:19:31 GMT DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=ibm.com; h=from : to : cc : subject : date : message-id : in-reply-to : references : mime-version : content-transfer-encoding; s=pp1; bh=JXdwpZss8Fzk+HcoOa1M7naY1vZ3MWYfHVtGE/uBdwc=; b=RmfDZM4xfozhMF8CYnVpw+L5GTP5+zkRXuB1UeoBwucVeTRyZh6u+VtQ8x/j91PK6KNg yhNyEej3KyfTO/XMosRTnfHPB9ol31rSb8zNqB9jPqELVKk92uPd9QyqD7KljWa2pLAR j/qQQW6zI+Enx/tmawBXKUeHm96wr2b5fDPkFW3XnnMk7bd3PipjGQWc1oQcxtk4Cyi+ YicPVCUT/0q7M9Peme0s3pY/AI+FLHUt9XMCHjaRTjxdg2/9dvaA350YJXE2TiexQwZ8 lf9XmaswExIDoY+m4byiXsEnrRpTE1tOXGDs6Qd/uXkjmsLP5x1xXStzWyo4En4vzSf4 VQ== Received: from pps.reinject (localhost [127.0.0.1]) by mx0a-001b2d01.pphosted.com with ESMTP id 3d1s4wt311-1 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NOT); Mon, 20 Dec 2021 18:19:31 +0000 Received: from m0098394.ppops.net (m0098394.ppops.net [127.0.0.1]) by pps.reinject (8.16.0.43/8.16.0.43) with SMTP id 1BKIIYLm021136; Mon, 20 Dec 2021 18:19:30 GMT Received: from ppma04dal.us.ibm.com (7a.29.35a9.ip4.static.sl-reverse.com [169.53.41.122]) by mx0a-001b2d01.pphosted.com with ESMTP id 3d1s4wt30r-1 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NOT); Mon, 20 Dec 2021 18:19:30 +0000 Received: from pps.filterd (ppma04dal.us.ibm.com [127.0.0.1]) by ppma04dal.us.ibm.com (8.16.1.2/8.16.1.2) with SMTP id 1BKIEV0j022789; Mon, 20 Dec 2021 18:19:29 GMT Received: from b03cxnp07028.gho.boulder.ibm.com (b03cxnp07028.gho.boulder.ibm.com [9.17.130.15]) by ppma04dal.us.ibm.com with ESMTP id 3d179aa5pn-1 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NOT); Mon, 20 Dec 2021 18:19:29 +0000 Received: from b03ledav006.gho.boulder.ibm.com (b03ledav006.gho.boulder.ibm.com [9.17.130.237]) by b03cxnp07028.gho.boulder.ibm.com (8.14.9/8.14.9/NCO v10.0) with ESMTP id 1BKIJSKR23265668 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-GCM-SHA384 bits=256 verify=OK); Mon, 20 Dec 2021 18:19:28 GMT Received: from b03ledav006.gho.boulder.ibm.com (unknown [127.0.0.1]) by IMSVA (Postfix) with ESMTP id 80505C6059; Mon, 20 Dec 2021 18:19:28 +0000 (GMT) Received: from b03ledav006.gho.boulder.ibm.com (unknown [127.0.0.1]) by IMSVA (Postfix) with ESMTP id 0A610C6065; Mon, 20 Dec 2021 18:19:27 +0000 (GMT) Received: from farosas.linux.ibm.com.com (unknown [9.211.60.53]) by b03ledav006.gho.boulder.ibm.com (Postfix) with ESMTP; Mon, 20 Dec 2021 18:19:26 +0000 (GMT) From: Fabiano Rosas To: qemu-devel@nongnu.org Subject: [RFC v2 08/12] target/ppc: Remove unimplemented interrupt code Date: Mon, 20 Dec 2021 15:18:59 -0300 Message-Id: <20211220181903.3456898-9-farosas@linux.ibm.com> X-Mailer: git-send-email 2.33.1 In-Reply-To: <20211220181903.3456898-1-farosas@linux.ibm.com> References: <20211220181903.3456898-1-farosas@linux.ibm.com> MIME-Version: 1.0 X-TM-AS-GCONF: 00 X-Proofpoint-ORIG-GUID: IVCqGZ41Hu7eoRbBJ9sOuvqiyh99h5Xw X-Proofpoint-GUID: Q13qKTTHJrsWZ4CpInGREjMF2PHABNub X-Proofpoint-Virus-Version: vendor=baseguard engine=ICAP:2.0.205,Aquarius:18.0.790,Hydra:6.0.425,FMLib:17.11.62.513 definitions=2021-12-20_08,2021-12-20_01,2021-12-02_01 X-Proofpoint-Spam-Details: rule=outbound_notspam policy=outbound score=0 malwarescore=0 clxscore=1015 mlxscore=0 bulkscore=0 lowpriorityscore=0 priorityscore=1501 mlxlogscore=999 spamscore=0 impostorscore=0 suspectscore=0 phishscore=0 adultscore=0 classifier=spam adjust=0 reason=mlx scancount=1 engine=8.12.0-2110150000 definitions=main-2112200101 Received-SPF: pass client-ip=148.163.156.1; envelope-from=farosas@linux.ibm.com; helo=mx0a-001b2d01.pphosted.com X-Spam_score_int: -19 X-Spam_score: -2.0 X-Spam_bar: -- X-Spam_report: (-2.0 / 5.0 requ) BAYES_00=-1.9, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_EF=-0.1, RCVD_IN_MSPIKE_H2=-0.001, SPF_HELO_NONE=0.001, SPF_PASS=-0.001 autolearn=ham autolearn_force=no X-Spam_action: no action X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: danielhb413@gmail.com, qemu-ppc@nongnu.org, clg@kaod.org, david@gibson.dropbear.id.au Errors-To: qemu-devel-bounces+qemu-devel=archiver.kernel.org@nongnu.org Sender: "Qemu-devel" Now that PPCInterrupt holds the interrupt name, we can remove all functions that just emitted the "unimplemented" message and leave that to the error handling at powerpc_excp(): if (!intr->fn) { cpu_abort(cs, "%s exception is not implemented yet !\n", intr->name); } The user visible change here is that the error message shown when QEMU tries to dispatch an interrupt that has no implementation will change from a custom one depending on the exception to a standard one (above) with the interrupt name as defined in interrupts.c. (I added ITLBE/DTLBE which were not being handled) Signed-off-by: Fabiano Rosas --- target/ppc/interrupts.c | 205 ++++------------------------------------ target/ppc/ppc_intr.h | 17 ---- 2 files changed, 19 insertions(+), 203 deletions(-) diff --git a/target/ppc/interrupts.c b/target/ppc/interrupts.c index 2dd3815167..1e4fb2d6db 100644 --- a/target/ppc/interrupts.c +++ b/target/ppc/interrupts.c @@ -334,33 +334,6 @@ void ppc_intr_spe_unavailable(PowerPCCPU *cpu, PPCIntrArgs *regs, bool *ignore) env->spr[SPR_BOOKE_ESR] = ESR_SPV; } -void ppc_intr_embedded_fp_data(PowerPCCPU *cpu, PPCIntrArgs *regs, bool *ignore) -{ - CPUPPCState *env = &cpu->env; - - /* XXX: TODO */ - cpu_abort(CPU(cpu), "Embedded floating point data exception " - "is not implemented yet !\n"); - env->spr[SPR_BOOKE_ESR] = ESR_SPV; -} - -void ppc_intr_embedded_fp_round(PowerPCCPU *cpu, PPCIntrArgs *regs, bool *ignore) -{ - CPUPPCState *env = &cpu->env; - - /* XXX: TODO */ - cpu_abort(CPU(cpu), "Embedded floating point round exception " - "is not implemented yet !\n"); - env->spr[SPR_BOOKE_ESR] = ESR_SPV; -} - -void ppc_intr_embedded_perf_monitor(PowerPCCPU *cpu, PPCIntrArgs *regs, bool *ignore) -{ - /* XXX: TODO */ - cpu_abort(CPU(cpu), - "Performance counter exception is not implemented yet !\n"); -} - void ppc_intr_embedded_doorbell_crit(PowerPCCPU *cpu, PPCIntrArgs *regs, bool *ignore) { regs->sprn_srr0 = SPR_BOOKE_CSRR0; @@ -499,24 +472,6 @@ void ppc_intr_programmable_timer(PowerPCCPU *cpu, PPCIntrArgs *regs, bool *ignor trace_ppc_excp_print("PIT"); } -void ppc_intr_io_error(PowerPCCPU *cpu, PPCIntrArgs *regs, bool *ignore) -{ - /* XXX: TODO */ - cpu_abort(CPU(cpu), "601 IO error exception is not implemented yet !\n"); -} - -void ppc_intr_run_mode(PowerPCCPU *cpu, PPCIntrArgs *regs, bool *ignore) -{ - /* XXX: TODO */ - cpu_abort(CPU(cpu), "601 run mode exception is not implemented yet !\n"); -} - -void ppc_intr_emulation(PowerPCCPU *cpu, PPCIntrArgs *regs, bool *ignore) -{ - /* XXX: TODO */ - cpu_abort(CPU(cpu), "602 emulation trap exception is not implemented yet !\n"); -} - void ppc_intr_tlb_miss(PowerPCCPU *cpu, PPCIntrArgs *regs, bool *ignore) { CPUPPCState *env = &cpu->env; @@ -575,79 +530,6 @@ void ppc_intr_tlb_miss(PowerPCCPU *cpu, PPCIntrArgs *regs, bool *ignore) } } -void ppc_intr_fpa(PowerPCCPU *cpu, PPCIntrArgs *regs, bool *ignore) -{ - /* XXX: TODO */ - cpu_abort(CPU(cpu), "Floating point assist exception " - "is not implemented yet !\n"); -} - -void ppc_intr_dabr(PowerPCCPU *cpu, PPCIntrArgs *regs, bool *ignore) -{ - /* XXX: TODO */ - cpu_abort(CPU(cpu), "DABR exception is not implemented yet !\n"); -} - -void ppc_intr_iabr(PowerPCCPU *cpu, PPCIntrArgs *regs, bool *ignore) -{ - /* XXX: TODO */ - cpu_abort(CPU(cpu), "IABR exception is not implemented yet !\n"); -} - -void ppc_intr_smi(PowerPCCPU *cpu, PPCIntrArgs *regs, bool *ignore) -{ - /* XXX: TODO */ - cpu_abort(CPU(cpu), "SMI exception is not implemented yet !\n"); -} - -void ppc_intr_therm(PowerPCCPU *cpu, PPCIntrArgs *regs, bool *ignore) -{ - /* XXX: TODO */ - cpu_abort(CPU(cpu), "Thermal management exception " - "is not implemented yet !\n"); -} - -void ppc_intr_perfm(PowerPCCPU *cpu, PPCIntrArgs *regs, bool *ignore) -{ - /* XXX: TODO */ - cpu_abort(CPU(cpu), - "Performance counter exception is not implemented yet !\n"); -} - -void ppc_intr_vpua(PowerPCCPU *cpu, PPCIntrArgs *regs, bool *ignore) -{ - /* XXX: TODO */ - cpu_abort(CPU(cpu), "VPU assist exception is not implemented yet !\n"); -} - -void ppc_intr_softp(PowerPCCPU *cpu, PPCIntrArgs *regs, bool *ignore) -{ - /* XXX: TODO */ - cpu_abort(CPU(cpu), - "970 soft-patch exception is not implemented yet !\n"); -} - -void ppc_intr_maint(PowerPCCPU *cpu, PPCIntrArgs *regs, bool *ignore) -{ - /* XXX: TODO */ - cpu_abort(CPU(cpu), - "970 maintenance exception is not implemented yet !\n"); -} - -void ppc_intr_mextbr(PowerPCCPU *cpu, PPCIntrArgs *regs, bool *ignore) -{ - /* XXX: TODO */ - cpu_abort(CPU(cpu), "Maskable external exception " - "is not implemented yet !\n"); -} - -void ppc_intr_nmextbr(PowerPCCPU *cpu, PPCIntrArgs *regs, bool *ignore) -{ - /* XXX: TODO */ - cpu_abort(CPU(cpu), "Non maskable external exception " - "is not implemented yet !\n"); -} - PPCInterrupt interrupts[POWERPC_EXCP_NB] = { [POWERPC_EXCP_ALIGN] = { "Alignment", ppc_intr_alignment @@ -657,10 +539,6 @@ PPCInterrupt interrupts[POWERPC_EXCP_NB] = { "Critical input", ppc_intr_critical }, - [POWERPC_EXCP_DABR] = { - "Data address breakpoint", ppc_intr_dabr - }, - [POWERPC_EXCP_DEBUG] = { "Debug", ppc_intr_debug }, @@ -681,22 +559,6 @@ PPCInterrupt interrupts[POWERPC_EXCP_NB] = { "Data store TLB error", ppc_intr_tlb_miss }, - [POWERPC_EXCP_EFPDI] = { - "Embedded floating-point data", ppc_intr_embedded_fp_data - }, - - [POWERPC_EXCP_EFPRI] = { - "Embedded floating-point round", ppc_intr_embedded_fp_round - }, - - [POWERPC_EXCP_EMUL] = { - "Emulation trap", ppc_intr_emulation - }, - - [POWERPC_EXCP_EPERFM] = { - "Embedded perf. monitor", ppc_intr_embedded_perf_monitor - }, - [POWERPC_EXCP_EXTERNAL] = { "External", ppc_intr_external }, @@ -705,10 +567,6 @@ PPCInterrupt interrupts[POWERPC_EXCP_NB] = { "Fixed-interval timer", ppc_intr_fit }, - [POWERPC_EXCP_FPA] = { - "Floating-point assist", ppc_intr_fpa - }, - [POWERPC_EXCP_FU] = { "Facility unavailable", ppc_intr_facility_unavail }, @@ -745,42 +603,18 @@ PPCInterrupt interrupts[POWERPC_EXCP_NB] = { "Hypervisor facility unavailable" , ppc_intr_hv_facility_unavail }, - [POWERPC_EXCP_IABR] = { - "Insn address breakpoint", ppc_intr_iabr - }, - [POWERPC_EXCP_IFTLB] = { "Insn fetch TLB error", ppc_intr_tlb_miss }, - [POWERPC_EXCP_IO] = { - "IO error", ppc_intr_io_error - }, - [POWERPC_EXCP_ISI] = { "Instruction storage", ppc_intr_insn_storage }, - [POWERPC_EXCP_MAINT] = { - "Maintenance", ppc_intr_maint - }, - [POWERPC_EXCP_MCHECK] = { "Machine check", ppc_intr_machine_check }, - [POWERPC_EXCP_MEXTBR] = { - "Maskable external", ppc_intr_mextbr - }, - - [POWERPC_EXCP_NMEXTBR] = { - "Non-maskable external", ppc_intr_nmextbr - }, - - [POWERPC_EXCP_PERFM] = { - "Performance counter", ppc_intr_perfm - }, - [POWERPC_EXCP_PIT] = { "Programmable interval timer", ppc_intr_programmable_timer }, @@ -793,22 +627,10 @@ PPCInterrupt interrupts[POWERPC_EXCP_NB] = { "System reset", ppc_intr_system_reset }, - [POWERPC_EXCP_RUNM] = { - "Run mode", ppc_intr_run_mode - }, - [POWERPC_EXCP_SDOOR_HV] = { "Hypervisor doorbell", ppc_intr_hv_doorbell }, - [POWERPC_EXCP_SMI] = { - "System management", ppc_intr_smi - }, - - [POWERPC_EXCP_SOFTP] = { - "Soft patch", ppc_intr_softp - }, - [POWERPC_EXCP_SPEU] = { "SPE/embedded FP unavailable/VPU", ppc_intr_spe_unavailable }, @@ -821,14 +643,6 @@ PPCInterrupt interrupts[POWERPC_EXCP_NB] = { "System call vectored", ppc_intr_system_call_vectored }, - [POWERPC_EXCP_THERM] = { - "Thermal management", ppc_intr_therm - }, - - [POWERPC_EXCP_VPUA] = { - "Vector assist", ppc_intr_vpua - }, - [POWERPC_EXCP_VPU] = { "Vector unavailable", ppc_intr_facility_unavail }, @@ -852,6 +666,25 @@ PPCInterrupt interrupts[POWERPC_EXCP_NB] = { [POWERPC_EXCP_TRACE] = { "Trace", ppc_intr_noop }, /* Not implemented */ + [POWERPC_EXCP_DABR] = { "Data address breakpoint" }, + [POWERPC_EXCP_DTLBE] = { "Data TLB error" }, + [POWERPC_EXCP_EFPDI] = { "Embedded floating-point data" }, + [POWERPC_EXCP_EFPRI] = { "Embedded floating-point round" }, + [POWERPC_EXCP_EMUL] = { "Emulation trap" }, + [POWERPC_EXCP_EPERFM] = { "Embedded perf. monitor" }, + [POWERPC_EXCP_FPA] = { "Floating-point assist" }, [POWERPC_EXCP_HV_MAINT] = { "Hypervisor maintenance" }, + [POWERPC_EXCP_IABR] = { "Insn address breakpoint" }, + [POWERPC_EXCP_IO] = { "IO error" }, + [POWERPC_EXCP_ITLBE] = { "Instruction TLB error" }, + [POWERPC_EXCP_MAINT] = { "Maintenance" }, + [POWERPC_EXCP_MEXTBR] = { "Maskable external" }, + [POWERPC_EXCP_NMEXTBR] = { "Non-maskable external" }, + [POWERPC_EXCP_PERFM] = { "Performance counter" }, + [POWERPC_EXCP_RUNM] = { "Run mode" }, [POWERPC_EXCP_SDOOR] = { "Server doorbell" }, + [POWERPC_EXCP_SMI] = { "System management" }, + [POWERPC_EXCP_SOFTP] = { "Soft patch" }, + [POWERPC_EXCP_THERM] = { "Thermal management" }, + [POWERPC_EXCP_VPUA] = { "Vector assist" }, }; diff --git a/target/ppc/ppc_intr.h b/target/ppc/ppc_intr.h index 82372ca227..a96062c583 100644 --- a/target/ppc/ppc_intr.h +++ b/target/ppc/ppc_intr.h @@ -21,18 +21,12 @@ struct PPCInterrupt { void ppc_intr_alignment(PowerPCCPU *cpu, PPCIntrArgs *regs, bool *ignore); void ppc_intr_critical(PowerPCCPU *cpu, PPCIntrArgs *regs, bool *ignore); -void ppc_intr_dabr(PowerPCCPU *cpu, PPCIntrArgs *regs, bool *ignore); void ppc_intr_data_storage(PowerPCCPU *cpu, PPCIntrArgs *regs, bool *ignore); void ppc_intr_debug(PowerPCCPU *cpu, PPCIntrArgs *regs, bool *ignore); void ppc_intr_embedded_doorbell_crit(PowerPCCPU *cpu, PPCIntrArgs *regs, bool *ignore); -void ppc_intr_embedded_fp_data(PowerPCCPU *cpu, PPCIntrArgs *regs, bool *ignore); -void ppc_intr_embedded_fp_round(PowerPCCPU *cpu, PPCIntrArgs *regs, bool *ignore); -void ppc_intr_embedded_perf_monitor(PowerPCCPU *cpu, PPCIntrArgs *regs, bool *ignore); -void ppc_intr_emulation(PowerPCCPU *cpu, PPCIntrArgs *regs, bool *ignore); void ppc_intr_external(PowerPCCPU *cpu, PPCIntrArgs *regs, bool *ignore); void ppc_intr_facility_unavail(PowerPCCPU *cpu, PPCIntrArgs *regs, bool *ignore); void ppc_intr_fit(PowerPCCPU *cpu, PPCIntrArgs *regs, bool *ignore); -void ppc_intr_fpa(PowerPCCPU *cpu, PPCIntrArgs *regs, bool *ignore); void ppc_intr_hv_data_segment(PowerPCCPU *cpu, PPCIntrArgs *regs, bool *ignore); void ppc_intr_hv_data_storage(PowerPCCPU *cpu, PPCIntrArgs *regs, bool *ignore); void ppc_intr_hv_decrementer(PowerPCCPU *cpu, PPCIntrArgs *regs, bool *ignore); @@ -42,27 +36,16 @@ void ppc_intr_hv_facility_unavail(PowerPCCPU *cpu, PPCIntrArgs *regs, bool *igno void ppc_intr_hv_insn_segment(PowerPCCPU *cpu, PPCIntrArgs *regs, bool *ignore); void ppc_intr_hv_insn_storage(PowerPCCPU *cpu, PPCIntrArgs *regs, bool *ignore); void ppc_intr_hv_virtualization(PowerPCCPU *cpu, PPCIntrArgs *regs, bool *ignore); -void ppc_intr_iabr(PowerPCCPU *cpu, PPCIntrArgs *regs, bool *ignore); void ppc_intr_insn_storage(PowerPCCPU *cpu, PPCIntrArgs *regs, bool *ignore); -void ppc_intr_io_error(PowerPCCPU *cpu, PPCIntrArgs *regs, bool *ignore); void ppc_intr_machine_check(PowerPCCPU *cpu, PPCIntrArgs *regs, bool *ignore); -void ppc_intr_maint(PowerPCCPU *cpu, PPCIntrArgs *regs, bool *ignore); -void ppc_intr_mextbr(PowerPCCPU *cpu, PPCIntrArgs *regs, bool *ignore); -void ppc_intr_nmextbr(PowerPCCPU *cpu, PPCIntrArgs *regs, bool *ignore); void ppc_intr_noop(PowerPCCPU *cpu, PPCIntrArgs *regs, bool *ignore); -void ppc_intr_perfm(PowerPCCPU *cpu, PPCIntrArgs *regs, bool *ignore); void ppc_intr_program(PowerPCCPU *cpu, PPCIntrArgs *regs, bool *ignore); void ppc_intr_programmable_timer(PowerPCCPU *cpu, PPCIntrArgs *regs, bool *ignore); -void ppc_intr_run_mode(PowerPCCPU *cpu, PPCIntrArgs *regs, bool *ignore); -void ppc_intr_smi(PowerPCCPU *cpu, PPCIntrArgs *regs, bool *ignore); -void ppc_intr_softp(PowerPCCPU *cpu, PPCIntrArgs *regs, bool *ignore); void ppc_intr_spe_unavailable(PowerPCCPU *cpu, PPCIntrArgs *regs, bool *ignore); void ppc_intr_system_call(PowerPCCPU *cpu, PPCIntrArgs *regs, bool *ignore); void ppc_intr_system_call_vectored(PowerPCCPU *cpu, PPCIntrArgs *regs, bool *ignore); void ppc_intr_system_reset(PowerPCCPU *cpu, PPCIntrArgs *regs, bool *ignore); -void ppc_intr_therm(PowerPCCPU *cpu, PPCIntrArgs *regs, bool *ignore); void ppc_intr_tlb_miss(PowerPCCPU *cpu, PPCIntrArgs *regs, bool *ignore); -void ppc_intr_vpua(PowerPCCPU *cpu, PPCIntrArgs *regs, bool *ignore); void ppc_intr_watchdog(PowerPCCPU *cpu, PPCIntrArgs *regs, bool *ignore); extern PPCInterrupt interrupts[POWERPC_EXCP_NB]; From patchwork Mon Dec 20 18:19:00 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Fabiano Rosas X-Patchwork-Id: 12688459 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.lore.kernel.org (Postfix) with ESMTPS id CF5F3C433EF for ; Mon, 20 Dec 2021 19:51:37 +0000 (UTC) Received: from localhost ([::1]:44674 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1mzOh6-0000lC-MV for qemu-devel@archiver.kernel.org; Mon, 20 Dec 2021 14:51:36 -0500 Received: from eggs.gnu.org ([209.51.188.92]:35926) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1mzNGE-00034E-DH; Mon, 20 Dec 2021 13:19:47 -0500 Received: from mx0b-001b2d01.pphosted.com ([148.163.158.5]:31694 helo=mx0a-001b2d01.pphosted.com) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1mzNGC-0006o3-Ms; Mon, 20 Dec 2021 13:19:46 -0500 Received: from pps.filterd (m0098414.ppops.net [127.0.0.1]) by mx0b-001b2d01.pphosted.com (8.16.1.2/8.16.1.2) with SMTP id 1BKHg5Qa024961; Mon, 20 Dec 2021 18:19:33 GMT DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=ibm.com; h=from : to : cc : subject : date : message-id : in-reply-to : references : mime-version : content-transfer-encoding; s=pp1; bh=p/TvljV6iO+8rW6DWhzVU3Y3n0V32wA1oU3x6DI8FXw=; b=NJNG2UAD65jLHthGzl+UDW6PapD2SbHCQVuXDvNSc4+E5V7RCKFl5QO1SQwaZTyn1Bvf ltmxu74BMwkm+oGiAZyXNSsImNWc4VScyLsEHUhMtC7WeDy1QM/wFZ8txyCa3me+jmBk AhxIFGpG+vrKfR221LgDBHCj8jCuKD3V3Oq15IRx8bdpBx7plqUFBHmmJvXjYTvlGHx3 IGIUw61A8LLX30sceAKMDut6NcfofXFWqoAIEbmqMp+jYma008SQoiWwJspvRaap3iXD +koiOBx530j3NdQNRieTrzQwLsoBxOyfE3z+Ai7rgyXXGV2TucUXfg8vY6B6/YbwfnCP eg== Received: from pps.reinject (localhost [127.0.0.1]) by mx0b-001b2d01.pphosted.com with ESMTP id 3d1891bvjq-1 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NOT); Mon, 20 Dec 2021 18:19:33 +0000 Received: from m0098414.ppops.net (m0098414.ppops.net [127.0.0.1]) by pps.reinject (8.16.0.43/8.16.0.43) with SMTP id 1BKHxB2Y003254; Mon, 20 Dec 2021 18:19:32 GMT Received: from ppma03dal.us.ibm.com (b.bd.3ea9.ip4.static.sl-reverse.com [169.62.189.11]) by mx0b-001b2d01.pphosted.com with ESMTP id 3d1891bvja-1 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NOT); Mon, 20 Dec 2021 18:19:32 +0000 Received: from pps.filterd (ppma03dal.us.ibm.com [127.0.0.1]) by ppma03dal.us.ibm.com (8.16.1.2/8.16.1.2) with SMTP id 1BKIDSNC016588; Mon, 20 Dec 2021 18:19:31 GMT Received: from b03cxnp08026.gho.boulder.ibm.com (b03cxnp08026.gho.boulder.ibm.com [9.17.130.18]) by ppma03dal.us.ibm.com with ESMTP id 3d179aa9rj-1 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NOT); Mon, 20 Dec 2021 18:19:31 +0000 Received: from b03ledav006.gho.boulder.ibm.com (b03ledav006.gho.boulder.ibm.com [9.17.130.237]) by b03cxnp08026.gho.boulder.ibm.com (8.14.9/8.14.9/NCO v10.0) with ESMTP id 1BKIJU3N19464518 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-GCM-SHA384 bits=256 verify=OK); Mon, 20 Dec 2021 18:19:30 GMT Received: from b03ledav006.gho.boulder.ibm.com (unknown [127.0.0.1]) by IMSVA (Postfix) with ESMTP id 657D1C6061; Mon, 20 Dec 2021 18:19:30 +0000 (GMT) Received: from b03ledav006.gho.boulder.ibm.com (unknown [127.0.0.1]) by IMSVA (Postfix) with ESMTP id DA73BC6055; Mon, 20 Dec 2021 18:19:28 +0000 (GMT) Received: from farosas.linux.ibm.com.com (unknown [9.211.60.53]) by b03ledav006.gho.boulder.ibm.com (Postfix) with ESMTP; Mon, 20 Dec 2021 18:19:28 +0000 (GMT) From: Fabiano Rosas To: qemu-devel@nongnu.org Subject: [RFC v2 09/12] target/ppc: Use common code for Hypervisor interrupts Date: Mon, 20 Dec 2021 15:19:00 -0300 Message-Id: <20211220181903.3456898-10-farosas@linux.ibm.com> X-Mailer: git-send-email 2.33.1 In-Reply-To: <20211220181903.3456898-1-farosas@linux.ibm.com> References: <20211220181903.3456898-1-farosas@linux.ibm.com> MIME-Version: 1.0 X-TM-AS-GCONF: 00 X-Proofpoint-GUID: twECGO6jLbsfinCjSHPo5oi-gbgEsFJ4 X-Proofpoint-ORIG-GUID: mAJhdgT7gNq-8bCC0CnNSGKNIpdZ4q7y X-Proofpoint-Virus-Version: vendor=baseguard engine=ICAP:2.0.205,Aquarius:18.0.790,Hydra:6.0.425,FMLib:17.11.62.513 definitions=2021-12-20_08,2021-12-20_01,2021-12-02_01 X-Proofpoint-Spam-Details: rule=outbound_notspam policy=outbound score=0 lowpriorityscore=0 adultscore=0 priorityscore=1501 mlxscore=0 phishscore=0 spamscore=0 bulkscore=0 mlxlogscore=999 clxscore=1015 malwarescore=0 suspectscore=0 impostorscore=0 classifier=spam adjust=0 reason=mlx scancount=1 engine=8.12.0-2110150000 definitions=main-2112200101 Received-SPF: pass client-ip=148.163.158.5; envelope-from=farosas@linux.ibm.com; helo=mx0a-001b2d01.pphosted.com X-Spam_score_int: -19 X-Spam_score: -2.0 X-Spam_bar: -- X-Spam_report: (-2.0 / 5.0 requ) BAYES_00=-1.9, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_EF=-0.1, RCVD_IN_MSPIKE_H2=-0.001, SPF_HELO_NONE=0.001, SPF_PASS=-0.001 autolearn=ham autolearn_force=no X-Spam_action: no action X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: danielhb413@gmail.com, qemu-ppc@nongnu.org, clg@kaod.org, david@gibson.dropbear.id.au Errors-To: qemu-devel-bounces+qemu-devel=archiver.kernel.org@nongnu.org Sender: "Qemu-devel" The Hypervisor interrupts all set the MSR_HV bit, and use HSRRs instead of SRRs, so we can use the same code to setup them all. No functional change. Signed-off-by: Fabiano Rosas --- target/ppc/interrupts.c | 128 +++++++--------------------------------- target/ppc/ppc_intr.h | 8 +-- 2 files changed, 21 insertions(+), 115 deletions(-) diff --git a/target/ppc/interrupts.c b/target/ppc/interrupts.c index 1e4fb2d6db..61a7dec682 100644 --- a/target/ppc/interrupts.c +++ b/target/ppc/interrupts.c @@ -364,86 +364,22 @@ void ppc_intr_system_reset(PowerPCCPU *cpu, PPCIntrArgs *regs, bool *ignore) } } +void ppc_intr_hv(PowerPCCPU *cpu, PPCIntrArgs *regs, bool *ignore) +{ + CPUPPCState *env = &cpu->env; + + regs->sprn_srr0 = SPR_HSRR0; + regs->sprn_srr1 = SPR_HSRR1; + regs->new_msr |= (target_ulong)MSR_HVB; + regs->new_msr |= env->msr & ((target_ulong)1 << MSR_RI); +} + void ppc_intr_hv_insn_storage(PowerPCCPU *cpu, PPCIntrArgs *regs, bool *ignore) { CPUPPCState *env = &cpu->env; regs->msr |= env->error_code; - - regs->sprn_srr0 = SPR_HSRR0; - regs->sprn_srr1 = SPR_HSRR1; - regs->new_msr |= (target_ulong)MSR_HVB; - regs->new_msr |= env->msr & ((target_ulong)1 << MSR_RI); -} - -void ppc_intr_hv_decrementer(PowerPCCPU *cpu, PPCIntrArgs *regs, bool *ignore) -{ - CPUPPCState *env = &cpu->env; - - regs->sprn_srr0 = SPR_HSRR0; - regs->sprn_srr1 = SPR_HSRR1; - regs->new_msr |= (target_ulong)MSR_HVB; - regs->new_msr |= env->msr & ((target_ulong)1 << MSR_RI); -} - -void ppc_intr_hv_data_storage(PowerPCCPU *cpu, PPCIntrArgs *regs, bool *ignore) -{ - CPUPPCState *env = &cpu->env; - - regs->sprn_srr0 = SPR_HSRR0; - regs->sprn_srr1 = SPR_HSRR1; - regs->new_msr |= (target_ulong)MSR_HVB; - regs->new_msr |= env->msr & ((target_ulong)1 << MSR_RI); -} - -void ppc_intr_hv_data_segment(PowerPCCPU *cpu, PPCIntrArgs *regs, bool *ignore) -{ - CPUPPCState *env = &cpu->env; - - regs->sprn_srr0 = SPR_HSRR0; - regs->sprn_srr1 = SPR_HSRR1; - regs->new_msr |= (target_ulong)MSR_HVB; - regs->new_msr |= env->msr & ((target_ulong)1 << MSR_RI); -} - -void ppc_intr_hv_insn_segment(PowerPCCPU *cpu, PPCIntrArgs *regs, bool *ignore) -{ - CPUPPCState *env = &cpu->env; - - regs->sprn_srr0 = SPR_HSRR0; - regs->sprn_srr1 = SPR_HSRR1; - regs->new_msr |= (target_ulong)MSR_HVB; - regs->new_msr |= env->msr & ((target_ulong)1 << MSR_RI); -} - -void ppc_intr_hv_doorbell(PowerPCCPU *cpu, PPCIntrArgs *regs, bool *ignore) -{ - CPUPPCState *env = &cpu->env; - - regs->sprn_srr0 = SPR_HSRR0; - regs->sprn_srr1 = SPR_HSRR1; - regs->new_msr |= (target_ulong)MSR_HVB; - regs->new_msr |= env->msr & ((target_ulong)1 << MSR_RI); -} - -void ppc_intr_hv_emulation(PowerPCCPU *cpu, PPCIntrArgs *regs, bool *ignore) -{ - CPUPPCState *env = &cpu->env; - - regs->sprn_srr0 = SPR_HSRR0; - regs->sprn_srr1 = SPR_HSRR1; - regs->new_msr |= (target_ulong)MSR_HVB; - regs->new_msr |= env->msr & ((target_ulong)1 << MSR_RI); -} - -void ppc_intr_hv_virtualization(PowerPCCPU *cpu, PPCIntrArgs *regs, bool *ignore) -{ - CPUPPCState *env = &cpu->env; - - regs->sprn_srr0 = SPR_HSRR0; - regs->sprn_srr1 = SPR_HSRR1; - regs->new_msr |= (target_ulong)MSR_HVB; - regs->new_msr |= env->msr & ((target_ulong)1 << MSR_RI); + ppc_intr_hv(cpu, regs, ignore); } void ppc_intr_facility_unavail(PowerPCCPU *cpu, PPCIntrArgs *regs, bool *ignore) @@ -459,11 +395,7 @@ void ppc_intr_hv_facility_unavail(PowerPCCPU *cpu, PPCIntrArgs *regs, bool *igno #ifdef TARGET_PPC64 CPUPPCState *env = &cpu->env; env->spr[SPR_FSCR] |= ((target_ulong)env->error_code << FSCR_IC_POS); - - regs->sprn_srr0 = SPR_HSRR0; - regs->sprn_srr1 = SPR_HSRR1; - regs->new_msr |= (target_ulong)MSR_HVB; - regs->new_msr |= env->msr & ((target_ulong)1 << MSR_RI); + ppc_intr_hv(cpu, regs, ignore); #endif } @@ -571,34 +503,10 @@ PPCInterrupt interrupts[POWERPC_EXCP_NB] = { "Facility unavailable", ppc_intr_facility_unavail }, - [POWERPC_EXCP_HDECR] = { - "Hypervisor decrementer", ppc_intr_hv_decrementer - }, - - [POWERPC_EXCP_HDSEG] = { - "Hypervisor data segment", ppc_intr_hv_data_segment - }, - - [POWERPC_EXCP_HDSI] = { - "Hypervisor data storage", ppc_intr_hv_data_storage - }, - - [POWERPC_EXCP_HISEG] = { - "Hypervisor insn segment", ppc_intr_hv_insn_segment - }, - [POWERPC_EXCP_HISI] = { "Hypervisor instruction storage", ppc_intr_hv_insn_storage }, - [POWERPC_EXCP_HVIRT] = { - "Hypervisor virtualization", ppc_intr_hv_virtualization - }, - - [POWERPC_EXCP_HV_EMU] = { - "Hypervisor emulation assist", ppc_intr_hv_emulation - }, - [POWERPC_EXCP_HV_FU] = { "Hypervisor facility unavailable" , ppc_intr_hv_facility_unavail }, @@ -627,10 +535,6 @@ PPCInterrupt interrupts[POWERPC_EXCP_NB] = { "System reset", ppc_intr_system_reset }, - [POWERPC_EXCP_SDOOR_HV] = { - "Hypervisor doorbell", ppc_intr_hv_doorbell - }, - [POWERPC_EXCP_SPEU] = { "SPE/embedded FP unavailable/VPU", ppc_intr_spe_unavailable }, @@ -655,6 +559,14 @@ PPCInterrupt interrupts[POWERPC_EXCP_NB] = { "Watchdog timer", ppc_intr_watchdog }, + [POWERPC_EXCP_HDECR] = { "Hypervisor decrementer", ppc_intr_hv }, + [POWERPC_EXCP_HDSEG] = { "Hypervisor data segment", ppc_intr_hv }, + [POWERPC_EXCP_HDSI] = { "Hypervisor data storage", ppc_intr_hv }, + [POWERPC_EXCP_HISEG] = { "Hypervisor insn segment", ppc_intr_hv }, + [POWERPC_EXCP_HVIRT] = { "Hypervisor virtualization", ppc_intr_hv }, + [POWERPC_EXCP_HV_EMU] = { "Hypervisor emulation assist", ppc_intr_hv }, + [POWERPC_EXCP_SDOOR_HV] = { "Hypervisor doorbell", ppc_intr_hv }, + [POWERPC_EXCP_APU] = { "Aux. processor unavailable", ppc_intr_noop }, [POWERPC_EXCP_DECR] = { "Decrementer", ppc_intr_noop }, [POWERPC_EXCP_DOORI] = { "Embedded doorbell", ppc_intr_noop }, diff --git a/target/ppc/ppc_intr.h b/target/ppc/ppc_intr.h index a96062c583..078906ed68 100644 --- a/target/ppc/ppc_intr.h +++ b/target/ppc/ppc_intr.h @@ -27,15 +27,9 @@ void ppc_intr_embedded_doorbell_crit(PowerPCCPU *cpu, PPCIntrArgs *regs, bool *i void ppc_intr_external(PowerPCCPU *cpu, PPCIntrArgs *regs, bool *ignore); void ppc_intr_facility_unavail(PowerPCCPU *cpu, PPCIntrArgs *regs, bool *ignore); void ppc_intr_fit(PowerPCCPU *cpu, PPCIntrArgs *regs, bool *ignore); -void ppc_intr_hv_data_segment(PowerPCCPU *cpu, PPCIntrArgs *regs, bool *ignore); -void ppc_intr_hv_data_storage(PowerPCCPU *cpu, PPCIntrArgs *regs, bool *ignore); -void ppc_intr_hv_decrementer(PowerPCCPU *cpu, PPCIntrArgs *regs, bool *ignore); -void ppc_intr_hv_doorbell(PowerPCCPU *cpu, PPCIntrArgs *regs, bool *ignore); -void ppc_intr_hv_emulation(PowerPCCPU *cpu, PPCIntrArgs *regs, bool *ignore); +void ppc_intr_hv(PowerPCCPU *cpu, PPCIntrArgs *regs, bool *ignore); void ppc_intr_hv_facility_unavail(PowerPCCPU *cpu, PPCIntrArgs *regs, bool *ignore); -void ppc_intr_hv_insn_segment(PowerPCCPU *cpu, PPCIntrArgs *regs, bool *ignore); void ppc_intr_hv_insn_storage(PowerPCCPU *cpu, PPCIntrArgs *regs, bool *ignore); -void ppc_intr_hv_virtualization(PowerPCCPU *cpu, PPCIntrArgs *regs, bool *ignore); void ppc_intr_insn_storage(PowerPCCPU *cpu, PPCIntrArgs *regs, bool *ignore); void ppc_intr_machine_check(PowerPCCPU *cpu, PPCIntrArgs *regs, bool *ignore); void ppc_intr_noop(PowerPCCPU *cpu, PPCIntrArgs *regs, bool *ignore); From patchwork Mon Dec 20 18:19:01 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Fabiano Rosas X-Patchwork-Id: 12688395 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.lore.kernel.org (Postfix) with ESMTPS id D663FC433EF for ; Mon, 20 Dec 2021 19:02:23 +0000 (UTC) Received: from localhost ([::1]:60522 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1mzNvS-00022t-KJ for qemu-devel@archiver.kernel.org; Mon, 20 Dec 2021 14:02:22 -0500 Received: from eggs.gnu.org ([209.51.188.92]:35880) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1mzNGC-00031F-Rg; Mon, 20 Dec 2021 13:19:45 -0500 Received: from mx0a-001b2d01.pphosted.com ([148.163.156.1]:5252) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1mzNG8-0006md-VQ; Mon, 20 Dec 2021 13:19:44 -0500 Received: from pps.filterd (m0098409.ppops.net [127.0.0.1]) by mx0a-001b2d01.pphosted.com (8.16.1.2/8.16.1.2) with SMTP id 1BKHqRkX005537; Mon, 20 Dec 2021 18:19:35 GMT DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=ibm.com; h=from : to : cc : subject : date : message-id : in-reply-to : references : mime-version : content-transfer-encoding; s=pp1; bh=FY8MFEwFUCUEQc3QoHRKWrc+IKTLR95gH1Lzl3q1y3o=; b=MRUNBhTM0mwEYxDffa/R+ZH1hnxafHW1RlXrhIH7bbbMAig2PZWYfhpHLc9uk2W8og5h sa+XvAGEvgy7lpt0UbORUTpzP/+ENhp9l3C46O6V46qhUHTbaGaxdDFR+EGpjFEH0/Ra +QROwusqnvR7WM3GU+u2g3v55+ccWuh8dEAmVIzBLyhhdkxM5483o4ZMy+jnGYm8nxGk 2YHXSte6BfXS4duToMLTEEJJ2D7M+SBAOblKpB37PfLLtotnmY5pRwrWXjgALOmwy1nE zrkBrI69aboWG3acUKTbaic7SWU7VU7IY+GHhdZIfOlDw12W3V/S9JvE2UWrmarWYTvY Vg== Received: from pps.reinject (localhost [127.0.0.1]) by mx0a-001b2d01.pphosted.com with ESMTP id 3d2q0jtpah-1 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NOT); Mon, 20 Dec 2021 18:19:35 +0000 Received: from m0098409.ppops.net (m0098409.ppops.net [127.0.0.1]) by pps.reinject (8.16.0.43/8.16.0.43) with SMTP id 1BKHc6u1003467; Mon, 20 Dec 2021 18:19:34 GMT Received: from ppma05wdc.us.ibm.com (1b.90.2fa9.ip4.static.sl-reverse.com [169.47.144.27]) by mx0a-001b2d01.pphosted.com with ESMTP id 3d2q0jtp9k-1 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NOT); Mon, 20 Dec 2021 18:19:34 +0000 Received: from pps.filterd (ppma05wdc.us.ibm.com [127.0.0.1]) by ppma05wdc.us.ibm.com (8.16.1.2/8.16.1.2) with SMTP id 1BKIDcQl017491; Mon, 20 Dec 2021 18:19:33 GMT Received: from b03cxnp08027.gho.boulder.ibm.com (b03cxnp08027.gho.boulder.ibm.com [9.17.130.19]) by ppma05wdc.us.ibm.com with ESMTP id 3d179ahw9a-1 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NOT); Mon, 20 Dec 2021 18:19:33 +0000 Received: from b03ledav006.gho.boulder.ibm.com (b03ledav006.gho.boulder.ibm.com [9.17.130.237]) by b03cxnp08027.gho.boulder.ibm.com (8.14.9/8.14.9/NCO v10.0) with ESMTP id 1BKIJW9f11403914 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-GCM-SHA384 bits=256 verify=OK); Mon, 20 Dec 2021 18:19:32 GMT Received: from b03ledav006.gho.boulder.ibm.com (unknown [127.0.0.1]) by IMSVA (Postfix) with ESMTP id 671F5C6063; Mon, 20 Dec 2021 18:19:32 +0000 (GMT) Received: from b03ledav006.gho.boulder.ibm.com (unknown [127.0.0.1]) by IMSVA (Postfix) with ESMTP id E1C73C605D; Mon, 20 Dec 2021 18:19:30 +0000 (GMT) Received: from farosas.linux.ibm.com.com (unknown [9.211.60.53]) by b03ledav006.gho.boulder.ibm.com (Postfix) with ESMTP; Mon, 20 Dec 2021 18:19:30 +0000 (GMT) From: Fabiano Rosas To: qemu-devel@nongnu.org Subject: [RFC v2 10/12] target/ppc: Split powerpc_excp into book3s, booke and 32 bit Date: Mon, 20 Dec 2021 15:19:01 -0300 Message-Id: <20211220181903.3456898-11-farosas@linux.ibm.com> X-Mailer: git-send-email 2.33.1 In-Reply-To: <20211220181903.3456898-1-farosas@linux.ibm.com> References: <20211220181903.3456898-1-farosas@linux.ibm.com> MIME-Version: 1.0 X-TM-AS-GCONF: 00 X-Proofpoint-GUID: PD0kvh9WjXSmnXkWe5f7eCX9qQwdq7UB X-Proofpoint-ORIG-GUID: ghOViJu85448aqk4cbXE0VbgjUH4fzcl X-Proofpoint-Virus-Version: vendor=baseguard engine=ICAP:2.0.205,Aquarius:18.0.790,Hydra:6.0.425,FMLib:17.11.62.513 definitions=2021-12-20_08,2021-12-20_01,2021-12-02_01 X-Proofpoint-Spam-Details: rule=outbound_notspam policy=outbound score=0 malwarescore=0 spamscore=0 impostorscore=0 bulkscore=0 clxscore=1015 mlxlogscore=999 phishscore=0 adultscore=0 suspectscore=0 priorityscore=1501 mlxscore=0 lowpriorityscore=0 classifier=spam adjust=0 reason=mlx scancount=1 engine=8.12.0-2110150000 definitions=main-2112200101 Received-SPF: pass client-ip=148.163.156.1; envelope-from=farosas@linux.ibm.com; helo=mx0a-001b2d01.pphosted.com X-Spam_score_int: -19 X-Spam_score: -2.0 X-Spam_bar: -- X-Spam_report: (-2.0 / 5.0 requ) BAYES_00=-1.9, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_EF=-0.1, RCVD_IN_MSPIKE_H2=-0.001, SPF_HELO_NONE=0.001, SPF_PASS=-0.001 autolearn=ham autolearn_force=no X-Spam_action: no action X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: danielhb413@gmail.com, qemu-ppc@nongnu.org, clg@kaod.org, david@gibson.dropbear.id.au Errors-To: qemu-devel-bounces+qemu-devel=archiver.kernel.org@nongnu.org Sender: "Qemu-devel" These are the three major categories of processors we support and they have slightly different requirements when it comes to dispatching interrupts. Having it all in the same function is somewhat confusing because one needs to keep guessing which parts of the code apply exactly to which processors. This patch splits powerpc_excp into three functions that will later be moved into their own file. (POWERPC_EXCP_DOORCI was removed because no CPUs use it) Signed-off-by: Fabiano Rosas --- target/ppc/excp_helper.c | 258 +++++++++++++++++++++++++-------------- target/ppc/interrupts.c | 223 ++++++++++++++++++++++++++------- target/ppc/ppc_intr.h | 7 +- 3 files changed, 350 insertions(+), 138 deletions(-) diff --git a/target/ppc/excp_helper.c b/target/ppc/excp_helper.c index 4f8a6c4ec8..9c785b75d5 100644 --- a/target/ppc/excp_helper.c +++ b/target/ppc/excp_helper.c @@ -37,6 +37,7 @@ /* Exception processing */ #if !defined(CONFIG_USER_ONLY) +#ifdef TARGET_PPC64 static int powerpc_reset_wakeup(CPUState *cs, CPUPPCState *env, int excp, target_ulong *msr) { @@ -140,7 +141,6 @@ static inline void ppc_excp_apply_ail(PowerPCCPU *cpu, int excp_model, int excp, target_ulong *new_msr, target_ulong *new_nip) { -#if defined(TARGET_PPC64) CPUPPCState *env = &cpu->env; bool mmu_all_on = ((msr >> MSR_IR) & 1) && ((msr >> MSR_DR) & 1); bool hv_escalation = !(msr & MSR_HVB) && (*new_msr & MSR_HVB); @@ -229,8 +229,9 @@ static inline void ppc_excp_apply_ail(PowerPCCPU *cpu, int excp_model, int excp, *new_nip |= 0xc000000000003000ull; /* Apply scv's AIL=3 offset */ } } -#endif } +#endif /* TARGET_PPC64 */ + static inline void powerpc_set_excp_state(PowerPCCPU *cpu, target_ulong new_nip, target_ulong new_msr) @@ -263,33 +264,16 @@ static inline void powerpc_set_excp_state(PowerPCCPU *cpu, target_ulong new_nip, check_tlb_flush(env, false); } -/* - * Note that this function should be greatly optimized when called - * with a constant excp, from ppc_hw_interrupt - */ -static inline void powerpc_excp(PowerPCCPU *cpu, int excp) +#if defined(TARGET_PPC64) +static inline void book3s_excp(PowerPCCPU *cpu, int excp) { CPUState *cs = CPU(cpu); CPUPPCState *env = &cpu->env; int excp_model = env->excp_model; PPCIntrArgs regs; - PPCInterrupt *intr; - bool ignore = false; + bool ignore; - qemu_log_mask(CPU_LOG_INT, "Raise exception at " TARGET_FMT_lx - " => %08x (%02x)\n", env->nip, excp, env->error_code); - - if (excp == POWERPC_EXCP_NONE) { - /* Should never happen */ - return; - } - - /* new srr1 value excluding must-be-zero bits */ - if (excp_model == POWERPC_EXCP_BOOKE) { - regs.msr = env->msr; - } else { - regs.msr = env->msr & ~0x783f0000ULL; - } + regs.msr = env->msr & ~0x783f0000ULL; regs.nip = env->nip; /* @@ -298,6 +282,9 @@ static inline void powerpc_excp(PowerPCCPU *cpu, int excp) */ regs.new_msr = env->msr & (((target_ulong)1 << MSR_ME) | MSR_HVB); + /* The Book3S cpus we support are 64 bit only */ + regs.new_msr |= (target_ulong)1 << MSR_SF; + regs.sprn_srr0 = SPR_SRR0; regs.sprn_srr1 = SPR_SRR1; @@ -310,71 +297,31 @@ static inline void powerpc_excp(PowerPCCPU *cpu, int excp) } /* - * Hypervisor emulation assistance interrupt only exists on server - * arch 2.05 server or later. We also don't want to generate it if - * we don't have HVB in msr_mask (PAPR mode). + * We don't want to generate an Hypervisor emulation assistance + * interrupt if we don't have HVB in msr_mask (PAPR mode). */ - if (excp == POWERPC_EXCP_HV_EMU -#if defined(TARGET_PPC64) - && !(mmu_is_64bit(env->mmu_model) && (env->msr_mask & MSR_HVB)) -#endif /* defined(TARGET_PPC64) */ - - ) { + if (excp == POWERPC_EXCP_HV_EMU && !(env->msr_mask & MSR_HVB)) { excp = POWERPC_EXCP_PROGRAM; } -#ifdef TARGET_PPC64 - /* - * SPEU and VPU share the same IVOR but they exist in different - * processors. SPEU is e500v1/2 only and VPU is e6500 only. - */ - if (excp_model == POWERPC_EXCP_BOOKE && excp == POWERPC_EXCP_VPU) { - excp = POWERPC_EXCP_SPEU; - } -#endif - regs.new_nip = env->excp_vectors[excp]; if (regs.new_nip == (target_ulong)-1ULL) { cpu_abort(cs, "Raised an exception without defined vector %d\n", excp); } - regs.new_nip |= env->excp_prefix; - - intr = &interrupts[excp]; - if (!intr->name) { - cpu_abort(cs, "Invalid PowerPC exception %d. Aborting\n", excp); - } - - if (!intr->fn) { - cpu_abort(cs, "%s exception is not implemented yet !\n", intr->name); - } - - /* Setup interrupt-specific registers before dispatching */ - intr->fn(cpu, ®s, &ignore); + /* Setup interrupt-specific registers before injecting */ + ignore = ppc_intr_prepare(cpu, interrupts_book3s, ®s, excp); if (ignore) { /* No further setup is needed for this interrupt */ return; } - /* Sanity check */ - if (!(env->msr_mask & MSR_HVB)) { - if (regs.new_msr & MSR_HVB) { - cpu_abort(cs, "Trying to deliver HV exception (MSR) %d with " - "no HV support\n", excp); - } - if (regs.sprn_srr0 == SPR_HSRR0) { - cpu_abort(cs, "Trying to deliver HV exception (HSRR) %d with " - "no HV support\n", excp); - } - } - /* * Sort out endianness of interrupt, this differs depending on the * CPU, the HV mode, etc... */ -#ifdef TARGET_PPC64 if (excp_model == POWERPC_EXCP_POWER7) { if (!(regs.new_msr & MSR_HVB) && (env->spr[SPR_LPCR] & LPCR_ILE)) { regs.new_msr |= (target_ulong)1 << MSR_LE; @@ -399,28 +346,6 @@ static inline void powerpc_excp(PowerPCCPU *cpu, int excp) } else if (msr_ile) { regs.new_msr |= (target_ulong)1 << MSR_LE; } -#else - if (msr_ile) { - regs.new_msr |= (target_ulong)1 << MSR_LE; - } -#endif - -#if defined(TARGET_PPC64) - if (excp_model == POWERPC_EXCP_BOOKE) { - if (env->spr[SPR_BOOKE_EPCR] & EPCR_ICM) { - /* Cat.64-bit: EPCR.ICM is copied to MSR.CM */ - regs.new_msr |= (target_ulong)1 << MSR_CM; - } else { - regs.new_nip = (uint32_t)regs.new_nip; - } - } else { - if (!msr_isf && !mmu_is_64bit(env->mmu_model)) { - regs.new_nip = (uint32_t)regs.new_nip; - } else { - regs.new_msr |= (target_ulong)1 << MSR_SF; - } - } -#endif if (excp != POWERPC_EXCP_SYSCALL_VECTORED) { /* Save PC */ @@ -436,6 +361,159 @@ static inline void powerpc_excp(PowerPCCPU *cpu, int excp) powerpc_set_excp_state(cpu, regs.new_nip, regs.new_msr); } +#endif /* defined(TARGET_PPC64) */ + +static inline void booke_excp(PowerPCCPU *cpu, int excp) +{ + CPUState *cs = CPU(cpu); + CPUPPCState *env = &cpu->env; + PPCIntrArgs regs; + bool ignore; + + regs.msr = env->msr; + regs.nip = env->nip; + + /* + * new interrupt handler msr preserves existing HV and ME unless + * explicitly overriden + */ + regs.new_msr = env->msr & (((target_ulong)1 << MSR_ME) | MSR_HVB); + + regs.sprn_srr0 = SPR_SRR0; + regs.sprn_srr1 = SPR_SRR1; + + /* + * Hypervisor emulation assistance interrupt only exists on server + * arch 2.05 server or later. + */ + if (excp == POWERPC_EXCP_HV_EMU) { + excp = POWERPC_EXCP_PROGRAM; + } + +#ifdef TARGET_PPC64 + /* + * SPEU and VPU share the same IVOR but they exist in different + * processors. SPEU is e500v1/2 only and VPU is e6500 only. + */ + if (env->excp_model == POWERPC_EXCP_BOOKE && excp == POWERPC_EXCP_VPU) { + excp = POWERPC_EXCP_SPEU; + } +#endif + + regs.new_nip = env->excp_vectors[excp]; + if (regs.new_nip == (target_ulong)-1ULL) { + cpu_abort(cs, "Raised an exception without defined vector %d\n", + excp); + } + + regs.new_nip |= env->excp_prefix; + + /* Setup interrupt-specific registers before injecting */ + ignore = ppc_intr_prepare(cpu, interrupts_booke, ®s, excp); + + if (ignore) { + /* No further setup is needed for this interrupt */ + return; + } + +#if defined(TARGET_PPC64) + if (env->spr[SPR_BOOKE_EPCR] & EPCR_ICM) { + /* Cat.64-bit: EPCR.ICM is copied to MSR.CM */ + regs.new_msr |= (target_ulong)1 << MSR_CM; + } else { + regs.new_nip = (uint32_t)regs.new_nip; + } +#endif + + /* Save PC */ + env->spr[regs.sprn_srr0] = regs.nip; + + /* Save MSR */ + env->spr[regs.sprn_srr1] = regs.msr; + + powerpc_set_excp_state(cpu, regs.new_nip, regs.new_msr); +} + +static inline void ppc32_excp(PowerPCCPU *cpu, int excp) +{ + CPUState *cs = CPU(cpu); + CPUPPCState *env = &cpu->env; + PPCIntrArgs regs; + bool ignore; + + regs.msr = env->msr & ~0x783f0000ULL; + regs.nip = env->nip; + + /* + * new interrupt handler msr preserves existing HV and ME unless + * explicitly overriden + */ + regs.new_msr = env->msr & (((target_ulong)1 << MSR_ME) | MSR_HVB); + + regs.sprn_srr0 = SPR_SRR0; + regs.sprn_srr1 = SPR_SRR1; + + /* + * Hypervisor emulation assistance interrupt only exists on server + * arch 2.05 server or later. + */ + if (excp == POWERPC_EXCP_HV_EMU) { + excp = POWERPC_EXCP_PROGRAM; + } + + regs.new_nip = env->excp_vectors[excp]; + if (regs.new_nip == (target_ulong)-1ULL) { + cpu_abort(cs, "Raised an exception without defined vector %d\n", + excp); + } + + regs.new_nip |= env->excp_prefix; + + /* Setup interrupt-specific registers before injecting */ + ignore = ppc_intr_prepare(cpu, interrupts_ppc32, ®s, excp); + + if (ignore) { + /* No further setup is needed for this interrupt */ + return; + } + + if (msr_ile) { + regs.new_msr |= (target_ulong)1 << MSR_LE; + } + + /* Save PC */ + env->spr[regs.sprn_srr0] = regs.nip; + + /* Save MSR */ + env->spr[regs.sprn_srr1] = regs.msr; + + powerpc_set_excp_state(cpu, regs.new_nip, regs.new_msr); +} + +static inline void powerpc_excp(PowerPCCPU *cpu, int excp) +{ + CPUPPCState *env = &cpu->env; + + qemu_log_mask(CPU_LOG_INT, "Raise exception at " TARGET_FMT_lx + " => %08x (%02x)\n", env->nip, excp, env->error_code); + + if (excp == POWERPC_EXCP_NONE) { + /* Should never happen */ + return; + } + +#ifdef TARGET_PPC64 + if (env->excp_model >= POWERPC_EXCP_970) { + return book3s_excp(cpu, excp); + } +#endif + + if (env->excp_model == POWERPC_EXCP_BOOKE) { + booke_excp(cpu, excp); + } else { + ppc32_excp(cpu, excp); + } +} void ppc_cpu_do_interrupt(CPUState *cs) { diff --git a/target/ppc/interrupts.c b/target/ppc/interrupts.c index 61a7dec682..743faddfee 100644 --- a/target/ppc/interrupts.c +++ b/target/ppc/interrupts.c @@ -334,12 +334,6 @@ void ppc_intr_spe_unavailable(PowerPCCPU *cpu, PPCIntrArgs *regs, bool *ignore) env->spr[SPR_BOOKE_ESR] = ESR_SPV; } -void ppc_intr_embedded_doorbell_crit(PowerPCCPU *cpu, PPCIntrArgs *regs, bool *ignore) -{ - regs->sprn_srr0 = SPR_BOOKE_CSRR0; - regs->sprn_srr1 = SPR_BOOKE_CSRR1; -} - void ppc_intr_system_reset(PowerPCCPU *cpu, PPCIntrArgs *regs, bool *ignore) { CPUPPCState *env = &cpu->env; @@ -462,7 +456,7 @@ void ppc_intr_tlb_miss(PowerPCCPU *cpu, PPCIntrArgs *regs, bool *ignore) } } -PPCInterrupt interrupts[POWERPC_EXCP_NB] = { +PPCInterrupt interrupts_ppc32[POWERPC_EXCP_NB] = { [POWERPC_EXCP_ALIGN] = { "Alignment", ppc_intr_alignment }, @@ -479,10 +473,6 @@ PPCInterrupt interrupts[POWERPC_EXCP_NB] = { "Data load TLB error", ppc_intr_tlb_miss }, - [POWERPC_EXCP_DOORCI] = { - "Embedded doorbell critical", ppc_intr_embedded_doorbell_crit - }, - [POWERPC_EXCP_DSI] = { "Data storage", ppc_intr_data_storage }, @@ -499,6 +489,78 @@ PPCInterrupt interrupts[POWERPC_EXCP_NB] = { "Fixed-interval timer", ppc_intr_fit }, + [POWERPC_EXCP_IFTLB] = { + "Insn fetch TLB error", ppc_intr_tlb_miss + }, + + [POWERPC_EXCP_ISI] = { + "Instruction storage", ppc_intr_insn_storage + }, + + [POWERPC_EXCP_MCHECK] = { + "Machine check", ppc_intr_machine_check + }, + + [POWERPC_EXCP_PIT] = { + "Programmable interval timer", ppc_intr_programmable_timer + }, + + [POWERPC_EXCP_PROGRAM] = { + "Program", ppc_intr_program + }, + + [POWERPC_EXCP_RESET] = { + "System reset", ppc_intr_system_reset + }, + + [POWERPC_EXCP_SYSCALL] = { + "System call", ppc_intr_system_call + }, + + [POWERPC_EXCP_VPU] = { + "Vector unavailable", ppc_intr_facility_unavail + }, + + [POWERPC_EXCP_WDT] = { + "Watchdog timer", ppc_intr_watchdog + }, + + [POWERPC_EXCP_DECR] = { "Decrementer", ppc_intr_noop }, + [POWERPC_EXCP_DTLB] = { "Data TLB error", ppc_intr_noop }, + [POWERPC_EXCP_FPU] = { "Floating-point unavailable", ppc_intr_noop }, + [POWERPC_EXCP_ITLB] = { "Instruction TLB error", ppc_intr_noop }, + [POWERPC_EXCP_TRACE] = { "Trace", ppc_intr_noop }, + +/* Not implemented */ + [POWERPC_EXCP_DABR] = { "Data address breakpoint" }, + [POWERPC_EXCP_DTLBE] = { "Data TLB error" }, + [POWERPC_EXCP_EMUL] = { "Emulation trap" }, + [POWERPC_EXCP_FPA] = { "Floating-point assist" }, + [POWERPC_EXCP_IABR] = { "Insn address breakpoint" }, + [POWERPC_EXCP_IO] = { "IO error" }, + [POWERPC_EXCP_ITLBE] = { "Instruction TLB error" }, + [POWERPC_EXCP_MEXTBR] = { "Maskable external" }, + [POWERPC_EXCP_NMEXTBR] = { "Non-maskable external" }, + [POWERPC_EXCP_PERFM] = { "Performance counter" }, + [POWERPC_EXCP_RUNM] = { "Run mode" }, + [POWERPC_EXCP_SMI] = { "System management" }, + [POWERPC_EXCP_THERM] = { "Thermal management" }, + [POWERPC_EXCP_VPUA] = { "Vector assist" }, +}; + +PPCInterrupt interrupts_book3s[POWERPC_EXCP_NB] = { + [POWERPC_EXCP_ALIGN] = { + "Alignment", ppc_intr_alignment + }, + + [POWERPC_EXCP_DSI] = { + "Data storage", ppc_intr_data_storage + }, + + [POWERPC_EXCP_EXTERNAL] = { + "External", ppc_intr_external + }, + [POWERPC_EXCP_FU] = { "Facility unavailable", ppc_intr_facility_unavail }, @@ -508,11 +570,7 @@ PPCInterrupt interrupts[POWERPC_EXCP_NB] = { }, [POWERPC_EXCP_HV_FU] = { - "Hypervisor facility unavailable" , ppc_intr_hv_facility_unavail - }, - - [POWERPC_EXCP_IFTLB] = { - "Insn fetch TLB error", ppc_intr_tlb_miss + "Hypervisor facility unavailable", ppc_intr_hv_facility_unavail }, [POWERPC_EXCP_ISI] = { @@ -523,10 +581,6 @@ PPCInterrupt interrupts[POWERPC_EXCP_NB] = { "Machine check", ppc_intr_machine_check }, - [POWERPC_EXCP_PIT] = { - "Programmable interval timer", ppc_intr_programmable_timer - }, - [POWERPC_EXCP_PROGRAM] = { "Program", ppc_intr_program }, @@ -535,10 +589,6 @@ PPCInterrupt interrupts[POWERPC_EXCP_NB] = { "System reset", ppc_intr_system_reset }, - [POWERPC_EXCP_SPEU] = { - "SPE/embedded FP unavailable/VPU", ppc_intr_spe_unavailable - }, - [POWERPC_EXCP_SYSCALL] = { "System call", ppc_intr_system_call }, @@ -555,48 +605,127 @@ PPCInterrupt interrupts[POWERPC_EXCP_NB] = { "VSX unavailable", ppc_intr_facility_unavail }, - [POWERPC_EXCP_WDT] = { - "Watchdog timer", ppc_intr_watchdog - }, - [POWERPC_EXCP_HDECR] = { "Hypervisor decrementer", ppc_intr_hv }, - [POWERPC_EXCP_HDSEG] = { "Hypervisor data segment", ppc_intr_hv }, [POWERPC_EXCP_HDSI] = { "Hypervisor data storage", ppc_intr_hv }, - [POWERPC_EXCP_HISEG] = { "Hypervisor insn segment", ppc_intr_hv }, [POWERPC_EXCP_HVIRT] = { "Hypervisor virtualization", ppc_intr_hv }, [POWERPC_EXCP_HV_EMU] = { "Hypervisor emulation assist", ppc_intr_hv }, [POWERPC_EXCP_SDOOR_HV] = { "Hypervisor doorbell", ppc_intr_hv }, - [POWERPC_EXCP_APU] = { "Aux. processor unavailable", ppc_intr_noop }, [POWERPC_EXCP_DECR] = { "Decrementer", ppc_intr_noop }, - [POWERPC_EXCP_DOORI] = { "Embedded doorbell", ppc_intr_noop }, [POWERPC_EXCP_DSEG] = { "Data segment", ppc_intr_noop }, - [POWERPC_EXCP_DTLB] = { "Data TLB error", ppc_intr_noop }, [POWERPC_EXCP_FPU] = { "Floating-point unavailable", ppc_intr_noop }, [POWERPC_EXCP_ISEG] = { "Instruction segment", ppc_intr_noop }, [POWERPC_EXCP_ITLB] = { "Instruction TLB error", ppc_intr_noop }, [POWERPC_EXCP_TRACE] = { "Trace", ppc_intr_noop }, /* Not implemented */ - [POWERPC_EXCP_DABR] = { "Data address breakpoint" }, - [POWERPC_EXCP_DTLBE] = { "Data TLB error" }, - [POWERPC_EXCP_EFPDI] = { "Embedded floating-point data" }, - [POWERPC_EXCP_EFPRI] = { "Embedded floating-point round" }, - [POWERPC_EXCP_EMUL] = { "Emulation trap" }, - [POWERPC_EXCP_EPERFM] = { "Embedded perf. monitor" }, - [POWERPC_EXCP_FPA] = { "Floating-point assist" }, [POWERPC_EXCP_HV_MAINT] = { "Hypervisor maintenance" }, [POWERPC_EXCP_IABR] = { "Insn address breakpoint" }, - [POWERPC_EXCP_IO] = { "IO error" }, - [POWERPC_EXCP_ITLBE] = { "Instruction TLB error" }, [POWERPC_EXCP_MAINT] = { "Maintenance" }, - [POWERPC_EXCP_MEXTBR] = { "Maskable external" }, - [POWERPC_EXCP_NMEXTBR] = { "Non-maskable external" }, [POWERPC_EXCP_PERFM] = { "Performance counter" }, - [POWERPC_EXCP_RUNM] = { "Run mode" }, [POWERPC_EXCP_SDOOR] = { "Server doorbell" }, - [POWERPC_EXCP_SMI] = { "System management" }, - [POWERPC_EXCP_SOFTP] = { "Soft patch" }, [POWERPC_EXCP_THERM] = { "Thermal management" }, [POWERPC_EXCP_VPUA] = { "Vector assist" }, }; + +PPCInterrupt interrupts_booke[POWERPC_EXCP_NB] = { + [POWERPC_EXCP_ALIGN] = { + "Alignment", ppc_intr_alignment + }, + + [POWERPC_EXCP_CRITICAL] = { + "Critical input", ppc_intr_critical + }, + + [POWERPC_EXCP_DEBUG] = { + "Debug", ppc_intr_debug + }, + + [POWERPC_EXCP_DLTLB] = { + "Data load TLB error", ppc_intr_tlb_miss + }, + + [POWERPC_EXCP_DSI] = { + "Data storage", ppc_intr_data_storage + }, + + [POWERPC_EXCP_EXTERNAL] = { + "External", ppc_intr_external + }, + + [POWERPC_EXCP_FIT] = { + "Fixed-interval timer", ppc_intr_fit + }, + + [POWERPC_EXCP_ISI] = { + "Instruction storage", ppc_intr_insn_storage + }, + + [POWERPC_EXCP_MCHECK] = { + "Machine check", ppc_intr_machine_check + }, + + [POWERPC_EXCP_PROGRAM] = { + "Program", ppc_intr_program + }, + + [POWERPC_EXCP_RESET] = { + "System reset", ppc_intr_system_reset + }, + + [POWERPC_EXCP_SPEU] = { + "SPE/embedded FP unavailable/VPU", ppc_intr_spe_unavailable + }, + + [POWERPC_EXCP_SYSCALL] = { + "System call", ppc_intr_system_call + }, + + [POWERPC_EXCP_WDT] = { + "Watchdog timer", ppc_intr_watchdog + }, + + [POWERPC_EXCP_APU] = { "Aux. processor unavailable", ppc_intr_noop }, + [POWERPC_EXCP_DECR] = { "Decrementer", ppc_intr_noop }, + [POWERPC_EXCP_DTLB] = { "Data TLB error", ppc_intr_noop }, + [POWERPC_EXCP_FPU] = { "Floating-point unavailable", ppc_intr_noop }, + [POWERPC_EXCP_ITLB] = { "Instruction TLB error", ppc_intr_noop }, + +/* Not impleemented */ + [POWERPC_EXCP_EFPDI] = { "Embedded floating-point data" }, + [POWERPC_EXCP_EFPRI] = { "Embedded floating-point round" }, +}; + +int ppc_intr_prepare(PowerPCCPU *cpu, PPCInterrupt *interrupts, + PPCIntrArgs *regs, int excp) +{ + CPUState *cs = CPU(cpu); + CPUPPCState *env = &cpu->env; + PPCInterrupt *intr; + bool ignore = false; + + intr = &interrupts[excp]; + if (!intr->name) { + cpu_abort(cs, "Invalid PowerPC exception %d. Aborting\n", excp); + } + + if (!intr->fn) { + cpu_abort(cs, "%s exception is not implemented yet !\n", intr->name); + } + + intr->fn(cpu, regs, &ignore); + + /* Sanity check */ + if (!(env->msr_mask & MSR_HVB)) { + if (regs->new_msr & MSR_HVB) { + cpu_abort(cs, "Trying to deliver HV exception (MSR) %d with " + "no HV support\n", excp); + } + if (regs->sprn_srr0 == SPR_HSRR0) { + cpu_abort(cs, "Trying to deliver HV exception (HSRR) %d with " + "no HV support\n", excp); + } + } + + return ignore; +} diff --git a/target/ppc/ppc_intr.h b/target/ppc/ppc_intr.h index 078906ed68..a12b3a9e4d 100644 --- a/target/ppc/ppc_intr.h +++ b/target/ppc/ppc_intr.h @@ -42,6 +42,11 @@ void ppc_intr_system_reset(PowerPCCPU *cpu, PPCIntrArgs *regs, bool *ignore); void ppc_intr_tlb_miss(PowerPCCPU *cpu, PPCIntrArgs *regs, bool *ignore); void ppc_intr_watchdog(PowerPCCPU *cpu, PPCIntrArgs *regs, bool *ignore); -extern PPCInterrupt interrupts[POWERPC_EXCP_NB]; +int ppc_intr_prepare(PowerPCCPU *cpu, PPCInterrupt *interrupts, + PPCIntrArgs *regs, int excp); + +extern PPCInterrupt interrupts_ppc32[POWERPC_EXCP_NB]; +extern PPCInterrupt interrupts_booke[POWERPC_EXCP_NB]; +extern PPCInterrupt interrupts_book3s[POWERPC_EXCP_NB]; #endif /* PPC_INTR_H */ From patchwork Mon Dec 20 18:19:02 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Fabiano Rosas X-Patchwork-Id: 12688421 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.lore.kernel.org (Postfix) with ESMTPS id 0F867C433F5 for ; Mon, 20 Dec 2021 19:14:55 +0000 (UTC) Received: from localhost ([::1]:51408 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1mzO7Z-0007ML-Vy for qemu-devel@archiver.kernel.org; Mon, 20 Dec 2021 14:14:54 -0500 Received: from eggs.gnu.org ([209.51.188.92]:35978) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1mzNGL-00037w-F5; Mon, 20 Dec 2021 13:19:54 -0500 Received: from mx0b-001b2d01.pphosted.com ([148.163.158.5]:40076) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1mzNGG-0006p7-Se; Mon, 20 Dec 2021 13:19:53 -0500 Received: from pps.filterd (m0127361.ppops.net [127.0.0.1]) by mx0a-001b2d01.pphosted.com (8.16.1.2/8.16.1.2) with SMTP id 1BKFovA2022746; Mon, 20 Dec 2021 18:19:37 GMT DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=ibm.com; h=from : to : cc : subject : date : message-id : in-reply-to : references : mime-version : content-transfer-encoding; s=pp1; bh=ETS5/aZICXsUpJfo8gjAjbrLEeoju7dH/+fNc0iNpmU=; b=jxgdaZsqXYS93Btea6GUjmvOHYgHqoMU7agRmJIn7V/ao87NCvBtuPV1+hCIL6GHWCxG OPS2NW1/8nlMeGT4Q7SfBd59Mz9X4NLB8MB6wYAxCYjUajgHmhCVN+80C461cwi8KZYY GN6SxhgIVqfa9MuLZjVadgxubzx69y6XpLTcIx4zx9zCXY0burKTlw2X3B1azIL9VL4u b/ox3auVfZilVlQAs7zxmJ3m7ow5YFiFvDSGkj1xu+240Bf0jEVH2AA4EjRXnmTJgtgT 3c3n2/FE2nzKz8MKcRH2tLPI8JBMGjhK3rsB5C09/bBmQRW3AM3LdmI1ZplsKGjMoqV4 Pg== Received: from pps.reinject (localhost [127.0.0.1]) by mx0a-001b2d01.pphosted.com with ESMTP id 3d1skej88p-1 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NOT); Mon, 20 Dec 2021 18:19:37 +0000 Received: from m0127361.ppops.net (m0127361.ppops.net [127.0.0.1]) by pps.reinject (8.16.0.43/8.16.0.43) with SMTP id 1BKIBHRG029844; Mon, 20 Dec 2021 18:19:36 GMT Received: from ppma02wdc.us.ibm.com (aa.5b.37a9.ip4.static.sl-reverse.com [169.55.91.170]) by mx0a-001b2d01.pphosted.com with ESMTP id 3d1skej88e-1 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NOT); Mon, 20 Dec 2021 18:19:36 +0000 Received: from pps.filterd (ppma02wdc.us.ibm.com [127.0.0.1]) by ppma02wdc.us.ibm.com (8.16.1.2/8.16.1.2) with SMTP id 1BKIE7et014697; Mon, 20 Dec 2021 18:19:35 GMT Received: from b03cxnp07029.gho.boulder.ibm.com (b03cxnp07029.gho.boulder.ibm.com [9.17.130.16]) by ppma02wdc.us.ibm.com with ESMTP id 3d179a217g-1 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NOT); Mon, 20 Dec 2021 18:19:35 +0000 Received: from b03ledav006.gho.boulder.ibm.com (b03ledav006.gho.boulder.ibm.com [9.17.130.237]) by b03cxnp07029.gho.boulder.ibm.com (8.14.9/8.14.9/NCO v10.0) with ESMTP id 1BKIJYLm23790052 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-GCM-SHA384 bits=256 verify=OK); Mon, 20 Dec 2021 18:19:34 GMT Received: from b03ledav006.gho.boulder.ibm.com (unknown [127.0.0.1]) by IMSVA (Postfix) with ESMTP id A51F2C6063; Mon, 20 Dec 2021 18:19:34 +0000 (GMT) Received: from b03ledav006.gho.boulder.ibm.com (unknown [127.0.0.1]) by IMSVA (Postfix) with ESMTP id ED584C6062; Mon, 20 Dec 2021 18:19:32 +0000 (GMT) Received: from farosas.linux.ibm.com.com (unknown [9.211.60.53]) by b03ledav006.gho.boulder.ibm.com (Postfix) with ESMTP; Mon, 20 Dec 2021 18:19:32 +0000 (GMT) From: Fabiano Rosas To: qemu-devel@nongnu.org Subject: [RFC v2 11/12] target/ppc: Create new files for book3s, booke and ppc32 exception code Date: Mon, 20 Dec 2021 15:19:02 -0300 Message-Id: <20211220181903.3456898-12-farosas@linux.ibm.com> X-Mailer: git-send-email 2.33.1 In-Reply-To: <20211220181903.3456898-1-farosas@linux.ibm.com> References: <20211220181903.3456898-1-farosas@linux.ibm.com> MIME-Version: 1.0 X-TM-AS-GCONF: 00 X-Proofpoint-ORIG-GUID: U8Vp1u7PN6jSWW3EPmzAtvMY8y7FbG1p X-Proofpoint-GUID: x0jvdDxK5TF04gx-fWxbOBMISegtCb6u X-Proofpoint-Virus-Version: vendor=baseguard engine=ICAP:2.0.205,Aquarius:18.0.790,Hydra:6.0.425,FMLib:17.11.62.513 definitions=2021-12-20_08,2021-12-20_01,2021-12-02_01 X-Proofpoint-Spam-Details: rule=outbound_notspam policy=outbound score=0 adultscore=0 bulkscore=0 spamscore=0 clxscore=1015 mlxscore=0 malwarescore=0 suspectscore=0 phishscore=0 lowpriorityscore=0 priorityscore=1501 mlxlogscore=999 impostorscore=0 classifier=spam adjust=0 reason=mlx scancount=1 engine=8.12.0-2110150000 definitions=main-2112200101 Received-SPF: pass client-ip=148.163.158.5; envelope-from=farosas@linux.ibm.com; helo=mx0b-001b2d01.pphosted.com X-Spam_score_int: -19 X-Spam_score: -2.0 X-Spam_bar: -- X-Spam_report: (-2.0 / 5.0 requ) BAYES_00=-1.9, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_EF=-0.1, RCVD_IN_MSPIKE_H2=-0.001, SPF_HELO_NONE=0.001, SPF_PASS=-0.001 autolearn=ham autolearn_force=no X-Spam_action: no action X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: danielhb413@gmail.com, qemu-ppc@nongnu.org, clg@kaod.org, david@gibson.dropbear.id.au Errors-To: qemu-devel-bounces+qemu-devel=archiver.kernel.org@nongnu.org Sender: "Qemu-devel" Now that everything is split we can move them to their own files. The rationale is that hopefully in the future we'll be able to move the cpu code along and give them each a separate CONFIG option. Another benefit is that we can now define static routines to replace any of the generic ones from interrupts.c in case we need it. book3s is now TARGET_PPC64 only. I also had to move some function definitions to put them all under an ifdef. ppc32 is now CONFIG_TCG only. I added a stub for ppc32_excp. Signed-off-by: Fabiano Rosas --- target/ppc/cpu.h | 2 + target/ppc/excp_helper.c | 426 +-------------------------------------- target/ppc/interrupts.c | 258 +----------------------- target/ppc/intr-book3s.c | 381 ++++++++++++++++++++++++++++++++++ target/ppc/intr-booke.c | 150 ++++++++++++++ target/ppc/intr-ppc32.c | 159 +++++++++++++++ target/ppc/meson.build | 3 + target/ppc/ppc_intr.h | 18 +- target/ppc/tcg-stub.c | 6 + 9 files changed, 724 insertions(+), 679 deletions(-) create mode 100644 target/ppc/intr-book3s.c create mode 100644 target/ppc/intr-booke.c create mode 100644 target/ppc/intr-ppc32.c diff --git a/target/ppc/cpu.h b/target/ppc/cpu.h index fc66c3561d..becb5e0eb8 100644 --- a/target/ppc/cpu.h +++ b/target/ppc/cpu.h @@ -1356,6 +1356,8 @@ void ppc_cpu_do_interrupt(CPUState *cpu); bool ppc_cpu_exec_interrupt(CPUState *cpu, int int_req); void ppc_cpu_do_system_reset(CPUState *cs); void ppc_cpu_do_fwnmi_machine_check(CPUState *cs, target_ulong vector); +void powerpc_set_excp_state(PowerPCCPU *cpu, target_ulong new_nip, + target_ulong new_msr); extern const VMStateDescription vmstate_ppc_cpu; #endif diff --git a/target/ppc/excp_helper.c b/target/ppc/excp_helper.c index 9c785b75d5..eb8dab1741 100644 --- a/target/ppc/excp_helper.c +++ b/target/ppc/excp_helper.c @@ -37,204 +37,8 @@ /* Exception processing */ #if !defined(CONFIG_USER_ONLY) -#ifdef TARGET_PPC64 -static int powerpc_reset_wakeup(CPUState *cs, CPUPPCState *env, int excp, - target_ulong *msr) -{ - /* We no longer are in a PM state */ - env->resume_as_sreset = false; - - /* Pretend to be returning from doze always as we don't lose state */ - *msr |= SRR1_WS_NOLOSS; - - /* Machine checks are sent normally */ - if (excp == POWERPC_EXCP_MCHECK) { - return excp; - } - switch (excp) { - case POWERPC_EXCP_RESET: - *msr |= SRR1_WAKERESET; - break; - case POWERPC_EXCP_EXTERNAL: - *msr |= SRR1_WAKEEE; - break; - case POWERPC_EXCP_DECR: - *msr |= SRR1_WAKEDEC; - break; - case POWERPC_EXCP_SDOOR: - *msr |= SRR1_WAKEDBELL; - break; - case POWERPC_EXCP_SDOOR_HV: - *msr |= SRR1_WAKEHDBELL; - break; - case POWERPC_EXCP_HV_MAINT: - *msr |= SRR1_WAKEHMI; - break; - case POWERPC_EXCP_HVIRT: - *msr |= SRR1_WAKEHVI; - break; - default: - cpu_abort(cs, "Unsupported exception %d in Power Save mode\n", - excp); - } - return POWERPC_EXCP_RESET; -} - -/* - * AIL - Alternate Interrupt Location, a mode that allows interrupts to be - * taken with the MMU on, and which uses an alternate location (e.g., so the - * kernel/hv can map the vectors there with an effective address). - * - * An interrupt is considered to be taken "with AIL" or "AIL applies" if they - * are delivered in this way. AIL requires the LPCR to be set to enable this - * mode, and then a number of conditions have to be true for AIL to apply. - * - * First of all, SRESET, MCE, and HMI are always delivered without AIL, because - * they specifically want to be in real mode (e.g., the MCE might be signaling - * a SLB multi-hit which requires SLB flush before the MMU can be enabled). - * - * After that, behaviour depends on the current MSR[IR], MSR[DR], MSR[HV], - * whether or not the interrupt changes MSR[HV] from 0 to 1, and the current - * radix mode (LPCR[HR]). - * - * POWER8, POWER9 with LPCR[HR]=0 - * | LPCR[AIL] | MSR[IR||DR] | MSR[HV] | new MSR[HV] | AIL | - * +-----------+-------------+---------+-------------+-----+ - * | a | 00/01/10 | x | x | 0 | - * | a | 11 | 0 | 1 | 0 | - * | a | 11 | 1 | 1 | a | - * | a | 11 | 0 | 0 | a | - * +-------------------------------------------------------+ - * - * POWER9 with LPCR[HR]=1 - * | LPCR[AIL] | MSR[IR||DR] | MSR[HV] | new MSR[HV] | AIL | - * +-----------+-------------+---------+-------------+-----+ - * | a | 00/01/10 | x | x | 0 | - * | a | 11 | x | x | a | - * +-------------------------------------------------------+ - * - * The difference with POWER9 being that MSR[HV] 0->1 interrupts can be sent to - * the hypervisor in AIL mode if the guest is radix. This is good for - * performance but allows the guest to influence the AIL of hypervisor - * interrupts using its MSR, and also the hypervisor must disallow guest - * interrupts (MSR[HV] 0->0) from using AIL if the hypervisor does not want to - * use AIL for its MSR[HV] 0->1 interrupts. - * - * POWER10 addresses those issues with a new LPCR[HAIL] bit that is applied to - * interrupts that begin execution with MSR[HV]=1 (so both MSR[HV] 0->1 and - * MSR[HV] 1->1). - * - * HAIL=1 is equivalent to AIL=3, for interrupts delivered with MSR[HV]=1. - * - * POWER10 behaviour is - * | LPCR[AIL] | LPCR[HAIL] | MSR[IR||DR] | MSR[HV] | new MSR[HV] | AIL | - * +-----------+------------+-------------+---------+-------------+-----+ - * | a | h | 00/01/10 | 0 | 0 | 0 | - * | a | h | 11 | 0 | 0 | a | - * | a | h | x | 0 | 1 | h | - * | a | h | 00/01/10 | 1 | 1 | 0 | - * | a | h | 11 | 1 | 1 | h | - * +--------------------------------------------------------------------+ - */ -static inline void ppc_excp_apply_ail(PowerPCCPU *cpu, int excp_model, int excp, - target_ulong msr, - target_ulong *new_msr, - target_ulong *new_nip) -{ - CPUPPCState *env = &cpu->env; - bool mmu_all_on = ((msr >> MSR_IR) & 1) && ((msr >> MSR_DR) & 1); - bool hv_escalation = !(msr & MSR_HVB) && (*new_msr & MSR_HVB); - int ail = 0; - - if (excp == POWERPC_EXCP_MCHECK || - excp == POWERPC_EXCP_RESET || - excp == POWERPC_EXCP_HV_MAINT) { - /* SRESET, MCE, HMI never apply AIL */ - return; - } - - if (excp_model == POWERPC_EXCP_POWER8 || - excp_model == POWERPC_EXCP_POWER9) { - if (!mmu_all_on) { - /* AIL only works if MSR[IR] and MSR[DR] are both enabled. */ - return; - } - if (hv_escalation && !(env->spr[SPR_LPCR] & LPCR_HR)) { - /* - * AIL does not work if there is a MSR[HV] 0->1 transition and the - * partition is in HPT mode. For radix guests, such interrupts are - * allowed to be delivered to the hypervisor in ail mode. - */ - return; - } - - ail = (env->spr[SPR_LPCR] & LPCR_AIL) >> LPCR_AIL_SHIFT; - if (ail == 0) { - return; - } - if (ail == 1) { - /* AIL=1 is reserved, treat it like AIL=0 */ - return; - } - - } else if (excp_model == POWERPC_EXCP_POWER10) { - if (!mmu_all_on && !hv_escalation) { - /* - * AIL works for HV interrupts even with guest MSR[IR/DR] disabled. - * Guest->guest and HV->HV interrupts do require MMU on. - */ - return; - } - - if (*new_msr & MSR_HVB) { - if (!(env->spr[SPR_LPCR] & LPCR_HAIL)) { - /* HV interrupts depend on LPCR[HAIL] */ - return; - } - ail = 3; /* HAIL=1 gives AIL=3 behaviour for HV interrupts */ - } else { - ail = (env->spr[SPR_LPCR] & LPCR_AIL) >> LPCR_AIL_SHIFT; - } - if (ail == 0) { - return; - } - if (ail == 1 || ail == 2) { - /* AIL=1 and AIL=2 are reserved, treat them like AIL=0 */ - return; - } - } else { - /* Other processors do not support AIL */ - return; - } - - /* - * AIL applies, so the new MSR gets IR and DR set, and an offset applied - * to the new IP. - */ - *new_msr |= (1 << MSR_IR) | (1 << MSR_DR); - - if (excp != POWERPC_EXCP_SYSCALL_VECTORED) { - if (ail == 2) { - *new_nip |= 0x0000000000018000ull; - } else if (ail == 3) { - *new_nip |= 0xc000000000004000ull; - } - } else { - /* - * scv AIL is a little different. AIL=2 does not change the address, - * only the MSR. AIL=3 replaces the 0x17000 base with 0xc...3000. - */ - if (ail == 3) { - *new_nip &= ~0x0000000000017000ull; /* Un-apply the base offset */ - *new_nip |= 0xc000000000003000ull; /* Apply scv's AIL=3 offset */ - } - } -} -#endif /* TARGET_PPC64 */ - - -static inline void powerpc_set_excp_state(PowerPCCPU *cpu, target_ulong new_nip, - target_ulong new_msr) +inline void powerpc_set_excp_state(PowerPCCPU *cpu, target_ulong new_nip, + target_ulong new_msr) { CPUState *cs = CPU(cpu); CPUPPCState *env = &cpu->env; @@ -264,232 +68,6 @@ static inline void powerpc_set_excp_state(PowerPCCPU *cpu, target_ulong new_nip, check_tlb_flush(env, false); } -#if defined(TARGET_PPC64) -static inline void book3s_excp(PowerPCCPU *cpu, int excp) -{ - CPUState *cs = CPU(cpu); - CPUPPCState *env = &cpu->env; - int excp_model = env->excp_model; - PPCIntrArgs regs; - bool ignore; - - regs.msr = env->msr & ~0x783f0000ULL; - regs.nip = env->nip; - - /* - * new interrupt handler msr preserves existing HV and ME unless - * explicitly overriden - */ - regs.new_msr = env->msr & (((target_ulong)1 << MSR_ME) | MSR_HVB); - - /* The Book3S cpus we support are 64 bit only */ - regs.new_msr |= (target_ulong)1 << MSR_SF; - - regs.sprn_srr0 = SPR_SRR0; - regs.sprn_srr1 = SPR_SRR1; - - /* - * check for special resume at 0x100 from doze/nap/sleep/winkle on - * P7/P8/P9 - */ - if (env->resume_as_sreset) { - excp = powerpc_reset_wakeup(cs, env, excp, ®s.msr); - } - - /* - * We don't want to generate an Hypervisor emulation assistance - * interrupt if we don't have HVB in msr_mask (PAPR mode). - */ - if (excp == POWERPC_EXCP_HV_EMU && !(env->msr_mask & MSR_HVB)) { - excp = POWERPC_EXCP_PROGRAM; - } - - regs.new_nip = env->excp_vectors[excp]; - if (regs.new_nip == (target_ulong)-1ULL) { - cpu_abort(cs, "Raised an exception without defined vector %d\n", - excp); - } - - /* Setup interrupt-specific registers before injecting */ - ignore = ppc_intr_prepare(cpu, interrupts_book3s, ®s, excp); - - if (ignore) { - /* No further setup is needed for this interrupt */ - return; - } - - /* - * Sort out endianness of interrupt, this differs depending on the - * CPU, the HV mode, etc... - */ - if (excp_model == POWERPC_EXCP_POWER7) { - if (!(regs.new_msr & MSR_HVB) && (env->spr[SPR_LPCR] & LPCR_ILE)) { - regs.new_msr |= (target_ulong)1 << MSR_LE; - } - } else if (excp_model == POWERPC_EXCP_POWER8) { - if (regs.new_msr & MSR_HVB) { - if (env->spr[SPR_HID0] & HID0_HILE) { - regs.new_msr |= (target_ulong)1 << MSR_LE; - } - } else if (env->spr[SPR_LPCR] & LPCR_ILE) { - regs.new_msr |= (target_ulong)1 << MSR_LE; - } - } else if (excp_model == POWERPC_EXCP_POWER9 || - excp_model == POWERPC_EXCP_POWER10) { - if (regs.new_msr & MSR_HVB) { - if (env->spr[SPR_HID0] & HID0_POWER9_HILE) { - regs.new_msr |= (target_ulong)1 << MSR_LE; - } - } else if (env->spr[SPR_LPCR] & LPCR_ILE) { - regs.new_msr |= (target_ulong)1 << MSR_LE; - } - } else if (msr_ile) { - regs.new_msr |= (target_ulong)1 << MSR_LE; - } - - if (excp != POWERPC_EXCP_SYSCALL_VECTORED) { - /* Save PC */ - env->spr[regs.sprn_srr0] = regs.nip; - - /* Save MSR */ - env->spr[regs.sprn_srr1] = regs.msr; - } - - /* This can update regs.new_msr and regs.new_nip if AIL applies */ - ppc_excp_apply_ail(cpu, excp_model, excp, regs.msr, ®s.new_msr, - ®s.new_nip); - - powerpc_set_excp_state(cpu, regs.new_nip, regs.new_msr); -} -#endif /* defined(TARGET_PPC64) */ - -static inline void booke_excp(PowerPCCPU *cpu, int excp) -{ - CPUState *cs = CPU(cpu); - CPUPPCState *env = &cpu->env; - PPCIntrArgs regs; - bool ignore; - - regs.msr = env->msr; - regs.nip = env->nip; - - /* - * new interrupt handler msr preserves existing HV and ME unless - * explicitly overriden - */ - regs.new_msr = env->msr & (((target_ulong)1 << MSR_ME) | MSR_HVB); - - regs.sprn_srr0 = SPR_SRR0; - regs.sprn_srr1 = SPR_SRR1; - - /* - * Hypervisor emulation assistance interrupt only exists on server - * arch 2.05 server or later. - */ - if (excp == POWERPC_EXCP_HV_EMU) { - excp = POWERPC_EXCP_PROGRAM; - } - -#ifdef TARGET_PPC64 - /* - * SPEU and VPU share the same IVOR but they exist in different - * processors. SPEU is e500v1/2 only and VPU is e6500 only. - */ - if (env->excp_model == POWERPC_EXCP_BOOKE && excp == POWERPC_EXCP_VPU) { - excp = POWERPC_EXCP_SPEU; - } -#endif - - regs.new_nip = env->excp_vectors[excp]; - if (regs.new_nip == (target_ulong)-1ULL) { - cpu_abort(cs, "Raised an exception without defined vector %d\n", - excp); - } - - regs.new_nip |= env->excp_prefix; - - /* Setup interrupt-specific registers before injecting */ - ignore = ppc_intr_prepare(cpu, interrupts_booke, ®s, excp); - - if (ignore) { - /* No further setup is needed for this interrupt */ - return; - } - -#if defined(TARGET_PPC64) - if (env->spr[SPR_BOOKE_EPCR] & EPCR_ICM) { - /* Cat.64-bit: EPCR.ICM is copied to MSR.CM */ - regs.new_msr |= (target_ulong)1 << MSR_CM; - } else { - regs.new_nip = (uint32_t)regs.new_nip; - } -#endif - - /* Save PC */ - env->spr[regs.sprn_srr0] = regs.nip; - - /* Save MSR */ - env->spr[regs.sprn_srr1] = regs.msr; - - powerpc_set_excp_state(cpu, regs.new_nip, regs.new_msr); -} - -static inline void ppc32_excp(PowerPCCPU *cpu, int excp) -{ - CPUState *cs = CPU(cpu); - CPUPPCState *env = &cpu->env; - PPCIntrArgs regs; - bool ignore; - - regs.msr = env->msr & ~0x783f0000ULL; - regs.nip = env->nip; - - /* - * new interrupt handler msr preserves existing HV and ME unless - * explicitly overriden - */ - regs.new_msr = env->msr & (((target_ulong)1 << MSR_ME) | MSR_HVB); - - regs.sprn_srr0 = SPR_SRR0; - regs.sprn_srr1 = SPR_SRR1; - - /* - * Hypervisor emulation assistance interrupt only exists on server - * arch 2.05 server or later. - */ - if (excp == POWERPC_EXCP_HV_EMU) { - excp = POWERPC_EXCP_PROGRAM; - } - - regs.new_nip = env->excp_vectors[excp]; - if (regs.new_nip == (target_ulong)-1ULL) { - cpu_abort(cs, "Raised an exception without defined vector %d\n", - excp); - } - - regs.new_nip |= env->excp_prefix; - - /* Setup interrupt-specific registers before injecting */ - ignore = ppc_intr_prepare(cpu, interrupts_ppc32, ®s, excp); - - if (ignore) { - /* No further setup is needed for this interrupt */ - return; - } - - if (msr_ile) { - regs.new_msr |= (target_ulong)1 << MSR_LE; - } - - /* Save PC */ - env->spr[regs.sprn_srr0] = regs.nip; - - /* Save MSR */ - env->spr[regs.sprn_srr1] = regs.msr; - - powerpc_set_excp_state(cpu, regs.new_nip, regs.new_msr); -} - static inline void powerpc_excp(PowerPCCPU *cpu, int excp) { CPUPPCState *env = &cpu->env; diff --git a/target/ppc/interrupts.c b/target/ppc/interrupts.c index 743faddfee..6f956029fd 100644 --- a/target/ppc/interrupts.c +++ b/target/ppc/interrupts.c @@ -358,6 +358,7 @@ void ppc_intr_system_reset(PowerPCCPU *cpu, PPCIntrArgs *regs, bool *ignore) } } +#ifdef TARGET_PPC64 void ppc_intr_hv(PowerPCCPU *cpu, PPCIntrArgs *regs, bool *ignore) { CPUPPCState *env = &cpu->env; @@ -376,20 +377,19 @@ void ppc_intr_hv_insn_storage(PowerPCCPU *cpu, PPCIntrArgs *regs, bool *ignore) ppc_intr_hv(cpu, regs, ignore); } -void ppc_intr_facility_unavail(PowerPCCPU *cpu, PPCIntrArgs *regs, bool *ignore) -{ -#ifdef TARGET_PPC64 - CPUPPCState *env = &cpu->env; - env->spr[SPR_FSCR] |= ((target_ulong)env->error_code << 56); -#endif -} - void ppc_intr_hv_facility_unavail(PowerPCCPU *cpu, PPCIntrArgs *regs, bool *ignore) { -#ifdef TARGET_PPC64 CPUPPCState *env = &cpu->env; env->spr[SPR_FSCR] |= ((target_ulong)env->error_code << FSCR_IC_POS); ppc_intr_hv(cpu, regs, ignore); +} +#endif /* TARGET PPC64 */ + +void ppc_intr_facility_unavail(PowerPCCPU *cpu, PPCIntrArgs *regs, bool *ignore) +{ +#ifdef TARGET_PPC64 + CPUPPCState *env = &cpu->env; + env->spr[SPR_FSCR] |= ((target_ulong)env->error_code << 56); #endif } @@ -456,246 +456,6 @@ void ppc_intr_tlb_miss(PowerPCCPU *cpu, PPCIntrArgs *regs, bool *ignore) } } -PPCInterrupt interrupts_ppc32[POWERPC_EXCP_NB] = { - [POWERPC_EXCP_ALIGN] = { - "Alignment", ppc_intr_alignment - }, - - [POWERPC_EXCP_CRITICAL] = { - "Critical input", ppc_intr_critical - }, - - [POWERPC_EXCP_DEBUG] = { - "Debug", ppc_intr_debug - }, - - [POWERPC_EXCP_DLTLB] = { - "Data load TLB error", ppc_intr_tlb_miss - }, - - [POWERPC_EXCP_DSI] = { - "Data storage", ppc_intr_data_storage - }, - - [POWERPC_EXCP_DSTLB] = { - "Data store TLB error", ppc_intr_tlb_miss - }, - - [POWERPC_EXCP_EXTERNAL] = { - "External", ppc_intr_external - }, - - [POWERPC_EXCP_FIT] = { - "Fixed-interval timer", ppc_intr_fit - }, - - [POWERPC_EXCP_IFTLB] = { - "Insn fetch TLB error", ppc_intr_tlb_miss - }, - - [POWERPC_EXCP_ISI] = { - "Instruction storage", ppc_intr_insn_storage - }, - - [POWERPC_EXCP_MCHECK] = { - "Machine check", ppc_intr_machine_check - }, - - [POWERPC_EXCP_PIT] = { - "Programmable interval timer", ppc_intr_programmable_timer - }, - - [POWERPC_EXCP_PROGRAM] = { - "Program", ppc_intr_program - }, - - [POWERPC_EXCP_RESET] = { - "System reset", ppc_intr_system_reset - }, - - [POWERPC_EXCP_SYSCALL] = { - "System call", ppc_intr_system_call - }, - - [POWERPC_EXCP_VPU] = { - "Vector unavailable", ppc_intr_facility_unavail - }, - - [POWERPC_EXCP_WDT] = { - "Watchdog timer", ppc_intr_watchdog - }, - - [POWERPC_EXCP_DECR] = { "Decrementer", ppc_intr_noop }, - [POWERPC_EXCP_DTLB] = { "Data TLB error", ppc_intr_noop }, - [POWERPC_EXCP_FPU] = { "Floating-point unavailable", ppc_intr_noop }, - [POWERPC_EXCP_ITLB] = { "Instruction TLB error", ppc_intr_noop }, - [POWERPC_EXCP_TRACE] = { "Trace", ppc_intr_noop }, - -/* Not implemented */ - [POWERPC_EXCP_DABR] = { "Data address breakpoint" }, - [POWERPC_EXCP_DTLBE] = { "Data TLB error" }, - [POWERPC_EXCP_EMUL] = { "Emulation trap" }, - [POWERPC_EXCP_FPA] = { "Floating-point assist" }, - [POWERPC_EXCP_IABR] = { "Insn address breakpoint" }, - [POWERPC_EXCP_IO] = { "IO error" }, - [POWERPC_EXCP_ITLBE] = { "Instruction TLB error" }, - [POWERPC_EXCP_MEXTBR] = { "Maskable external" }, - [POWERPC_EXCP_NMEXTBR] = { "Non-maskable external" }, - [POWERPC_EXCP_PERFM] = { "Performance counter" }, - [POWERPC_EXCP_RUNM] = { "Run mode" }, - [POWERPC_EXCP_SMI] = { "System management" }, - [POWERPC_EXCP_THERM] = { "Thermal management" }, - [POWERPC_EXCP_VPUA] = { "Vector assist" }, -}; - -PPCInterrupt interrupts_book3s[POWERPC_EXCP_NB] = { - [POWERPC_EXCP_ALIGN] = { - "Alignment", ppc_intr_alignment - }, - - [POWERPC_EXCP_DSI] = { - "Data storage", ppc_intr_data_storage - }, - - [POWERPC_EXCP_EXTERNAL] = { - "External", ppc_intr_external - }, - - [POWERPC_EXCP_FU] = { - "Facility unavailable", ppc_intr_facility_unavail - }, - - [POWERPC_EXCP_HISI] = { - "Hypervisor instruction storage", ppc_intr_hv_insn_storage - }, - - [POWERPC_EXCP_HV_FU] = { - "Hypervisor facility unavailable", ppc_intr_hv_facility_unavail - }, - - [POWERPC_EXCP_ISI] = { - "Instruction storage", ppc_intr_insn_storage - }, - - [POWERPC_EXCP_MCHECK] = { - "Machine check", ppc_intr_machine_check - }, - - [POWERPC_EXCP_PROGRAM] = { - "Program", ppc_intr_program - }, - - [POWERPC_EXCP_RESET] = { - "System reset", ppc_intr_system_reset - }, - - [POWERPC_EXCP_SYSCALL] = { - "System call", ppc_intr_system_call - }, - - [POWERPC_EXCP_SYSCALL_VECTORED] = { - "System call vectored", ppc_intr_system_call_vectored - }, - - [POWERPC_EXCP_VPU] = { - "Vector unavailable", ppc_intr_facility_unavail - }, - - [POWERPC_EXCP_VSXU] = { - "VSX unavailable", ppc_intr_facility_unavail - }, - - [POWERPC_EXCP_HDECR] = { "Hypervisor decrementer", ppc_intr_hv }, - [POWERPC_EXCP_HDSI] = { "Hypervisor data storage", ppc_intr_hv }, - [POWERPC_EXCP_HVIRT] = { "Hypervisor virtualization", ppc_intr_hv }, - [POWERPC_EXCP_HV_EMU] = { "Hypervisor emulation assist", ppc_intr_hv }, - [POWERPC_EXCP_SDOOR_HV] = { "Hypervisor doorbell", ppc_intr_hv }, - - [POWERPC_EXCP_DECR] = { "Decrementer", ppc_intr_noop }, - [POWERPC_EXCP_DSEG] = { "Data segment", ppc_intr_noop }, - [POWERPC_EXCP_FPU] = { "Floating-point unavailable", ppc_intr_noop }, - [POWERPC_EXCP_ISEG] = { "Instruction segment", ppc_intr_noop }, - [POWERPC_EXCP_ITLB] = { "Instruction TLB error", ppc_intr_noop }, - [POWERPC_EXCP_TRACE] = { "Trace", ppc_intr_noop }, - -/* Not implemented */ - [POWERPC_EXCP_HV_MAINT] = { "Hypervisor maintenance" }, - [POWERPC_EXCP_IABR] = { "Insn address breakpoint" }, - [POWERPC_EXCP_MAINT] = { "Maintenance" }, - [POWERPC_EXCP_PERFM] = { "Performance counter" }, - [POWERPC_EXCP_SDOOR] = { "Server doorbell" }, - [POWERPC_EXCP_THERM] = { "Thermal management" }, - [POWERPC_EXCP_VPUA] = { "Vector assist" }, -}; - -PPCInterrupt interrupts_booke[POWERPC_EXCP_NB] = { - [POWERPC_EXCP_ALIGN] = { - "Alignment", ppc_intr_alignment - }, - - [POWERPC_EXCP_CRITICAL] = { - "Critical input", ppc_intr_critical - }, - - [POWERPC_EXCP_DEBUG] = { - "Debug", ppc_intr_debug - }, - - [POWERPC_EXCP_DLTLB] = { - "Data load TLB error", ppc_intr_tlb_miss - }, - - [POWERPC_EXCP_DSI] = { - "Data storage", ppc_intr_data_storage - }, - - [POWERPC_EXCP_EXTERNAL] = { - "External", ppc_intr_external - }, - - [POWERPC_EXCP_FIT] = { - "Fixed-interval timer", ppc_intr_fit - }, - - [POWERPC_EXCP_ISI] = { - "Instruction storage", ppc_intr_insn_storage - }, - - [POWERPC_EXCP_MCHECK] = { - "Machine check", ppc_intr_machine_check - }, - - [POWERPC_EXCP_PROGRAM] = { - "Program", ppc_intr_program - }, - - [POWERPC_EXCP_RESET] = { - "System reset", ppc_intr_system_reset - }, - - [POWERPC_EXCP_SPEU] = { - "SPE/embedded FP unavailable/VPU", ppc_intr_spe_unavailable - }, - - [POWERPC_EXCP_SYSCALL] = { - "System call", ppc_intr_system_call - }, - - [POWERPC_EXCP_WDT] = { - "Watchdog timer", ppc_intr_watchdog - }, - - [POWERPC_EXCP_APU] = { "Aux. processor unavailable", ppc_intr_noop }, - [POWERPC_EXCP_DECR] = { "Decrementer", ppc_intr_noop }, - [POWERPC_EXCP_DTLB] = { "Data TLB error", ppc_intr_noop }, - [POWERPC_EXCP_FPU] = { "Floating-point unavailable", ppc_intr_noop }, - [POWERPC_EXCP_ITLB] = { "Instruction TLB error", ppc_intr_noop }, - -/* Not impleemented */ - [POWERPC_EXCP_EFPDI] = { "Embedded floating-point data" }, - [POWERPC_EXCP_EFPRI] = { "Embedded floating-point round" }, -}; - int ppc_intr_prepare(PowerPCCPU *cpu, PPCInterrupt *interrupts, PPCIntrArgs *regs, int excp) { diff --git a/target/ppc/intr-book3s.c b/target/ppc/intr-book3s.c new file mode 100644 index 0000000000..cd279de346 --- /dev/null +++ b/target/ppc/intr-book3s.c @@ -0,0 +1,381 @@ +/* + * PowerPC interrupt dispatching for Book3S CPUs + * + * Copyright (C) 2021 IBM Corporation. + * + * This code is licensed under the GPL version 2 or later. See the + * COPYING file in the top-level directory. + */ +#include "qemu/osdep.h" +#include "cpu.h" +#include "ppc_intr.h" + +static PPCInterrupt interrupts_book3s[POWERPC_EXCP_NB] = { + [POWERPC_EXCP_ALIGN] = { + "Alignment", ppc_intr_alignment + }, + + [POWERPC_EXCP_DSI] = { + "Data storage", ppc_intr_data_storage + }, + + [POWERPC_EXCP_EXTERNAL] = { + "External", ppc_intr_external + }, + + [POWERPC_EXCP_FU] = { + "Facility unavailable", ppc_intr_facility_unavail + }, + + [POWERPC_EXCP_HISI] = { + "Hypervisor instruction storage", ppc_intr_hv_insn_storage + }, + + [POWERPC_EXCP_HV_FU] = { + "Hypervisor facility unavailable", ppc_intr_hv_facility_unavail + }, + + [POWERPC_EXCP_ISI] = { + "Instruction storage", ppc_intr_insn_storage + }, + + [POWERPC_EXCP_MCHECK] = { + "Machine check", ppc_intr_machine_check + }, + + [POWERPC_EXCP_PROGRAM] = { + "Program", ppc_intr_program + }, + + [POWERPC_EXCP_RESET] = { + "System reset", ppc_intr_system_reset + }, + + [POWERPC_EXCP_SYSCALL] = { + "System call", ppc_intr_system_call + }, + + [POWERPC_EXCP_SYSCALL_VECTORED] = { + "System call vectored", ppc_intr_system_call_vectored + }, + + [POWERPC_EXCP_VPU] = { + "Vector unavailable", ppc_intr_facility_unavail + }, + + [POWERPC_EXCP_VSXU] = { + "VSX unavailable", ppc_intr_facility_unavail + }, + + [POWERPC_EXCP_HDECR] = { "Hypervisor decrementer", ppc_intr_hv }, + [POWERPC_EXCP_HDSI] = { "Hypervisor data storage", ppc_intr_hv }, + [POWERPC_EXCP_HVIRT] = { "Hypervisor virtualization", ppc_intr_hv }, + [POWERPC_EXCP_HV_EMU] = { "Hypervisor emulation assist", ppc_intr_hv }, + [POWERPC_EXCP_SDOOR_HV] = { "Hypervisor doorbell", ppc_intr_hv }, + + [POWERPC_EXCP_DECR] = { "Decrementer", ppc_intr_noop }, + [POWERPC_EXCP_DSEG] = { "Data segment", ppc_intr_noop }, + [POWERPC_EXCP_FPU] = { "Floating-point unavailable", ppc_intr_noop }, + [POWERPC_EXCP_ISEG] = { "Instruction segment", ppc_intr_noop }, + [POWERPC_EXCP_ITLB] = { "Instruction TLB error", ppc_intr_noop }, + [POWERPC_EXCP_TRACE] = { "Trace", ppc_intr_noop }, + +/* Not implemented */ + [POWERPC_EXCP_HV_MAINT] = { "Hypervisor maintenance" }, + [POWERPC_EXCP_IABR] = { "Insn address breakpoint" }, + [POWERPC_EXCP_MAINT] = { "Maintenance" }, + [POWERPC_EXCP_PERFM] = { "Performance counter" }, + [POWERPC_EXCP_SDOOR] = { "Server doorbell" }, + [POWERPC_EXCP_THERM] = { "Thermal management" }, + [POWERPC_EXCP_VPUA] = { "Vector assist" }, +}; + +static int powerpc_reset_wakeup(CPUState *cs, CPUPPCState *env, int excp, + target_ulong *msr) +{ + /* We no longer are in a PM state */ + env->resume_as_sreset = false; + + /* Pretend to be returning from doze always as we don't lose state */ + *msr |= SRR1_WS_NOLOSS; + + /* Machine checks are sent normally */ + if (excp == POWERPC_EXCP_MCHECK) { + return excp; + } + switch (excp) { + case POWERPC_EXCP_RESET: + *msr |= SRR1_WAKERESET; + break; + case POWERPC_EXCP_EXTERNAL: + *msr |= SRR1_WAKEEE; + break; + case POWERPC_EXCP_DECR: + *msr |= SRR1_WAKEDEC; + break; + case POWERPC_EXCP_SDOOR: + *msr |= SRR1_WAKEDBELL; + break; + case POWERPC_EXCP_SDOOR_HV: + *msr |= SRR1_WAKEHDBELL; + break; + case POWERPC_EXCP_HV_MAINT: + *msr |= SRR1_WAKEHMI; + break; + case POWERPC_EXCP_HVIRT: + *msr |= SRR1_WAKEHVI; + break; + default: + cpu_abort(cs, "Unsupported exception %d in Power Save mode\n", + excp); + } + return POWERPC_EXCP_RESET; +} + +/* + * AIL - Alternate Interrupt Location, a mode that allows interrupts to be + * taken with the MMU on, and which uses an alternate location (e.g., so the + * kernel/hv can map the vectors there with an effective address). + * + * An interrupt is considered to be taken "with AIL" or "AIL applies" if they + * are delivered in this way. AIL requires the LPCR to be set to enable this + * mode, and then a number of conditions have to be true for AIL to apply. + * + * First of all, SRESET, MCE, and HMI are always delivered without AIL, because + * they specifically want to be in real mode (e.g., the MCE might be signaling + * a SLB multi-hit which requires SLB flush before the MMU can be enabled). + * + * After that, behaviour depends on the current MSR[IR], MSR[DR], MSR[HV], + * whether or not the interrupt changes MSR[HV] from 0 to 1, and the current + * radix mode (LPCR[HR]). + * + * POWER8, POWER9 with LPCR[HR]=0 + * | LPCR[AIL] | MSR[IR||DR] | MSR[HV] | new MSR[HV] | AIL | + * +-----------+-------------+---------+-------------+-----+ + * | a | 00/01/10 | x | x | 0 | + * | a | 11 | 0 | 1 | 0 | + * | a | 11 | 1 | 1 | a | + * | a | 11 | 0 | 0 | a | + * +-------------------------------------------------------+ + * + * POWER9 with LPCR[HR]=1 + * | LPCR[AIL] | MSR[IR||DR] | MSR[HV] | new MSR[HV] | AIL | + * +-----------+-------------+---------+-------------+-----+ + * | a | 00/01/10 | x | x | 0 | + * | a | 11 | x | x | a | + * +-------------------------------------------------------+ + * + * The difference with POWER9 being that MSR[HV] 0->1 interrupts can be sent to + * the hypervisor in AIL mode if the guest is radix. This is good for + * performance but allows the guest to influence the AIL of hypervisor + * interrupts using its MSR, and also the hypervisor must disallow guest + * interrupts (MSR[HV] 0->0) from using AIL if the hypervisor does not want to + * use AIL for its MSR[HV] 0->1 interrupts. + * + * POWER10 addresses those issues with a new LPCR[HAIL] bit that is applied to + * interrupts that begin execution with MSR[HV]=1 (so both MSR[HV] 0->1 and + * MSR[HV] 1->1). + * + * HAIL=1 is equivalent to AIL=3, for interrupts delivered with MSR[HV]=1. + * + * POWER10 behaviour is + * | LPCR[AIL] | LPCR[HAIL] | MSR[IR||DR] | MSR[HV] | new MSR[HV] | AIL | + * +-----------+------------+-------------+---------+-------------+-----+ + * | a | h | 00/01/10 | 0 | 0 | 0 | + * | a | h | 11 | 0 | 0 | a | + * | a | h | x | 0 | 1 | h | + * | a | h | 00/01/10 | 1 | 1 | 0 | + * | a | h | 11 | 1 | 1 | h | + * +--------------------------------------------------------------------+ + */ +static inline void ppc_excp_apply_ail(PowerPCCPU *cpu, int excp_model, int excp, + target_ulong msr, + target_ulong *new_msr, + target_ulong *new_nip) +{ + CPUPPCState *env = &cpu->env; + bool mmu_all_on = ((msr >> MSR_IR) & 1) && ((msr >> MSR_DR) & 1); + bool hv_escalation = !(msr & MSR_HVB) && (*new_msr & MSR_HVB); + int ail = 0; + + if (excp == POWERPC_EXCP_MCHECK || + excp == POWERPC_EXCP_RESET || + excp == POWERPC_EXCP_HV_MAINT) { + /* SRESET, MCE, HMI never apply AIL */ + return; + } + + if (excp_model == POWERPC_EXCP_POWER8 || + excp_model == POWERPC_EXCP_POWER9) { + if (!mmu_all_on) { + /* AIL only works if MSR[IR] and MSR[DR] are both enabled. */ + return; + } + if (hv_escalation && !(env->spr[SPR_LPCR] & LPCR_HR)) { + /* + * AIL does not work if there is a MSR[HV] 0->1 transition and the + * partition is in HPT mode. For radix guests, such interrupts are + * allowed to be delivered to the hypervisor in ail mode. + */ + return; + } + + ail = (env->spr[SPR_LPCR] & LPCR_AIL) >> LPCR_AIL_SHIFT; + if (ail == 0) { + return; + } + if (ail == 1) { + /* AIL=1 is reserved, treat it like AIL=0 */ + return; + } + + } else if (excp_model == POWERPC_EXCP_POWER10) { + if (!mmu_all_on && !hv_escalation) { + /* + * AIL works for HV interrupts even with guest MSR[IR/DR] disabled. + * Guest->guest and HV->HV interrupts do require MMU on. + */ + return; + } + + if (*new_msr & MSR_HVB) { + if (!(env->spr[SPR_LPCR] & LPCR_HAIL)) { + /* HV interrupts depend on LPCR[HAIL] */ + return; + } + ail = 3; /* HAIL=1 gives AIL=3 behaviour for HV interrupts */ + } else { + ail = (env->spr[SPR_LPCR] & LPCR_AIL) >> LPCR_AIL_SHIFT; + } + if (ail == 0) { + return; + } + if (ail == 1 || ail == 2) { + /* AIL=1 and AIL=2 are reserved, treat them like AIL=0 */ + return; + } + } else { + /* Other processors do not support AIL */ + return; + } + + /* + * AIL applies, so the new MSR gets IR and DR set, and an offset applied + * to the new IP. + */ + *new_msr |= (1 << MSR_IR) | (1 << MSR_DR); + + if (excp != POWERPC_EXCP_SYSCALL_VECTORED) { + if (ail == 2) { + *new_nip |= 0x0000000000018000ull; + } else if (ail == 3) { + *new_nip |= 0xc000000000004000ull; + } + } else { + /* + * scv AIL is a little different. AIL=2 does not change the address, + * only the MSR. AIL=3 replaces the 0x17000 base with 0xc...3000. + */ + if (ail == 3) { + *new_nip &= ~0x0000000000017000ull; /* Un-apply the base offset */ + *new_nip |= 0xc000000000003000ull; /* Apply scv's AIL=3 offset */ + } + } +} + +void book3s_excp(PowerPCCPU *cpu, int excp) +{ + CPUState *cs = CPU(cpu); + CPUPPCState *env = &cpu->env; + int excp_model = env->excp_model; + PPCIntrArgs regs; + bool ignore; + + regs.msr = env->msr & ~0x783f0000ULL; + regs.nip = env->nip; + + /* + * new interrupt handler msr preserves existing HV and ME unless + * explicitly overriden + */ + regs.new_msr = env->msr & (((target_ulong)1 << MSR_ME) | MSR_HVB); + + /* The Book3S cpus we support are 64 bit only */ + regs.new_msr |= (target_ulong)1 << MSR_SF; + + regs.sprn_srr0 = SPR_SRR0; + regs.sprn_srr1 = SPR_SRR1; + + /* + * check for special resume at 0x100 from doze/nap/sleep/winkle on + * P7/P8/P9 + */ + if (env->resume_as_sreset) { + excp = powerpc_reset_wakeup(cs, env, excp, ®s.msr); + } + + /* + * We don't want to generate an Hypervisor emulation assistance + * interrupt if we don't have HVB in msr_mask (PAPR mode). + */ + if (excp == POWERPC_EXCP_HV_EMU && !(env->msr_mask & MSR_HVB)) { + excp = POWERPC_EXCP_PROGRAM; + } + + regs.new_nip = env->excp_vectors[excp]; + if (regs.new_nip == (target_ulong)-1ULL) { + cpu_abort(cs, "Raised an exception without defined vector %d\n", + excp); + } + + /* Setup interrupt-specific registers before injecting */ + ignore = ppc_intr_prepare(cpu, interrupts_book3s, ®s, excp); + + if (ignore) { + /* No further setup is needed for this interrupt */ + return; + } + + /* + * Sort out endianness of interrupt, this differs depending on the + * CPU, the HV mode, etc... + */ + if (excp_model == POWERPC_EXCP_POWER7) { + if (!(regs.new_msr & MSR_HVB) && (env->spr[SPR_LPCR] & LPCR_ILE)) { + regs.new_msr |= (target_ulong)1 << MSR_LE; + } + } else if (excp_model == POWERPC_EXCP_POWER8) { + if (regs.new_msr & MSR_HVB) { + if (env->spr[SPR_HID0] & HID0_HILE) { + regs.new_msr |= (target_ulong)1 << MSR_LE; + } + } else if (env->spr[SPR_LPCR] & LPCR_ILE) { + regs.new_msr |= (target_ulong)1 << MSR_LE; + } + } else if (excp_model == POWERPC_EXCP_POWER9 || + excp_model == POWERPC_EXCP_POWER10) { + if (regs.new_msr & MSR_HVB) { + if (env->spr[SPR_HID0] & HID0_POWER9_HILE) { + regs.new_msr |= (target_ulong)1 << MSR_LE; + } + } else if (env->spr[SPR_LPCR] & LPCR_ILE) { + regs.new_msr |= (target_ulong)1 << MSR_LE; + } + } else if (msr_ile) { + regs.new_msr |= (target_ulong)1 << MSR_LE; + } + + if (excp != POWERPC_EXCP_SYSCALL_VECTORED) { + /* Save PC */ + env->spr[regs.sprn_srr0] = regs.nip; + + /* Save MSR */ + env->spr[regs.sprn_srr1] = regs.msr; + } + + /* This can update regs.new_msr and regs.new_nip if AIL applies */ + ppc_excp_apply_ail(cpu, excp_model, excp, regs.msr, ®s.new_msr, + ®s.new_nip); + + powerpc_set_excp_state(cpu, regs.new_nip, regs.new_msr); +} diff --git a/target/ppc/intr-booke.c b/target/ppc/intr-booke.c new file mode 100644 index 0000000000..598d372069 --- /dev/null +++ b/target/ppc/intr-booke.c @@ -0,0 +1,150 @@ +/* + * PowerPC exception dispatching for BookE CPUs + * + * Copyright (C) 2021 IBM Corporation. + * + * This code is licensed under the GPL version 2 or later. See the + * COPYING file in the top-level directory. + */ +#include "qemu/osdep.h" +#include "cpu.h" +#include "ppc_intr.h" + +static PPCInterrupt interrupts_booke[POWERPC_EXCP_NB] = { + [POWERPC_EXCP_ALIGN] = { + "Alignment", ppc_intr_alignment + }, + + [POWERPC_EXCP_CRITICAL] = { + "Critical input", ppc_intr_critical + }, + + [POWERPC_EXCP_DEBUG] = { + "Debug", ppc_intr_debug + }, + + [POWERPC_EXCP_DLTLB] = { + "Data load TLB error", ppc_intr_tlb_miss + }, + + [POWERPC_EXCP_DSI] = { + "Data storage", ppc_intr_data_storage + }, + + [POWERPC_EXCP_EXTERNAL] = { + "External", ppc_intr_external + }, + + [POWERPC_EXCP_FIT] = { + "Fixed-interval timer", ppc_intr_fit + }, + + [POWERPC_EXCP_ISI] = { + "Instruction storage", ppc_intr_insn_storage + }, + + [POWERPC_EXCP_MCHECK] = { + "Machine check", ppc_intr_machine_check + }, + + [POWERPC_EXCP_PROGRAM] = { + "Program", ppc_intr_program + }, + + [POWERPC_EXCP_RESET] = { + "System reset", ppc_intr_system_reset + }, + + [POWERPC_EXCP_SPEU] = { + "SPE/embedded FP unavailable/VPU", ppc_intr_spe_unavailable + }, + + [POWERPC_EXCP_SYSCALL] = { + "System call", ppc_intr_system_call + }, + + [POWERPC_EXCP_WDT] = { + "Watchdog timer", ppc_intr_watchdog + }, + + [POWERPC_EXCP_APU] = { "Aux. processor unavailable", ppc_intr_noop }, + [POWERPC_EXCP_DECR] = { "Decrementer", ppc_intr_noop }, + [POWERPC_EXCP_DTLB] = { "Data TLB error", ppc_intr_noop }, + [POWERPC_EXCP_FPU] = { "Floating-point unavailable", ppc_intr_noop }, + [POWERPC_EXCP_ITLB] = { "Instruction TLB error", ppc_intr_noop }, + +/* Not impleemented */ + [POWERPC_EXCP_EFPDI] = { "Embedded floating-point data" }, + [POWERPC_EXCP_EFPRI] = { "Embedded floating-point round" }, +}; + +void booke_excp(PowerPCCPU *cpu, int excp) +{ + CPUState *cs = CPU(cpu); + CPUPPCState *env = &cpu->env; + PPCIntrArgs regs; + bool ignore; + + regs.msr = env->msr; + regs.nip = env->nip; + + /* + * new interrupt handler msr preserves existing HV and ME unless + * explicitly overriden + */ + regs.new_msr = env->msr & (((target_ulong)1 << MSR_ME) | MSR_HVB); + + regs.sprn_srr0 = SPR_SRR0; + regs.sprn_srr1 = SPR_SRR1; + + /* + * Hypervisor emulation assistance interrupt only exists on server + * arch 2.05 server or later. + */ + if (excp == POWERPC_EXCP_HV_EMU) { + excp = POWERPC_EXCP_PROGRAM; + } + +#ifdef TARGET_PPC64 + /* + * SPEU and VPU share the same IVOR but they exist in different + * processors. SPEU is e500v1/2 only and VPU is e6500 only. + */ + if (env->excp_model == POWERPC_EXCP_BOOKE && excp == POWERPC_EXCP_VPU) { + excp = POWERPC_EXCP_SPEU; + } +#endif + + regs.new_nip = env->excp_vectors[excp]; + if (regs.new_nip == (target_ulong)-1ULL) { + cpu_abort(cs, "Raised an exception without defined vector %d\n", + excp); + } + + regs.new_nip |= env->excp_prefix; + + /* Setup interrupt-specific registers before injecting */ + ignore = ppc_intr_prepare(cpu, interrupts_booke, ®s, excp); + + if (ignore) { + /* No further setup is needed for this interrupt */ + return; + } + +#if defined(TARGET_PPC64) + if (env->spr[SPR_BOOKE_EPCR] & EPCR_ICM) { + /* Cat.64-bit: EPCR.ICM is copied to MSR.CM */ + regs.new_msr |= (target_ulong)1 << MSR_CM; + } else { + regs.new_nip = (uint32_t)regs.new_nip; + } +#endif + + /* Save PC */ + env->spr[regs.sprn_srr0] = regs.nip; + + /* Save MSR */ + env->spr[regs.sprn_srr1] = regs.msr; + + powerpc_set_excp_state(cpu, regs.new_nip, regs.new_msr); +} diff --git a/target/ppc/intr-ppc32.c b/target/ppc/intr-ppc32.c new file mode 100644 index 0000000000..a4b89da536 --- /dev/null +++ b/target/ppc/intr-ppc32.c @@ -0,0 +1,159 @@ +/* + * PowerPC exception dispatching for 32bit CPUs + * + * Copyright (C) 2021 IBM Corporation. + * + * This code is licensed under the GPL version 2 or later. See the + * COPYING file in the top-level directory. + */ +#include "qemu/osdep.h" +#include "cpu.h" +#include "ppc_intr.h" + +static PPCInterrupt interrupts_ppc32[POWERPC_EXCP_NB] = { + [POWERPC_EXCP_ALIGN] = { + "Alignment", ppc_intr_alignment + }, + + [POWERPC_EXCP_CRITICAL] = { + "Critical input", ppc_intr_critical + }, + + [POWERPC_EXCP_DEBUG] = { + "Debug", ppc_intr_debug + }, + + [POWERPC_EXCP_DLTLB] = { + "Data load TLB error", ppc_intr_tlb_miss + }, + + [POWERPC_EXCP_DSI] = { + "Data storage", ppc_intr_data_storage + }, + + [POWERPC_EXCP_DSTLB] = { + "Data store TLB error", ppc_intr_tlb_miss + }, + + [POWERPC_EXCP_EXTERNAL] = { + "External", ppc_intr_external + }, + + [POWERPC_EXCP_FIT] = { + "Fixed-interval timer", ppc_intr_fit + }, + + [POWERPC_EXCP_IFTLB] = { + "Insn fetch TLB error", ppc_intr_tlb_miss + }, + + [POWERPC_EXCP_ISI] = { + "Instruction storage", ppc_intr_insn_storage + }, + + [POWERPC_EXCP_MCHECK] = { + "Machine check", ppc_intr_machine_check + }, + + [POWERPC_EXCP_PIT] = { + "Programmable interval timer", ppc_intr_programmable_timer + }, + + [POWERPC_EXCP_PROGRAM] = { + "Program", ppc_intr_program + }, + + [POWERPC_EXCP_RESET] = { + "System reset", ppc_intr_system_reset + }, + + [POWERPC_EXCP_SYSCALL] = { + "System call", ppc_intr_system_call + }, + + [POWERPC_EXCP_VPU] = { + "Vector unavailable", ppc_intr_facility_unavail + }, + + [POWERPC_EXCP_WDT] = { + "Watchdog timer", ppc_intr_watchdog + }, + + [POWERPC_EXCP_DECR] = { "Decrementer", ppc_intr_noop }, + [POWERPC_EXCP_DTLB] = { "Data TLB error", ppc_intr_noop }, + [POWERPC_EXCP_FPU] = { "Floating-point unavailable", ppc_intr_noop }, + [POWERPC_EXCP_ITLB] = { "Instruction TLB error", ppc_intr_noop }, + [POWERPC_EXCP_TRACE] = { "Trace", ppc_intr_noop }, + +/* Not implemented */ + [POWERPC_EXCP_DABR] = { "Data address breakpoint" }, + [POWERPC_EXCP_DTLBE] = { "Data TLB error" }, + [POWERPC_EXCP_EMUL] = { "Emulation trap" }, + [POWERPC_EXCP_FPA] = { "Floating-point assist" }, + [POWERPC_EXCP_IABR] = { "Insn address breakpoint" }, + [POWERPC_EXCP_IO] = { "IO error" }, + [POWERPC_EXCP_ITLBE] = { "Instruction TLB error" }, + [POWERPC_EXCP_MEXTBR] = { "Maskable external" }, + [POWERPC_EXCP_NMEXTBR] = { "Non-maskable external" }, + [POWERPC_EXCP_PERFM] = { "Performance counter" }, + [POWERPC_EXCP_RUNM] = { "Run mode" }, + [POWERPC_EXCP_SMI] = { "System management" }, + [POWERPC_EXCP_THERM] = { "Thermal management" }, + [POWERPC_EXCP_VPUA] = { "Vector assist" }, +}; + +void ppc32_excp(PowerPCCPU *cpu, int excp) +{ + CPUState *cs = CPU(cpu); + CPUPPCState *env = &cpu->env; + PPCIntrArgs regs; + bool ignore; + + regs.msr = env->msr & ~0x783f0000ULL; + regs.nip = env->nip; + + /* + * new interrupt handler msr preserves existing HV and ME unless + * explicitly overriden + */ + regs.new_msr = env->msr & (((target_ulong)1 << MSR_ME) | MSR_HVB); + + regs.sprn_srr0 = SPR_SRR0; + regs.sprn_srr1 = SPR_SRR1; + + /* + * Hypervisor emulation assistance interrupt only exists on server + * arch 2.05 server or later. + */ + if (excp == POWERPC_EXCP_HV_EMU) { + excp = POWERPC_EXCP_PROGRAM; + } + + regs.new_nip = env->excp_vectors[excp]; + if (regs.new_nip == (target_ulong)-1ULL) { + cpu_abort(cs, "Raised an exception without defined vector %d\n", + excp); + } + + regs.new_nip |= env->excp_prefix; + + /* Setup interrupt-specific registers before injecting */ + ignore = ppc_intr_prepare(cpu, interrupts_ppc32, ®s, excp); + + if (ignore) { + /* No further setup is needed for this interrupt */ + return; + } + + if (msr_ile) { + regs.new_msr |= (target_ulong)1 << MSR_LE; + } + + /* Save PC */ + env->spr[regs.sprn_srr0] = regs.nip; + + /* Save MSR */ + env->spr[regs.sprn_srr1] = regs.msr; + + powerpc_set_excp_state(cpu, regs.new_nip, regs.new_msr); +} diff --git a/target/ppc/meson.build b/target/ppc/meson.build index 53b8e0a98e..9ec335d438 100644 --- a/target/ppc/meson.build +++ b/target/ppc/meson.build @@ -40,9 +40,11 @@ ppc_softmmu_ss.add(files( 'mmu_common.c', 'monitor.c', 'interrupts.c', + 'intr-booke.c', )) ppc_softmmu_ss.add(when: 'CONFIG_TCG', if_true: files( 'mmu_helper.c', + 'intr-ppc32.c', ), if_false: files( 'tcg-stub.c', )) @@ -53,6 +55,7 @@ ppc_softmmu_ss.add(when: 'TARGET_PPC64', if_true: files( 'mmu-hash64.c', 'mmu-radix64.c', 'power8-pmu.c', + 'intr-book3s.c', )) target_arch += {'ppc': ppc_ss} diff --git a/target/ppc/ppc_intr.h b/target/ppc/ppc_intr.h index a12b3a9e4d..a0362f4248 100644 --- a/target/ppc/ppc_intr.h +++ b/target/ppc/ppc_intr.h @@ -27,9 +27,6 @@ void ppc_intr_embedded_doorbell_crit(PowerPCCPU *cpu, PPCIntrArgs *regs, bool *i void ppc_intr_external(PowerPCCPU *cpu, PPCIntrArgs *regs, bool *ignore); void ppc_intr_facility_unavail(PowerPCCPU *cpu, PPCIntrArgs *regs, bool *ignore); void ppc_intr_fit(PowerPCCPU *cpu, PPCIntrArgs *regs, bool *ignore); -void ppc_intr_hv(PowerPCCPU *cpu, PPCIntrArgs *regs, bool *ignore); -void ppc_intr_hv_facility_unavail(PowerPCCPU *cpu, PPCIntrArgs *regs, bool *ignore); -void ppc_intr_hv_insn_storage(PowerPCCPU *cpu, PPCIntrArgs *regs, bool *ignore); void ppc_intr_insn_storage(PowerPCCPU *cpu, PPCIntrArgs *regs, bool *ignore); void ppc_intr_machine_check(PowerPCCPU *cpu, PPCIntrArgs *regs, bool *ignore); void ppc_intr_noop(PowerPCCPU *cpu, PPCIntrArgs *regs, bool *ignore); @@ -42,11 +39,20 @@ void ppc_intr_system_reset(PowerPCCPU *cpu, PPCIntrArgs *regs, bool *ignore); void ppc_intr_tlb_miss(PowerPCCPU *cpu, PPCIntrArgs *regs, bool *ignore); void ppc_intr_watchdog(PowerPCCPU *cpu, PPCIntrArgs *regs, bool *ignore); +#ifdef TARGET_PPC64 +void ppc_intr_hv(PowerPCCPU *cpu, PPCIntrArgs *regs, bool *ignore); +void ppc_intr_hv_facility_unavail(PowerPCCPU *cpu, PPCIntrArgs *regs, bool *ignore); +void ppc_intr_hv_insn_storage(PowerPCCPU *cpu, PPCIntrArgs *regs, bool *ignore); +#endif + int ppc_intr_prepare(PowerPCCPU *cpu, PPCInterrupt *interrupts, PPCIntrArgs *regs, int excp); -extern PPCInterrupt interrupts_ppc32[POWERPC_EXCP_NB]; -extern PPCInterrupt interrupts_booke[POWERPC_EXCP_NB]; -extern PPCInterrupt interrupts_book3s[POWERPC_EXCP_NB]; +void ppc32_excp(PowerPCCPU *cpu, int excp); +void booke_excp(PowerPCCPU *cpu, int excp); + +#ifdef TARGET_PPC64 +void book3s_excp(PowerPCCPU *cpu, int excp); +#endif #endif /* PPC_INTR_H */ diff --git a/target/ppc/tcg-stub.c b/target/ppc/tcg-stub.c index aadcf59d26..2b40258b01 100644 --- a/target/ppc/tcg-stub.c +++ b/target/ppc/tcg-stub.c @@ -20,6 +20,7 @@ #include "cpu.h" #include "internal.h" #include "hw/ppc/spapr.h" +#include "ppc_intr.h" void create_ppc_opcodes(PowerPCCPU *cpu, Error **errp) { @@ -43,3 +44,8 @@ target_ulong softmmu_resize_hpt_commit(PowerPCCPU *cpu, { g_assert_not_reached(); } + +void ppc32_excp(PowerPCCPU *cpu, int excp) +{ + g_assert_not_reached(); +} From patchwork Mon Dec 20 18:19:03 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Fabiano Rosas X-Patchwork-Id: 12688417 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.lore.kernel.org (Postfix) with ESMTPS id 9023BC433EF for ; Mon, 20 Dec 2021 19:12:14 +0000 (UTC) Received: from localhost ([::1]:46762 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1mzO4z-0003vq-8D for qemu-devel@archiver.kernel.org; Mon, 20 Dec 2021 14:12:13 -0500 Received: from eggs.gnu.org ([209.51.188.92]:35948) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1mzNGF-00034b-OG; Mon, 20 Dec 2021 13:19:49 -0500 Received: from mx0a-001b2d01.pphosted.com ([148.163.156.1]:38470) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1mzNGC-0006o5-Rn; Mon, 20 Dec 2021 13:19:47 -0500 Received: from pps.filterd (m0098394.ppops.net [127.0.0.1]) by mx0a-001b2d01.pphosted.com (8.16.1.2/8.16.1.2) with SMTP id 1BKHJOXi013131; Mon, 20 Dec 2021 18:19:39 GMT DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=ibm.com; h=from : to : cc : subject : date : message-id : in-reply-to : references : mime-version : content-transfer-encoding; s=pp1; bh=vOGYN9GpzDQPb1zAsdt2ewCNMRPiZ0GMZJDwRfFdWPM=; b=rQQM87mAnJYPN8b19nVbJYSBaMaLzuyOixfkTYTgK0gZXuzCwaeXyYvadAb2lKD4HHLc P4JFZdbw+aWF1FRSlyb/GkNBgBdSq8tB5uQxN69JLRiCeR489scAQdYtpvVTV0v6p0Mx rfaHEOVrIuOhbvsYadN5OmEQXQTx49++IrE/FTmcvTLJ0zSUWh3rPRcEwi8ot1fuueZD 9wpQ/90/IthCB3HhzNxjCZXQIGMHhTArmxUD3WO1CgvbFEdqSy0/Dq8YOfTdQZtdxjrf yFtkOY1ZE858bAUNTY+2N+VmdJvBC9/N7d2VqwkQiesehT1EpaeWhRqIzlr4zRE4t5ef ow== Received: from pps.reinject (localhost [127.0.0.1]) by mx0a-001b2d01.pphosted.com with ESMTP id 3d1s4wt341-1 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NOT); Mon, 20 Dec 2021 18:19:39 +0000 Received: from m0098394.ppops.net (m0098394.ppops.net [127.0.0.1]) by pps.reinject (8.16.0.43/8.16.0.43) with SMTP id 1BKIIVE2020764; Mon, 20 Dec 2021 18:19:38 GMT Received: from ppma02dal.us.ibm.com (a.bd.3ea9.ip4.static.sl-reverse.com [169.62.189.10]) by mx0a-001b2d01.pphosted.com with ESMTP id 3d1s4wt33n-1 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NOT); Mon, 20 Dec 2021 18:19:38 +0000 Received: from pps.filterd (ppma02dal.us.ibm.com [127.0.0.1]) by ppma02dal.us.ibm.com (8.16.1.2/8.16.1.2) with SMTP id 1BKIEi4n017567; Mon, 20 Dec 2021 18:19:37 GMT Received: from b03cxnp08025.gho.boulder.ibm.com (b03cxnp08025.gho.boulder.ibm.com [9.17.130.17]) by ppma02dal.us.ibm.com with ESMTP id 3d179aa8mj-1 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NOT); Mon, 20 Dec 2021 18:19:37 +0000 Received: from b03ledav006.gho.boulder.ibm.com (b03ledav006.gho.boulder.ibm.com [9.17.130.237]) by b03cxnp08025.gho.boulder.ibm.com (8.14.9/8.14.9/NCO v10.0) with ESMTP id 1BKIJaIJ28115322 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-GCM-SHA384 bits=256 verify=OK); Mon, 20 Dec 2021 18:19:36 GMT Received: from b03ledav006.gho.boulder.ibm.com (unknown [127.0.0.1]) by IMSVA (Postfix) with ESMTP id A19CFC6069; Mon, 20 Dec 2021 18:19:36 +0000 (GMT) Received: from b03ledav006.gho.boulder.ibm.com (unknown [127.0.0.1]) by IMSVA (Postfix) with ESMTP id 1DF4FC6067; Mon, 20 Dec 2021 18:19:35 +0000 (GMT) Received: from farosas.linux.ibm.com.com (unknown [9.211.60.53]) by b03ledav006.gho.boulder.ibm.com (Postfix) with ESMTP; Mon, 20 Dec 2021 18:19:34 +0000 (GMT) From: Fabiano Rosas To: qemu-devel@nongnu.org Subject: [RFC v2 12/12] target/ppc: Do not enable all interrupts when running KVM Date: Mon, 20 Dec 2021 15:19:03 -0300 Message-Id: <20211220181903.3456898-13-farosas@linux.ibm.com> X-Mailer: git-send-email 2.33.1 In-Reply-To: <20211220181903.3456898-1-farosas@linux.ibm.com> References: <20211220181903.3456898-1-farosas@linux.ibm.com> MIME-Version: 1.0 X-TM-AS-GCONF: 00 X-Proofpoint-ORIG-GUID: bxxhQEQ8tTKxnSBIAOsaItNOew9Uil0I X-Proofpoint-GUID: vve0Aq6qi0hdP-v3VEQwErdGLAJvQtJG X-Proofpoint-Virus-Version: vendor=baseguard engine=ICAP:2.0.205,Aquarius:18.0.790,Hydra:6.0.425,FMLib:17.11.62.513 definitions=2021-12-20_08,2021-12-20_01,2021-12-02_01 X-Proofpoint-Spam-Details: rule=outbound_notspam policy=outbound score=0 malwarescore=0 clxscore=1015 mlxscore=0 bulkscore=0 lowpriorityscore=0 priorityscore=1501 mlxlogscore=999 spamscore=0 impostorscore=0 suspectscore=0 phishscore=0 adultscore=0 classifier=spam adjust=0 reason=mlx scancount=1 engine=8.12.0-2110150000 definitions=main-2112200101 Received-SPF: pass client-ip=148.163.156.1; envelope-from=farosas@linux.ibm.com; helo=mx0a-001b2d01.pphosted.com X-Spam_score_int: -19 X-Spam_score: -2.0 X-Spam_bar: -- X-Spam_report: (-2.0 / 5.0 requ) BAYES_00=-1.9, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_EF=-0.1, RCVD_IN_MSPIKE_H2=-0.001, SPF_HELO_NONE=0.001, SPF_PASS=-0.001 autolearn=ham autolearn_force=no X-Spam_action: no action X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: danielhb413@gmail.com, qemu-ppc@nongnu.org, clg@kaod.org, david@gibson.dropbear.id.au Errors-To: qemu-devel-bounces+qemu-devel=archiver.kernel.org@nongnu.org Sender: "Qemu-devel" When running with KVM, QEMU only needs to dispatch a few interrupts in specific occasions, so we don't need to have all interrupts registered. We also want to better identify code that is used with KVM to avoid breaking the --disable-tcg|kvm builds, so this patch also adds ifdefs to make that distinction. Signed-off-by: Fabiano Rosas --- target/ppc/interrupts.c | 268 ++++++++++++++++++++++----------------- target/ppc/intr-book3s.c | 2 + target/ppc/intr-booke.c | 2 + target/ppc/ppc_intr.h | 12 +- 4 files changed, 161 insertions(+), 123 deletions(-) diff --git a/target/ppc/interrupts.c b/target/ppc/interrupts.c index 6f956029fd..be2755b1a8 100644 --- a/target/ppc/interrupts.c +++ b/target/ppc/interrupts.c @@ -11,7 +11,9 @@ #include "cpu.h" #include "ppc_intr.h" #include "trace.h" +#include "sysemu/kvm.h" +#ifdef CONFIG_TCG /* for hreg_swap_gpr_tgpr */ #include "helper_regs.h" @@ -43,56 +45,6 @@ void ppc_intr_critical(PowerPCCPU *cpu, PPCIntrArgs *regs, bool *ignore) } } -void ppc_intr_machine_check(PowerPCCPU *cpu, PPCIntrArgs *regs, bool *ignore) -{ - CPUState *cs = CPU(cpu); - CPUPPCState *env = &cpu->env; - int excp_model = env->excp_model; - - if (msr_me == 0) { - /* - * Machine check exception is not enabled. Enter - * checkstop state. - */ - fprintf(stderr, "Machine check while not allowed. " - "Entering checkstop state\n"); - if (qemu_log_separate()) { - qemu_log("Machine check while not allowed. " - "Entering checkstop state\n"); - } - cs->halted = 1; - cpu_interrupt_exittb(cs); - } - if (env->msr_mask & MSR_HVB) { - /* - * ISA specifies HV, but can be delivered to guest with HV - * clear (e.g., see FWNMI in PAPR). - */ - regs->new_msr |= (target_ulong)MSR_HVB; - } - - /* machine check exceptions don't have ME set */ - regs->new_msr &= ~((target_ulong)1 << MSR_ME); - - /* XXX: should also have something loaded in DAR / DSISR */ - switch (excp_model) { - case POWERPC_EXCP_40x: - regs->sprn_srr0 = SPR_40x_SRR2; - regs->sprn_srr1 = SPR_40x_SRR3; - break; - case POWERPC_EXCP_BOOKE: - /* FIXME: choose one or the other based on CPU type */ - regs->sprn_srr0 = SPR_BOOKE_MCSRR0; - regs->sprn_srr1 = SPR_BOOKE_MCSRR1; - - env->spr[SPR_BOOKE_CSRR0] = regs->nip; - env->spr[SPR_BOOKE_CSRR1] = regs->msr; - break; - default: - break; - } -} - void ppc_intr_data_storage(PowerPCCPU *cpu, PPCIntrArgs *regs, bool *ignore) { CPUPPCState *env = &cpu->env; @@ -165,51 +117,6 @@ void ppc_intr_alignment(PowerPCCPU *cpu, PPCIntrArgs *regs, bool *ignore) env->spr[SPR_DSISR] |= (env->error_code & 0x03FF0000) >> 16; } -void ppc_intr_program(PowerPCCPU *cpu, PPCIntrArgs *regs, bool *ignore) -{ - CPUState *cs = CPU(cpu); - CPUPPCState *env = &cpu->env; - - switch (env->error_code & ~0xF) { - case POWERPC_EXCP_FP: - if ((msr_fe0 == 0 && msr_fe1 == 0) || msr_fp == 0) { - trace_ppc_excp_fp_ignore(); - cs->exception_index = POWERPC_EXCP_NONE; - env->error_code = 0; - - *ignore = true; - return; - } - - /* - * FP exceptions always have NIP pointing to the faulting - * instruction, so always use store_next and claim we are - * precise in the MSR. - */ - regs->msr |= 0x00100000; - env->spr[SPR_BOOKE_ESR] = ESR_FP; - break; - case POWERPC_EXCP_INVAL: - trace_ppc_excp_inval(regs->nip); - regs->msr |= 0x00080000; - env->spr[SPR_BOOKE_ESR] = ESR_PIL; - break; - case POWERPC_EXCP_PRIV: - regs->msr |= 0x00040000; - env->spr[SPR_BOOKE_ESR] = ESR_PPR; - break; - case POWERPC_EXCP_TRAP: - regs->msr |= 0x00020000; - env->spr[SPR_BOOKE_ESR] = ESR_PTR; - break; - default: - /* Should never occur */ - cpu_abort(cs, "Invalid program exception %d. Aborting\n", - env->error_code); - break; - } -} - static inline void dump_syscall(CPUPPCState *env) { qemu_log_mask(CPU_LOG_INT, "syscall r0=%016" PRIx64 @@ -334,30 +241,6 @@ void ppc_intr_spe_unavailable(PowerPCCPU *cpu, PPCIntrArgs *regs, bool *ignore) env->spr[SPR_BOOKE_ESR] = ESR_SPV; } -void ppc_intr_system_reset(PowerPCCPU *cpu, PPCIntrArgs *regs, bool *ignore) -{ - CPUPPCState *env = &cpu->env; - - /* A power-saving exception sets ME, otherwise it is unchanged */ - if (msr_pow) { - /* indicate that we resumed from power save mode */ - regs->msr |= 0x10000; - regs->new_msr |= ((target_ulong)1 << MSR_ME); - } - if (env->msr_mask & MSR_HVB) { - /* - * ISA specifies HV, but can be delivered to guest with HV - * clear (e.g., see FWNMI in PAPR, NMI injection in QEMU). - */ - regs->new_msr |= (target_ulong)MSR_HVB; - } else { - if (msr_pow) { - cpu_abort(CPU(cpu), "Trying to deliver power-saving system reset " - "exception with no HV support\n"); - } - } -} - #ifdef TARGET_PPC64 void ppc_intr_hv(PowerPCCPU *cpu, PPCIntrArgs *regs, bool *ignore) { @@ -455,6 +338,149 @@ void ppc_intr_tlb_miss(PowerPCCPU *cpu, PPCIntrArgs *regs, bool *ignore) break; } } +#endif /* CONFIG_TCG */ + +void ppc_intr_machine_check(PowerPCCPU *cpu, PPCIntrArgs *regs, bool *ignore) +{ + CPUState *cs = CPU(cpu); + CPUPPCState *env = &cpu->env; + int excp_model = env->excp_model; + + if (msr_me == 0) { + /* + * Machine check exception is not enabled. Enter + * checkstop state. + */ + fprintf(stderr, "Machine check while not allowed. " + "Entering checkstop state\n"); + if (qemu_log_separate()) { + qemu_log("Machine check while not allowed. " + "Entering checkstop state\n"); + } + cs->halted = 1; +#if defined(CONFIG_TCG) + cpu_interrupt_exittb(cs); +#endif + } + if (env->msr_mask & MSR_HVB) { + /* + * ISA specifies HV, but can be delivered to guest with HV + * clear (e.g., see FWNMI in PAPR). + */ + regs->new_msr |= (target_ulong)MSR_HVB; + } + + /* machine check exceptions don't have ME set */ + regs->new_msr &= ~((target_ulong)1 << MSR_ME); + + /* XXX: should also have something loaded in DAR / DSISR */ + switch (excp_model) { + case POWERPC_EXCP_40x: + regs->sprn_srr0 = SPR_40x_SRR2; + regs->sprn_srr1 = SPR_40x_SRR3; + break; + case POWERPC_EXCP_BOOKE: + /* FIXME: choose one or the other based on CPU type */ + regs->sprn_srr0 = SPR_BOOKE_MCSRR0; + regs->sprn_srr1 = SPR_BOOKE_MCSRR1; + + env->spr[SPR_BOOKE_CSRR0] = regs->nip; + env->spr[SPR_BOOKE_CSRR1] = regs->msr; + break; + default: + break; + } +} + +void ppc_intr_program(PowerPCCPU *cpu, PPCIntrArgs *regs, bool *ignore) +{ + CPUState *cs = CPU(cpu); + CPUPPCState *env = &cpu->env; + + switch (env->error_code & ~0xF) { + case POWERPC_EXCP_FP: + if ((msr_fe0 == 0 && msr_fe1 == 0) || msr_fp == 0) { + trace_ppc_excp_fp_ignore(); + cs->exception_index = POWERPC_EXCP_NONE; + env->error_code = 0; + + *ignore = true; + return; + } + + /* + * FP exceptions always have NIP pointing to the faulting + * instruction, so always use store_next and claim we are + * precise in the MSR. + */ + regs->msr |= 0x00100000; + env->spr[SPR_BOOKE_ESR] = ESR_FP; + break; + case POWERPC_EXCP_INVAL: + trace_ppc_excp_inval(regs->nip); + regs->msr |= 0x00080000; + env->spr[SPR_BOOKE_ESR] = ESR_PIL; + break; + case POWERPC_EXCP_PRIV: + regs->msr |= 0x00040000; + env->spr[SPR_BOOKE_ESR] = ESR_PPR; + break; + case POWERPC_EXCP_TRAP: + regs->msr |= 0x00020000; + env->spr[SPR_BOOKE_ESR] = ESR_PTR; + break; + default: + /* Should never occur */ + cpu_abort(cs, "Invalid program exception %d. Aborting\n", + env->error_code); + break; + } +} + +void ppc_intr_system_reset(PowerPCCPU *cpu, PPCIntrArgs *regs, bool *ignore) +{ + CPUPPCState *env = &cpu->env; + + /* A power-saving exception sets ME, otherwise it is unchanged */ + if (msr_pow) { + /* indicate that we resumed from power save mode */ + regs->msr |= 0x10000; + regs->new_msr |= ((target_ulong)1 << MSR_ME); + } + if (env->msr_mask & MSR_HVB) { + /* + * ISA specifies HV, but can be delivered to guest with HV + * clear (e.g., see FWNMI in PAPR, NMI injection in QEMU). + */ + regs->new_msr |= (target_ulong)MSR_HVB; + } else { + if (msr_pow) { + cpu_abort(CPU(cpu), "Trying to deliver power-saving system reset " + "exception with no HV support\n"); + } + } +} + +/* + * Book3S and BookE support KVM, but QEMU only dispatches a small + * set of interrupts in very specific ocasions. All other + * interrupts are dispatched by the real harware and QEMU knows + * nothing about them. + */ +PPCInterrupt interrupts_kvm[POWERPC_EXCP_NB] = { + + [POWERPC_EXCP_MCHECK] = { + "Machine check", ppc_intr_machine_check + }, + + [POWERPC_EXCP_PROGRAM] = { + "Program", ppc_intr_program + }, + + [POWERPC_EXCP_RESET] = { + "System reset", ppc_intr_system_reset + }, +}; int ppc_intr_prepare(PowerPCCPU *cpu, PPCInterrupt *interrupts, PPCIntrArgs *regs, int excp) @@ -464,6 +490,10 @@ int ppc_intr_prepare(PowerPCCPU *cpu, PPCInterrupt *interrupts, PPCInterrupt *intr; bool ignore = false; + if (kvm_enabled()) { + interrupts = interrupts_kvm; + } + intr = &interrupts[excp]; if (!intr->name) { cpu_abort(cs, "Invalid PowerPC exception %d. Aborting\n", excp); diff --git a/target/ppc/intr-book3s.c b/target/ppc/intr-book3s.c index cd279de346..a475c668ed 100644 --- a/target/ppc/intr-book3s.c +++ b/target/ppc/intr-book3s.c @@ -11,6 +11,7 @@ #include "ppc_intr.h" static PPCInterrupt interrupts_book3s[POWERPC_EXCP_NB] = { +#ifdef CONFIG_TCG [POWERPC_EXCP_ALIGN] = { "Alignment", ppc_intr_alignment }, @@ -88,6 +89,7 @@ static PPCInterrupt interrupts_book3s[POWERPC_EXCP_NB] = { [POWERPC_EXCP_SDOOR] = { "Server doorbell" }, [POWERPC_EXCP_THERM] = { "Thermal management" }, [POWERPC_EXCP_VPUA] = { "Vector assist" }, +#endif }; static int powerpc_reset_wakeup(CPUState *cs, CPUPPCState *env, int excp, diff --git a/target/ppc/intr-booke.c b/target/ppc/intr-booke.c index 598d372069..9297b14ed6 100644 --- a/target/ppc/intr-booke.c +++ b/target/ppc/intr-booke.c @@ -11,6 +11,7 @@ #include "ppc_intr.h" static PPCInterrupt interrupts_booke[POWERPC_EXCP_NB] = { +#ifdef CONFIG_TCG [POWERPC_EXCP_ALIGN] = { "Alignment", ppc_intr_alignment }, @@ -76,6 +77,7 @@ static PPCInterrupt interrupts_booke[POWERPC_EXCP_NB] = { /* Not impleemented */ [POWERPC_EXCP_EFPDI] = { "Embedded floating-point data" }, [POWERPC_EXCP_EFPRI] = { "Embedded floating-point round" }, +#endif }; void booke_excp(PowerPCCPU *cpu, int excp) diff --git a/target/ppc/ppc_intr.h b/target/ppc/ppc_intr.h index a0362f4248..4aab37ea28 100644 --- a/target/ppc/ppc_intr.h +++ b/target/ppc/ppc_intr.h @@ -19,6 +19,7 @@ struct PPCInterrupt { ppc_intr_fn_t fn; }; +#ifdef CONFIG_TCG void ppc_intr_alignment(PowerPCCPU *cpu, PPCIntrArgs *regs, bool *ignore); void ppc_intr_critical(PowerPCCPU *cpu, PPCIntrArgs *regs, bool *ignore); void ppc_intr_data_storage(PowerPCCPU *cpu, PPCIntrArgs *regs, bool *ignore); @@ -28,14 +29,11 @@ void ppc_intr_external(PowerPCCPU *cpu, PPCIntrArgs *regs, bool *ignore); void ppc_intr_facility_unavail(PowerPCCPU *cpu, PPCIntrArgs *regs, bool *ignore); void ppc_intr_fit(PowerPCCPU *cpu, PPCIntrArgs *regs, bool *ignore); void ppc_intr_insn_storage(PowerPCCPU *cpu, PPCIntrArgs *regs, bool *ignore); -void ppc_intr_machine_check(PowerPCCPU *cpu, PPCIntrArgs *regs, bool *ignore); void ppc_intr_noop(PowerPCCPU *cpu, PPCIntrArgs *regs, bool *ignore); -void ppc_intr_program(PowerPCCPU *cpu, PPCIntrArgs *regs, bool *ignore); void ppc_intr_programmable_timer(PowerPCCPU *cpu, PPCIntrArgs *regs, bool *ignore); void ppc_intr_spe_unavailable(PowerPCCPU *cpu, PPCIntrArgs *regs, bool *ignore); void ppc_intr_system_call(PowerPCCPU *cpu, PPCIntrArgs *regs, bool *ignore); void ppc_intr_system_call_vectored(PowerPCCPU *cpu, PPCIntrArgs *regs, bool *ignore); -void ppc_intr_system_reset(PowerPCCPU *cpu, PPCIntrArgs *regs, bool *ignore); void ppc_intr_tlb_miss(PowerPCCPU *cpu, PPCIntrArgs *regs, bool *ignore); void ppc_intr_watchdog(PowerPCCPU *cpu, PPCIntrArgs *regs, bool *ignore); @@ -43,7 +41,13 @@ void ppc_intr_watchdog(PowerPCCPU *cpu, PPCIntrArgs *regs, bool *ignore); void ppc_intr_hv(PowerPCCPU *cpu, PPCIntrArgs *regs, bool *ignore); void ppc_intr_hv_facility_unavail(PowerPCCPU *cpu, PPCIntrArgs *regs, bool *ignore); void ppc_intr_hv_insn_storage(PowerPCCPU *cpu, PPCIntrArgs *regs, bool *ignore); -#endif +#endif /* TARGET_PPC64 */ + +#endif /* CONFIG_TCG */ + +void ppc_intr_machine_check(PowerPCCPU *cpu, PPCIntrArgs *regs, bool *ignore); +void ppc_intr_program(PowerPCCPU *cpu, PPCIntrArgs *regs, bool *ignore); +void ppc_intr_system_reset(PowerPCCPU *cpu, PPCIntrArgs *regs, bool *ignore); int ppc_intr_prepare(PowerPCCPU *cpu, PPCInterrupt *interrupts, PPCIntrArgs *regs, int excp);