From patchwork Tue Mar 1 13:56:04 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Fabiano Rosas X-Patchwork-Id: 12764745 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 A80CAC433EF for ; Tue, 1 Mar 2022 13:58:59 +0000 (UTC) Received: from localhost ([::1]:50588 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1nP31k-0008PS-N5 for qemu-devel@archiver.kernel.org; Tue, 01 Mar 2022 08:58:56 -0500 Received: from eggs.gnu.org ([209.51.188.92]:33252) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1nP2zd-0005f5-2P; Tue, 01 Mar 2022 08:56:45 -0500 Received: from mx0b-001b2d01.pphosted.com ([148.163.158.5]:10388) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1nP2zb-00022c-7M; Tue, 01 Mar 2022 08:56:44 -0500 Received: from pps.filterd (m0098421.ppops.net [127.0.0.1]) by mx0a-001b2d01.pphosted.com (8.16.1.2/8.16.1.2) with SMTP id 221DBqrn032633; Tue, 1 Mar 2022 13:56:32 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=sZ0HIjKjxTnflZ/xf+1R0NjOgPxuWt0UAPwtBEa5K3U=; b=Wf4NefDPFv6Sm0IVJEipEgvf+dyM2Ctg33qJjDa7GS6lyhD1MPF/p31nPhIg9/uAV7Gm FXA082vnnF9J8ZCG7TTxhbTlbac+qw/Rnw8H1ZRM/yQ8qn4UGdARV8x4DUR39fWx5Bjs ArkEHnOzwDkZaA0OiOTT33SapZ/SzCg5vreC6uKuLwnU9x6o9h1FbSSDZEjAImJs8Is6 yJB9U9rOucb3WKFPyhumQAeys/lSpNneAEqUqWfbiQdYPurui4Qy6sbaGdOzvUr7gWq1 yB8+pQuITjYELZriYTWidwNQFGeBaR3ka5vNCTPxUQUM9Ch9l0fGRXguZjTn3uKYZS99 8g== Received: from pps.reinject (localhost [127.0.0.1]) by mx0a-001b2d01.pphosted.com with ESMTP id 3ehm5es000-1 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NOT); Tue, 01 Mar 2022 13:56:31 +0000 Received: from m0098421.ppops.net (m0098421.ppops.net [127.0.0.1]) by pps.reinject (8.16.0.43/8.16.0.43) with SMTP id 221DmSGj019323; Tue, 1 Mar 2022 13:56:31 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 3ehm5eryya-1 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NOT); Tue, 01 Mar 2022 13:56:31 +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 221DtmGo030100; Tue, 1 Mar 2022 13:56:30 GMT Received: from b03cxnp08025.gho.boulder.ibm.com (b03cxnp08025.gho.boulder.ibm.com [9.17.130.17]) by ppma02wdc.us.ibm.com with ESMTP id 3efbu9w0tf-1 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NOT); Tue, 01 Mar 2022 13:56:30 +0000 Received: from b03ledav005.gho.boulder.ibm.com (b03ledav005.gho.boulder.ibm.com [9.17.130.236]) by b03cxnp08025.gho.boulder.ibm.com (8.14.9/8.14.9/NCO v10.0) with ESMTP id 221DuTMa28180896 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-GCM-SHA384 bits=256 verify=OK); Tue, 1 Mar 2022 13:56:29 GMT Received: from b03ledav005.gho.boulder.ibm.com (unknown [127.0.0.1]) by IMSVA (Postfix) with ESMTP id 52388BE058; Tue, 1 Mar 2022 13:56:29 +0000 (GMT) Received: from b03ledav005.gho.boulder.ibm.com (unknown [127.0.0.1]) by IMSVA (Postfix) with ESMTP id DF3BABE053; Tue, 1 Mar 2022 13:56:27 +0000 (GMT) Received: from farosas.linux.ibm.com.com (unknown [9.211.51.129]) by b03ledav005.gho.boulder.ibm.com (Postfix) with ESMTP; Tue, 1 Mar 2022 13:56:27 +0000 (GMT) From: Fabiano Rosas To: qemu-devel@nongnu.org Subject: [PATCH 01/17] target/ppc: Add a tracepoint for System Calls Date: Tue, 1 Mar 2022 10:56:04 -0300 Message-Id: <20220301135620.2411952-2-farosas@linux.ibm.com> X-Mailer: git-send-email 2.34.1 In-Reply-To: <20220301135620.2411952-1-farosas@linux.ibm.com> References: <20220301135620.2411952-1-farosas@linux.ibm.com> MIME-Version: 1.0 X-TM-AS-GCONF: 00 X-Proofpoint-ORIG-GUID: R31JGdENjXO1fDnEE3nmTiLdcn06pWiM X-Proofpoint-GUID: Cb1DgGEM7jPFx6IpikqeeT4NrKcP2m8J X-Proofpoint-Virus-Version: vendor=baseguard engine=ICAP:2.0.205,Aquarius:18.0.816,Hydra:6.0.425,FMLib:17.11.64.514 definitions=2022-03-01_07,2022-02-26_01,2022-02-23_01 X-Proofpoint-Spam-Details: rule=outbound_notspam policy=outbound score=0 priorityscore=1501 mlxscore=0 impostorscore=0 adultscore=0 bulkscore=0 phishscore=0 malwarescore=0 suspectscore=0 spamscore=0 mlxlogscore=999 lowpriorityscore=0 clxscore=1015 classifier=spam adjust=0 reason=mlx scancount=1 engine=8.12.0-2201110000 definitions=main-2203010074 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_H5=0.001, RCVD_IN_MSPIKE_WL=0.001, SPF_HELO_NONE=0.001, SPF_PASS=-0.001, T_SCC_BODY_TEXT_LINE=-0.01 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" This replaces the old dump_syscall qemu_log print with a tracepoint. One immediate effect of this is that we can now avoid flooding the console with syscall prints when debugging. Signed-off-by: Fabiano Rosas --- target/ppc/excp_helper.c | 53 ++++++---------------------------------- target/ppc/trace-events | 2 ++ target/ppc/trace.h | 18 ++++++++++++++ 3 files changed, 27 insertions(+), 46 deletions(-) diff --git a/target/ppc/excp_helper.c b/target/ppc/excp_helper.c index d3e2cfcd71..dd1e9c20b9 100644 --- a/target/ppc/excp_helper.c +++ b/target/ppc/excp_helper.c @@ -105,33 +105,6 @@ static const char *powerpc_excp_name(int excp) } } -static 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 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 void ppc_excp_debug_sw_tlb(CPUPPCState *env, int excp) { const char *es; @@ -502,7 +475,7 @@ static void powerpc_excp_40x(PowerPCCPU *cpu, int excp) } break; case POWERPC_EXCP_SYSCALL: /* System call exception */ - dump_syscall(env); + trace_ppc_syscall(env, 0); /* * We need to correct the NIP which in this case is supposed @@ -646,7 +619,7 @@ static void powerpc_excp_6xx(PowerPCCPU *cpu, int excp) } break; case POWERPC_EXCP_SYSCALL: /* System call exception */ - dump_syscall(env); + trace_ppc_syscall(env, 0); /* * We need to correct the NIP which in this case is supposed @@ -822,11 +795,7 @@ static void powerpc_excp_7xx(PowerPCCPU *cpu, int excp) { int lev = env->error_code; - if (lev == 1 && cpu->vhyp) { - dump_hcall(env); - } else { - dump_syscall(env); - } + trace_ppc_syscall(env, lev); /* * We need to correct the NIP which in this case is supposed @@ -1007,11 +976,7 @@ static void powerpc_excp_74xx(PowerPCCPU *cpu, int excp) { int lev = env->error_code; - if ((lev == 1) && cpu->vhyp) { - dump_hcall(env); - } else { - dump_syscall(env); - } + trace_ppc_syscall(env, lev); /* * We need to correct the NIP which in this case is supposed @@ -1206,7 +1171,7 @@ static void powerpc_excp_booke(PowerPCCPU *cpu, int excp) } break; case POWERPC_EXCP_SYSCALL: /* System call exception */ - dump_syscall(env); + trace_ppc_syscall(env, 0); /* * We need to correct the NIP which in this case is supposed @@ -1467,11 +1432,7 @@ static void powerpc_excp_books(PowerPCCPU *cpu, int excp) case POWERPC_EXCP_SYSCALL: /* System call exception */ lev = env->error_code; - if ((lev == 1) && cpu->vhyp) { - dump_hcall(env); - } else { - dump_syscall(env); - } + trace_ppc_syscall(env, lev); /* * We need to correct the NIP which in this case is supposed @@ -1492,7 +1453,7 @@ static void powerpc_excp_books(PowerPCCPU *cpu, int excp) break; case POWERPC_EXCP_SYSCALL_VECTORED: /* scv exception */ lev = env->error_code; - dump_syscall(env); + trace_ppc_syscall(env, 0); env->nip += 4; new_msr |= env->msr & ((target_ulong)1 << MSR_EE); new_msr |= env->msr & ((target_ulong)1 << MSR_RI); diff --git a/target/ppc/trace-events b/target/ppc/trace-events index 53b107f56e..0f6af7d73f 100644 --- a/target/ppc/trace-events +++ b/target/ppc/trace-events @@ -36,3 +36,5 @@ ppc_excp_isi(uint64_t msr, uint64_t nip) "ISI exception: msr=0x%016" PRIx64 " ni ppc_excp_fp_ignore(void) "Ignore floating point exception" ppc_excp_inval(uint64_t nip) "Invalid instruction at 0x%" PRIx64 ppc_excp_print(const char *excp) "%s exception" +ppc_excp_syscall(unsigned long r0, unsigned long r3, unsigned long r4, unsigned long r5, unsigned long r6, unsigned long r7, unsigned long r8, unsigned long nip) "r0=0x%016" PRIx64 " r3=0x%016" PRIx64 " r4=0x%016" PRIx64 " r5=0x%016" PRIx64 " r6=0x%016" PRIx64 " r7=0x%016" PRIx64 " r8=0x%016" PRIx64 " nip=0x%" PRIx64 +ppc_excp_hypercall(unsigned long r3, unsigned long r4, unsigned long r5, unsigned long r6, unsigned long r7, unsigned long r8, unsigned long r9, unsigned long r10, unsigned long nip) "r3=0x%016" PRIx64 " r4=0x%016" PRIx64 " r5=0x%016" PRIx64 " r6=0x%016" PRIx64 " r7=0x%016" PRIx64 " r8=0x%016" PRIx64 " r9=0x%016" PRIx64 " r10=0x%016" PRIx64 " nip=0x%" PRIx64 diff --git a/target/ppc/trace.h b/target/ppc/trace.h index a9e8962828..49adcfc1e6 100644 --- a/target/ppc/trace.h +++ b/target/ppc/trace.h @@ -1 +1,19 @@ #include "trace/trace-target_ppc.h" + +static inline void trace_ppc_syscall(CPUPPCState *env, int lev) +{ + PowerPCCPU *cpu = env_archcpu(env); + + if (lev == 1 && cpu->vhyp) { + trace_ppc_excp_hypercall(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), + env->nip); + } else { + trace_ppc_excp_syscall(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); + } +} From patchwork Tue Mar 1 13:56:05 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Fabiano Rosas X-Patchwork-Id: 12764760 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 EC2E2C433F5 for ; Tue, 1 Mar 2022 14:13:49 +0000 (UTC) Received: from localhost ([::1]:55388 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1nP3G9-0006Db-5I for qemu-devel@archiver.kernel.org; Tue, 01 Mar 2022 09:13:49 -0500 Received: from eggs.gnu.org ([209.51.188.92]:34930) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1nP34k-0005at-V4; Tue, 01 Mar 2022 09:02:02 -0500 Received: from mx0b-001b2d01.pphosted.com ([148.163.158.5]:38130 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 1nP34V-0003LF-Mr; Tue, 01 Mar 2022 09:02:02 -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 221DDY2O013733; Tue, 1 Mar 2022 13:56: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=GsosNbU5secFvhVxCQaLMNtcNCZ6t8n3RbMzBe3Yp0A=; b=dfLtINwJtbLs1ee7rfgUyEiVMTZcDo7RomquWD3RCnrTBi4uyl5RadPYdvD0tvFJpE8p zbYSKwtlygv/n493EpgIo1TguI9XOQw+cmJgUTHstI5FowQiAYT8SjbpFvcJE7EMnsTZ rocJ9ZkVnq3yCNWVhdTb0BXQKeCUhE6lYaP237pAcLhfakfZF+9kzotJD1wLfyaYOD3z WRQhuzZIUfJrXMcph6dGjAbtynWrX8gIqD3PqGoWNF7pa9hYYR6kiKsdVD0T+kepG+Ok I3GA6jWHuc7EtrF+ATGOowihajrqE5WF8h34KpRETFOPsnbntPZLP2niDJss9y0hp41A 0g== Received: from pps.reinject (localhost [127.0.0.1]) by mx0b-001b2d01.pphosted.com with ESMTP id 3ehm6e0xkg-1 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NOT); Tue, 01 Mar 2022 13:56: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 221Ds6PX022837; Tue, 1 Mar 2022 13:56:33 GMT Received: from ppma03wdc.us.ibm.com (ba.79.3fa9.ip4.static.sl-reverse.com [169.63.121.186]) by mx0b-001b2d01.pphosted.com with ESMTP id 3ehm6e0xk2-1 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NOT); Tue, 01 Mar 2022 13:56:32 +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 221DtZmF030911; Tue, 1 Mar 2022 13:56:32 GMT Received: from b03cxnp07028.gho.boulder.ibm.com (b03cxnp07028.gho.boulder.ibm.com [9.17.130.15]) by ppma03wdc.us.ibm.com with ESMTP id 3efbu9w11e-1 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NOT); Tue, 01 Mar 2022 13:56:32 +0000 Received: from b03ledav005.gho.boulder.ibm.com (b03ledav005.gho.boulder.ibm.com [9.17.130.236]) by b03cxnp07028.gho.boulder.ibm.com (8.14.9/8.14.9/NCO v10.0) with ESMTP id 221DuVlf20906430 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-GCM-SHA384 bits=256 verify=OK); Tue, 1 Mar 2022 13:56:31 GMT Received: from b03ledav005.gho.boulder.ibm.com (unknown [127.0.0.1]) by IMSVA (Postfix) with ESMTP id 4C7EDBE056; Tue, 1 Mar 2022 13:56:31 +0000 (GMT) Received: from b03ledav005.gho.boulder.ibm.com (unknown [127.0.0.1]) by IMSVA (Postfix) with ESMTP id BCDB8BE054; Tue, 1 Mar 2022 13:56:29 +0000 (GMT) Received: from farosas.linux.ibm.com.com (unknown [9.211.51.129]) by b03ledav005.gho.boulder.ibm.com (Postfix) with ESMTP; Tue, 1 Mar 2022 13:56:29 +0000 (GMT) From: Fabiano Rosas To: qemu-devel@nongnu.org Subject: [PATCH 02/17] target/ppc: Use trace-events instead of CPU_LOG_INT Date: Tue, 1 Mar 2022 10:56:05 -0300 Message-Id: <20220301135620.2411952-3-farosas@linux.ibm.com> X-Mailer: git-send-email 2.34.1 In-Reply-To: <20220301135620.2411952-1-farosas@linux.ibm.com> References: <20220301135620.2411952-1-farosas@linux.ibm.com> MIME-Version: 1.0 X-TM-AS-GCONF: 00 X-Proofpoint-GUID: gB4Z8_QYEv6xWgFV7Df6meTspYx4lRum X-Proofpoint-ORIG-GUID: U11q_SkeqVozh-uEzn1LT7yoQJKe9YZt X-Proofpoint-Virus-Version: vendor=baseguard engine=ICAP:2.0.205,Aquarius:18.0.816,Hydra:6.0.425,FMLib:17.11.64.514 definitions=2022-03-01_07,2022-02-26_01,2022-02-23_01 X-Proofpoint-Spam-Details: rule=outbound_notspam policy=outbound score=0 malwarescore=0 spamscore=0 mlxscore=0 lowpriorityscore=0 bulkscore=0 suspectscore=0 adultscore=0 mlxlogscore=942 impostorscore=0 phishscore=0 clxscore=1015 priorityscore=1501 classifier=spam adjust=0 reason=mlx scancount=1 engine=8.12.0-2201110000 definitions=main-2203010074 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, SPF_HELO_NONE=0.001, SPF_PASS=-0.001, T_SCC_BODY_TEXT_LINE=-0.01 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" Part of our exception logging is using qemu_log_mask and part is using trace-events. Move the remaining users of '-d int' to the trace-events infrastructure. Signed-off-by: Fabiano Rosas --- target/ppc/excp_helper.c | 9 ++++++--- target/ppc/misc_helper.c | 4 ++-- target/ppc/trace-events | 2 ++ 3 files changed, 10 insertions(+), 5 deletions(-) diff --git a/target/ppc/excp_helper.c b/target/ppc/excp_helper.c index dd1e9c20b9..2b5b1e00d8 100644 --- a/target/ppc/excp_helper.c +++ b/target/ppc/excp_helper.c @@ -19,6 +19,7 @@ #include "qemu/osdep.h" #include "qemu/main-loop.h" #include "qemu/log.h" +#include "qemu/error-report.h" #include "cpu.h" #include "exec/exec-all.h" #include "internal.h" @@ -1599,9 +1600,11 @@ static void powerpc_excp(PowerPCCPU *cpu, int excp) cpu_abort(cs, "Invalid PowerPC exception %d. Aborting\n", excp); } - qemu_log_mask(CPU_LOG_INT, "Raise exception at " TARGET_FMT_lx - " => %s (%d) error=%02x\n", env->nip, powerpc_excp_name(excp), - excp, env->error_code); + if (qemu_loglevel_mask(CPU_LOG_INT)) { + warn_report_once("use -trace ppc_excp* instead of -d int\n"); + } + + trace_ppc_excp(env->nip, powerpc_excp_name(excp), excp, env->error_code); switch (env->excp_model) { case POWERPC_EXCP_40x: diff --git a/target/ppc/misc_helper.c b/target/ppc/misc_helper.c index 06aa716cab..6bef03b154 100644 --- a/target/ppc/misc_helper.c +++ b/target/ppc/misc_helper.c @@ -27,6 +27,7 @@ #include "mmu-book3s-v3.h" #include "helper_regs.h" +#include "trace.h" /*****************************************************************************/ /* SPR accesses */ @@ -47,8 +48,7 @@ static void raise_hv_fu_exception(CPUPPCState *env, uint32_t bit, const char *caller, uint32_t cause, uintptr_t raddr) { - qemu_log_mask(CPU_LOG_INT, "HV Facility %d is unavailable (%s)\n", - bit, caller); + trace_ppc_excp_hv_fu(bit, caller); env->spr[SPR_HFSCR] &= ~((target_ulong)FSCR_IC_MASK << FSCR_IC_POS); diff --git a/target/ppc/trace-events b/target/ppc/trace-events index 0f6af7d73f..064b8f3e1f 100644 --- a/target/ppc/trace-events +++ b/target/ppc/trace-events @@ -38,3 +38,5 @@ ppc_excp_inval(uint64_t nip) "Invalid instruction at 0x%" PRIx64 ppc_excp_print(const char *excp) "%s exception" ppc_excp_syscall(unsigned long r0, unsigned long r3, unsigned long r4, unsigned long r5, unsigned long r6, unsigned long r7, unsigned long r8, unsigned long nip) "r0=0x%016" PRIx64 " r3=0x%016" PRIx64 " r4=0x%016" PRIx64 " r5=0x%016" PRIx64 " r6=0x%016" PRIx64 " r7=0x%016" PRIx64 " r8=0x%016" PRIx64 " nip=0x%" PRIx64 ppc_excp_hypercall(unsigned long r3, unsigned long r4, unsigned long r5, unsigned long r6, unsigned long r7, unsigned long r8, unsigned long r9, unsigned long r10, unsigned long nip) "r3=0x%016" PRIx64 " r4=0x%016" PRIx64 " r5=0x%016" PRIx64 " r6=0x%016" PRIx64 " r7=0x%016" PRIx64 " r8=0x%016" PRIx64 " r9=0x%016" PRIx64 " r10=0x%016" PRIx64 " nip=0x%" PRIx64 +ppc_excp_hv_fu(uint32_t bit, const char* caller) "HV Facility 0x%x is unavailable (%s)" +ppc_excp(unsigned long nip, const char* name, int excp, uint32_t flags) "Raise exception at 0x%" PRIx64 " => %s (%d) error=0x%02x" From patchwork Tue Mar 1 13:56:06 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Fabiano Rosas X-Patchwork-Id: 12764746 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 A428DC433F5 for ; Tue, 1 Mar 2022 13:59:11 +0000 (UTC) Received: from localhost ([::1]:50868 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1nP31y-00009z-K7 for qemu-devel@archiver.kernel.org; Tue, 01 Mar 2022 08:59:10 -0500 Received: from eggs.gnu.org ([209.51.188.92]:33262) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1nP2ze-0005hN-6J; Tue, 01 Mar 2022 08:56:46 -0500 Received: from mx0a-001b2d01.pphosted.com ([148.163.156.1]:13690) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1nP2zb-00022f-LX; Tue, 01 Mar 2022 08:56:45 -0500 Received: from pps.filterd (m0098404.ppops.net [127.0.0.1]) by mx0a-001b2d01.pphosted.com (8.16.1.2/8.16.1.2) with SMTP id 221Dcr8Y023287; Tue, 1 Mar 2022 13:56:36 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=UL/IM1fcO/c/oBJg7e1eLCuqz9WMe3D6d9xZ6lGlDws=; b=o0ludDnr5GldB0aD6xTKC0NdjWab+kTPUS1uxwhk3l27LjOw4o6X8Zx5FJhmtspnrqeC Ya1kCxMtJImZiEdiUzKOeRsarpzPAf43Xskk2o5/NcbmBUgd7SYbcpCzCHlNgiEIPDcf 2KFxWwyE81XLUVXnMssjmNzxFZYWF+2jogbt7yfBV8IDxq01bzRXf7bDwOYOfnZ61UUn X1FwIJ5atEWcHBKT7aBsg0wBC9XjkanfBr0i9teZFXNyi5LYurJTaS4H15cNnlIZVENj zy8xXD0QmwG2SDaN43CwdanMcbSNpmbzF4lR/8wF5O1S/3cJocZR/6WKUm60e4ZXJpog YA== Received: from pps.reinject (localhost [127.0.0.1]) by mx0a-001b2d01.pphosted.com with ESMTP id 3ehkqe1k7t-1 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NOT); Tue, 01 Mar 2022 13:56:36 +0000 Received: from m0098404.ppops.net (m0098404.ppops.net [127.0.0.1]) by pps.reinject (8.16.0.43/8.16.0.43) with SMTP id 221Ddd4T026392; Tue, 1 Mar 2022 13:56:36 GMT Received: from ppma04wdc.us.ibm.com (1a.90.2fa9.ip4.static.sl-reverse.com [169.47.144.26]) by mx0a-001b2d01.pphosted.com with ESMTP id 3ehkqe1k77-1 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NOT); Tue, 01 Mar 2022 13:56:35 +0000 Received: from pps.filterd (ppma04wdc.us.ibm.com [127.0.0.1]) by ppma04wdc.us.ibm.com (8.16.1.2/8.16.1.2) with SMTP id 221DtrLD002511; Tue, 1 Mar 2022 13:56:34 GMT Received: from b03cxnp08028.gho.boulder.ibm.com (b03cxnp08028.gho.boulder.ibm.com [9.17.130.20]) by ppma04wdc.us.ibm.com with ESMTP id 3eftrreupv-1 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NOT); Tue, 01 Mar 2022 13:56:34 +0000 Received: from b03ledav005.gho.boulder.ibm.com (b03ledav005.gho.boulder.ibm.com [9.17.130.236]) by b03cxnp08028.gho.boulder.ibm.com (8.14.9/8.14.9/NCO v10.0) with ESMTP id 221DuXlw39584080 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-GCM-SHA384 bits=256 verify=OK); Tue, 1 Mar 2022 13:56:33 GMT Received: from b03ledav005.gho.boulder.ibm.com (unknown [127.0.0.1]) by IMSVA (Postfix) with ESMTP id 8467ABE056; Tue, 1 Mar 2022 13:56:33 +0000 (GMT) Received: from b03ledav005.gho.boulder.ibm.com (unknown [127.0.0.1]) by IMSVA (Postfix) with ESMTP id AF73DBE053; Tue, 1 Mar 2022 13:56:31 +0000 (GMT) Received: from farosas.linux.ibm.com.com (unknown [9.211.51.129]) by b03ledav005.gho.boulder.ibm.com (Postfix) with ESMTP; Tue, 1 Mar 2022 13:56:31 +0000 (GMT) From: Fabiano Rosas To: qemu-devel@nongnu.org Subject: [PATCH 03/17] target/ppc: Move 40x CPUs code to their own file Date: Tue, 1 Mar 2022 10:56:06 -0300 Message-Id: <20220301135620.2411952-4-farosas@linux.ibm.com> X-Mailer: git-send-email 2.34.1 In-Reply-To: <20220301135620.2411952-1-farosas@linux.ibm.com> References: <20220301135620.2411952-1-farosas@linux.ibm.com> MIME-Version: 1.0 X-TM-AS-GCONF: 00 X-Proofpoint-GUID: K3H32e7yF_5Mz2LIQ88Jh4-G1FjRjx8B X-Proofpoint-ORIG-GUID: -JGTs2BHpVcNjW70ycdqACopz3BkVoDP X-Proofpoint-Virus-Version: vendor=baseguard engine=ICAP:2.0.205,Aquarius:18.0.816,Hydra:6.0.425,FMLib:17.11.64.514 definitions=2022-03-01_07,2022-02-26_01,2022-02-23_01 X-Proofpoint-Spam-Details: rule=outbound_notspam policy=outbound score=0 bulkscore=0 clxscore=1015 suspectscore=0 impostorscore=0 mlxscore=0 lowpriorityscore=0 malwarescore=0 spamscore=0 mlxlogscore=999 phishscore=0 adultscore=0 priorityscore=1501 classifier=spam adjust=0 reason=mlx scancount=1 engine=8.12.0-2201110000 definitions=main-2203010074 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_H5=0.001, RCVD_IN_MSPIKE_WL=0.001, SPF_HELO_NONE=0.001, SPF_PASS=-0.001, T_SCC_BODY_TEXT_LINE=-0.01 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" Affects the 405 CPU. This moves init_proc, init_excp and register_*sprs functions that are related to the 40x CPUs (currently only 405) into a separate file. Signed-off-by: Fabiano Rosas --- target/ppc/cpu_40x.c | 263 +++++++++++++++++++++++++++++++++++++++++ target/ppc/cpu_init.c | 250 --------------------------------------- target/ppc/meson.build | 1 + 3 files changed, 264 insertions(+), 250 deletions(-) create mode 100644 target/ppc/cpu_40x.c diff --git a/target/ppc/cpu_40x.c b/target/ppc/cpu_40x.c new file mode 100644 index 0000000000..4ed2cbc305 --- /dev/null +++ b/target/ppc/cpu_40x.c @@ -0,0 +1,263 @@ +/* + * CPU initialization for PowerPC 40x CPUs + * + * Copyright IBM Corp. 2022 + * + * This work is licensed under the terms of the GNU GPL, version 2 or later. + * See the COPYING file in the top-level directory. + */ + +#include "qemu/osdep.h" +#include "hw/ppc/ppc.h" +#include "cpu.h" +#include "spr_common.h" + +/* SPR shared between PowerPC 40x implementations */ +static void register_40x_sprs(CPUPPCState *env) +{ + /* Cache */ + /* not emulated, as QEMU do not emulate caches */ + spr_register(env, SPR_40x_DCCR, "DCCR", + SPR_NOACCESS, SPR_NOACCESS, + &spr_read_generic, &spr_write_generic, + 0x00000000); + /* not emulated, as QEMU do not emulate caches */ + spr_register(env, SPR_40x_ICCR, "ICCR", + SPR_NOACCESS, SPR_NOACCESS, + &spr_read_generic, &spr_write_generic, + 0x00000000); + /* not emulated, as QEMU do not emulate caches */ + spr_register(env, SPR_BOOKE_ICDBDR, "ICDBDR", + SPR_NOACCESS, SPR_NOACCESS, + &spr_read_generic, SPR_NOACCESS, + 0x00000000); + /* Exception */ + spr_register(env, SPR_40x_DEAR, "DEAR", + SPR_NOACCESS, SPR_NOACCESS, + &spr_read_generic, &spr_write_generic, + 0x00000000); + spr_register(env, SPR_40x_ESR, "ESR", + SPR_NOACCESS, SPR_NOACCESS, + &spr_read_generic, &spr_write_generic, + 0x00000000); + spr_register(env, SPR_40x_EVPR, "EVPR", + SPR_NOACCESS, SPR_NOACCESS, + &spr_read_generic, &spr_write_excp_prefix, + 0x00000000); + spr_register(env, SPR_40x_SRR2, "SRR2", + &spr_read_generic, &spr_write_generic, + &spr_read_generic, &spr_write_generic, + 0x00000000); + spr_register(env, SPR_40x_SRR3, "SRR3", + &spr_read_generic, &spr_write_generic, + &spr_read_generic, &spr_write_generic, + 0x00000000); + /* Timers */ + spr_register(env, SPR_40x_PIT, "PIT", + SPR_NOACCESS, SPR_NOACCESS, + &spr_read_40x_pit, &spr_write_40x_pit, + 0x00000000); + spr_register(env, SPR_40x_TCR, "TCR", + SPR_NOACCESS, SPR_NOACCESS, + &spr_read_generic, &spr_write_40x_tcr, + 0x00000000); + spr_register(env, SPR_40x_TSR, "TSR", + SPR_NOACCESS, SPR_NOACCESS, + &spr_read_generic, &spr_write_40x_tsr, + 0x00000000); +} + +/* SPR specific to PowerPC 405 implementation */ +static void register_405_sprs(CPUPPCState *env) +{ + /* MMU */ + spr_register(env, SPR_40x_PID, "PID", + SPR_NOACCESS, SPR_NOACCESS, + &spr_read_generic, &spr_write_40x_pid, + 0x00000000); + spr_register(env, SPR_4xx_CCR0, "CCR0", + SPR_NOACCESS, SPR_NOACCESS, + &spr_read_generic, &spr_write_generic, + 0x00700000); + /* Debug interface */ + spr_register(env, SPR_40x_DBCR0, "DBCR0", + SPR_NOACCESS, SPR_NOACCESS, + &spr_read_generic, &spr_write_40x_dbcr0, + 0x00000000); + + spr_register(env, SPR_405_DBCR1, "DBCR1", + SPR_NOACCESS, SPR_NOACCESS, + &spr_read_generic, &spr_write_generic, + 0x00000000); + + spr_register(env, SPR_40x_DBSR, "DBSR", + SPR_NOACCESS, SPR_NOACCESS, + &spr_read_generic, &spr_write_clear, + /* Last reset was system reset */ + 0x00000300); + + spr_register(env, SPR_40x_DAC1, "DAC1", + SPR_NOACCESS, SPR_NOACCESS, + &spr_read_generic, &spr_write_generic, + 0x00000000); + spr_register(env, SPR_40x_DAC2, "DAC2", + SPR_NOACCESS, SPR_NOACCESS, + &spr_read_generic, &spr_write_generic, + 0x00000000); + + spr_register(env, SPR_405_DVC1, "DVC1", + SPR_NOACCESS, SPR_NOACCESS, + &spr_read_generic, &spr_write_generic, + 0x00000000); + + spr_register(env, SPR_405_DVC2, "DVC2", + SPR_NOACCESS, SPR_NOACCESS, + &spr_read_generic, &spr_write_generic, + 0x00000000); + + spr_register(env, SPR_40x_IAC1, "IAC1", + SPR_NOACCESS, SPR_NOACCESS, + &spr_read_generic, &spr_write_generic, + 0x00000000); + spr_register(env, SPR_40x_IAC2, "IAC2", + SPR_NOACCESS, SPR_NOACCESS, + &spr_read_generic, &spr_write_generic, + 0x00000000); + + spr_register(env, SPR_405_IAC3, "IAC3", + SPR_NOACCESS, SPR_NOACCESS, + &spr_read_generic, &spr_write_generic, + 0x00000000); + + spr_register(env, SPR_405_IAC4, "IAC4", + SPR_NOACCESS, SPR_NOACCESS, + &spr_read_generic, &spr_write_generic, + 0x00000000); + /* Storage control */ + spr_register(env, SPR_405_SLER, "SLER", + SPR_NOACCESS, SPR_NOACCESS, + &spr_read_generic, &spr_write_40x_sler, + 0x00000000); + spr_register(env, SPR_40x_ZPR, "ZPR", + SPR_NOACCESS, SPR_NOACCESS, + &spr_read_generic, &spr_write_generic, + 0x00000000); + + spr_register(env, SPR_405_SU0R, "SU0R", + SPR_NOACCESS, SPR_NOACCESS, + &spr_read_generic, &spr_write_generic, + 0x00000000); + /* SPRG */ + spr_register(env, SPR_USPRG0, "USPRG0", + &spr_read_ureg, SPR_NOACCESS, + &spr_read_ureg, SPR_NOACCESS, + 0x00000000); + spr_register(env, SPR_SPRG4, "SPRG4", + SPR_NOACCESS, SPR_NOACCESS, + &spr_read_generic, &spr_write_generic, + 0x00000000); + spr_register(env, SPR_SPRG5, "SPRG5", + SPR_NOACCESS, SPR_NOACCESS, + spr_read_generic, &spr_write_generic, + 0x00000000); + spr_register(env, SPR_SPRG6, "SPRG6", + SPR_NOACCESS, SPR_NOACCESS, + spr_read_generic, &spr_write_generic, + 0x00000000); + spr_register(env, SPR_SPRG7, "SPRG7", + SPR_NOACCESS, SPR_NOACCESS, + spr_read_generic, &spr_write_generic, + 0x00000000); + + /* Bus access control */ + /* not emulated, as QEMU never does speculative access */ + spr_register(env, SPR_40x_SGR, "SGR", + SPR_NOACCESS, SPR_NOACCESS, + &spr_read_generic, &spr_write_generic, + 0xFFFFFFFF); + /* not emulated, as QEMU do not emulate caches */ + spr_register(env, SPR_40x_DCWR, "DCWR", + SPR_NOACCESS, SPR_NOACCESS, + &spr_read_generic, &spr_write_generic, + 0x00000000); +} + +static void init_excp_4xx_softmmu(CPUPPCState *env) +{ +#if !defined(CONFIG_USER_ONLY) + env->excp_vectors[POWERPC_EXCP_CRITICAL] = 0x00000100; + env->excp_vectors[POWERPC_EXCP_MCHECK] = 0x00000200; + env->excp_vectors[POWERPC_EXCP_DSI] = 0x00000300; + env->excp_vectors[POWERPC_EXCP_ISI] = 0x00000400; + env->excp_vectors[POWERPC_EXCP_EXTERNAL] = 0x00000500; + env->excp_vectors[POWERPC_EXCP_ALIGN] = 0x00000600; + env->excp_vectors[POWERPC_EXCP_PROGRAM] = 0x00000700; + env->excp_vectors[POWERPC_EXCP_SYSCALL] = 0x00000C00; + env->excp_vectors[POWERPC_EXCP_PIT] = 0x00001000; + env->excp_vectors[POWERPC_EXCP_FIT] = 0x00001010; + env->excp_vectors[POWERPC_EXCP_WDT] = 0x00001020; + env->excp_vectors[POWERPC_EXCP_DTLB] = 0x00001100; + env->excp_vectors[POWERPC_EXCP_ITLB] = 0x00001200; + env->excp_vectors[POWERPC_EXCP_DEBUG] = 0x00002000; + env->ivor_mask = 0x0000FFF0UL; + env->ivpr_mask = 0xFFFF0000UL; + /* Hardware reset vector */ + env->hreset_vector = 0xFFFFFFFCUL; +#endif +} + +static void init_proc_405(CPUPPCState *env) +{ + register_40x_sprs(env); + register_405_sprs(env); + register_usprgh_sprs(env); + + /* Memory management */ +#if !defined(CONFIG_USER_ONLY) + env->nb_tlb = 64; + env->nb_ways = 1; + env->id_tlbs = 0; + env->tlb_type = TLB_EMB; +#endif + init_excp_4xx_softmmu(env); + env->dcache_line_size = 32; + env->icache_line_size = 32; + /* Allocate hardware IRQ controller */ + ppc40x_irq_init(env_archcpu(env)); + + SET_FIT_PERIOD(8, 12, 16, 20); + SET_WDT_PERIOD(16, 20, 24, 28); +} + +POWERPC_FAMILY(405)(ObjectClass *oc, void *data) +{ + DeviceClass *dc = DEVICE_CLASS(oc); + PowerPCCPUClass *pcc = POWERPC_CPU_CLASS(oc); + + dc->desc = "PowerPC 405"; + pcc->init_proc = init_proc_405; + pcc->check_pow = check_pow_nocheck; + pcc->insns_flags = PPC_INSNS_BASE | PPC_STRING | PPC_MFTB | + PPC_DCR | PPC_WRTEE | + PPC_CACHE | PPC_CACHE_ICBI | PPC_40x_ICBT | + PPC_CACHE_DCBZ | PPC_CACHE_DCBA | + PPC_MEM_SYNC | PPC_MEM_EIEIO | + PPC_40x_TLB | PPC_MEM_TLBIA | PPC_MEM_TLBSYNC | + PPC_4xx_COMMON | PPC_405_MAC | PPC_40x_EXCP; + pcc->msr_mask = (1ull << MSR_WE) | + (1ull << MSR_CE) | + (1ull << MSR_EE) | + (1ull << MSR_PR) | + (1ull << MSR_FP) | + (1ull << MSR_ME) | + (1ull << MSR_DWE) | + (1ull << MSR_DE) | + (1ull << MSR_IR) | + (1ull << MSR_DR); + pcc->mmu_model = POWERPC_MMU_SOFT_4xx; + pcc->excp_model = POWERPC_EXCP_40x; + pcc->bus_model = PPC_FLAGS_INPUT_405; + pcc->bfd_mach = bfd_mach_ppc_403; + pcc->flags = POWERPC_FLAG_CE | POWERPC_FLAG_DWE | + POWERPC_FLAG_DE | POWERPC_FLAG_BUS_CLK; +} diff --git a/target/ppc/cpu_init.c b/target/ppc/cpu_init.c index 073fd10168..28c017b048 100644 --- a/target/ppc/cpu_init.c +++ b/target/ppc/cpu_init.c @@ -1081,177 +1081,6 @@ static void register_440_sprs(CPUPPCState *env) 0x00000000); } -/* SPR shared between PowerPC 40x implementations */ -static void register_40x_sprs(CPUPPCState *env) -{ - /* Cache */ - /* not emulated, as QEMU do not emulate caches */ - spr_register(env, SPR_40x_DCCR, "DCCR", - SPR_NOACCESS, SPR_NOACCESS, - &spr_read_generic, &spr_write_generic, - 0x00000000); - /* not emulated, as QEMU do not emulate caches */ - spr_register(env, SPR_40x_ICCR, "ICCR", - SPR_NOACCESS, SPR_NOACCESS, - &spr_read_generic, &spr_write_generic, - 0x00000000); - /* not emulated, as QEMU do not emulate caches */ - spr_register(env, SPR_BOOKE_ICDBDR, "ICDBDR", - SPR_NOACCESS, SPR_NOACCESS, - &spr_read_generic, SPR_NOACCESS, - 0x00000000); - /* Exception */ - spr_register(env, SPR_40x_DEAR, "DEAR", - SPR_NOACCESS, SPR_NOACCESS, - &spr_read_generic, &spr_write_generic, - 0x00000000); - spr_register(env, SPR_40x_ESR, "ESR", - SPR_NOACCESS, SPR_NOACCESS, - &spr_read_generic, &spr_write_generic, - 0x00000000); - spr_register(env, SPR_40x_EVPR, "EVPR", - SPR_NOACCESS, SPR_NOACCESS, - &spr_read_generic, &spr_write_excp_prefix, - 0x00000000); - spr_register(env, SPR_40x_SRR2, "SRR2", - &spr_read_generic, &spr_write_generic, - &spr_read_generic, &spr_write_generic, - 0x00000000); - spr_register(env, SPR_40x_SRR3, "SRR3", - &spr_read_generic, &spr_write_generic, - &spr_read_generic, &spr_write_generic, - 0x00000000); - /* Timers */ - spr_register(env, SPR_40x_PIT, "PIT", - SPR_NOACCESS, SPR_NOACCESS, - &spr_read_40x_pit, &spr_write_40x_pit, - 0x00000000); - spr_register(env, SPR_40x_TCR, "TCR", - SPR_NOACCESS, SPR_NOACCESS, - &spr_read_generic, &spr_write_40x_tcr, - 0x00000000); - spr_register(env, SPR_40x_TSR, "TSR", - SPR_NOACCESS, SPR_NOACCESS, - &spr_read_generic, &spr_write_40x_tsr, - 0x00000000); -} - -/* SPR specific to PowerPC 405 implementation */ -static void register_405_sprs(CPUPPCState *env) -{ - /* MMU */ - spr_register(env, SPR_40x_PID, "PID", - SPR_NOACCESS, SPR_NOACCESS, - &spr_read_generic, &spr_write_40x_pid, - 0x00000000); - spr_register(env, SPR_4xx_CCR0, "CCR0", - SPR_NOACCESS, SPR_NOACCESS, - &spr_read_generic, &spr_write_generic, - 0x00700000); - /* Debug interface */ - spr_register(env, SPR_40x_DBCR0, "DBCR0", - SPR_NOACCESS, SPR_NOACCESS, - &spr_read_generic, &spr_write_40x_dbcr0, - 0x00000000); - - spr_register(env, SPR_405_DBCR1, "DBCR1", - SPR_NOACCESS, SPR_NOACCESS, - &spr_read_generic, &spr_write_generic, - 0x00000000); - - spr_register(env, SPR_40x_DBSR, "DBSR", - SPR_NOACCESS, SPR_NOACCESS, - &spr_read_generic, &spr_write_clear, - /* Last reset was system reset */ - 0x00000300); - - spr_register(env, SPR_40x_DAC1, "DAC1", - SPR_NOACCESS, SPR_NOACCESS, - &spr_read_generic, &spr_write_generic, - 0x00000000); - spr_register(env, SPR_40x_DAC2, "DAC2", - SPR_NOACCESS, SPR_NOACCESS, - &spr_read_generic, &spr_write_generic, - 0x00000000); - - spr_register(env, SPR_405_DVC1, "DVC1", - SPR_NOACCESS, SPR_NOACCESS, - &spr_read_generic, &spr_write_generic, - 0x00000000); - - spr_register(env, SPR_405_DVC2, "DVC2", - SPR_NOACCESS, SPR_NOACCESS, - &spr_read_generic, &spr_write_generic, - 0x00000000); - - spr_register(env, SPR_40x_IAC1, "IAC1", - SPR_NOACCESS, SPR_NOACCESS, - &spr_read_generic, &spr_write_generic, - 0x00000000); - spr_register(env, SPR_40x_IAC2, "IAC2", - SPR_NOACCESS, SPR_NOACCESS, - &spr_read_generic, &spr_write_generic, - 0x00000000); - - spr_register(env, SPR_405_IAC3, "IAC3", - SPR_NOACCESS, SPR_NOACCESS, - &spr_read_generic, &spr_write_generic, - 0x00000000); - - spr_register(env, SPR_405_IAC4, "IAC4", - SPR_NOACCESS, SPR_NOACCESS, - &spr_read_generic, &spr_write_generic, - 0x00000000); - /* Storage control */ - spr_register(env, SPR_405_SLER, "SLER", - SPR_NOACCESS, SPR_NOACCESS, - &spr_read_generic, &spr_write_40x_sler, - 0x00000000); - spr_register(env, SPR_40x_ZPR, "ZPR", - SPR_NOACCESS, SPR_NOACCESS, - &spr_read_generic, &spr_write_generic, - 0x00000000); - - spr_register(env, SPR_405_SU0R, "SU0R", - SPR_NOACCESS, SPR_NOACCESS, - &spr_read_generic, &spr_write_generic, - 0x00000000); - /* SPRG */ - spr_register(env, SPR_USPRG0, "USPRG0", - &spr_read_ureg, SPR_NOACCESS, - &spr_read_ureg, SPR_NOACCESS, - 0x00000000); - spr_register(env, SPR_SPRG4, "SPRG4", - SPR_NOACCESS, SPR_NOACCESS, - &spr_read_generic, &spr_write_generic, - 0x00000000); - spr_register(env, SPR_SPRG5, "SPRG5", - SPR_NOACCESS, SPR_NOACCESS, - spr_read_generic, &spr_write_generic, - 0x00000000); - spr_register(env, SPR_SPRG6, "SPRG6", - SPR_NOACCESS, SPR_NOACCESS, - spr_read_generic, &spr_write_generic, - 0x00000000); - spr_register(env, SPR_SPRG7, "SPRG7", - SPR_NOACCESS, SPR_NOACCESS, - spr_read_generic, &spr_write_generic, - 0x00000000); - - /* Bus access control */ - /* not emulated, as QEMU never does speculative access */ - spr_register(env, SPR_40x_SGR, "SGR", - SPR_NOACCESS, SPR_NOACCESS, - &spr_read_generic, &spr_write_generic, - 0xFFFFFFFF); - /* not emulated, as QEMU do not emulate caches */ - spr_register(env, SPR_40x_DCWR, "DCWR", - SPR_NOACCESS, SPR_NOACCESS, - &spr_read_generic, &spr_write_generic, - 0x00000000); -} - - static void register_5xx_8xx_sprs(CPUPPCState *env) { /* Exception processing */ @@ -1637,29 +1466,6 @@ static void register_8xx_sprs(CPUPPCState *env) /*****************************************************************************/ /* Exception vectors models */ -static void init_excp_4xx_softmmu(CPUPPCState *env) -{ -#if !defined(CONFIG_USER_ONLY) - env->excp_vectors[POWERPC_EXCP_CRITICAL] = 0x00000100; - env->excp_vectors[POWERPC_EXCP_MCHECK] = 0x00000200; - env->excp_vectors[POWERPC_EXCP_DSI] = 0x00000300; - env->excp_vectors[POWERPC_EXCP_ISI] = 0x00000400; - env->excp_vectors[POWERPC_EXCP_EXTERNAL] = 0x00000500; - env->excp_vectors[POWERPC_EXCP_ALIGN] = 0x00000600; - env->excp_vectors[POWERPC_EXCP_PROGRAM] = 0x00000700; - env->excp_vectors[POWERPC_EXCP_SYSCALL] = 0x00000C00; - env->excp_vectors[POWERPC_EXCP_PIT] = 0x00001000; - env->excp_vectors[POWERPC_EXCP_FIT] = 0x00001010; - env->excp_vectors[POWERPC_EXCP_WDT] = 0x00001020; - env->excp_vectors[POWERPC_EXCP_DTLB] = 0x00001100; - env->excp_vectors[POWERPC_EXCP_ITLB] = 0x00001200; - env->excp_vectors[POWERPC_EXCP_DEBUG] = 0x00002000; - env->ivor_mask = 0x0000FFF0UL; - env->ivpr_mask = 0xFFFF0000UL; - /* Hardware reset vector */ - env->hreset_vector = 0xFFFFFFFCUL; -#endif -} static void init_excp_MPC5xx(CPUPPCState *env) { @@ -2102,62 +1908,6 @@ static int check_pow_hid0_74xx(CPUPPCState *env) return 0; } -static void init_proc_405(CPUPPCState *env) -{ - register_40x_sprs(env); - register_405_sprs(env); - register_usprgh_sprs(env); - - /* Memory management */ -#if !defined(CONFIG_USER_ONLY) - env->nb_tlb = 64; - env->nb_ways = 1; - env->id_tlbs = 0; - env->tlb_type = TLB_EMB; -#endif - init_excp_4xx_softmmu(env); - env->dcache_line_size = 32; - env->icache_line_size = 32; - /* Allocate hardware IRQ controller */ - ppc40x_irq_init(env_archcpu(env)); - - SET_FIT_PERIOD(8, 12, 16, 20); - SET_WDT_PERIOD(16, 20, 24, 28); -} - -POWERPC_FAMILY(405)(ObjectClass *oc, void *data) -{ - DeviceClass *dc = DEVICE_CLASS(oc); - PowerPCCPUClass *pcc = POWERPC_CPU_CLASS(oc); - - dc->desc = "PowerPC 405"; - pcc->init_proc = init_proc_405; - pcc->check_pow = check_pow_nocheck; - pcc->insns_flags = PPC_INSNS_BASE | PPC_STRING | PPC_MFTB | - PPC_DCR | PPC_WRTEE | - PPC_CACHE | PPC_CACHE_ICBI | PPC_40x_ICBT | - PPC_CACHE_DCBZ | PPC_CACHE_DCBA | - PPC_MEM_SYNC | PPC_MEM_EIEIO | - PPC_40x_TLB | PPC_MEM_TLBIA | PPC_MEM_TLBSYNC | - PPC_4xx_COMMON | PPC_405_MAC | PPC_40x_EXCP; - pcc->msr_mask = (1ull << MSR_WE) | - (1ull << MSR_CE) | - (1ull << MSR_EE) | - (1ull << MSR_PR) | - (1ull << MSR_FP) | - (1ull << MSR_ME) | - (1ull << MSR_DWE) | - (1ull << MSR_DE) | - (1ull << MSR_IR) | - (1ull << MSR_DR); - pcc->mmu_model = POWERPC_MMU_SOFT_4xx; - pcc->excp_model = POWERPC_EXCP_40x; - pcc->bus_model = PPC_FLAGS_INPUT_405; - pcc->bfd_mach = bfd_mach_ppc_403; - pcc->flags = POWERPC_FLAG_CE | POWERPC_FLAG_DWE | - POWERPC_FLAG_DE | POWERPC_FLAG_BUS_CLK; -} - static void init_proc_440EP(CPUPPCState *env) { register_BookE_sprs(env, 0x000000000000FFFFULL); diff --git a/target/ppc/meson.build b/target/ppc/meson.build index 79beaff147..45f7802da5 100644 --- a/target/ppc/meson.build +++ b/target/ppc/meson.build @@ -3,6 +3,7 @@ ppc_ss.add(files( 'cpu-models.c', 'cpu.c', 'cpu_init.c', + 'cpu_40x.c', 'excp_helper.c', 'gdbstub.c', 'helper_regs.c', From patchwork Tue Mar 1 13:56:07 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Fabiano Rosas X-Patchwork-Id: 12764751 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 737DAC433F5 for ; Tue, 1 Mar 2022 14:05:51 +0000 (UTC) Received: from localhost ([::1]:35530 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1nP38Q-0000iu-Fv for qemu-devel@archiver.kernel.org; Tue, 01 Mar 2022 09:05:50 -0500 Received: from eggs.gnu.org ([209.51.188.92]:33322) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1nP2zp-00062x-1L; Tue, 01 Mar 2022 08:56:57 -0500 Received: from mx0a-001b2d01.pphosted.com ([148.163.156.1]:2490) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1nP2zk-00024B-Ig; Tue, 01 Mar 2022 08:56:56 -0500 Received: from pps.filterd (m0098399.ppops.net [127.0.0.1]) by mx0a-001b2d01.pphosted.com (8.16.1.2/8.16.1.2) with SMTP id 221Dm0Ma002611; Tue, 1 Mar 2022 13:56:40 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=yfO/43Kx0ET4YFyIzGIJElmtTI1DK9sbtaK6izICAEw=; b=n+tPWKRPXA6ulTORfDhr7CuNEcrhthZXRum/BuaW8VS+gUDZ78hNlp2YuvEHkdY0uvem cOuaRVUIrREoUkkkUUPx8vBLyfi4+ilyaZgpnPECKgwgyWpWCIYIEyhukxiwnYPlwzR4 1/MWXhvuh/VS5k3XBa2/jkqZnJoPLmbFKLNHwqenowZ5RgtLKt8Q70fm5ZCiwtziqu6P 5ClDJ2ajD4rB/GQ0vTqYTLzxMA0EVmzgmblbgP/1YStLF717d6WJqhVPvOVr+9JVQ1LQ p5m+rmLaoCcGgKQbnHHXtHwh4AlFbvw+++Au7y1tevzCwJcD2T7+cyCpIaaVVkngHkgf aA== Received: from pps.reinject (localhost [127.0.0.1]) by mx0a-001b2d01.pphosted.com with ESMTP id 3ehgc6pha7-1 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NOT); Tue, 01 Mar 2022 13:56:39 +0000 Received: from m0098399.ppops.net (m0098399.ppops.net [127.0.0.1]) by pps.reinject (8.16.0.43/8.16.0.43) with SMTP id 221CqgXw022577; Tue, 1 Mar 2022 13:56:38 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 3ehgc6ph9v-1 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NOT); Tue, 01 Mar 2022 13:56:38 +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 221Dtwso002084; Tue, 1 Mar 2022 13:56:37 GMT Received: from b03cxnp07029.gho.boulder.ibm.com (b03cxnp07029.gho.boulder.ibm.com [9.17.130.16]) by ppma04dal.us.ibm.com with ESMTP id 3efbu9v52x-1 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NOT); Tue, 01 Mar 2022 13:56:37 +0000 Received: from b03ledav005.gho.boulder.ibm.com (b03ledav005.gho.boulder.ibm.com [9.17.130.236]) by b03cxnp07029.gho.boulder.ibm.com (8.14.9/8.14.9/NCO v10.0) with ESMTP id 221DuZYt11993442 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-GCM-SHA384 bits=256 verify=OK); Tue, 1 Mar 2022 13:56:36 GMT Received: from b03ledav005.gho.boulder.ibm.com (unknown [127.0.0.1]) by IMSVA (Postfix) with ESMTP id C7105BE053; Tue, 1 Mar 2022 13:56:35 +0000 (GMT) Received: from b03ledav005.gho.boulder.ibm.com (unknown [127.0.0.1]) by IMSVA (Postfix) with ESMTP id EC9D1BE04F; Tue, 1 Mar 2022 13:56:33 +0000 (GMT) Received: from farosas.linux.ibm.com.com (unknown [9.211.51.129]) by b03ledav005.gho.boulder.ibm.com (Postfix) with ESMTP; Tue, 1 Mar 2022 13:56:33 +0000 (GMT) From: Fabiano Rosas To: qemu-devel@nongnu.org Subject: [PATCH 04/17] target/ppc: Move 6xx CPUs code to their own file Date: Tue, 1 Mar 2022 10:56:07 -0300 Message-Id: <20220301135620.2411952-5-farosas@linux.ibm.com> X-Mailer: git-send-email 2.34.1 In-Reply-To: <20220301135620.2411952-1-farosas@linux.ibm.com> References: <20220301135620.2411952-1-farosas@linux.ibm.com> MIME-Version: 1.0 X-TM-AS-GCONF: 00 X-Proofpoint-GUID: gKOg4rhtT691Jbxo76fyBGErB0kc1kGj X-Proofpoint-ORIG-GUID: FnkzMOzxI7FDUBOFI5VrCHV-oI7CIlDT X-Proofpoint-Virus-Version: vendor=baseguard engine=ICAP:2.0.205,Aquarius:18.0.816,Hydra:6.0.425,FMLib:17.11.64.514 definitions=2022-03-01_07,2022-02-26_01,2022-02-23_01 X-Proofpoint-Spam-Details: rule=outbound_notspam policy=outbound score=0 mlxscore=0 mlxlogscore=999 spamscore=0 malwarescore=0 impostorscore=0 adultscore=0 suspectscore=0 lowpriorityscore=0 phishscore=0 priorityscore=1501 clxscore=1015 bulkscore=0 classifier=spam adjust=0 reason=mlx scancount=1 engine=8.12.0-2201110000 definitions=main-2203010074 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_H5=0.001, RCVD_IN_MSPIKE_WL=0.001, SPF_HELO_NONE=0.001, SPF_PASS=-0.001, T_SCC_BODY_TEXT_LINE=-0.01 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" Affects the MPC5xx, MPC8xx, G2, G2LE, 603, 603e, e300, 604 and 604e. This moves init_proc, init_excp and register_*sprs functions that are related to the 6xx CPUs into a separate file. Some points: - the inclusion of sysemu/hw_accel.h is because of the DABR definition that comes from linux-headers kvm.h; - I'm copying check_pow_hid0 instead of moving it to avoid having to keep it exposed in a header file. Signed-off-by: Fabiano Rosas --- target/ppc/cpu_6xx.c | 1146 ++++++++++++++++++++++++++++++++++++++++ target/ppc/cpu_init.c | 1129 --------------------------------------- target/ppc/meson.build | 1 + 3 files changed, 1147 insertions(+), 1129 deletions(-) create mode 100644 target/ppc/cpu_6xx.c diff --git a/target/ppc/cpu_6xx.c b/target/ppc/cpu_6xx.c new file mode 100644 index 0000000000..a909f79e87 --- /dev/null +++ b/target/ppc/cpu_6xx.c @@ -0,0 +1,1146 @@ +/* + * CPU initialization for PowerPC 6xx CPUs + * + * Copyright IBM Corp. 2022 + * + * This work is licensed under the terms of the GNU GPL, version 2 or later. + * See the COPYING file in the top-level directory. + */ + +#include "qemu/osdep.h" +#include "sysemu/hw_accel.h" +#include "hw/ppc/ppc.h" +#include "cpu.h" +#include "spr_common.h" + +static int check_pow_hid0(CPUPPCState *env) +{ + if (env->spr[SPR_HID0] & 0x00E00000) { + return 1; + } + + return 0; +} + +static void register_5xx_8xx_sprs(CPUPPCState *env) +{ + /* Exception processing */ + spr_register_kvm(env, SPR_DSISR, "DSISR", + SPR_NOACCESS, SPR_NOACCESS, + &spr_read_generic, &spr_write_generic, + KVM_REG_PPC_DSISR, 0x00000000); + spr_register_kvm(env, SPR_DAR, "DAR", + SPR_NOACCESS, SPR_NOACCESS, + &spr_read_generic, &spr_write_generic, + KVM_REG_PPC_DAR, 0x00000000); + /* Timer */ + spr_register(env, SPR_DECR, "DECR", + SPR_NOACCESS, SPR_NOACCESS, + &spr_read_decr, &spr_write_decr, + 0x00000000); + + spr_register(env, SPR_MPC_EIE, "EIE", + SPR_NOACCESS, SPR_NOACCESS, + &spr_read_generic, &spr_write_generic, + 0x00000000); + + spr_register(env, SPR_MPC_EID, "EID", + SPR_NOACCESS, SPR_NOACCESS, + &spr_read_generic, &spr_write_generic, + 0x00000000); + + spr_register(env, SPR_MPC_NRI, "NRI", + SPR_NOACCESS, SPR_NOACCESS, + &spr_read_generic, &spr_write_generic, + 0x00000000); + + spr_register(env, SPR_MPC_CMPA, "CMPA", + SPR_NOACCESS, SPR_NOACCESS, + &spr_read_generic, &spr_write_generic, + 0x00000000); + + spr_register(env, SPR_MPC_CMPB, "CMPB", + SPR_NOACCESS, SPR_NOACCESS, + &spr_read_generic, &spr_write_generic, + 0x00000000); + + spr_register(env, SPR_MPC_CMPC, "CMPC", + SPR_NOACCESS, SPR_NOACCESS, + &spr_read_generic, &spr_write_generic, + 0x00000000); + + spr_register(env, SPR_MPC_CMPD, "CMPD", + SPR_NOACCESS, SPR_NOACCESS, + &spr_read_generic, &spr_write_generic, + 0x00000000); + + spr_register(env, SPR_MPC_ECR, "ECR", + SPR_NOACCESS, SPR_NOACCESS, + &spr_read_generic, &spr_write_generic, + 0x00000000); + + spr_register(env, SPR_MPC_DER, "DER", + SPR_NOACCESS, SPR_NOACCESS, + &spr_read_generic, &spr_write_generic, + 0x00000000); + + spr_register(env, SPR_MPC_COUNTA, "COUNTA", + SPR_NOACCESS, SPR_NOACCESS, + &spr_read_generic, &spr_write_generic, + 0x00000000); + + spr_register(env, SPR_MPC_COUNTB, "COUNTB", + SPR_NOACCESS, SPR_NOACCESS, + &spr_read_generic, &spr_write_generic, + 0x00000000); + + spr_register(env, SPR_MPC_CMPE, "CMPE", + SPR_NOACCESS, SPR_NOACCESS, + &spr_read_generic, &spr_write_generic, + 0x00000000); + + spr_register(env, SPR_MPC_CMPF, "CMPF", + SPR_NOACCESS, SPR_NOACCESS, + &spr_read_generic, &spr_write_generic, + 0x00000000); + + spr_register(env, SPR_MPC_CMPG, "CMPG", + SPR_NOACCESS, SPR_NOACCESS, + &spr_read_generic, &spr_write_generic, + 0x00000000); + + spr_register(env, SPR_MPC_CMPH, "CMPH", + SPR_NOACCESS, SPR_NOACCESS, + &spr_read_generic, &spr_write_generic, + 0x00000000); + + spr_register(env, SPR_MPC_LCTRL1, "LCTRL1", + SPR_NOACCESS, SPR_NOACCESS, + &spr_read_generic, &spr_write_generic, + 0x00000000); + + spr_register(env, SPR_MPC_LCTRL2, "LCTRL2", + SPR_NOACCESS, SPR_NOACCESS, + &spr_read_generic, &spr_write_generic, + 0x00000000); + + spr_register(env, SPR_MPC_BAR, "BAR", + SPR_NOACCESS, SPR_NOACCESS, + &spr_read_generic, &spr_write_generic, + 0x00000000); + + spr_register(env, SPR_MPC_DPDR, "DPDR", + SPR_NOACCESS, SPR_NOACCESS, + &spr_read_generic, &spr_write_generic, + 0x00000000); + + spr_register(env, SPR_MPC_IMMR, "IMMR", + SPR_NOACCESS, SPR_NOACCESS, + &spr_read_generic, &spr_write_generic, + 0x00000000); +} + +static void register_5xx_sprs(CPUPPCState *env) +{ + spr_register(env, SPR_RCPU_MI_GRA, "MI_GRA", + SPR_NOACCESS, SPR_NOACCESS, + &spr_read_generic, &spr_write_generic, + 0x00000000); + + spr_register(env, SPR_RCPU_L2U_GRA, "L2U_GRA", + SPR_NOACCESS, SPR_NOACCESS, + &spr_read_generic, &spr_write_generic, + 0x00000000); + + spr_register(env, SPR_RPCU_BBCMCR, "L2U_BBCMCR", + SPR_NOACCESS, SPR_NOACCESS, + &spr_read_generic, &spr_write_generic, + 0x00000000); + + spr_register(env, SPR_RCPU_L2U_MCR, "L2U_MCR", + SPR_NOACCESS, SPR_NOACCESS, + &spr_read_generic, &spr_write_generic, + 0x00000000); + + spr_register(env, SPR_RCPU_MI_RBA0, "MI_RBA0", + SPR_NOACCESS, SPR_NOACCESS, + &spr_read_generic, &spr_write_generic, + 0x00000000); + + spr_register(env, SPR_RCPU_MI_RBA1, "MI_RBA1", + SPR_NOACCESS, SPR_NOACCESS, + &spr_read_generic, &spr_write_generic, + 0x00000000); + + spr_register(env, SPR_RCPU_MI_RBA2, "MI_RBA2", + SPR_NOACCESS, SPR_NOACCESS, + &spr_read_generic, &spr_write_generic, + 0x00000000); + + spr_register(env, SPR_RCPU_MI_RBA3, "MI_RBA3", + SPR_NOACCESS, SPR_NOACCESS, + &spr_read_generic, &spr_write_generic, + 0x00000000); + + spr_register(env, SPR_RCPU_L2U_RBA0, "L2U_RBA0", + SPR_NOACCESS, SPR_NOACCESS, + &spr_read_generic, &spr_write_generic, + 0x00000000); + + spr_register(env, SPR_RCPU_L2U_RBA1, "L2U_RBA1", + SPR_NOACCESS, SPR_NOACCESS, + &spr_read_generic, &spr_write_generic, + 0x00000000); + + spr_register(env, SPR_RCPU_L2U_RBA2, "L2U_RBA2", + SPR_NOACCESS, SPR_NOACCESS, + &spr_read_generic, &spr_write_generic, + 0x00000000); + + spr_register(env, SPR_RCPU_L2U_RBA3, "L2U_RBA3", + SPR_NOACCESS, SPR_NOACCESS, + &spr_read_generic, &spr_write_generic, + 0x00000000); + + spr_register(env, SPR_RCPU_MI_RA0, "MI_RA0", + SPR_NOACCESS, SPR_NOACCESS, + &spr_read_generic, &spr_write_generic, + 0x00000000); + + spr_register(env, SPR_RCPU_MI_RA1, "MI_RA1", + SPR_NOACCESS, SPR_NOACCESS, + &spr_read_generic, &spr_write_generic, + 0x00000000); + + spr_register(env, SPR_RCPU_MI_RA2, "MI_RA2", + SPR_NOACCESS, SPR_NOACCESS, + &spr_read_generic, &spr_write_generic, + 0x00000000); + + spr_register(env, SPR_RCPU_MI_RA3, "MI_RA3", + SPR_NOACCESS, SPR_NOACCESS, + &spr_read_generic, &spr_write_generic, + 0x00000000); + + spr_register(env, SPR_RCPU_L2U_RA0, "L2U_RA0", + SPR_NOACCESS, SPR_NOACCESS, + &spr_read_generic, &spr_write_generic, + 0x00000000); + + spr_register(env, SPR_RCPU_L2U_RA1, "L2U_RA1", + SPR_NOACCESS, SPR_NOACCESS, + &spr_read_generic, &spr_write_generic, + 0x00000000); + + spr_register(env, SPR_RCPU_L2U_RA2, "L2U_RA2", + SPR_NOACCESS, SPR_NOACCESS, + &spr_read_generic, &spr_write_generic, + 0x00000000); + + spr_register(env, SPR_RCPU_L2U_RA3, "L2U_RA3", + SPR_NOACCESS, SPR_NOACCESS, + &spr_read_generic, &spr_write_generic, + 0x00000000); + + spr_register(env, SPR_RCPU_FPECR, "FPECR", + SPR_NOACCESS, SPR_NOACCESS, + &spr_read_generic, &spr_write_generic, + 0x00000000); +} + +static void register_8xx_sprs(CPUPPCState *env) +{ + + spr_register(env, SPR_MPC_IC_CST, "IC_CST", + SPR_NOACCESS, SPR_NOACCESS, + &spr_read_generic, &spr_write_generic, + 0x00000000); + + spr_register(env, SPR_MPC_IC_ADR, "IC_ADR", + SPR_NOACCESS, SPR_NOACCESS, + &spr_read_generic, &spr_write_generic, + 0x00000000); + + spr_register(env, SPR_MPC_IC_DAT, "IC_DAT", + SPR_NOACCESS, SPR_NOACCESS, + &spr_read_generic, &spr_write_generic, + 0x00000000); + + spr_register(env, SPR_MPC_DC_CST, "DC_CST", + SPR_NOACCESS, SPR_NOACCESS, + &spr_read_generic, &spr_write_generic, + 0x00000000); + + spr_register(env, SPR_MPC_DC_ADR, "DC_ADR", + SPR_NOACCESS, SPR_NOACCESS, + &spr_read_generic, &spr_write_generic, + 0x00000000); + + spr_register(env, SPR_MPC_DC_DAT, "DC_DAT", + SPR_NOACCESS, SPR_NOACCESS, + &spr_read_generic, &spr_write_generic, + 0x00000000); + + spr_register(env, SPR_MPC_MI_CTR, "MI_CTR", + SPR_NOACCESS, SPR_NOACCESS, + &spr_read_generic, &spr_write_generic, + 0x00000000); + + spr_register(env, SPR_MPC_MI_AP, "MI_AP", + SPR_NOACCESS, SPR_NOACCESS, + &spr_read_generic, &spr_write_generic, + 0x00000000); + + spr_register(env, SPR_MPC_MI_EPN, "MI_EPN", + SPR_NOACCESS, SPR_NOACCESS, + &spr_read_generic, &spr_write_generic, + 0x00000000); + + spr_register(env, SPR_MPC_MI_TWC, "MI_TWC", + SPR_NOACCESS, SPR_NOACCESS, + &spr_read_generic, &spr_write_generic, + 0x00000000); + + spr_register(env, SPR_MPC_MI_RPN, "MI_RPN", + SPR_NOACCESS, SPR_NOACCESS, + &spr_read_generic, &spr_write_generic, + 0x00000000); + + spr_register(env, SPR_MPC_MI_DBCAM, "MI_DBCAM", + SPR_NOACCESS, SPR_NOACCESS, + &spr_read_generic, &spr_write_generic, + 0x00000000); + + spr_register(env, SPR_MPC_MI_DBRAM0, "MI_DBRAM0", + SPR_NOACCESS, SPR_NOACCESS, + &spr_read_generic, &spr_write_generic, + 0x00000000); + + spr_register(env, SPR_MPC_MI_DBRAM1, "MI_DBRAM1", + SPR_NOACCESS, SPR_NOACCESS, + &spr_read_generic, &spr_write_generic, + 0x00000000); + + spr_register(env, SPR_MPC_MD_CTR, "MD_CTR", + SPR_NOACCESS, SPR_NOACCESS, + &spr_read_generic, &spr_write_generic, + 0x00000000); + + spr_register(env, SPR_MPC_MD_CASID, "MD_CASID", + SPR_NOACCESS, SPR_NOACCESS, + &spr_read_generic, &spr_write_generic, + 0x00000000); + + spr_register(env, SPR_MPC_MD_AP, "MD_AP", + SPR_NOACCESS, SPR_NOACCESS, + &spr_read_generic, &spr_write_generic, + 0x00000000); + + spr_register(env, SPR_MPC_MD_EPN, "MD_EPN", + SPR_NOACCESS, SPR_NOACCESS, + &spr_read_generic, &spr_write_generic, + 0x00000000); + + spr_register(env, SPR_MPC_MD_TWB, "MD_TWB", + SPR_NOACCESS, SPR_NOACCESS, + &spr_read_generic, &spr_write_generic, + 0x00000000); + + spr_register(env, SPR_MPC_MD_TWC, "MD_TWC", + SPR_NOACCESS, SPR_NOACCESS, + &spr_read_generic, &spr_write_generic, + 0x00000000); + + spr_register(env, SPR_MPC_MD_RPN, "MD_RPN", + SPR_NOACCESS, SPR_NOACCESS, + &spr_read_generic, &spr_write_generic, + 0x00000000); + + spr_register(env, SPR_MPC_MD_TW, "MD_TW", + SPR_NOACCESS, SPR_NOACCESS, + &spr_read_generic, &spr_write_generic, + 0x00000000); + + spr_register(env, SPR_MPC_MD_DBCAM, "MD_DBCAM", + SPR_NOACCESS, SPR_NOACCESS, + &spr_read_generic, &spr_write_generic, + 0x00000000); + + spr_register(env, SPR_MPC_MD_DBRAM0, "MD_DBRAM0", + SPR_NOACCESS, SPR_NOACCESS, + &spr_read_generic, &spr_write_generic, + 0x00000000); + + spr_register(env, SPR_MPC_MD_DBRAM1, "MD_DBRAM1", + SPR_NOACCESS, SPR_NOACCESS, + &spr_read_generic, &spr_write_generic, + 0x00000000); +} + +static void register_G2_sprs(CPUPPCState *env) +{ + /* Memory base address */ + /* MBAR */ + spr_register(env, SPR_MBAR, "MBAR", + SPR_NOACCESS, SPR_NOACCESS, + &spr_read_generic, &spr_write_generic, + 0x00000000); + /* Exception processing */ + spr_register(env, SPR_BOOKE_CSRR0, "CSRR0", + SPR_NOACCESS, SPR_NOACCESS, + &spr_read_generic, &spr_write_generic, + 0x00000000); + spr_register(env, SPR_BOOKE_CSRR1, "CSRR1", + SPR_NOACCESS, SPR_NOACCESS, + &spr_read_generic, &spr_write_generic, + 0x00000000); + /* Breakpoints */ + spr_register(env, SPR_DABR, "DABR", + SPR_NOACCESS, SPR_NOACCESS, + &spr_read_generic, &spr_write_generic, + 0x00000000); + + spr_register(env, SPR_DABR2, "DABR2", + SPR_NOACCESS, SPR_NOACCESS, + &spr_read_generic, &spr_write_generic, + 0x00000000); + + spr_register(env, SPR_IABR, "IABR", + SPR_NOACCESS, SPR_NOACCESS, + &spr_read_generic, &spr_write_generic, + 0x00000000); + + spr_register(env, SPR_IABR2, "IABR2", + SPR_NOACCESS, SPR_NOACCESS, + &spr_read_generic, &spr_write_generic, + 0x00000000); + + spr_register(env, SPR_IBCR, "IBCR", + SPR_NOACCESS, SPR_NOACCESS, + &spr_read_generic, &spr_write_generic, + 0x00000000); + + spr_register(env, SPR_DBCR, "DBCR", + SPR_NOACCESS, SPR_NOACCESS, + &spr_read_generic, &spr_write_generic, + 0x00000000); + + /* External access control */ + spr_register(env, SPR_EAR, "EAR", + SPR_NOACCESS, SPR_NOACCESS, + &spr_read_generic, &spr_write_generic, + 0x00000000); + /* Hardware implementation register */ + spr_register(env, SPR_HID0, "HID0", + SPR_NOACCESS, SPR_NOACCESS, + &spr_read_generic, &spr_write_generic, + 0x00000000); + + spr_register(env, SPR_HID1, "HID1", + SPR_NOACCESS, SPR_NOACCESS, + &spr_read_generic, &spr_write_generic, + 0x00000000); + + spr_register(env, SPR_HID2, "HID2", + SPR_NOACCESS, SPR_NOACCESS, + &spr_read_generic, &spr_write_generic, + 0x00000000); + + /* SGPRs */ + spr_register(env, SPR_SPRG4, "SPRG4", + SPR_NOACCESS, SPR_NOACCESS, + &spr_read_generic, &spr_write_generic, + 0x00000000); + spr_register(env, SPR_SPRG5, "SPRG5", + SPR_NOACCESS, SPR_NOACCESS, + &spr_read_generic, &spr_write_generic, + 0x00000000); + spr_register(env, SPR_SPRG6, "SPRG6", + SPR_NOACCESS, SPR_NOACCESS, + &spr_read_generic, &spr_write_generic, + 0x00000000); + spr_register(env, SPR_SPRG7, "SPRG7", + SPR_NOACCESS, SPR_NOACCESS, + &spr_read_generic, &spr_write_generic, + 0x00000000); +} + +static void register_603_sprs(CPUPPCState *env) +{ + /* External access control */ + spr_register(env, SPR_EAR, "EAR", + SPR_NOACCESS, SPR_NOACCESS, + &spr_read_generic, &spr_write_generic, + 0x00000000); + /* Breakpoints */ + spr_register(env, SPR_IABR, "IABR", + SPR_NOACCESS, SPR_NOACCESS, + &spr_read_generic, &spr_write_generic, + 0x00000000); + + spr_register(env, SPR_HID0, "HID0", + SPR_NOACCESS, SPR_NOACCESS, + &spr_read_generic, &spr_write_generic, + 0x00000000); + + spr_register(env, SPR_HID1, "HID1", + SPR_NOACCESS, SPR_NOACCESS, + &spr_read_generic, &spr_write_generic, + 0x00000000); +} + +static void register_e300_sprs(CPUPPCState *env) +{ + /* hardware implementation registers */ + spr_register(env, SPR_HID2, "HID2", + SPR_NOACCESS, SPR_NOACCESS, + &spr_read_generic, &spr_write_generic, + 0x00000000); + /* Breakpoints */ + spr_register(env, SPR_DABR, "DABR", + SPR_NOACCESS, SPR_NOACCESS, + &spr_read_generic, &spr_write_generic, + 0x00000000); + + spr_register(env, SPR_DABR2, "DABR2", + SPR_NOACCESS, SPR_NOACCESS, + &spr_read_generic, &spr_write_generic, + 0x00000000); + + spr_register(env, SPR_IABR2, "IABR2", + SPR_NOACCESS, SPR_NOACCESS, + &spr_read_generic, &spr_write_generic, + 0x00000000); + + spr_register(env, SPR_IBCR, "IBCR", + SPR_NOACCESS, SPR_NOACCESS, + &spr_read_generic, &spr_write_generic, + 0x00000000); + + spr_register(env, SPR_DBCR, "DBCR", + SPR_NOACCESS, SPR_NOACCESS, + &spr_read_generic, &spr_write_generic, + 0x00000000); +} + +static void register_604_sprs(CPUPPCState *env) +{ + /* Processor identification */ + spr_register(env, SPR_PIR, "PIR", + SPR_NOACCESS, SPR_NOACCESS, + &spr_read_generic, &spr_write_pir, + 0x00000000); + /* Breakpoints */ + spr_register(env, SPR_IABR, "IABR", + SPR_NOACCESS, SPR_NOACCESS, + &spr_read_generic, &spr_write_generic, + 0x00000000); + + spr_register_kvm(env, SPR_DABR, "DABR", + SPR_NOACCESS, SPR_NOACCESS, + &spr_read_generic, &spr_write_generic, + KVM_REG_PPC_DABR, 0x00000000); + /* Performance counters */ + spr_register(env, SPR_7XX_MMCR0, "MMCR0", + SPR_NOACCESS, SPR_NOACCESS, + &spr_read_generic, &spr_write_generic, + 0x00000000); + + spr_register(env, SPR_7XX_PMC1, "PMC1", + SPR_NOACCESS, SPR_NOACCESS, + &spr_read_generic, &spr_write_generic, + 0x00000000); + + spr_register(env, SPR_7XX_PMC2, "PMC2", + SPR_NOACCESS, SPR_NOACCESS, + &spr_read_generic, &spr_write_generic, + 0x00000000); + + spr_register(env, SPR_7XX_SIAR, "SIAR", + SPR_NOACCESS, SPR_NOACCESS, + &spr_read_generic, SPR_NOACCESS, + 0x00000000); + + spr_register(env, SPR_SDA, "SDA", + SPR_NOACCESS, SPR_NOACCESS, + &spr_read_generic, SPR_NOACCESS, + 0x00000000); + /* External access control */ + spr_register(env, SPR_EAR, "EAR", + SPR_NOACCESS, SPR_NOACCESS, + &spr_read_generic, &spr_write_generic, + 0x00000000); + + /* Hardware implementation registers */ + spr_register(env, SPR_HID0, "HID0", + SPR_NOACCESS, SPR_NOACCESS, + &spr_read_generic, &spr_write_generic, + 0x00000000); +} + +static void register_604e_sprs(CPUPPCState *env) +{ + spr_register(env, SPR_7XX_MMCR1, "MMCR1", + SPR_NOACCESS, SPR_NOACCESS, + &spr_read_generic, &spr_write_generic, + 0x00000000); + + spr_register(env, SPR_7XX_PMC3, "PMC3", + SPR_NOACCESS, SPR_NOACCESS, + &spr_read_generic, &spr_write_generic, + 0x00000000); + + spr_register(env, SPR_7XX_PMC4, "PMC4", + SPR_NOACCESS, SPR_NOACCESS, + &spr_read_generic, &spr_write_generic, + 0x00000000); + /* Hardware implementation registers */ + spr_register(env, SPR_HID1, "HID1", + SPR_NOACCESS, SPR_NOACCESS, + &spr_read_generic, &spr_write_generic, + 0x00000000); +} + +static void init_excp_MPC5xx(CPUPPCState *env) +{ +#if !defined(CONFIG_USER_ONLY) + env->excp_vectors[POWERPC_EXCP_RESET] = 0x00000100; + env->excp_vectors[POWERPC_EXCP_MCHECK] = 0x00000200; + env->excp_vectors[POWERPC_EXCP_EXTERNAL] = 0x00000500; + env->excp_vectors[POWERPC_EXCP_ALIGN] = 0x00000600; + env->excp_vectors[POWERPC_EXCP_PROGRAM] = 0x00000700; + env->excp_vectors[POWERPC_EXCP_FPU] = 0x00000800; + env->excp_vectors[POWERPC_EXCP_DECR] = 0x00000900; + env->excp_vectors[POWERPC_EXCP_SYSCALL] = 0x00000C00; + env->excp_vectors[POWERPC_EXCP_TRACE] = 0x00000D00; + env->excp_vectors[POWERPC_EXCP_FPA] = 0x00000E00; + env->excp_vectors[POWERPC_EXCP_EMUL] = 0x00001000; + env->excp_vectors[POWERPC_EXCP_DABR] = 0x00001C00; + env->excp_vectors[POWERPC_EXCP_IABR] = 0x00001C00; + env->excp_vectors[POWERPC_EXCP_MEXTBR] = 0x00001E00; + env->excp_vectors[POWERPC_EXCP_NMEXTBR] = 0x00001F00; + env->ivor_mask = 0x0000FFF0UL; + env->ivpr_mask = 0xFFFF0000UL; + /* Hardware reset vector */ + env->hreset_vector = 0x00000100UL; +#endif +} + +static void init_excp_MPC8xx(CPUPPCState *env) +{ +#if !defined(CONFIG_USER_ONLY) + env->excp_vectors[POWERPC_EXCP_RESET] = 0x00000100; + env->excp_vectors[POWERPC_EXCP_MCHECK] = 0x00000200; + env->excp_vectors[POWERPC_EXCP_DSI] = 0x00000300; + env->excp_vectors[POWERPC_EXCP_ISI] = 0x00000400; + env->excp_vectors[POWERPC_EXCP_EXTERNAL] = 0x00000500; + env->excp_vectors[POWERPC_EXCP_ALIGN] = 0x00000600; + env->excp_vectors[POWERPC_EXCP_PROGRAM] = 0x00000700; + env->excp_vectors[POWERPC_EXCP_FPU] = 0x00000800; + env->excp_vectors[POWERPC_EXCP_DECR] = 0x00000900; + env->excp_vectors[POWERPC_EXCP_SYSCALL] = 0x00000C00; + env->excp_vectors[POWERPC_EXCP_TRACE] = 0x00000D00; + env->excp_vectors[POWERPC_EXCP_FPA] = 0x00000E00; + env->excp_vectors[POWERPC_EXCP_EMUL] = 0x00001000; + env->excp_vectors[POWERPC_EXCP_ITLB] = 0x00001100; + env->excp_vectors[POWERPC_EXCP_DTLB] = 0x00001200; + env->excp_vectors[POWERPC_EXCP_ITLBE] = 0x00001300; + env->excp_vectors[POWERPC_EXCP_DTLBE] = 0x00001400; + env->excp_vectors[POWERPC_EXCP_DABR] = 0x00001C00; + env->excp_vectors[POWERPC_EXCP_IABR] = 0x00001C00; + env->excp_vectors[POWERPC_EXCP_MEXTBR] = 0x00001E00; + env->excp_vectors[POWERPC_EXCP_NMEXTBR] = 0x00001F00; + env->ivor_mask = 0x0000FFF0UL; + env->ivpr_mask = 0xFFFF0000UL; + /* Hardware reset vector */ + env->hreset_vector = 0x00000100UL; +#endif +} + +static void init_excp_G2(CPUPPCState *env) +{ +#if !defined(CONFIG_USER_ONLY) + env->excp_vectors[POWERPC_EXCP_RESET] = 0x00000100; + env->excp_vectors[POWERPC_EXCP_MCHECK] = 0x00000200; + env->excp_vectors[POWERPC_EXCP_DSI] = 0x00000300; + env->excp_vectors[POWERPC_EXCP_ISI] = 0x00000400; + env->excp_vectors[POWERPC_EXCP_EXTERNAL] = 0x00000500; + env->excp_vectors[POWERPC_EXCP_ALIGN] = 0x00000600; + env->excp_vectors[POWERPC_EXCP_PROGRAM] = 0x00000700; + env->excp_vectors[POWERPC_EXCP_FPU] = 0x00000800; + env->excp_vectors[POWERPC_EXCP_DECR] = 0x00000900; + env->excp_vectors[POWERPC_EXCP_CRITICAL] = 0x00000A00; + env->excp_vectors[POWERPC_EXCP_SYSCALL] = 0x00000C00; + env->excp_vectors[POWERPC_EXCP_TRACE] = 0x00000D00; + env->excp_vectors[POWERPC_EXCP_IFTLB] = 0x00001000; + env->excp_vectors[POWERPC_EXCP_DLTLB] = 0x00001100; + env->excp_vectors[POWERPC_EXCP_DSTLB] = 0x00001200; + env->excp_vectors[POWERPC_EXCP_IABR] = 0x00001300; + env->excp_vectors[POWERPC_EXCP_SMI] = 0x00001400; + /* Hardware reset vector */ + env->hreset_vector = 0x00000100UL; +#endif +} + +static void init_excp_603(CPUPPCState *env) +{ +#if !defined(CONFIG_USER_ONLY) + env->excp_vectors[POWERPC_EXCP_RESET] = 0x00000100; + env->excp_vectors[POWERPC_EXCP_MCHECK] = 0x00000200; + env->excp_vectors[POWERPC_EXCP_DSI] = 0x00000300; + env->excp_vectors[POWERPC_EXCP_ISI] = 0x00000400; + env->excp_vectors[POWERPC_EXCP_EXTERNAL] = 0x00000500; + env->excp_vectors[POWERPC_EXCP_ALIGN] = 0x00000600; + env->excp_vectors[POWERPC_EXCP_PROGRAM] = 0x00000700; + env->excp_vectors[POWERPC_EXCP_FPU] = 0x00000800; + env->excp_vectors[POWERPC_EXCP_DECR] = 0x00000900; + env->excp_vectors[POWERPC_EXCP_SYSCALL] = 0x00000C00; + env->excp_vectors[POWERPC_EXCP_TRACE] = 0x00000D00; + env->excp_vectors[POWERPC_EXCP_IFTLB] = 0x00001000; + env->excp_vectors[POWERPC_EXCP_DLTLB] = 0x00001100; + env->excp_vectors[POWERPC_EXCP_DSTLB] = 0x00001200; + env->excp_vectors[POWERPC_EXCP_IABR] = 0x00001300; + env->excp_vectors[POWERPC_EXCP_SMI] = 0x00001400; + /* Hardware reset vector */ + env->hreset_vector = 0x00000100UL; +#endif +} + +static void init_excp_604(CPUPPCState *env) +{ +#if !defined(CONFIG_USER_ONLY) + env->excp_vectors[POWERPC_EXCP_RESET] = 0x00000100; + env->excp_vectors[POWERPC_EXCP_MCHECK] = 0x00000200; + env->excp_vectors[POWERPC_EXCP_DSI] = 0x00000300; + env->excp_vectors[POWERPC_EXCP_ISI] = 0x00000400; + env->excp_vectors[POWERPC_EXCP_EXTERNAL] = 0x00000500; + env->excp_vectors[POWERPC_EXCP_ALIGN] = 0x00000600; + env->excp_vectors[POWERPC_EXCP_PROGRAM] = 0x00000700; + env->excp_vectors[POWERPC_EXCP_FPU] = 0x00000800; + env->excp_vectors[POWERPC_EXCP_DECR] = 0x00000900; + env->excp_vectors[POWERPC_EXCP_SYSCALL] = 0x00000C00; + env->excp_vectors[POWERPC_EXCP_TRACE] = 0x00000D00; + env->excp_vectors[POWERPC_EXCP_PERFM] = 0x00000F00; + env->excp_vectors[POWERPC_EXCP_IABR] = 0x00001300; + env->excp_vectors[POWERPC_EXCP_SMI] = 0x00001400; + /* Hardware reset vector */ + env->hreset_vector = 0x00000100UL; +#endif +} + +static void init_proc_MPC5xx(CPUPPCState *env) +{ + register_5xx_8xx_sprs(env); + register_5xx_sprs(env); + init_excp_MPC5xx(env); + env->dcache_line_size = 32; + env->icache_line_size = 32; + /* XXX: TODO: allocate internal IRQ controller */ +} + +static void init_proc_MPC8xx(CPUPPCState *env) +{ + register_5xx_8xx_sprs(env); + register_8xx_sprs(env); + init_excp_MPC8xx(env); + env->dcache_line_size = 32; + env->icache_line_size = 32; + /* XXX: TODO: allocate internal IRQ controller */ +} + +static void init_proc_G2(CPUPPCState *env) +{ + register_non_embedded_sprs(env); + register_sdr1_sprs(env); + register_G2_sprs(env); + + /* Memory management */ + register_low_BATs(env); + register_high_BATs(env); + register_6xx_7xx_soft_tlb(env, 64, 2); + init_excp_G2(env); + env->dcache_line_size = 32; + env->icache_line_size = 32; + /* Allocate hardware IRQ controller */ + ppc6xx_irq_init(env_archcpu(env)); +} + +static void init_proc_603(CPUPPCState *env) +{ + register_non_embedded_sprs(env); + register_sdr1_sprs(env); + register_603_sprs(env); + + /* Memory management */ + register_low_BATs(env); + register_6xx_7xx_soft_tlb(env, 64, 2); + init_excp_603(env); + env->dcache_line_size = 32; + env->icache_line_size = 32; + /* Allocate hardware IRQ controller */ + ppc6xx_irq_init(env_archcpu(env)); +} + +static void init_proc_e300(CPUPPCState *env) +{ + init_proc_603(env); + register_e300_sprs(env); +} + +static void init_proc_604(CPUPPCState *env) +{ + register_non_embedded_sprs(env); + register_sdr1_sprs(env); + register_604_sprs(env); + + /* Memory management */ + register_low_BATs(env); + init_excp_604(env); + env->dcache_line_size = 32; + env->icache_line_size = 32; + /* Allocate hardware IRQ controller */ + ppc6xx_irq_init(env_archcpu(env)); +} + +static void init_proc_604E(CPUPPCState *env) +{ + init_proc_604(env); + register_604e_sprs(env); +} + +POWERPC_FAMILY(MPC5xx)(ObjectClass *oc, void *data) +{ + DeviceClass *dc = DEVICE_CLASS(oc); + PowerPCCPUClass *pcc = POWERPC_CPU_CLASS(oc); + + dc->desc = "Freescale 5xx cores (aka RCPU)"; + pcc->init_proc = init_proc_MPC5xx; + pcc->check_pow = check_pow_none; + pcc->insns_flags = PPC_INSNS_BASE | PPC_STRING | + PPC_MEM_EIEIO | PPC_MEM_SYNC | + PPC_CACHE_ICBI | PPC_FLOAT | PPC_FLOAT_STFIWX | + PPC_MFTB; + pcc->msr_mask = (1ull << MSR_ILE) | + (1ull << MSR_EE) | + (1ull << MSR_PR) | + (1ull << MSR_FP) | + (1ull << MSR_ME) | + (1ull << MSR_FE0) | + (1ull << MSR_SE) | + (1ull << MSR_DE) | + (1ull << MSR_FE1) | + (1ull << MSR_EP) | + (1ull << MSR_RI) | + (1ull << MSR_LE); + pcc->mmu_model = POWERPC_MMU_REAL; + pcc->excp_model = POWERPC_EXCP_6xx; + pcc->bus_model = PPC_FLAGS_INPUT_RCPU; + pcc->bfd_mach = bfd_mach_ppc_505; + pcc->flags = POWERPC_FLAG_SE | POWERPC_FLAG_BE | + POWERPC_FLAG_BUS_CLK; +} + +POWERPC_FAMILY(MPC8xx)(ObjectClass *oc, void *data) +{ + DeviceClass *dc = DEVICE_CLASS(oc); + PowerPCCPUClass *pcc = POWERPC_CPU_CLASS(oc); + + dc->desc = "Freescale 8xx cores (aka PowerQUICC)"; + pcc->init_proc = init_proc_MPC8xx; + pcc->check_pow = check_pow_none; + pcc->insns_flags = PPC_INSNS_BASE | PPC_STRING | + PPC_MEM_EIEIO | PPC_MEM_SYNC | + PPC_CACHE_ICBI | PPC_MFTB; + pcc->msr_mask = (1ull << MSR_ILE) | + (1ull << MSR_EE) | + (1ull << MSR_PR) | + (1ull << MSR_FP) | + (1ull << MSR_ME) | + (1ull << MSR_SE) | + (1ull << MSR_DE) | + (1ull << MSR_EP) | + (1ull << MSR_IR) | + (1ull << MSR_DR) | + (1ull << MSR_RI) | + (1ull << MSR_LE); + pcc->mmu_model = POWERPC_MMU_MPC8xx; + pcc->excp_model = POWERPC_EXCP_6xx; + pcc->bus_model = PPC_FLAGS_INPUT_RCPU; + pcc->bfd_mach = bfd_mach_ppc_860; + pcc->flags = POWERPC_FLAG_SE | POWERPC_FLAG_BE | + POWERPC_FLAG_BUS_CLK; +} + +POWERPC_FAMILY(G2)(ObjectClass *oc, void *data) +{ + DeviceClass *dc = DEVICE_CLASS(oc); + PowerPCCPUClass *pcc = POWERPC_CPU_CLASS(oc); + + dc->desc = "PowerPC G2"; + pcc->init_proc = init_proc_G2; + pcc->check_pow = check_pow_hid0; + pcc->insns_flags = PPC_INSNS_BASE | PPC_STRING | PPC_MFTB | + PPC_FLOAT | PPC_FLOAT_FSEL | PPC_FLOAT_FRES | + PPC_FLOAT_STFIWX | + PPC_CACHE | PPC_CACHE_ICBI | PPC_CACHE_DCBZ | + PPC_MEM_SYNC | PPC_MEM_EIEIO | + PPC_MEM_TLBIE | PPC_MEM_TLBSYNC | PPC_6xx_TLB | + PPC_SEGMENT | PPC_EXTERN; + pcc->msr_mask = (1ull << MSR_POW) | + (1ull << MSR_TGPR) | + (1ull << MSR_EE) | + (1ull << MSR_PR) | + (1ull << MSR_FP) | + (1ull << MSR_ME) | + (1ull << MSR_FE0) | + (1ull << MSR_SE) | + (1ull << MSR_DE) | + (1ull << MSR_FE1) | + (1ull << MSR_AL) | + (1ull << MSR_EP) | + (1ull << MSR_IR) | + (1ull << MSR_DR) | + (1ull << MSR_RI); + pcc->mmu_model = POWERPC_MMU_SOFT_6xx; + pcc->excp_model = POWERPC_EXCP_6xx; + pcc->bus_model = PPC_FLAGS_INPUT_6xx; + pcc->bfd_mach = bfd_mach_ppc_ec603e; + pcc->flags = POWERPC_FLAG_TGPR | POWERPC_FLAG_SE | + POWERPC_FLAG_BE | POWERPC_FLAG_BUS_CLK; +} + +POWERPC_FAMILY(G2LE)(ObjectClass *oc, void *data) +{ + DeviceClass *dc = DEVICE_CLASS(oc); + PowerPCCPUClass *pcc = POWERPC_CPU_CLASS(oc); + + dc->desc = "PowerPC G2LE"; + pcc->init_proc = init_proc_G2; + pcc->check_pow = check_pow_hid0; + pcc->insns_flags = PPC_INSNS_BASE | PPC_STRING | PPC_MFTB | + PPC_FLOAT | PPC_FLOAT_FSEL | PPC_FLOAT_FRES | + PPC_FLOAT_STFIWX | + PPC_CACHE | PPC_CACHE_ICBI | PPC_CACHE_DCBZ | + PPC_MEM_SYNC | PPC_MEM_EIEIO | + PPC_MEM_TLBIE | PPC_MEM_TLBSYNC | PPC_6xx_TLB | + PPC_SEGMENT | PPC_EXTERN; + pcc->msr_mask = (1ull << MSR_POW) | + (1ull << MSR_TGPR) | + (1ull << MSR_ILE) | + (1ull << MSR_EE) | + (1ull << MSR_PR) | + (1ull << MSR_FP) | + (1ull << MSR_ME) | + (1ull << MSR_FE0) | + (1ull << MSR_SE) | + (1ull << MSR_DE) | + (1ull << MSR_FE1) | + (1ull << MSR_AL) | + (1ull << MSR_EP) | + (1ull << MSR_IR) | + (1ull << MSR_DR) | + (1ull << MSR_RI) | + (1ull << MSR_LE); + pcc->mmu_model = POWERPC_MMU_SOFT_6xx; + pcc->excp_model = POWERPC_EXCP_6xx; + pcc->bus_model = PPC_FLAGS_INPUT_6xx; + pcc->bfd_mach = bfd_mach_ppc_ec603e; + pcc->flags = POWERPC_FLAG_TGPR | POWERPC_FLAG_SE | + POWERPC_FLAG_BE | POWERPC_FLAG_BUS_CLK; +} + +POWERPC_FAMILY(603)(ObjectClass *oc, void *data) +{ + DeviceClass *dc = DEVICE_CLASS(oc); + PowerPCCPUClass *pcc = POWERPC_CPU_CLASS(oc); + + dc->desc = "PowerPC 603"; + pcc->init_proc = init_proc_603; + pcc->check_pow = check_pow_hid0; + pcc->insns_flags = PPC_INSNS_BASE | PPC_STRING | PPC_MFTB | + PPC_FLOAT | PPC_FLOAT_FSEL | PPC_FLOAT_FRES | + PPC_FLOAT_FRSQRTE | PPC_FLOAT_STFIWX | + PPC_CACHE | PPC_CACHE_ICBI | PPC_CACHE_DCBZ | + PPC_MEM_SYNC | PPC_MEM_EIEIO | + PPC_MEM_TLBIE | PPC_MEM_TLBSYNC | PPC_6xx_TLB | + PPC_SEGMENT | PPC_EXTERN; + pcc->msr_mask = (1ull << MSR_POW) | + (1ull << MSR_TGPR) | + (1ull << MSR_ILE) | + (1ull << MSR_EE) | + (1ull << MSR_PR) | + (1ull << MSR_FP) | + (1ull << MSR_ME) | + (1ull << MSR_FE0) | + (1ull << MSR_SE) | + (1ull << MSR_DE) | + (1ull << MSR_FE1) | + (1ull << MSR_EP) | + (1ull << MSR_IR) | + (1ull << MSR_DR) | + (1ull << MSR_RI) | + (1ull << MSR_LE); + pcc->mmu_model = POWERPC_MMU_SOFT_6xx; + pcc->excp_model = POWERPC_EXCP_6xx; + pcc->bus_model = PPC_FLAGS_INPUT_6xx; + pcc->bfd_mach = bfd_mach_ppc_603; + pcc->flags = POWERPC_FLAG_TGPR | POWERPC_FLAG_SE | + POWERPC_FLAG_BE | POWERPC_FLAG_BUS_CLK; +} + +POWERPC_FAMILY(603E)(ObjectClass *oc, void *data) +{ + DeviceClass *dc = DEVICE_CLASS(oc); + PowerPCCPUClass *pcc = POWERPC_CPU_CLASS(oc); + + dc->desc = "PowerPC 603e"; + pcc->init_proc = init_proc_603; + pcc->check_pow = check_pow_hid0; + pcc->insns_flags = PPC_INSNS_BASE | PPC_STRING | PPC_MFTB | + PPC_FLOAT | PPC_FLOAT_FSEL | PPC_FLOAT_FRES | + PPC_FLOAT_FRSQRTE | PPC_FLOAT_STFIWX | + PPC_CACHE | PPC_CACHE_ICBI | PPC_CACHE_DCBZ | + PPC_MEM_SYNC | PPC_MEM_EIEIO | + PPC_MEM_TLBIE | PPC_MEM_TLBSYNC | PPC_6xx_TLB | + PPC_SEGMENT | PPC_EXTERN; + pcc->msr_mask = (1ull << MSR_POW) | + (1ull << MSR_TGPR) | + (1ull << MSR_ILE) | + (1ull << MSR_EE) | + (1ull << MSR_PR) | + (1ull << MSR_FP) | + (1ull << MSR_ME) | + (1ull << MSR_FE0) | + (1ull << MSR_SE) | + (1ull << MSR_DE) | + (1ull << MSR_FE1) | + (1ull << MSR_EP) | + (1ull << MSR_IR) | + (1ull << MSR_DR) | + (1ull << MSR_RI) | + (1ull << MSR_LE); + pcc->mmu_model = POWERPC_MMU_SOFT_6xx; + pcc->excp_model = POWERPC_EXCP_6xx; + pcc->bus_model = PPC_FLAGS_INPUT_6xx; + pcc->bfd_mach = bfd_mach_ppc_ec603e; + pcc->flags = POWERPC_FLAG_TGPR | POWERPC_FLAG_SE | + POWERPC_FLAG_BE | POWERPC_FLAG_BUS_CLK; +} + +POWERPC_FAMILY(e300)(ObjectClass *oc, void *data) +{ + DeviceClass *dc = DEVICE_CLASS(oc); + PowerPCCPUClass *pcc = POWERPC_CPU_CLASS(oc); + + dc->desc = "e300 core"; + pcc->init_proc = init_proc_e300; + pcc->check_pow = check_pow_hid0; + pcc->insns_flags = PPC_INSNS_BASE | PPC_STRING | PPC_MFTB | + PPC_FLOAT | PPC_FLOAT_FSEL | PPC_FLOAT_FRES | + PPC_FLOAT_STFIWX | + PPC_CACHE | PPC_CACHE_ICBI | PPC_CACHE_DCBZ | + PPC_MEM_SYNC | PPC_MEM_EIEIO | + PPC_MEM_TLBIE | PPC_MEM_TLBSYNC | PPC_6xx_TLB | + PPC_SEGMENT | PPC_EXTERN; + pcc->msr_mask = (1ull << MSR_POW) | + (1ull << MSR_TGPR) | + (1ull << MSR_ILE) | + (1ull << MSR_EE) | + (1ull << MSR_PR) | + (1ull << MSR_FP) | + (1ull << MSR_ME) | + (1ull << MSR_FE0) | + (1ull << MSR_SE) | + (1ull << MSR_DE) | + (1ull << MSR_FE1) | + (1ull << MSR_AL) | + (1ull << MSR_EP) | + (1ull << MSR_IR) | + (1ull << MSR_DR) | + (1ull << MSR_RI) | + (1ull << MSR_LE); + pcc->mmu_model = POWERPC_MMU_SOFT_6xx; + pcc->excp_model = POWERPC_EXCP_6xx; + pcc->bus_model = PPC_FLAGS_INPUT_6xx; + pcc->bfd_mach = bfd_mach_ppc_603; + pcc->flags = POWERPC_FLAG_TGPR | POWERPC_FLAG_SE | + POWERPC_FLAG_BE | POWERPC_FLAG_BUS_CLK; +} + +POWERPC_FAMILY(604)(ObjectClass *oc, void *data) +{ + DeviceClass *dc = DEVICE_CLASS(oc); + PowerPCCPUClass *pcc = POWERPC_CPU_CLASS(oc); + + dc->desc = "PowerPC 604"; + pcc->init_proc = init_proc_604; + pcc->check_pow = check_pow_nocheck; + pcc->insns_flags = PPC_INSNS_BASE | PPC_STRING | PPC_MFTB | + PPC_FLOAT | PPC_FLOAT_FSEL | PPC_FLOAT_FRES | + PPC_FLOAT_FRSQRTE | PPC_FLOAT_STFIWX | + PPC_CACHE | PPC_CACHE_ICBI | PPC_CACHE_DCBZ | + PPC_MEM_SYNC | PPC_MEM_EIEIO | + PPC_MEM_TLBIE | PPC_MEM_TLBSYNC | + PPC_SEGMENT | PPC_EXTERN; + pcc->msr_mask = (1ull << MSR_POW) | + (1ull << MSR_ILE) | + (1ull << MSR_EE) | + (1ull << MSR_PR) | + (1ull << MSR_FP) | + (1ull << MSR_ME) | + (1ull << MSR_FE0) | + (1ull << MSR_SE) | + (1ull << MSR_DE) | + (1ull << MSR_FE1) | + (1ull << MSR_EP) | + (1ull << MSR_IR) | + (1ull << MSR_DR) | + (1ull << MSR_PMM) | + (1ull << MSR_RI) | + (1ull << MSR_LE); + pcc->mmu_model = POWERPC_MMU_32B; + pcc->excp_model = POWERPC_EXCP_6xx; + pcc->bus_model = PPC_FLAGS_INPUT_6xx; + pcc->bfd_mach = bfd_mach_ppc_604; + pcc->flags = POWERPC_FLAG_SE | POWERPC_FLAG_BE | + POWERPC_FLAG_PMM | POWERPC_FLAG_BUS_CLK; +} + +POWERPC_FAMILY(604E)(ObjectClass *oc, void *data) +{ + DeviceClass *dc = DEVICE_CLASS(oc); + PowerPCCPUClass *pcc = POWERPC_CPU_CLASS(oc); + + dc->desc = "PowerPC 604E"; + pcc->init_proc = init_proc_604E; + pcc->check_pow = check_pow_nocheck; + pcc->insns_flags = PPC_INSNS_BASE | PPC_STRING | PPC_MFTB | + PPC_FLOAT | PPC_FLOAT_FSEL | PPC_FLOAT_FRES | + PPC_FLOAT_FRSQRTE | PPC_FLOAT_STFIWX | + PPC_CACHE | PPC_CACHE_ICBI | PPC_CACHE_DCBZ | + PPC_MEM_SYNC | PPC_MEM_EIEIO | + PPC_MEM_TLBIE | PPC_MEM_TLBSYNC | + PPC_SEGMENT | PPC_EXTERN; + pcc->msr_mask = (1ull << MSR_POW) | + (1ull << MSR_ILE) | + (1ull << MSR_EE) | + (1ull << MSR_PR) | + (1ull << MSR_FP) | + (1ull << MSR_ME) | + (1ull << MSR_FE0) | + (1ull << MSR_SE) | + (1ull << MSR_DE) | + (1ull << MSR_FE1) | + (1ull << MSR_EP) | + (1ull << MSR_IR) | + (1ull << MSR_DR) | + (1ull << MSR_PMM) | + (1ull << MSR_RI) | + (1ull << MSR_LE); + pcc->mmu_model = POWERPC_MMU_32B; + pcc->excp_model = POWERPC_EXCP_6xx; + pcc->bus_model = PPC_FLAGS_INPUT_6xx; + pcc->bfd_mach = bfd_mach_ppc_604; + pcc->flags = POWERPC_FLAG_SE | POWERPC_FLAG_BE | + POWERPC_FLAG_PMM | POWERPC_FLAG_BUS_CLK; +} diff --git a/target/ppc/cpu_init.c b/target/ppc/cpu_init.c index 28c017b048..b828dc1e88 100644 --- a/target/ppc/cpu_init.c +++ b/target/ppc/cpu_init.c @@ -259,233 +259,6 @@ static void register_iamr_sprs(CPUPPCState *env) } #endif /* TARGET_PPC64 */ -/* SPR specific to PowerPC 604 implementation */ -static void register_604_sprs(CPUPPCState *env) -{ - /* Processor identification */ - spr_register(env, SPR_PIR, "PIR", - SPR_NOACCESS, SPR_NOACCESS, - &spr_read_generic, &spr_write_pir, - 0x00000000); - /* Breakpoints */ - spr_register(env, SPR_IABR, "IABR", - SPR_NOACCESS, SPR_NOACCESS, - &spr_read_generic, &spr_write_generic, - 0x00000000); - - spr_register_kvm(env, SPR_DABR, "DABR", - SPR_NOACCESS, SPR_NOACCESS, - &spr_read_generic, &spr_write_generic, - KVM_REG_PPC_DABR, 0x00000000); - /* Performance counters */ - spr_register(env, SPR_7XX_MMCR0, "MMCR0", - SPR_NOACCESS, SPR_NOACCESS, - &spr_read_generic, &spr_write_generic, - 0x00000000); - - spr_register(env, SPR_7XX_PMC1, "PMC1", - SPR_NOACCESS, SPR_NOACCESS, - &spr_read_generic, &spr_write_generic, - 0x00000000); - - spr_register(env, SPR_7XX_PMC2, "PMC2", - SPR_NOACCESS, SPR_NOACCESS, - &spr_read_generic, &spr_write_generic, - 0x00000000); - - spr_register(env, SPR_7XX_SIAR, "SIAR", - SPR_NOACCESS, SPR_NOACCESS, - &spr_read_generic, SPR_NOACCESS, - 0x00000000); - - spr_register(env, SPR_SDA, "SDA", - SPR_NOACCESS, SPR_NOACCESS, - &spr_read_generic, SPR_NOACCESS, - 0x00000000); - /* External access control */ - spr_register(env, SPR_EAR, "EAR", - SPR_NOACCESS, SPR_NOACCESS, - &spr_read_generic, &spr_write_generic, - 0x00000000); - - /* Hardware implementation registers */ - spr_register(env, SPR_HID0, "HID0", - SPR_NOACCESS, SPR_NOACCESS, - &spr_read_generic, &spr_write_generic, - 0x00000000); -} - -static void register_604e_sprs(CPUPPCState *env) -{ - spr_register(env, SPR_7XX_MMCR1, "MMCR1", - SPR_NOACCESS, SPR_NOACCESS, - &spr_read_generic, &spr_write_generic, - 0x00000000); - - spr_register(env, SPR_7XX_PMC3, "PMC3", - SPR_NOACCESS, SPR_NOACCESS, - &spr_read_generic, &spr_write_generic, - 0x00000000); - - spr_register(env, SPR_7XX_PMC4, "PMC4", - SPR_NOACCESS, SPR_NOACCESS, - &spr_read_generic, &spr_write_generic, - 0x00000000); - /* Hardware implementation registers */ - spr_register(env, SPR_HID1, "HID1", - SPR_NOACCESS, SPR_NOACCESS, - &spr_read_generic, &spr_write_generic, - 0x00000000); -} - -/* SPR specific to PowerPC 603 implementation */ -static void register_603_sprs(CPUPPCState *env) -{ - /* External access control */ - spr_register(env, SPR_EAR, "EAR", - SPR_NOACCESS, SPR_NOACCESS, - &spr_read_generic, &spr_write_generic, - 0x00000000); - /* Breakpoints */ - spr_register(env, SPR_IABR, "IABR", - SPR_NOACCESS, SPR_NOACCESS, - &spr_read_generic, &spr_write_generic, - 0x00000000); - - spr_register(env, SPR_HID0, "HID0", - SPR_NOACCESS, SPR_NOACCESS, - &spr_read_generic, &spr_write_generic, - 0x00000000); - - spr_register(env, SPR_HID1, "HID1", - SPR_NOACCESS, SPR_NOACCESS, - &spr_read_generic, &spr_write_generic, - 0x00000000); -} - -static void register_e300_sprs(CPUPPCState *env) -{ - /* hardware implementation registers */ - spr_register(env, SPR_HID2, "HID2", - SPR_NOACCESS, SPR_NOACCESS, - &spr_read_generic, &spr_write_generic, - 0x00000000); - /* Breakpoints */ - spr_register(env, SPR_DABR, "DABR", - SPR_NOACCESS, SPR_NOACCESS, - &spr_read_generic, &spr_write_generic, - 0x00000000); - - spr_register(env, SPR_DABR2, "DABR2", - SPR_NOACCESS, SPR_NOACCESS, - &spr_read_generic, &spr_write_generic, - 0x00000000); - - spr_register(env, SPR_IABR2, "IABR2", - SPR_NOACCESS, SPR_NOACCESS, - &spr_read_generic, &spr_write_generic, - 0x00000000); - - spr_register(env, SPR_IBCR, "IBCR", - SPR_NOACCESS, SPR_NOACCESS, - &spr_read_generic, &spr_write_generic, - 0x00000000); - - spr_register(env, SPR_DBCR, "DBCR", - SPR_NOACCESS, SPR_NOACCESS, - &spr_read_generic, &spr_write_generic, - 0x00000000); -} - -/* SPR specific to PowerPC G2 implementation */ -static void register_G2_sprs(CPUPPCState *env) -{ - /* Memory base address */ - /* MBAR */ - spr_register(env, SPR_MBAR, "MBAR", - SPR_NOACCESS, SPR_NOACCESS, - &spr_read_generic, &spr_write_generic, - 0x00000000); - /* Exception processing */ - spr_register(env, SPR_BOOKE_CSRR0, "CSRR0", - SPR_NOACCESS, SPR_NOACCESS, - &spr_read_generic, &spr_write_generic, - 0x00000000); - spr_register(env, SPR_BOOKE_CSRR1, "CSRR1", - SPR_NOACCESS, SPR_NOACCESS, - &spr_read_generic, &spr_write_generic, - 0x00000000); - /* Breakpoints */ - spr_register(env, SPR_DABR, "DABR", - SPR_NOACCESS, SPR_NOACCESS, - &spr_read_generic, &spr_write_generic, - 0x00000000); - - spr_register(env, SPR_DABR2, "DABR2", - SPR_NOACCESS, SPR_NOACCESS, - &spr_read_generic, &spr_write_generic, - 0x00000000); - - spr_register(env, SPR_IABR, "IABR", - SPR_NOACCESS, SPR_NOACCESS, - &spr_read_generic, &spr_write_generic, - 0x00000000); - - spr_register(env, SPR_IABR2, "IABR2", - SPR_NOACCESS, SPR_NOACCESS, - &spr_read_generic, &spr_write_generic, - 0x00000000); - - spr_register(env, SPR_IBCR, "IBCR", - SPR_NOACCESS, SPR_NOACCESS, - &spr_read_generic, &spr_write_generic, - 0x00000000); - - spr_register(env, SPR_DBCR, "DBCR", - SPR_NOACCESS, SPR_NOACCESS, - &spr_read_generic, &spr_write_generic, - 0x00000000); - - /* External access control */ - spr_register(env, SPR_EAR, "EAR", - SPR_NOACCESS, SPR_NOACCESS, - &spr_read_generic, &spr_write_generic, - 0x00000000); - /* Hardware implementation register */ - spr_register(env, SPR_HID0, "HID0", - SPR_NOACCESS, SPR_NOACCESS, - &spr_read_generic, &spr_write_generic, - 0x00000000); - - spr_register(env, SPR_HID1, "HID1", - SPR_NOACCESS, SPR_NOACCESS, - &spr_read_generic, &spr_write_generic, - 0x00000000); - - spr_register(env, SPR_HID2, "HID2", - SPR_NOACCESS, SPR_NOACCESS, - &spr_read_generic, &spr_write_generic, - 0x00000000); - - /* SGPRs */ - spr_register(env, SPR_SPRG4, "SPRG4", - SPR_NOACCESS, SPR_NOACCESS, - &spr_read_generic, &spr_write_generic, - 0x00000000); - spr_register(env, SPR_SPRG5, "SPRG5", - SPR_NOACCESS, SPR_NOACCESS, - &spr_read_generic, &spr_write_generic, - 0x00000000); - spr_register(env, SPR_SPRG6, "SPRG6", - SPR_NOACCESS, SPR_NOACCESS, - &spr_read_generic, &spr_write_generic, - 0x00000000); - spr_register(env, SPR_SPRG7, "SPRG7", - SPR_NOACCESS, SPR_NOACCESS, - &spr_read_generic, &spr_write_generic, - 0x00000000); -} - static void register_74xx_sprs(CPUPPCState *env) { /* Breakpoints */ @@ -1081,361 +854,6 @@ static void register_440_sprs(CPUPPCState *env) 0x00000000); } -static void register_5xx_8xx_sprs(CPUPPCState *env) -{ - /* Exception processing */ - spr_register_kvm(env, SPR_DSISR, "DSISR", - SPR_NOACCESS, SPR_NOACCESS, - &spr_read_generic, &spr_write_generic, - KVM_REG_PPC_DSISR, 0x00000000); - spr_register_kvm(env, SPR_DAR, "DAR", - SPR_NOACCESS, SPR_NOACCESS, - &spr_read_generic, &spr_write_generic, - KVM_REG_PPC_DAR, 0x00000000); - /* Timer */ - spr_register(env, SPR_DECR, "DECR", - SPR_NOACCESS, SPR_NOACCESS, - &spr_read_decr, &spr_write_decr, - 0x00000000); - - spr_register(env, SPR_MPC_EIE, "EIE", - SPR_NOACCESS, SPR_NOACCESS, - &spr_read_generic, &spr_write_generic, - 0x00000000); - - spr_register(env, SPR_MPC_EID, "EID", - SPR_NOACCESS, SPR_NOACCESS, - &spr_read_generic, &spr_write_generic, - 0x00000000); - - spr_register(env, SPR_MPC_NRI, "NRI", - SPR_NOACCESS, SPR_NOACCESS, - &spr_read_generic, &spr_write_generic, - 0x00000000); - - spr_register(env, SPR_MPC_CMPA, "CMPA", - SPR_NOACCESS, SPR_NOACCESS, - &spr_read_generic, &spr_write_generic, - 0x00000000); - - spr_register(env, SPR_MPC_CMPB, "CMPB", - SPR_NOACCESS, SPR_NOACCESS, - &spr_read_generic, &spr_write_generic, - 0x00000000); - - spr_register(env, SPR_MPC_CMPC, "CMPC", - SPR_NOACCESS, SPR_NOACCESS, - &spr_read_generic, &spr_write_generic, - 0x00000000); - - spr_register(env, SPR_MPC_CMPD, "CMPD", - SPR_NOACCESS, SPR_NOACCESS, - &spr_read_generic, &spr_write_generic, - 0x00000000); - - spr_register(env, SPR_MPC_ECR, "ECR", - SPR_NOACCESS, SPR_NOACCESS, - &spr_read_generic, &spr_write_generic, - 0x00000000); - - spr_register(env, SPR_MPC_DER, "DER", - SPR_NOACCESS, SPR_NOACCESS, - &spr_read_generic, &spr_write_generic, - 0x00000000); - - spr_register(env, SPR_MPC_COUNTA, "COUNTA", - SPR_NOACCESS, SPR_NOACCESS, - &spr_read_generic, &spr_write_generic, - 0x00000000); - - spr_register(env, SPR_MPC_COUNTB, "COUNTB", - SPR_NOACCESS, SPR_NOACCESS, - &spr_read_generic, &spr_write_generic, - 0x00000000); - - spr_register(env, SPR_MPC_CMPE, "CMPE", - SPR_NOACCESS, SPR_NOACCESS, - &spr_read_generic, &spr_write_generic, - 0x00000000); - - spr_register(env, SPR_MPC_CMPF, "CMPF", - SPR_NOACCESS, SPR_NOACCESS, - &spr_read_generic, &spr_write_generic, - 0x00000000); - - spr_register(env, SPR_MPC_CMPG, "CMPG", - SPR_NOACCESS, SPR_NOACCESS, - &spr_read_generic, &spr_write_generic, - 0x00000000); - - spr_register(env, SPR_MPC_CMPH, "CMPH", - SPR_NOACCESS, SPR_NOACCESS, - &spr_read_generic, &spr_write_generic, - 0x00000000); - - spr_register(env, SPR_MPC_LCTRL1, "LCTRL1", - SPR_NOACCESS, SPR_NOACCESS, - &spr_read_generic, &spr_write_generic, - 0x00000000); - - spr_register(env, SPR_MPC_LCTRL2, "LCTRL2", - SPR_NOACCESS, SPR_NOACCESS, - &spr_read_generic, &spr_write_generic, - 0x00000000); - - spr_register(env, SPR_MPC_BAR, "BAR", - SPR_NOACCESS, SPR_NOACCESS, - &spr_read_generic, &spr_write_generic, - 0x00000000); - - spr_register(env, SPR_MPC_DPDR, "DPDR", - SPR_NOACCESS, SPR_NOACCESS, - &spr_read_generic, &spr_write_generic, - 0x00000000); - - spr_register(env, SPR_MPC_IMMR, "IMMR", - SPR_NOACCESS, SPR_NOACCESS, - &spr_read_generic, &spr_write_generic, - 0x00000000); -} - -static void register_5xx_sprs(CPUPPCState *env) -{ - spr_register(env, SPR_RCPU_MI_GRA, "MI_GRA", - SPR_NOACCESS, SPR_NOACCESS, - &spr_read_generic, &spr_write_generic, - 0x00000000); - - spr_register(env, SPR_RCPU_L2U_GRA, "L2U_GRA", - SPR_NOACCESS, SPR_NOACCESS, - &spr_read_generic, &spr_write_generic, - 0x00000000); - - spr_register(env, SPR_RPCU_BBCMCR, "L2U_BBCMCR", - SPR_NOACCESS, SPR_NOACCESS, - &spr_read_generic, &spr_write_generic, - 0x00000000); - - spr_register(env, SPR_RCPU_L2U_MCR, "L2U_MCR", - SPR_NOACCESS, SPR_NOACCESS, - &spr_read_generic, &spr_write_generic, - 0x00000000); - - spr_register(env, SPR_RCPU_MI_RBA0, "MI_RBA0", - SPR_NOACCESS, SPR_NOACCESS, - &spr_read_generic, &spr_write_generic, - 0x00000000); - - spr_register(env, SPR_RCPU_MI_RBA1, "MI_RBA1", - SPR_NOACCESS, SPR_NOACCESS, - &spr_read_generic, &spr_write_generic, - 0x00000000); - - spr_register(env, SPR_RCPU_MI_RBA2, "MI_RBA2", - SPR_NOACCESS, SPR_NOACCESS, - &spr_read_generic, &spr_write_generic, - 0x00000000); - - spr_register(env, SPR_RCPU_MI_RBA3, "MI_RBA3", - SPR_NOACCESS, SPR_NOACCESS, - &spr_read_generic, &spr_write_generic, - 0x00000000); - - spr_register(env, SPR_RCPU_L2U_RBA0, "L2U_RBA0", - SPR_NOACCESS, SPR_NOACCESS, - &spr_read_generic, &spr_write_generic, - 0x00000000); - - spr_register(env, SPR_RCPU_L2U_RBA1, "L2U_RBA1", - SPR_NOACCESS, SPR_NOACCESS, - &spr_read_generic, &spr_write_generic, - 0x00000000); - - spr_register(env, SPR_RCPU_L2U_RBA2, "L2U_RBA2", - SPR_NOACCESS, SPR_NOACCESS, - &spr_read_generic, &spr_write_generic, - 0x00000000); - - spr_register(env, SPR_RCPU_L2U_RBA3, "L2U_RBA3", - SPR_NOACCESS, SPR_NOACCESS, - &spr_read_generic, &spr_write_generic, - 0x00000000); - - spr_register(env, SPR_RCPU_MI_RA0, "MI_RA0", - SPR_NOACCESS, SPR_NOACCESS, - &spr_read_generic, &spr_write_generic, - 0x00000000); - - spr_register(env, SPR_RCPU_MI_RA1, "MI_RA1", - SPR_NOACCESS, SPR_NOACCESS, - &spr_read_generic, &spr_write_generic, - 0x00000000); - - spr_register(env, SPR_RCPU_MI_RA2, "MI_RA2", - SPR_NOACCESS, SPR_NOACCESS, - &spr_read_generic, &spr_write_generic, - 0x00000000); - - spr_register(env, SPR_RCPU_MI_RA3, "MI_RA3", - SPR_NOACCESS, SPR_NOACCESS, - &spr_read_generic, &spr_write_generic, - 0x00000000); - - spr_register(env, SPR_RCPU_L2U_RA0, "L2U_RA0", - SPR_NOACCESS, SPR_NOACCESS, - &spr_read_generic, &spr_write_generic, - 0x00000000); - - spr_register(env, SPR_RCPU_L2U_RA1, "L2U_RA1", - SPR_NOACCESS, SPR_NOACCESS, - &spr_read_generic, &spr_write_generic, - 0x00000000); - - spr_register(env, SPR_RCPU_L2U_RA2, "L2U_RA2", - SPR_NOACCESS, SPR_NOACCESS, - &spr_read_generic, &spr_write_generic, - 0x00000000); - - spr_register(env, SPR_RCPU_L2U_RA3, "L2U_RA3", - SPR_NOACCESS, SPR_NOACCESS, - &spr_read_generic, &spr_write_generic, - 0x00000000); - - spr_register(env, SPR_RCPU_FPECR, "FPECR", - SPR_NOACCESS, SPR_NOACCESS, - &spr_read_generic, &spr_write_generic, - 0x00000000); -} - -static void register_8xx_sprs(CPUPPCState *env) -{ - - spr_register(env, SPR_MPC_IC_CST, "IC_CST", - SPR_NOACCESS, SPR_NOACCESS, - &spr_read_generic, &spr_write_generic, - 0x00000000); - - spr_register(env, SPR_MPC_IC_ADR, "IC_ADR", - SPR_NOACCESS, SPR_NOACCESS, - &spr_read_generic, &spr_write_generic, - 0x00000000); - - spr_register(env, SPR_MPC_IC_DAT, "IC_DAT", - SPR_NOACCESS, SPR_NOACCESS, - &spr_read_generic, &spr_write_generic, - 0x00000000); - - spr_register(env, SPR_MPC_DC_CST, "DC_CST", - SPR_NOACCESS, SPR_NOACCESS, - &spr_read_generic, &spr_write_generic, - 0x00000000); - - spr_register(env, SPR_MPC_DC_ADR, "DC_ADR", - SPR_NOACCESS, SPR_NOACCESS, - &spr_read_generic, &spr_write_generic, - 0x00000000); - - spr_register(env, SPR_MPC_DC_DAT, "DC_DAT", - SPR_NOACCESS, SPR_NOACCESS, - &spr_read_generic, &spr_write_generic, - 0x00000000); - - spr_register(env, SPR_MPC_MI_CTR, "MI_CTR", - SPR_NOACCESS, SPR_NOACCESS, - &spr_read_generic, &spr_write_generic, - 0x00000000); - - spr_register(env, SPR_MPC_MI_AP, "MI_AP", - SPR_NOACCESS, SPR_NOACCESS, - &spr_read_generic, &spr_write_generic, - 0x00000000); - - spr_register(env, SPR_MPC_MI_EPN, "MI_EPN", - SPR_NOACCESS, SPR_NOACCESS, - &spr_read_generic, &spr_write_generic, - 0x00000000); - - spr_register(env, SPR_MPC_MI_TWC, "MI_TWC", - SPR_NOACCESS, SPR_NOACCESS, - &spr_read_generic, &spr_write_generic, - 0x00000000); - - spr_register(env, SPR_MPC_MI_RPN, "MI_RPN", - SPR_NOACCESS, SPR_NOACCESS, - &spr_read_generic, &spr_write_generic, - 0x00000000); - - spr_register(env, SPR_MPC_MI_DBCAM, "MI_DBCAM", - SPR_NOACCESS, SPR_NOACCESS, - &spr_read_generic, &spr_write_generic, - 0x00000000); - - spr_register(env, SPR_MPC_MI_DBRAM0, "MI_DBRAM0", - SPR_NOACCESS, SPR_NOACCESS, - &spr_read_generic, &spr_write_generic, - 0x00000000); - - spr_register(env, SPR_MPC_MI_DBRAM1, "MI_DBRAM1", - SPR_NOACCESS, SPR_NOACCESS, - &spr_read_generic, &spr_write_generic, - 0x00000000); - - spr_register(env, SPR_MPC_MD_CTR, "MD_CTR", - SPR_NOACCESS, SPR_NOACCESS, - &spr_read_generic, &spr_write_generic, - 0x00000000); - - spr_register(env, SPR_MPC_MD_CASID, "MD_CASID", - SPR_NOACCESS, SPR_NOACCESS, - &spr_read_generic, &spr_write_generic, - 0x00000000); - - spr_register(env, SPR_MPC_MD_AP, "MD_AP", - SPR_NOACCESS, SPR_NOACCESS, - &spr_read_generic, &spr_write_generic, - 0x00000000); - - spr_register(env, SPR_MPC_MD_EPN, "MD_EPN", - SPR_NOACCESS, SPR_NOACCESS, - &spr_read_generic, &spr_write_generic, - 0x00000000); - - spr_register(env, SPR_MPC_MD_TWB, "MD_TWB", - SPR_NOACCESS, SPR_NOACCESS, - &spr_read_generic, &spr_write_generic, - 0x00000000); - - spr_register(env, SPR_MPC_MD_TWC, "MD_TWC", - SPR_NOACCESS, SPR_NOACCESS, - &spr_read_generic, &spr_write_generic, - 0x00000000); - - spr_register(env, SPR_MPC_MD_RPN, "MD_RPN", - SPR_NOACCESS, SPR_NOACCESS, - &spr_read_generic, &spr_write_generic, - 0x00000000); - - spr_register(env, SPR_MPC_MD_TW, "MD_TW", - SPR_NOACCESS, SPR_NOACCESS, - &spr_read_generic, &spr_write_generic, - 0x00000000); - - spr_register(env, SPR_MPC_MD_DBCAM, "MD_DBCAM", - SPR_NOACCESS, SPR_NOACCESS, - &spr_read_generic, &spr_write_generic, - 0x00000000); - - spr_register(env, SPR_MPC_MD_DBRAM0, "MD_DBRAM0", - SPR_NOACCESS, SPR_NOACCESS, - &spr_read_generic, &spr_write_generic, - 0x00000000); - - spr_register(env, SPR_MPC_MD_DBRAM1, "MD_DBRAM1", - SPR_NOACCESS, SPR_NOACCESS, - &spr_read_generic, &spr_write_generic, - 0x00000000); -} - /* * AMR => SPR 29 (Power 2.04) * CTRL => SPR 136 (Power 2.04) @@ -1467,87 +885,6 @@ static void register_8xx_sprs(CPUPPCState *env) /*****************************************************************************/ /* Exception vectors models */ -static void init_excp_MPC5xx(CPUPPCState *env) -{ -#if !defined(CONFIG_USER_ONLY) - env->excp_vectors[POWERPC_EXCP_RESET] = 0x00000100; - env->excp_vectors[POWERPC_EXCP_MCHECK] = 0x00000200; - env->excp_vectors[POWERPC_EXCP_EXTERNAL] = 0x00000500; - env->excp_vectors[POWERPC_EXCP_ALIGN] = 0x00000600; - env->excp_vectors[POWERPC_EXCP_PROGRAM] = 0x00000700; - env->excp_vectors[POWERPC_EXCP_FPU] = 0x00000800; - env->excp_vectors[POWERPC_EXCP_DECR] = 0x00000900; - env->excp_vectors[POWERPC_EXCP_SYSCALL] = 0x00000C00; - env->excp_vectors[POWERPC_EXCP_TRACE] = 0x00000D00; - env->excp_vectors[POWERPC_EXCP_FPA] = 0x00000E00; - env->excp_vectors[POWERPC_EXCP_EMUL] = 0x00001000; - env->excp_vectors[POWERPC_EXCP_DABR] = 0x00001C00; - env->excp_vectors[POWERPC_EXCP_IABR] = 0x00001C00; - env->excp_vectors[POWERPC_EXCP_MEXTBR] = 0x00001E00; - env->excp_vectors[POWERPC_EXCP_NMEXTBR] = 0x00001F00; - env->ivor_mask = 0x0000FFF0UL; - env->ivpr_mask = 0xFFFF0000UL; - /* Hardware reset vector */ - env->hreset_vector = 0x00000100UL; -#endif -} - -static void init_excp_MPC8xx(CPUPPCState *env) -{ -#if !defined(CONFIG_USER_ONLY) - env->excp_vectors[POWERPC_EXCP_RESET] = 0x00000100; - env->excp_vectors[POWERPC_EXCP_MCHECK] = 0x00000200; - env->excp_vectors[POWERPC_EXCP_DSI] = 0x00000300; - env->excp_vectors[POWERPC_EXCP_ISI] = 0x00000400; - env->excp_vectors[POWERPC_EXCP_EXTERNAL] = 0x00000500; - env->excp_vectors[POWERPC_EXCP_ALIGN] = 0x00000600; - env->excp_vectors[POWERPC_EXCP_PROGRAM] = 0x00000700; - env->excp_vectors[POWERPC_EXCP_FPU] = 0x00000800; - env->excp_vectors[POWERPC_EXCP_DECR] = 0x00000900; - env->excp_vectors[POWERPC_EXCP_SYSCALL] = 0x00000C00; - env->excp_vectors[POWERPC_EXCP_TRACE] = 0x00000D00; - env->excp_vectors[POWERPC_EXCP_FPA] = 0x00000E00; - env->excp_vectors[POWERPC_EXCP_EMUL] = 0x00001000; - env->excp_vectors[POWERPC_EXCP_ITLB] = 0x00001100; - env->excp_vectors[POWERPC_EXCP_DTLB] = 0x00001200; - env->excp_vectors[POWERPC_EXCP_ITLBE] = 0x00001300; - env->excp_vectors[POWERPC_EXCP_DTLBE] = 0x00001400; - env->excp_vectors[POWERPC_EXCP_DABR] = 0x00001C00; - env->excp_vectors[POWERPC_EXCP_IABR] = 0x00001C00; - env->excp_vectors[POWERPC_EXCP_MEXTBR] = 0x00001E00; - env->excp_vectors[POWERPC_EXCP_NMEXTBR] = 0x00001F00; - env->ivor_mask = 0x0000FFF0UL; - env->ivpr_mask = 0xFFFF0000UL; - /* Hardware reset vector */ - env->hreset_vector = 0x00000100UL; -#endif -} - -static void init_excp_G2(CPUPPCState *env) -{ -#if !defined(CONFIG_USER_ONLY) - env->excp_vectors[POWERPC_EXCP_RESET] = 0x00000100; - env->excp_vectors[POWERPC_EXCP_MCHECK] = 0x00000200; - env->excp_vectors[POWERPC_EXCP_DSI] = 0x00000300; - env->excp_vectors[POWERPC_EXCP_ISI] = 0x00000400; - env->excp_vectors[POWERPC_EXCP_EXTERNAL] = 0x00000500; - env->excp_vectors[POWERPC_EXCP_ALIGN] = 0x00000600; - env->excp_vectors[POWERPC_EXCP_PROGRAM] = 0x00000700; - env->excp_vectors[POWERPC_EXCP_FPU] = 0x00000800; - env->excp_vectors[POWERPC_EXCP_DECR] = 0x00000900; - env->excp_vectors[POWERPC_EXCP_CRITICAL] = 0x00000A00; - env->excp_vectors[POWERPC_EXCP_SYSCALL] = 0x00000C00; - env->excp_vectors[POWERPC_EXCP_TRACE] = 0x00000D00; - env->excp_vectors[POWERPC_EXCP_IFTLB] = 0x00001000; - env->excp_vectors[POWERPC_EXCP_DLTLB] = 0x00001100; - env->excp_vectors[POWERPC_EXCP_DSTLB] = 0x00001200; - env->excp_vectors[POWERPC_EXCP_IABR] = 0x00001300; - env->excp_vectors[POWERPC_EXCP_SMI] = 0x00001400; - /* Hardware reset vector */ - env->hreset_vector = 0x00000100UL; -#endif -} - static void init_excp_e200(CPUPPCState *env, target_ulong ivpr_mask) { #if !defined(CONFIG_USER_ONLY) @@ -1610,52 +947,6 @@ static void init_excp_BookE(CPUPPCState *env) #endif } -static void init_excp_603(CPUPPCState *env) -{ -#if !defined(CONFIG_USER_ONLY) - env->excp_vectors[POWERPC_EXCP_RESET] = 0x00000100; - env->excp_vectors[POWERPC_EXCP_MCHECK] = 0x00000200; - env->excp_vectors[POWERPC_EXCP_DSI] = 0x00000300; - env->excp_vectors[POWERPC_EXCP_ISI] = 0x00000400; - env->excp_vectors[POWERPC_EXCP_EXTERNAL] = 0x00000500; - env->excp_vectors[POWERPC_EXCP_ALIGN] = 0x00000600; - env->excp_vectors[POWERPC_EXCP_PROGRAM] = 0x00000700; - env->excp_vectors[POWERPC_EXCP_FPU] = 0x00000800; - env->excp_vectors[POWERPC_EXCP_DECR] = 0x00000900; - env->excp_vectors[POWERPC_EXCP_SYSCALL] = 0x00000C00; - env->excp_vectors[POWERPC_EXCP_TRACE] = 0x00000D00; - env->excp_vectors[POWERPC_EXCP_IFTLB] = 0x00001000; - env->excp_vectors[POWERPC_EXCP_DLTLB] = 0x00001100; - env->excp_vectors[POWERPC_EXCP_DSTLB] = 0x00001200; - env->excp_vectors[POWERPC_EXCP_IABR] = 0x00001300; - env->excp_vectors[POWERPC_EXCP_SMI] = 0x00001400; - /* Hardware reset vector */ - env->hreset_vector = 0x00000100UL; -#endif -} - -static void init_excp_604(CPUPPCState *env) -{ -#if !defined(CONFIG_USER_ONLY) - env->excp_vectors[POWERPC_EXCP_RESET] = 0x00000100; - env->excp_vectors[POWERPC_EXCP_MCHECK] = 0x00000200; - env->excp_vectors[POWERPC_EXCP_DSI] = 0x00000300; - env->excp_vectors[POWERPC_EXCP_ISI] = 0x00000400; - env->excp_vectors[POWERPC_EXCP_EXTERNAL] = 0x00000500; - env->excp_vectors[POWERPC_EXCP_ALIGN] = 0x00000600; - env->excp_vectors[POWERPC_EXCP_PROGRAM] = 0x00000700; - env->excp_vectors[POWERPC_EXCP_FPU] = 0x00000800; - env->excp_vectors[POWERPC_EXCP_DECR] = 0x00000900; - env->excp_vectors[POWERPC_EXCP_SYSCALL] = 0x00000C00; - env->excp_vectors[POWERPC_EXCP_TRACE] = 0x00000D00; - env->excp_vectors[POWERPC_EXCP_PERFM] = 0x00000F00; - env->excp_vectors[POWERPC_EXCP_IABR] = 0x00001300; - env->excp_vectors[POWERPC_EXCP_SMI] = 0x00001400; - /* Hardware reset vector */ - env->hreset_vector = 0x00000100UL; -#endif -} - static void init_excp_7x0(CPUPPCState *env) { #if !defined(CONFIG_USER_ONLY) @@ -2192,186 +1483,6 @@ POWERPC_FAMILY(440x5wDFPU)(ObjectClass *oc, void *data) POWERPC_FLAG_DE | POWERPC_FLAG_BUS_CLK; } -static void init_proc_MPC5xx(CPUPPCState *env) -{ - register_5xx_8xx_sprs(env); - register_5xx_sprs(env); - init_excp_MPC5xx(env); - env->dcache_line_size = 32; - env->icache_line_size = 32; - /* XXX: TODO: allocate internal IRQ controller */ -} - -POWERPC_FAMILY(MPC5xx)(ObjectClass *oc, void *data) -{ - DeviceClass *dc = DEVICE_CLASS(oc); - PowerPCCPUClass *pcc = POWERPC_CPU_CLASS(oc); - - dc->desc = "Freescale 5xx cores (aka RCPU)"; - pcc->init_proc = init_proc_MPC5xx; - pcc->check_pow = check_pow_none; - pcc->insns_flags = PPC_INSNS_BASE | PPC_STRING | - PPC_MEM_EIEIO | PPC_MEM_SYNC | - PPC_CACHE_ICBI | PPC_FLOAT | PPC_FLOAT_STFIWX | - PPC_MFTB; - pcc->msr_mask = (1ull << MSR_ILE) | - (1ull << MSR_EE) | - (1ull << MSR_PR) | - (1ull << MSR_FP) | - (1ull << MSR_ME) | - (1ull << MSR_FE0) | - (1ull << MSR_SE) | - (1ull << MSR_DE) | - (1ull << MSR_FE1) | - (1ull << MSR_EP) | - (1ull << MSR_RI) | - (1ull << MSR_LE); - pcc->mmu_model = POWERPC_MMU_REAL; - pcc->excp_model = POWERPC_EXCP_6xx; - pcc->bus_model = PPC_FLAGS_INPUT_RCPU; - pcc->bfd_mach = bfd_mach_ppc_505; - pcc->flags = POWERPC_FLAG_SE | POWERPC_FLAG_BE | - POWERPC_FLAG_BUS_CLK; -} - -static void init_proc_MPC8xx(CPUPPCState *env) -{ - register_5xx_8xx_sprs(env); - register_8xx_sprs(env); - init_excp_MPC8xx(env); - env->dcache_line_size = 32; - env->icache_line_size = 32; - /* XXX: TODO: allocate internal IRQ controller */ -} - -POWERPC_FAMILY(MPC8xx)(ObjectClass *oc, void *data) -{ - DeviceClass *dc = DEVICE_CLASS(oc); - PowerPCCPUClass *pcc = POWERPC_CPU_CLASS(oc); - - dc->desc = "Freescale 8xx cores (aka PowerQUICC)"; - pcc->init_proc = init_proc_MPC8xx; - pcc->check_pow = check_pow_none; - pcc->insns_flags = PPC_INSNS_BASE | PPC_STRING | - PPC_MEM_EIEIO | PPC_MEM_SYNC | - PPC_CACHE_ICBI | PPC_MFTB; - pcc->msr_mask = (1ull << MSR_ILE) | - (1ull << MSR_EE) | - (1ull << MSR_PR) | - (1ull << MSR_FP) | - (1ull << MSR_ME) | - (1ull << MSR_SE) | - (1ull << MSR_DE) | - (1ull << MSR_EP) | - (1ull << MSR_IR) | - (1ull << MSR_DR) | - (1ull << MSR_RI) | - (1ull << MSR_LE); - pcc->mmu_model = POWERPC_MMU_MPC8xx; - pcc->excp_model = POWERPC_EXCP_6xx; - pcc->bus_model = PPC_FLAGS_INPUT_RCPU; - pcc->bfd_mach = bfd_mach_ppc_860; - pcc->flags = POWERPC_FLAG_SE | POWERPC_FLAG_BE | - POWERPC_FLAG_BUS_CLK; -} - -/* Freescale 82xx cores (aka PowerQUICC-II) */ - -static void init_proc_G2(CPUPPCState *env) -{ - register_non_embedded_sprs(env); - register_sdr1_sprs(env); - register_G2_sprs(env); - - /* Memory management */ - register_low_BATs(env); - register_high_BATs(env); - register_6xx_7xx_soft_tlb(env, 64, 2); - init_excp_G2(env); - env->dcache_line_size = 32; - env->icache_line_size = 32; - /* Allocate hardware IRQ controller */ - ppc6xx_irq_init(env_archcpu(env)); -} - -POWERPC_FAMILY(G2)(ObjectClass *oc, void *data) -{ - DeviceClass *dc = DEVICE_CLASS(oc); - PowerPCCPUClass *pcc = POWERPC_CPU_CLASS(oc); - - dc->desc = "PowerPC G2"; - pcc->init_proc = init_proc_G2; - pcc->check_pow = check_pow_hid0; - pcc->insns_flags = PPC_INSNS_BASE | PPC_STRING | PPC_MFTB | - PPC_FLOAT | PPC_FLOAT_FSEL | PPC_FLOAT_FRES | - PPC_FLOAT_STFIWX | - PPC_CACHE | PPC_CACHE_ICBI | PPC_CACHE_DCBZ | - PPC_MEM_SYNC | PPC_MEM_EIEIO | - PPC_MEM_TLBIE | PPC_MEM_TLBSYNC | PPC_6xx_TLB | - PPC_SEGMENT | PPC_EXTERN; - pcc->msr_mask = (1ull << MSR_POW) | - (1ull << MSR_TGPR) | - (1ull << MSR_EE) | - (1ull << MSR_PR) | - (1ull << MSR_FP) | - (1ull << MSR_ME) | - (1ull << MSR_FE0) | - (1ull << MSR_SE) | - (1ull << MSR_DE) | - (1ull << MSR_FE1) | - (1ull << MSR_AL) | - (1ull << MSR_EP) | - (1ull << MSR_IR) | - (1ull << MSR_DR) | - (1ull << MSR_RI); - pcc->mmu_model = POWERPC_MMU_SOFT_6xx; - pcc->excp_model = POWERPC_EXCP_6xx; - pcc->bus_model = PPC_FLAGS_INPUT_6xx; - pcc->bfd_mach = bfd_mach_ppc_ec603e; - pcc->flags = POWERPC_FLAG_TGPR | POWERPC_FLAG_SE | - POWERPC_FLAG_BE | POWERPC_FLAG_BUS_CLK; -} - -POWERPC_FAMILY(G2LE)(ObjectClass *oc, void *data) -{ - DeviceClass *dc = DEVICE_CLASS(oc); - PowerPCCPUClass *pcc = POWERPC_CPU_CLASS(oc); - - dc->desc = "PowerPC G2LE"; - pcc->init_proc = init_proc_G2; - pcc->check_pow = check_pow_hid0; - pcc->insns_flags = PPC_INSNS_BASE | PPC_STRING | PPC_MFTB | - PPC_FLOAT | PPC_FLOAT_FSEL | PPC_FLOAT_FRES | - PPC_FLOAT_STFIWX | - PPC_CACHE | PPC_CACHE_ICBI | PPC_CACHE_DCBZ | - PPC_MEM_SYNC | PPC_MEM_EIEIO | - PPC_MEM_TLBIE | PPC_MEM_TLBSYNC | PPC_6xx_TLB | - PPC_SEGMENT | PPC_EXTERN; - pcc->msr_mask = (1ull << MSR_POW) | - (1ull << MSR_TGPR) | - (1ull << MSR_ILE) | - (1ull << MSR_EE) | - (1ull << MSR_PR) | - (1ull << MSR_FP) | - (1ull << MSR_ME) | - (1ull << MSR_FE0) | - (1ull << MSR_SE) | - (1ull << MSR_DE) | - (1ull << MSR_FE1) | - (1ull << MSR_AL) | - (1ull << MSR_EP) | - (1ull << MSR_IR) | - (1ull << MSR_DR) | - (1ull << MSR_RI) | - (1ull << MSR_LE); - pcc->mmu_model = POWERPC_MMU_SOFT_6xx; - pcc->excp_model = POWERPC_EXCP_6xx; - pcc->bus_model = PPC_FLAGS_INPUT_6xx; - pcc->bfd_mach = bfd_mach_ppc_ec603e; - pcc->flags = POWERPC_FLAG_TGPR | POWERPC_FLAG_SE | - POWERPC_FLAG_BE | POWERPC_FLAG_BUS_CLK; -} - static void init_proc_e200(CPUPPCState *env) { register_BookE_sprs(env, 0x000000070000FFFFULL); @@ -2991,246 +2102,6 @@ POWERPC_FAMILY(e6500)(ObjectClass *oc, void *data) #endif -/* Non-embedded PowerPC */ -static void init_proc_603(CPUPPCState *env) -{ - register_non_embedded_sprs(env); - register_sdr1_sprs(env); - register_603_sprs(env); - - /* Memory management */ - register_low_BATs(env); - register_6xx_7xx_soft_tlb(env, 64, 2); - init_excp_603(env); - env->dcache_line_size = 32; - env->icache_line_size = 32; - /* Allocate hardware IRQ controller */ - ppc6xx_irq_init(env_archcpu(env)); -} - -POWERPC_FAMILY(603)(ObjectClass *oc, void *data) -{ - DeviceClass *dc = DEVICE_CLASS(oc); - PowerPCCPUClass *pcc = POWERPC_CPU_CLASS(oc); - - dc->desc = "PowerPC 603"; - pcc->init_proc = init_proc_603; - pcc->check_pow = check_pow_hid0; - pcc->insns_flags = PPC_INSNS_BASE | PPC_STRING | PPC_MFTB | - PPC_FLOAT | PPC_FLOAT_FSEL | PPC_FLOAT_FRES | - PPC_FLOAT_FRSQRTE | PPC_FLOAT_STFIWX | - PPC_CACHE | PPC_CACHE_ICBI | PPC_CACHE_DCBZ | - PPC_MEM_SYNC | PPC_MEM_EIEIO | - PPC_MEM_TLBIE | PPC_MEM_TLBSYNC | PPC_6xx_TLB | - PPC_SEGMENT | PPC_EXTERN; - pcc->msr_mask = (1ull << MSR_POW) | - (1ull << MSR_TGPR) | - (1ull << MSR_ILE) | - (1ull << MSR_EE) | - (1ull << MSR_PR) | - (1ull << MSR_FP) | - (1ull << MSR_ME) | - (1ull << MSR_FE0) | - (1ull << MSR_SE) | - (1ull << MSR_DE) | - (1ull << MSR_FE1) | - (1ull << MSR_EP) | - (1ull << MSR_IR) | - (1ull << MSR_DR) | - (1ull << MSR_RI) | - (1ull << MSR_LE); - pcc->mmu_model = POWERPC_MMU_SOFT_6xx; - pcc->excp_model = POWERPC_EXCP_6xx; - pcc->bus_model = PPC_FLAGS_INPUT_6xx; - pcc->bfd_mach = bfd_mach_ppc_603; - pcc->flags = POWERPC_FLAG_TGPR | POWERPC_FLAG_SE | - POWERPC_FLAG_BE | POWERPC_FLAG_BUS_CLK; -} - -POWERPC_FAMILY(603E)(ObjectClass *oc, void *data) -{ - DeviceClass *dc = DEVICE_CLASS(oc); - PowerPCCPUClass *pcc = POWERPC_CPU_CLASS(oc); - - dc->desc = "PowerPC 603e"; - pcc->init_proc = init_proc_603; - pcc->check_pow = check_pow_hid0; - pcc->insns_flags = PPC_INSNS_BASE | PPC_STRING | PPC_MFTB | - PPC_FLOAT | PPC_FLOAT_FSEL | PPC_FLOAT_FRES | - PPC_FLOAT_FRSQRTE | PPC_FLOAT_STFIWX | - PPC_CACHE | PPC_CACHE_ICBI | PPC_CACHE_DCBZ | - PPC_MEM_SYNC | PPC_MEM_EIEIO | - PPC_MEM_TLBIE | PPC_MEM_TLBSYNC | PPC_6xx_TLB | - PPC_SEGMENT | PPC_EXTERN; - pcc->msr_mask = (1ull << MSR_POW) | - (1ull << MSR_TGPR) | - (1ull << MSR_ILE) | - (1ull << MSR_EE) | - (1ull << MSR_PR) | - (1ull << MSR_FP) | - (1ull << MSR_ME) | - (1ull << MSR_FE0) | - (1ull << MSR_SE) | - (1ull << MSR_DE) | - (1ull << MSR_FE1) | - (1ull << MSR_EP) | - (1ull << MSR_IR) | - (1ull << MSR_DR) | - (1ull << MSR_RI) | - (1ull << MSR_LE); - pcc->mmu_model = POWERPC_MMU_SOFT_6xx; - pcc->excp_model = POWERPC_EXCP_6xx; - pcc->bus_model = PPC_FLAGS_INPUT_6xx; - pcc->bfd_mach = bfd_mach_ppc_ec603e; - pcc->flags = POWERPC_FLAG_TGPR | POWERPC_FLAG_SE | - POWERPC_FLAG_BE | POWERPC_FLAG_BUS_CLK; -} - -static void init_proc_e300(CPUPPCState *env) -{ - init_proc_603(env); - register_e300_sprs(env); -} - -POWERPC_FAMILY(e300)(ObjectClass *oc, void *data) -{ - DeviceClass *dc = DEVICE_CLASS(oc); - PowerPCCPUClass *pcc = POWERPC_CPU_CLASS(oc); - - dc->desc = "e300 core"; - pcc->init_proc = init_proc_e300; - pcc->check_pow = check_pow_hid0; - pcc->insns_flags = PPC_INSNS_BASE | PPC_STRING | PPC_MFTB | - PPC_FLOAT | PPC_FLOAT_FSEL | PPC_FLOAT_FRES | - PPC_FLOAT_STFIWX | - PPC_CACHE | PPC_CACHE_ICBI | PPC_CACHE_DCBZ | - PPC_MEM_SYNC | PPC_MEM_EIEIO | - PPC_MEM_TLBIE | PPC_MEM_TLBSYNC | PPC_6xx_TLB | - PPC_SEGMENT | PPC_EXTERN; - pcc->msr_mask = (1ull << MSR_POW) | - (1ull << MSR_TGPR) | - (1ull << MSR_ILE) | - (1ull << MSR_EE) | - (1ull << MSR_PR) | - (1ull << MSR_FP) | - (1ull << MSR_ME) | - (1ull << MSR_FE0) | - (1ull << MSR_SE) | - (1ull << MSR_DE) | - (1ull << MSR_FE1) | - (1ull << MSR_AL) | - (1ull << MSR_EP) | - (1ull << MSR_IR) | - (1ull << MSR_DR) | - (1ull << MSR_RI) | - (1ull << MSR_LE); - pcc->mmu_model = POWERPC_MMU_SOFT_6xx; - pcc->excp_model = POWERPC_EXCP_6xx; - pcc->bus_model = PPC_FLAGS_INPUT_6xx; - pcc->bfd_mach = bfd_mach_ppc_603; - pcc->flags = POWERPC_FLAG_TGPR | POWERPC_FLAG_SE | - POWERPC_FLAG_BE | POWERPC_FLAG_BUS_CLK; -} - -static void init_proc_604(CPUPPCState *env) -{ - register_non_embedded_sprs(env); - register_sdr1_sprs(env); - register_604_sprs(env); - - /* Memory management */ - register_low_BATs(env); - init_excp_604(env); - env->dcache_line_size = 32; - env->icache_line_size = 32; - /* Allocate hardware IRQ controller */ - ppc6xx_irq_init(env_archcpu(env)); -} - -POWERPC_FAMILY(604)(ObjectClass *oc, void *data) -{ - DeviceClass *dc = DEVICE_CLASS(oc); - PowerPCCPUClass *pcc = POWERPC_CPU_CLASS(oc); - - dc->desc = "PowerPC 604"; - pcc->init_proc = init_proc_604; - pcc->check_pow = check_pow_nocheck; - pcc->insns_flags = PPC_INSNS_BASE | PPC_STRING | PPC_MFTB | - PPC_FLOAT | PPC_FLOAT_FSEL | PPC_FLOAT_FRES | - PPC_FLOAT_FRSQRTE | PPC_FLOAT_STFIWX | - PPC_CACHE | PPC_CACHE_ICBI | PPC_CACHE_DCBZ | - PPC_MEM_SYNC | PPC_MEM_EIEIO | - PPC_MEM_TLBIE | PPC_MEM_TLBSYNC | - PPC_SEGMENT | PPC_EXTERN; - pcc->msr_mask = (1ull << MSR_POW) | - (1ull << MSR_ILE) | - (1ull << MSR_EE) | - (1ull << MSR_PR) | - (1ull << MSR_FP) | - (1ull << MSR_ME) | - (1ull << MSR_FE0) | - (1ull << MSR_SE) | - (1ull << MSR_DE) | - (1ull << MSR_FE1) | - (1ull << MSR_EP) | - (1ull << MSR_IR) | - (1ull << MSR_DR) | - (1ull << MSR_PMM) | - (1ull << MSR_RI) | - (1ull << MSR_LE); - pcc->mmu_model = POWERPC_MMU_32B; - pcc->excp_model = POWERPC_EXCP_6xx; - pcc->bus_model = PPC_FLAGS_INPUT_6xx; - pcc->bfd_mach = bfd_mach_ppc_604; - pcc->flags = POWERPC_FLAG_SE | POWERPC_FLAG_BE | - POWERPC_FLAG_PMM | POWERPC_FLAG_BUS_CLK; -} - -static void init_proc_604E(CPUPPCState *env) -{ - init_proc_604(env); - register_604e_sprs(env); -} - -POWERPC_FAMILY(604E)(ObjectClass *oc, void *data) -{ - DeviceClass *dc = DEVICE_CLASS(oc); - PowerPCCPUClass *pcc = POWERPC_CPU_CLASS(oc); - - dc->desc = "PowerPC 604E"; - pcc->init_proc = init_proc_604E; - pcc->check_pow = check_pow_nocheck; - pcc->insns_flags = PPC_INSNS_BASE | PPC_STRING | PPC_MFTB | - PPC_FLOAT | PPC_FLOAT_FSEL | PPC_FLOAT_FRES | - PPC_FLOAT_FRSQRTE | PPC_FLOAT_STFIWX | - PPC_CACHE | PPC_CACHE_ICBI | PPC_CACHE_DCBZ | - PPC_MEM_SYNC | PPC_MEM_EIEIO | - PPC_MEM_TLBIE | PPC_MEM_TLBSYNC | - PPC_SEGMENT | PPC_EXTERN; - pcc->msr_mask = (1ull << MSR_POW) | - (1ull << MSR_ILE) | - (1ull << MSR_EE) | - (1ull << MSR_PR) | - (1ull << MSR_FP) | - (1ull << MSR_ME) | - (1ull << MSR_FE0) | - (1ull << MSR_SE) | - (1ull << MSR_DE) | - (1ull << MSR_FE1) | - (1ull << MSR_EP) | - (1ull << MSR_IR) | - (1ull << MSR_DR) | - (1ull << MSR_PMM) | - (1ull << MSR_RI) | - (1ull << MSR_LE); - pcc->mmu_model = POWERPC_MMU_32B; - pcc->excp_model = POWERPC_EXCP_6xx; - pcc->bus_model = PPC_FLAGS_INPUT_6xx; - pcc->bfd_mach = bfd_mach_ppc_604; - pcc->flags = POWERPC_FLAG_SE | POWERPC_FLAG_BE | - POWERPC_FLAG_PMM | POWERPC_FLAG_BUS_CLK; -} - static void init_proc_740(CPUPPCState *env) { register_non_embedded_sprs(env); diff --git a/target/ppc/meson.build b/target/ppc/meson.build index 45f7802da5..f4ded2ecdc 100644 --- a/target/ppc/meson.build +++ b/target/ppc/meson.build @@ -4,6 +4,7 @@ ppc_ss.add(files( 'cpu.c', 'cpu_init.c', 'cpu_40x.c', + 'cpu_6xx.c', 'excp_helper.c', 'gdbstub.c', 'helper_regs.c', From patchwork Tue Mar 1 13:56:08 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Fabiano Rosas X-Patchwork-Id: 12764749 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 19CE7C433EF for ; Tue, 1 Mar 2022 14:04:03 +0000 (UTC) Received: from localhost ([::1]:60374 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1nP36f-0006lB-Di for qemu-devel@archiver.kernel.org; Tue, 01 Mar 2022 09:04:01 -0500 Received: from eggs.gnu.org ([209.51.188.92]:33342) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1nP2zq-00066Z-7h; Tue, 01 Mar 2022 08:56:58 -0500 Received: from mx0a-001b2d01.pphosted.com ([148.163.156.1]:21990) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1nP2zl-00024K-Un; Tue, 01 Mar 2022 08:56:57 -0500 Received: from pps.filterd (m0098396.ppops.net [127.0.0.1]) by mx0a-001b2d01.pphosted.com (8.16.1.2/8.16.1.2) with SMTP id 221DheWK024677; Tue, 1 Mar 2022 13:56:41 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=Cxw05pZC0POTOxV1un4vnRXNHBkCKylf2CuzNl0z5AI=; b=nrDCiM1RYPe4Fgh3rL/WXkdVgRU6lm5mYUjo/DVIJrDP86kPFwZ2Eti2FLiEq42KDj0S 4a93BwpMQ0r1KnEajYGGeyErOCymZDWwAkpYyfeKzYJLIxPxFCRi2/N2lldQnmslUwfY 1Ci67q82Rn3sK6ZT6fF02XGp3fq4Lnp8QZHw3P23M6tLOPeyG0Hf2+7IVkAV+yn9HJeY B8T9jZwgvyGvUcGAm8zNEBa1N/hOSI3lcm8uf6/0WCXFgxpChrbdo4GKXfck2Z6NtWRu 0jmTGXA8Ys7aHDqODSAYap3OfKbUKU6lZBGbFhS/X56OlGzs/UjCc1EMYNKDNitOLc0+ Gg== Received: from pps.reinject (localhost [127.0.0.1]) by mx0a-001b2d01.pphosted.com with ESMTP id 3ehmmh08a8-1 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NOT); Tue, 01 Mar 2022 13:56:41 +0000 Received: from m0098396.ppops.net (m0098396.ppops.net [127.0.0.1]) by pps.reinject (8.16.0.43/8.16.0.43) with SMTP id 221DkVeg031652; Tue, 1 Mar 2022 13:56:40 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 3ehmmh089h-1 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NOT); Tue, 01 Mar 2022 13:56:40 +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 221DtmGw030100; Tue, 1 Mar 2022 13:56:39 GMT Received: from b03cxnp07028.gho.boulder.ibm.com (b03cxnp07028.gho.boulder.ibm.com [9.17.130.15]) by ppma02wdc.us.ibm.com with ESMTP id 3efbu9w0uq-1 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NOT); Tue, 01 Mar 2022 13:56:39 +0000 Received: from b03ledav005.gho.boulder.ibm.com (b03ledav005.gho.boulder.ibm.com [9.17.130.236]) by b03cxnp07028.gho.boulder.ibm.com (8.14.9/8.14.9/NCO v10.0) with ESMTP id 221DucxC24052204 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-GCM-SHA384 bits=256 verify=OK); Tue, 1 Mar 2022 13:56:38 GMT Received: from b03ledav005.gho.boulder.ibm.com (unknown [127.0.0.1]) by IMSVA (Postfix) with ESMTP id DD6CABE05A; Tue, 1 Mar 2022 13:56:37 +0000 (GMT) Received: from b03ledav005.gho.boulder.ibm.com (unknown [127.0.0.1]) by IMSVA (Postfix) with ESMTP id 34C01BE058; Tue, 1 Mar 2022 13:56:36 +0000 (GMT) Received: from farosas.linux.ibm.com.com (unknown [9.211.51.129]) by b03ledav005.gho.boulder.ibm.com (Postfix) with ESMTP; Tue, 1 Mar 2022 13:56:35 +0000 (GMT) From: Fabiano Rosas To: qemu-devel@nongnu.org Subject: [PATCH 05/17] target/ppc: Move 7xx CPUs code to their own file Date: Tue, 1 Mar 2022 10:56:08 -0300 Message-Id: <20220301135620.2411952-6-farosas@linux.ibm.com> X-Mailer: git-send-email 2.34.1 In-Reply-To: <20220301135620.2411952-1-farosas@linux.ibm.com> References: <20220301135620.2411952-1-farosas@linux.ibm.com> MIME-Version: 1.0 X-TM-AS-GCONF: 00 X-Proofpoint-GUID: Efjx-DU8lETL44mScdVr6h4ctBOrwFg9 X-Proofpoint-ORIG-GUID: W_7GB98h-XNUxCj6MnXUYeDKDpDDbhT5 X-Proofpoint-Virus-Version: vendor=baseguard engine=ICAP:2.0.205,Aquarius:18.0.816,Hydra:6.0.425,FMLib:17.11.64.514 definitions=2022-03-01_07,2022-02-26_01,2022-02-23_01 X-Proofpoint-Spam-Details: rule=outbound_notspam policy=outbound score=0 mlxlogscore=999 adultscore=0 priorityscore=1501 suspectscore=0 malwarescore=0 bulkscore=0 mlxscore=0 spamscore=0 lowpriorityscore=0 clxscore=1015 phishscore=0 impostorscore=0 classifier=spam adjust=0 reason=mlx scancount=1 engine=8.12.0-2201110000 definitions=main-2203010074 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_H5=0.001, RCVD_IN_MSPIKE_WL=0.001, SPF_HELO_NONE=0.001, SPF_PASS=-0.001, T_SCC_BODY_TEXT_LINE=-0.01 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" Affects the 740, 750, 750cl, 750cx, 750fx, 750gx, 745 and 755. This moves init_proc, init_excp and register_*sprs functions that are related to the 7xx CPUs into a separate file. The same comments from 6xx apply: - the inclusion of sysemu/hw_accel.h is because of the DABR definition that comes from linux-headers kvm.h; - I'm copying check_pow_hid0 instead of moving it to avoid having to keep it exposed in a header file. Signed-off-by: Fabiano Rosas --- target/ppc/cpu_7xx.c | 896 +++++++++++++++++++++++++++++++++++++++++ target/ppc/cpu_init.c | 873 --------------------------------------- target/ppc/meson.build | 1 + 3 files changed, 897 insertions(+), 873 deletions(-) create mode 100644 target/ppc/cpu_7xx.c diff --git a/target/ppc/cpu_7xx.c b/target/ppc/cpu_7xx.c new file mode 100644 index 0000000000..423f4cb97a --- /dev/null +++ b/target/ppc/cpu_7xx.c @@ -0,0 +1,896 @@ +/* + * CPU initialization for PowerPC 7xx CPUs + * + * Copyright IBM Corp. 2022 + * + * This work is licensed under the terms of the GNU GPL, version 2 or later. + * See the COPYING file in the top-level directory. + */ + +#include "qemu/osdep.h" +#include "sysemu/hw_accel.h" +#include "hw/ppc/ppc.h" +#include "cpu.h" +#include "spr_common.h" + +static int check_pow_hid0(CPUPPCState *env) +{ + if (env->spr[SPR_HID0] & 0x00E00000) { + return 1; + } + + return 0; +} + +static void register_745_sprs(CPUPPCState *env) +{ + /* SGPRs */ + spr_register(env, SPR_SPRG4, "SPRG4", + SPR_NOACCESS, SPR_NOACCESS, + &spr_read_generic, &spr_write_generic, + 0x00000000); + spr_register(env, SPR_SPRG5, "SPRG5", + SPR_NOACCESS, SPR_NOACCESS, + &spr_read_generic, &spr_write_generic, + 0x00000000); + spr_register(env, SPR_SPRG6, "SPRG6", + SPR_NOACCESS, SPR_NOACCESS, + &spr_read_generic, &spr_write_generic, + 0x00000000); + spr_register(env, SPR_SPRG7, "SPRG7", + SPR_NOACCESS, SPR_NOACCESS, + &spr_read_generic, &spr_write_generic, + 0x00000000); + + /* Hardware implementation registers */ + spr_register(env, SPR_HID0, "HID0", + SPR_NOACCESS, SPR_NOACCESS, + &spr_read_generic, &spr_write_generic, + 0x00000000); + + spr_register(env, SPR_HID1, "HID1", + SPR_NOACCESS, SPR_NOACCESS, + &spr_read_generic, &spr_write_generic, + 0x00000000); + + spr_register(env, SPR_HID2, "HID2", + SPR_NOACCESS, SPR_NOACCESS, + &spr_read_generic, &spr_write_generic, + 0x00000000); +} + +static void register_755_sprs(CPUPPCState *env) +{ + /* L2 cache control */ + spr_register(env, SPR_L2CR, "L2CR", + SPR_NOACCESS, SPR_NOACCESS, + &spr_read_generic, spr_access_nop, + 0x00000000); + + spr_register(env, SPR_L2PMCR, "L2PMCR", + SPR_NOACCESS, SPR_NOACCESS, + &spr_read_generic, &spr_write_generic, + 0x00000000); +} + +/* SPR common to all 7xx PowerPC implementations */ +static void register_7xx_sprs(CPUPPCState *env) +{ + /* Breakpoints */ + spr_register_kvm(env, SPR_DABR, "DABR", + SPR_NOACCESS, SPR_NOACCESS, + &spr_read_generic, &spr_write_generic, + KVM_REG_PPC_DABR, 0x00000000); + + spr_register(env, SPR_IABR, "IABR", + SPR_NOACCESS, SPR_NOACCESS, + &spr_read_generic, &spr_write_generic, + 0x00000000); + /* Cache management */ + spr_register(env, SPR_ICTC, "ICTC", + SPR_NOACCESS, SPR_NOACCESS, + &spr_read_generic, &spr_write_generic, + 0x00000000); + /* Performance monitors */ + spr_register(env, SPR_7XX_MMCR0, "MMCR0", + SPR_NOACCESS, SPR_NOACCESS, + &spr_read_generic, &spr_write_generic, + 0x00000000); + + spr_register(env, SPR_7XX_MMCR1, "MMCR1", + SPR_NOACCESS, SPR_NOACCESS, + &spr_read_generic, &spr_write_generic, + 0x00000000); + + spr_register(env, SPR_7XX_PMC1, "PMC1", + SPR_NOACCESS, SPR_NOACCESS, + &spr_read_generic, &spr_write_generic, + 0x00000000); + + spr_register(env, SPR_7XX_PMC2, "PMC2", + SPR_NOACCESS, SPR_NOACCESS, + &spr_read_generic, &spr_write_generic, + 0x00000000); + + spr_register(env, SPR_7XX_PMC3, "PMC3", + SPR_NOACCESS, SPR_NOACCESS, + &spr_read_generic, &spr_write_generic, + 0x00000000); + + spr_register(env, SPR_7XX_PMC4, "PMC4", + SPR_NOACCESS, SPR_NOACCESS, + &spr_read_generic, &spr_write_generic, + 0x00000000); + + spr_register(env, SPR_7XX_SIAR, "SIAR", + SPR_NOACCESS, SPR_NOACCESS, + &spr_read_generic, SPR_NOACCESS, + 0x00000000); + + spr_register(env, SPR_7XX_UMMCR0, "UMMCR0", + &spr_read_ureg, SPR_NOACCESS, + &spr_read_ureg, SPR_NOACCESS, + 0x00000000); + + spr_register(env, SPR_7XX_UMMCR1, "UMMCR1", + &spr_read_ureg, SPR_NOACCESS, + &spr_read_ureg, SPR_NOACCESS, + 0x00000000); + + spr_register(env, SPR_7XX_UPMC1, "UPMC1", + &spr_read_ureg, SPR_NOACCESS, + &spr_read_ureg, SPR_NOACCESS, + 0x00000000); + + spr_register(env, SPR_7XX_UPMC2, "UPMC2", + &spr_read_ureg, SPR_NOACCESS, + &spr_read_ureg, SPR_NOACCESS, + 0x00000000); + + spr_register(env, SPR_7XX_UPMC3, "UPMC3", + &spr_read_ureg, SPR_NOACCESS, + &spr_read_ureg, SPR_NOACCESS, + 0x00000000); + + spr_register(env, SPR_7XX_UPMC4, "UPMC4", + &spr_read_ureg, SPR_NOACCESS, + &spr_read_ureg, SPR_NOACCESS, + 0x00000000); + + spr_register(env, SPR_7XX_USIAR, "USIAR", + &spr_read_ureg, SPR_NOACCESS, + &spr_read_ureg, SPR_NOACCESS, + 0x00000000); + /* External access control */ + spr_register(env, SPR_EAR, "EAR", + SPR_NOACCESS, SPR_NOACCESS, + &spr_read_generic, &spr_write_generic, + 0x00000000); + + /* Hardware implementation registers */ + spr_register(env, SPR_HID0, "HID0", + SPR_NOACCESS, SPR_NOACCESS, + &spr_read_generic, &spr_write_generic, + 0x00000000); + + spr_register(env, SPR_HID1, "HID1", + SPR_NOACCESS, SPR_NOACCESS, + &spr_read_generic, &spr_write_generic, + 0x00000000); +} + +static void init_excp_7x0(CPUPPCState *env) +{ +#if !defined(CONFIG_USER_ONLY) + env->excp_vectors[POWERPC_EXCP_RESET] = 0x00000100; + env->excp_vectors[POWERPC_EXCP_MCHECK] = 0x00000200; + env->excp_vectors[POWERPC_EXCP_DSI] = 0x00000300; + env->excp_vectors[POWERPC_EXCP_ISI] = 0x00000400; + env->excp_vectors[POWERPC_EXCP_EXTERNAL] = 0x00000500; + env->excp_vectors[POWERPC_EXCP_ALIGN] = 0x00000600; + env->excp_vectors[POWERPC_EXCP_PROGRAM] = 0x00000700; + env->excp_vectors[POWERPC_EXCP_FPU] = 0x00000800; + env->excp_vectors[POWERPC_EXCP_DECR] = 0x00000900; + env->excp_vectors[POWERPC_EXCP_SYSCALL] = 0x00000C00; + env->excp_vectors[POWERPC_EXCP_TRACE] = 0x00000D00; + env->excp_vectors[POWERPC_EXCP_PERFM] = 0x00000F00; + env->excp_vectors[POWERPC_EXCP_IABR] = 0x00001300; + env->excp_vectors[POWERPC_EXCP_SMI] = 0x00001400; + env->excp_vectors[POWERPC_EXCP_THERM] = 0x00001700; + /* Hardware reset vector */ + env->hreset_vector = 0x00000100UL; +#endif +} + +static void init_excp_750cl(CPUPPCState *env) +{ +#if !defined(CONFIG_USER_ONLY) + env->excp_vectors[POWERPC_EXCP_RESET] = 0x00000100; + env->excp_vectors[POWERPC_EXCP_MCHECK] = 0x00000200; + env->excp_vectors[POWERPC_EXCP_DSI] = 0x00000300; + env->excp_vectors[POWERPC_EXCP_ISI] = 0x00000400; + env->excp_vectors[POWERPC_EXCP_EXTERNAL] = 0x00000500; + env->excp_vectors[POWERPC_EXCP_ALIGN] = 0x00000600; + env->excp_vectors[POWERPC_EXCP_PROGRAM] = 0x00000700; + env->excp_vectors[POWERPC_EXCP_FPU] = 0x00000800; + env->excp_vectors[POWERPC_EXCP_DECR] = 0x00000900; + env->excp_vectors[POWERPC_EXCP_SYSCALL] = 0x00000C00; + env->excp_vectors[POWERPC_EXCP_TRACE] = 0x00000D00; + env->excp_vectors[POWERPC_EXCP_PERFM] = 0x00000F00; + env->excp_vectors[POWERPC_EXCP_IABR] = 0x00001300; + env->excp_vectors[POWERPC_EXCP_SMI] = 0x00001400; + /* Hardware reset vector */ + env->hreset_vector = 0x00000100UL; +#endif +} + +static void init_excp_750cx(CPUPPCState *env) +{ +#if !defined(CONFIG_USER_ONLY) + env->excp_vectors[POWERPC_EXCP_RESET] = 0x00000100; + env->excp_vectors[POWERPC_EXCP_MCHECK] = 0x00000200; + env->excp_vectors[POWERPC_EXCP_DSI] = 0x00000300; + env->excp_vectors[POWERPC_EXCP_ISI] = 0x00000400; + env->excp_vectors[POWERPC_EXCP_EXTERNAL] = 0x00000500; + env->excp_vectors[POWERPC_EXCP_ALIGN] = 0x00000600; + env->excp_vectors[POWERPC_EXCP_PROGRAM] = 0x00000700; + env->excp_vectors[POWERPC_EXCP_FPU] = 0x00000800; + env->excp_vectors[POWERPC_EXCP_DECR] = 0x00000900; + env->excp_vectors[POWERPC_EXCP_SYSCALL] = 0x00000C00; + env->excp_vectors[POWERPC_EXCP_TRACE] = 0x00000D00; + env->excp_vectors[POWERPC_EXCP_PERFM] = 0x00000F00; + env->excp_vectors[POWERPC_EXCP_IABR] = 0x00001300; + env->excp_vectors[POWERPC_EXCP_THERM] = 0x00001700; + /* Hardware reset vector */ + env->hreset_vector = 0x00000100UL; +#endif +} + +/* XXX: Check if this is correct */ +static void init_excp_7x5(CPUPPCState *env) +{ +#if !defined(CONFIG_USER_ONLY) + env->excp_vectors[POWERPC_EXCP_RESET] = 0x00000100; + env->excp_vectors[POWERPC_EXCP_MCHECK] = 0x00000200; + env->excp_vectors[POWERPC_EXCP_DSI] = 0x00000300; + env->excp_vectors[POWERPC_EXCP_ISI] = 0x00000400; + env->excp_vectors[POWERPC_EXCP_EXTERNAL] = 0x00000500; + env->excp_vectors[POWERPC_EXCP_ALIGN] = 0x00000600; + env->excp_vectors[POWERPC_EXCP_PROGRAM] = 0x00000700; + env->excp_vectors[POWERPC_EXCP_FPU] = 0x00000800; + env->excp_vectors[POWERPC_EXCP_DECR] = 0x00000900; + env->excp_vectors[POWERPC_EXCP_SYSCALL] = 0x00000C00; + env->excp_vectors[POWERPC_EXCP_TRACE] = 0x00000D00; + env->excp_vectors[POWERPC_EXCP_PERFM] = 0x00000F00; + env->excp_vectors[POWERPC_EXCP_IFTLB] = 0x00001000; + env->excp_vectors[POWERPC_EXCP_DLTLB] = 0x00001100; + env->excp_vectors[POWERPC_EXCP_DSTLB] = 0x00001200; + env->excp_vectors[POWERPC_EXCP_IABR] = 0x00001300; + env->excp_vectors[POWERPC_EXCP_SMI] = 0x00001400; + env->excp_vectors[POWERPC_EXCP_THERM] = 0x00001700; + /* Hardware reset vector */ + env->hreset_vector = 0x00000100UL; +#endif +} + +static void init_proc_740(CPUPPCState *env) +{ + register_non_embedded_sprs(env); + register_sdr1_sprs(env); + register_7xx_sprs(env); + /* Thermal management */ + register_thrm_sprs(env); + + /* Memory management */ + register_low_BATs(env); + init_excp_7x0(env); + env->dcache_line_size = 32; + env->icache_line_size = 32; + /* Allocate hardware IRQ controller */ + ppc6xx_irq_init(env_archcpu(env)); +} + +static void init_proc_750(CPUPPCState *env) +{ + register_non_embedded_sprs(env); + register_sdr1_sprs(env); + register_7xx_sprs(env); + + spr_register(env, SPR_L2CR, "L2CR", + SPR_NOACCESS, SPR_NOACCESS, + &spr_read_generic, spr_access_nop, + 0x00000000); + /* Thermal management */ + register_thrm_sprs(env); + + /* Memory management */ + register_low_BATs(env); + /* + * XXX: high BATs are also present but are known to be bugged on + * die version 1.x + */ + init_excp_7x0(env); + env->dcache_line_size = 32; + env->icache_line_size = 32; + /* Allocate hardware IRQ controller */ + ppc6xx_irq_init(env_archcpu(env)); +} + +static void init_proc_750cl(CPUPPCState *env) +{ + register_non_embedded_sprs(env); + register_sdr1_sprs(env); + register_7xx_sprs(env); + + spr_register(env, SPR_L2CR, "L2CR", + SPR_NOACCESS, SPR_NOACCESS, + &spr_read_generic, spr_access_nop, + 0x00000000); + /* Thermal management */ + /* Those registers are fake on 750CL */ + spr_register(env, SPR_THRM1, "THRM1", + SPR_NOACCESS, SPR_NOACCESS, + &spr_read_generic, &spr_write_generic, + 0x00000000); + spr_register(env, SPR_THRM2, "THRM2", + SPR_NOACCESS, SPR_NOACCESS, + &spr_read_generic, &spr_write_generic, + 0x00000000); + spr_register(env, SPR_THRM3, "THRM3", + SPR_NOACCESS, SPR_NOACCESS, + &spr_read_generic, &spr_write_generic, + 0x00000000); + + spr_register(env, SPR_750_TDCL, "TDCL", + SPR_NOACCESS, SPR_NOACCESS, + &spr_read_generic, &spr_write_generic, + 0x00000000); + spr_register(env, SPR_750_TDCH, "TDCH", + SPR_NOACCESS, SPR_NOACCESS, + &spr_read_generic, &spr_write_generic, + 0x00000000); + /* DMA */ + spr_register(env, SPR_750_WPAR, "WPAR", + SPR_NOACCESS, SPR_NOACCESS, + &spr_read_generic, &spr_write_generic, + 0x00000000); + spr_register(env, SPR_750_DMAL, "DMAL", + SPR_NOACCESS, SPR_NOACCESS, + &spr_read_generic, &spr_write_generic, + 0x00000000); + spr_register(env, SPR_750_DMAU, "DMAU", + SPR_NOACCESS, SPR_NOACCESS, + &spr_read_generic, &spr_write_generic, + 0x00000000); + /* Hardware implementation registers */ + spr_register(env, SPR_750CL_HID2, "HID2", + SPR_NOACCESS, SPR_NOACCESS, + &spr_read_generic, &spr_write_generic, + 0x00000000); + + spr_register(env, SPR_750CL_HID4, "HID4", + SPR_NOACCESS, SPR_NOACCESS, + &spr_read_generic, &spr_write_generic, + 0x00000000); + /* Quantization registers */ + spr_register(env, SPR_750_GQR0, "GQR0", + SPR_NOACCESS, SPR_NOACCESS, + &spr_read_generic, &spr_write_generic, + 0x00000000); + + spr_register(env, SPR_750_GQR1, "GQR1", + SPR_NOACCESS, SPR_NOACCESS, + &spr_read_generic, &spr_write_generic, + 0x00000000); + + spr_register(env, SPR_750_GQR2, "GQR2", + SPR_NOACCESS, SPR_NOACCESS, + &spr_read_generic, &spr_write_generic, + 0x00000000); + + spr_register(env, SPR_750_GQR3, "GQR3", + SPR_NOACCESS, SPR_NOACCESS, + &spr_read_generic, &spr_write_generic, + 0x00000000); + + spr_register(env, SPR_750_GQR4, "GQR4", + SPR_NOACCESS, SPR_NOACCESS, + &spr_read_generic, &spr_write_generic, + 0x00000000); + + spr_register(env, SPR_750_GQR5, "GQR5", + SPR_NOACCESS, SPR_NOACCESS, + &spr_read_generic, &spr_write_generic, + 0x00000000); + + spr_register(env, SPR_750_GQR6, "GQR6", + SPR_NOACCESS, SPR_NOACCESS, + &spr_read_generic, &spr_write_generic, + 0x00000000); + + spr_register(env, SPR_750_GQR7, "GQR7", + SPR_NOACCESS, SPR_NOACCESS, + &spr_read_generic, &spr_write_generic, + 0x00000000); + /* Memory management */ + register_low_BATs(env); + /* PowerPC 750cl has 8 DBATs and 8 IBATs */ + register_high_BATs(env); + init_excp_750cl(env); + env->dcache_line_size = 32; + env->icache_line_size = 32; + /* Allocate hardware IRQ controller */ + ppc6xx_irq_init(env_archcpu(env)); +} + +static void init_proc_750cx(CPUPPCState *env) +{ + register_non_embedded_sprs(env); + register_sdr1_sprs(env); + register_7xx_sprs(env); + + spr_register(env, SPR_L2CR, "L2CR", + SPR_NOACCESS, SPR_NOACCESS, + &spr_read_generic, spr_access_nop, + 0x00000000); + /* Thermal management */ + register_thrm_sprs(env); + + spr_register(env, SPR_SDA, "SDA", + SPR_NOACCESS, SPR_NOACCESS, + &spr_read_generic, &spr_write_generic, + 0x00000000); + + /* Memory management */ + register_low_BATs(env); + /* PowerPC 750cx has 8 DBATs and 8 IBATs */ + register_high_BATs(env); + init_excp_750cx(env); + env->dcache_line_size = 32; + env->icache_line_size = 32; + /* Allocate hardware IRQ controller */ + ppc6xx_irq_init(env_archcpu(env)); +} + +static void init_proc_750fx(CPUPPCState *env) +{ + register_non_embedded_sprs(env); + register_sdr1_sprs(env); + register_7xx_sprs(env); + + spr_register(env, SPR_L2CR, "L2CR", + SPR_NOACCESS, SPR_NOACCESS, + &spr_read_generic, spr_access_nop, + 0x00000000); + /* Thermal management */ + register_thrm_sprs(env); + + spr_register(env, SPR_750_THRM4, "THRM4", + SPR_NOACCESS, SPR_NOACCESS, + &spr_read_generic, &spr_write_generic, + 0x00000000); + /* Hardware implementation registers */ + spr_register(env, SPR_750FX_HID2, "HID2", + SPR_NOACCESS, SPR_NOACCESS, + &spr_read_generic, &spr_write_generic, + 0x00000000); + /* Memory management */ + register_low_BATs(env); + /* PowerPC 750fx & 750gx has 8 DBATs and 8 IBATs */ + register_high_BATs(env); + init_excp_7x0(env); + env->dcache_line_size = 32; + env->icache_line_size = 32; + /* Allocate hardware IRQ controller */ + ppc6xx_irq_init(env_archcpu(env)); +} + +static void init_proc_750gx(CPUPPCState *env) +{ + register_non_embedded_sprs(env); + register_sdr1_sprs(env); + register_7xx_sprs(env); + + spr_register(env, SPR_L2CR, "L2CR", + SPR_NOACCESS, SPR_NOACCESS, + &spr_read_generic, spr_access_nop, + 0x00000000); + /* Thermal management */ + register_thrm_sprs(env); + + spr_register(env, SPR_750_THRM4, "THRM4", + SPR_NOACCESS, SPR_NOACCESS, + &spr_read_generic, &spr_write_generic, + 0x00000000); + /* Hardware implementation registers */ + spr_register(env, SPR_750FX_HID2, "HID2", + SPR_NOACCESS, SPR_NOACCESS, + &spr_read_generic, &spr_write_generic, + 0x00000000); + /* Memory management */ + register_low_BATs(env); + /* PowerPC 750fx & 750gx has 8 DBATs and 8 IBATs */ + register_high_BATs(env); + init_excp_7x0(env); + env->dcache_line_size = 32; + env->icache_line_size = 32; + /* Allocate hardware IRQ controller */ + ppc6xx_irq_init(env_archcpu(env)); +} + +static void init_proc_745(CPUPPCState *env) +{ + register_non_embedded_sprs(env); + register_sdr1_sprs(env); + register_7xx_sprs(env); + register_745_sprs(env); + /* Thermal management */ + register_thrm_sprs(env); + + /* Memory management */ + register_low_BATs(env); + register_high_BATs(env); + register_6xx_7xx_soft_tlb(env, 64, 2); + init_excp_7x5(env); + env->dcache_line_size = 32; + env->icache_line_size = 32; + /* Allocate hardware IRQ controller */ + ppc6xx_irq_init(env_archcpu(env)); +} + +static void init_proc_755(CPUPPCState *env) +{ + init_proc_745(env); + register_755_sprs(env); +} + +POWERPC_FAMILY(740)(ObjectClass *oc, void *data) +{ + DeviceClass *dc = DEVICE_CLASS(oc); + PowerPCCPUClass *pcc = POWERPC_CPU_CLASS(oc); + + dc->desc = "PowerPC 740"; + pcc->init_proc = init_proc_740; + pcc->check_pow = check_pow_hid0; + pcc->insns_flags = PPC_INSNS_BASE | PPC_STRING | PPC_MFTB | + PPC_FLOAT | PPC_FLOAT_FSEL | PPC_FLOAT_FRES | + PPC_FLOAT_FRSQRTE | PPC_FLOAT_STFIWX | + PPC_CACHE | PPC_CACHE_ICBI | PPC_CACHE_DCBZ | + PPC_MEM_SYNC | PPC_MEM_EIEIO | + PPC_MEM_TLBIE | PPC_MEM_TLBSYNC | + PPC_SEGMENT | PPC_EXTERN; + pcc->msr_mask = (1ull << MSR_POW) | + (1ull << MSR_ILE) | + (1ull << MSR_EE) | + (1ull << MSR_PR) | + (1ull << MSR_FP) | + (1ull << MSR_ME) | + (1ull << MSR_FE0) | + (1ull << MSR_SE) | + (1ull << MSR_DE) | + (1ull << MSR_FE1) | + (1ull << MSR_EP) | + (1ull << MSR_IR) | + (1ull << MSR_DR) | + (1ull << MSR_PMM) | + (1ull << MSR_RI) | + (1ull << MSR_LE); + pcc->mmu_model = POWERPC_MMU_32B; + pcc->excp_model = POWERPC_EXCP_7xx; + pcc->bus_model = PPC_FLAGS_INPUT_6xx; + pcc->bfd_mach = bfd_mach_ppc_750; + pcc->flags = POWERPC_FLAG_SE | POWERPC_FLAG_BE | + POWERPC_FLAG_PMM | POWERPC_FLAG_BUS_CLK; +} + +POWERPC_FAMILY(750)(ObjectClass *oc, void *data) +{ + DeviceClass *dc = DEVICE_CLASS(oc); + PowerPCCPUClass *pcc = POWERPC_CPU_CLASS(oc); + + dc->desc = "PowerPC 750"; + pcc->init_proc = init_proc_750; + pcc->check_pow = check_pow_hid0; + pcc->insns_flags = PPC_INSNS_BASE | PPC_STRING | PPC_MFTB | + PPC_FLOAT | PPC_FLOAT_FSEL | PPC_FLOAT_FRES | + PPC_FLOAT_FRSQRTE | PPC_FLOAT_STFIWX | + PPC_CACHE | PPC_CACHE_ICBI | PPC_CACHE_DCBZ | + PPC_MEM_SYNC | PPC_MEM_EIEIO | + PPC_MEM_TLBIE | PPC_MEM_TLBSYNC | + PPC_SEGMENT | PPC_EXTERN; + pcc->msr_mask = (1ull << MSR_POW) | + (1ull << MSR_ILE) | + (1ull << MSR_EE) | + (1ull << MSR_PR) | + (1ull << MSR_FP) | + (1ull << MSR_ME) | + (1ull << MSR_FE0) | + (1ull << MSR_SE) | + (1ull << MSR_DE) | + (1ull << MSR_FE1) | + (1ull << MSR_EP) | + (1ull << MSR_IR) | + (1ull << MSR_DR) | + (1ull << MSR_PMM) | + (1ull << MSR_RI) | + (1ull << MSR_LE); + pcc->mmu_model = POWERPC_MMU_32B; + pcc->excp_model = POWERPC_EXCP_7xx; + pcc->bus_model = PPC_FLAGS_INPUT_6xx; + pcc->bfd_mach = bfd_mach_ppc_750; + pcc->flags = POWERPC_FLAG_SE | POWERPC_FLAG_BE | + POWERPC_FLAG_PMM | POWERPC_FLAG_BUS_CLK; +} + +POWERPC_FAMILY(750cl)(ObjectClass *oc, void *data) +{ + DeviceClass *dc = DEVICE_CLASS(oc); + PowerPCCPUClass *pcc = POWERPC_CPU_CLASS(oc); + + dc->desc = "PowerPC 750 CL"; + pcc->init_proc = init_proc_750cl; + pcc->check_pow = check_pow_hid0; + /* + * XXX: not implemented: + * cache lock instructions: + * dcbz_l + * floating point paired instructions + * psq_lux + * psq_lx + * psq_stux + * psq_stx + * ps_abs + * ps_add + * ps_cmpo0 + * ps_cmpo1 + * ps_cmpu0 + * ps_cmpu1 + * ps_div + * ps_madd + * ps_madds0 + * ps_madds1 + * ps_merge00 + * ps_merge01 + * ps_merge10 + * ps_merge11 + * ps_mr + * ps_msub + * ps_mul + * ps_muls0 + * ps_muls1 + * ps_nabs + * ps_neg + * ps_nmadd + * ps_nmsub + * ps_res + * ps_rsqrte + * ps_sel + * ps_sub + * ps_sum0 + * ps_sum1 + */ + pcc->insns_flags = PPC_INSNS_BASE | PPC_STRING | PPC_MFTB | + PPC_FLOAT | PPC_FLOAT_FSEL | PPC_FLOAT_FRES | + PPC_FLOAT_FRSQRTE | PPC_FLOAT_STFIWX | + PPC_CACHE | PPC_CACHE_ICBI | PPC_CACHE_DCBZ | + PPC_MEM_SYNC | PPC_MEM_EIEIO | + PPC_MEM_TLBIE | PPC_MEM_TLBSYNC | + PPC_SEGMENT | PPC_EXTERN; + pcc->msr_mask = (1ull << MSR_POW) | + (1ull << MSR_ILE) | + (1ull << MSR_EE) | + (1ull << MSR_PR) | + (1ull << MSR_FP) | + (1ull << MSR_ME) | + (1ull << MSR_FE0) | + (1ull << MSR_SE) | + (1ull << MSR_DE) | + (1ull << MSR_FE1) | + (1ull << MSR_EP) | + (1ull << MSR_IR) | + (1ull << MSR_DR) | + (1ull << MSR_PMM) | + (1ull << MSR_RI) | + (1ull << MSR_LE); + pcc->mmu_model = POWERPC_MMU_32B; + pcc->excp_model = POWERPC_EXCP_7xx; + pcc->bus_model = PPC_FLAGS_INPUT_6xx; + pcc->bfd_mach = bfd_mach_ppc_750; + pcc->flags = POWERPC_FLAG_SE | POWERPC_FLAG_BE | + POWERPC_FLAG_PMM | POWERPC_FLAG_BUS_CLK; +} + +POWERPC_FAMILY(750cx)(ObjectClass *oc, void *data) +{ + DeviceClass *dc = DEVICE_CLASS(oc); + PowerPCCPUClass *pcc = POWERPC_CPU_CLASS(oc); + + dc->desc = "PowerPC 750CX"; + pcc->init_proc = init_proc_750cx; + pcc->check_pow = check_pow_hid0; + pcc->insns_flags = PPC_INSNS_BASE | PPC_STRING | PPC_MFTB | + PPC_FLOAT | PPC_FLOAT_FSEL | PPC_FLOAT_FRES | + PPC_FLOAT_FRSQRTE | PPC_FLOAT_STFIWX | + PPC_CACHE | PPC_CACHE_ICBI | PPC_CACHE_DCBZ | + PPC_MEM_SYNC | PPC_MEM_EIEIO | + PPC_MEM_TLBIE | PPC_MEM_TLBSYNC | + PPC_SEGMENT | PPC_EXTERN; + pcc->msr_mask = (1ull << MSR_POW) | + (1ull << MSR_ILE) | + (1ull << MSR_EE) | + (1ull << MSR_PR) | + (1ull << MSR_FP) | + (1ull << MSR_ME) | + (1ull << MSR_FE0) | + (1ull << MSR_SE) | + (1ull << MSR_DE) | + (1ull << MSR_FE1) | + (1ull << MSR_EP) | + (1ull << MSR_IR) | + (1ull << MSR_DR) | + (1ull << MSR_PMM) | + (1ull << MSR_RI) | + (1ull << MSR_LE); + pcc->mmu_model = POWERPC_MMU_32B; + pcc->excp_model = POWERPC_EXCP_7xx; + pcc->bus_model = PPC_FLAGS_INPUT_6xx; + pcc->bfd_mach = bfd_mach_ppc_750; + pcc->flags = POWERPC_FLAG_SE | POWERPC_FLAG_BE | + POWERPC_FLAG_PMM | POWERPC_FLAG_BUS_CLK; +} + +POWERPC_FAMILY(750fx)(ObjectClass *oc, void *data) +{ + DeviceClass *dc = DEVICE_CLASS(oc); + PowerPCCPUClass *pcc = POWERPC_CPU_CLASS(oc); + + dc->desc = "PowerPC 750FX"; + pcc->init_proc = init_proc_750fx; + pcc->check_pow = check_pow_hid0; + pcc->insns_flags = PPC_INSNS_BASE | PPC_STRING | PPC_MFTB | + PPC_FLOAT | PPC_FLOAT_FSEL | PPC_FLOAT_FRES | + PPC_FLOAT_FRSQRTE | PPC_FLOAT_STFIWX | + PPC_CACHE | PPC_CACHE_ICBI | PPC_CACHE_DCBZ | + PPC_MEM_SYNC | PPC_MEM_EIEIO | + PPC_MEM_TLBIE | PPC_MEM_TLBSYNC | + PPC_SEGMENT | PPC_EXTERN; + pcc->msr_mask = (1ull << MSR_POW) | + (1ull << MSR_ILE) | + (1ull << MSR_EE) | + (1ull << MSR_PR) | + (1ull << MSR_FP) | + (1ull << MSR_ME) | + (1ull << MSR_FE0) | + (1ull << MSR_SE) | + (1ull << MSR_DE) | + (1ull << MSR_FE1) | + (1ull << MSR_EP) | + (1ull << MSR_IR) | + (1ull << MSR_DR) | + (1ull << MSR_PMM) | + (1ull << MSR_RI) | + (1ull << MSR_LE); + pcc->mmu_model = POWERPC_MMU_32B; + pcc->excp_model = POWERPC_EXCP_7xx; + pcc->bus_model = PPC_FLAGS_INPUT_6xx; + pcc->bfd_mach = bfd_mach_ppc_750; + pcc->flags = POWERPC_FLAG_SE | POWERPC_FLAG_BE | + POWERPC_FLAG_PMM | POWERPC_FLAG_BUS_CLK; +} + +POWERPC_FAMILY(750gx)(ObjectClass *oc, void *data) +{ + DeviceClass *dc = DEVICE_CLASS(oc); + PowerPCCPUClass *pcc = POWERPC_CPU_CLASS(oc); + + dc->desc = "PowerPC 750GX"; + pcc->init_proc = init_proc_750gx; + pcc->check_pow = check_pow_hid0; + pcc->insns_flags = PPC_INSNS_BASE | PPC_STRING | PPC_MFTB | + PPC_FLOAT | PPC_FLOAT_FSEL | PPC_FLOAT_FRES | + PPC_FLOAT_FRSQRTE | PPC_FLOAT_STFIWX | + PPC_CACHE | PPC_CACHE_ICBI | PPC_CACHE_DCBZ | + PPC_MEM_SYNC | PPC_MEM_EIEIO | + PPC_MEM_TLBIE | PPC_MEM_TLBSYNC | + PPC_SEGMENT | PPC_EXTERN; + pcc->msr_mask = (1ull << MSR_POW) | + (1ull << MSR_ILE) | + (1ull << MSR_EE) | + (1ull << MSR_PR) | + (1ull << MSR_FP) | + (1ull << MSR_ME) | + (1ull << MSR_FE0) | + (1ull << MSR_SE) | + (1ull << MSR_DE) | + (1ull << MSR_FE1) | + (1ull << MSR_EP) | + (1ull << MSR_IR) | + (1ull << MSR_DR) | + (1ull << MSR_PMM) | + (1ull << MSR_RI) | + (1ull << MSR_LE); + pcc->mmu_model = POWERPC_MMU_32B; + pcc->excp_model = POWERPC_EXCP_7xx; + pcc->bus_model = PPC_FLAGS_INPUT_6xx; + pcc->bfd_mach = bfd_mach_ppc_750; + pcc->flags = POWERPC_FLAG_SE | POWERPC_FLAG_BE | + POWERPC_FLAG_PMM | POWERPC_FLAG_BUS_CLK; +} + +POWERPC_FAMILY(745)(ObjectClass *oc, void *data) +{ + DeviceClass *dc = DEVICE_CLASS(oc); + PowerPCCPUClass *pcc = POWERPC_CPU_CLASS(oc); + + dc->desc = "PowerPC 745"; + pcc->init_proc = init_proc_745; + pcc->check_pow = check_pow_hid0; + pcc->insns_flags = PPC_INSNS_BASE | PPC_STRING | PPC_MFTB | + PPC_FLOAT | PPC_FLOAT_FSEL | PPC_FLOAT_FRES | + PPC_FLOAT_FRSQRTE | PPC_FLOAT_STFIWX | + PPC_CACHE | PPC_CACHE_ICBI | PPC_CACHE_DCBZ | + PPC_MEM_SYNC | PPC_MEM_EIEIO | + PPC_MEM_TLBIE | PPC_MEM_TLBSYNC | PPC_6xx_TLB | + PPC_SEGMENT | PPC_EXTERN; + pcc->msr_mask = (1ull << MSR_POW) | + (1ull << MSR_ILE) | + (1ull << MSR_EE) | + (1ull << MSR_PR) | + (1ull << MSR_FP) | + (1ull << MSR_ME) | + (1ull << MSR_FE0) | + (1ull << MSR_SE) | + (1ull << MSR_DE) | + (1ull << MSR_FE1) | + (1ull << MSR_EP) | + (1ull << MSR_IR) | + (1ull << MSR_DR) | + (1ull << MSR_PMM) | + (1ull << MSR_RI) | + (1ull << MSR_LE); + pcc->mmu_model = POWERPC_MMU_SOFT_6xx; + pcc->excp_model = POWERPC_EXCP_7xx; + pcc->bus_model = PPC_FLAGS_INPUT_6xx; + pcc->bfd_mach = bfd_mach_ppc_750; + pcc->flags = POWERPC_FLAG_SE | POWERPC_FLAG_BE | + POWERPC_FLAG_PMM | POWERPC_FLAG_BUS_CLK; +} + +POWERPC_FAMILY(755)(ObjectClass *oc, void *data) +{ + DeviceClass *dc = DEVICE_CLASS(oc); + PowerPCCPUClass *pcc = POWERPC_CPU_CLASS(oc); + + dc->desc = "PowerPC 755"; + pcc->init_proc = init_proc_755; + pcc->check_pow = check_pow_hid0; + pcc->insns_flags = PPC_INSNS_BASE | PPC_STRING | PPC_MFTB | + PPC_FLOAT | PPC_FLOAT_FSEL | PPC_FLOAT_FRES | + PPC_FLOAT_FRSQRTE | PPC_FLOAT_STFIWX | + PPC_CACHE | PPC_CACHE_ICBI | PPC_CACHE_DCBZ | + PPC_MEM_SYNC | PPC_MEM_EIEIO | + PPC_MEM_TLBIE | PPC_MEM_TLBSYNC | PPC_6xx_TLB | + PPC_SEGMENT | PPC_EXTERN; + pcc->msr_mask = (1ull << MSR_POW) | + (1ull << MSR_ILE) | + (1ull << MSR_EE) | + (1ull << MSR_PR) | + (1ull << MSR_FP) | + (1ull << MSR_ME) | + (1ull << MSR_FE0) | + (1ull << MSR_SE) | + (1ull << MSR_DE) | + (1ull << MSR_FE1) | + (1ull << MSR_EP) | + (1ull << MSR_IR) | + (1ull << MSR_DR) | + (1ull << MSR_PMM) | + (1ull << MSR_RI) | + (1ull << MSR_LE); + pcc->mmu_model = POWERPC_MMU_SOFT_6xx; + pcc->excp_model = POWERPC_EXCP_7xx; + pcc->bus_model = PPC_FLAGS_INPUT_6xx; + pcc->bfd_mach = bfd_mach_ppc_750; + pcc->flags = POWERPC_FLAG_SE | POWERPC_FLAG_BE | + POWERPC_FLAG_PMM | POWERPC_FLAG_BUS_CLK; +} diff --git a/target/ppc/cpu_init.c b/target/ppc/cpu_init.c index b828dc1e88..c9a5e020b1 100644 --- a/target/ppc/cpu_init.c +++ b/target/ppc/cpu_init.c @@ -57,163 +57,6 @@ static inline void vscr_init(CPUPPCState *env, uint32_t val) ppc_store_vscr(env, val); } -static void register_745_sprs(CPUPPCState *env) -{ - /* SGPRs */ - spr_register(env, SPR_SPRG4, "SPRG4", - SPR_NOACCESS, SPR_NOACCESS, - &spr_read_generic, &spr_write_generic, - 0x00000000); - spr_register(env, SPR_SPRG5, "SPRG5", - SPR_NOACCESS, SPR_NOACCESS, - &spr_read_generic, &spr_write_generic, - 0x00000000); - spr_register(env, SPR_SPRG6, "SPRG6", - SPR_NOACCESS, SPR_NOACCESS, - &spr_read_generic, &spr_write_generic, - 0x00000000); - spr_register(env, SPR_SPRG7, "SPRG7", - SPR_NOACCESS, SPR_NOACCESS, - &spr_read_generic, &spr_write_generic, - 0x00000000); - - /* Hardware implementation registers */ - spr_register(env, SPR_HID0, "HID0", - SPR_NOACCESS, SPR_NOACCESS, - &spr_read_generic, &spr_write_generic, - 0x00000000); - - spr_register(env, SPR_HID1, "HID1", - SPR_NOACCESS, SPR_NOACCESS, - &spr_read_generic, &spr_write_generic, - 0x00000000); - - spr_register(env, SPR_HID2, "HID2", - SPR_NOACCESS, SPR_NOACCESS, - &spr_read_generic, &spr_write_generic, - 0x00000000); -} - -static void register_755_sprs(CPUPPCState *env) -{ - /* L2 cache control */ - spr_register(env, SPR_L2CR, "L2CR", - SPR_NOACCESS, SPR_NOACCESS, - &spr_read_generic, spr_access_nop, - 0x00000000); - - spr_register(env, SPR_L2PMCR, "L2PMCR", - SPR_NOACCESS, SPR_NOACCESS, - &spr_read_generic, &spr_write_generic, - 0x00000000); -} - -/* SPR common to all 7xx PowerPC implementations */ -static void register_7xx_sprs(CPUPPCState *env) -{ - /* Breakpoints */ - spr_register_kvm(env, SPR_DABR, "DABR", - SPR_NOACCESS, SPR_NOACCESS, - &spr_read_generic, &spr_write_generic, - KVM_REG_PPC_DABR, 0x00000000); - - spr_register(env, SPR_IABR, "IABR", - SPR_NOACCESS, SPR_NOACCESS, - &spr_read_generic, &spr_write_generic, - 0x00000000); - /* Cache management */ - spr_register(env, SPR_ICTC, "ICTC", - SPR_NOACCESS, SPR_NOACCESS, - &spr_read_generic, &spr_write_generic, - 0x00000000); - /* Performance monitors */ - spr_register(env, SPR_7XX_MMCR0, "MMCR0", - SPR_NOACCESS, SPR_NOACCESS, - &spr_read_generic, &spr_write_generic, - 0x00000000); - - spr_register(env, SPR_7XX_MMCR1, "MMCR1", - SPR_NOACCESS, SPR_NOACCESS, - &spr_read_generic, &spr_write_generic, - 0x00000000); - - spr_register(env, SPR_7XX_PMC1, "PMC1", - SPR_NOACCESS, SPR_NOACCESS, - &spr_read_generic, &spr_write_generic, - 0x00000000); - - spr_register(env, SPR_7XX_PMC2, "PMC2", - SPR_NOACCESS, SPR_NOACCESS, - &spr_read_generic, &spr_write_generic, - 0x00000000); - - spr_register(env, SPR_7XX_PMC3, "PMC3", - SPR_NOACCESS, SPR_NOACCESS, - &spr_read_generic, &spr_write_generic, - 0x00000000); - - spr_register(env, SPR_7XX_PMC4, "PMC4", - SPR_NOACCESS, SPR_NOACCESS, - &spr_read_generic, &spr_write_generic, - 0x00000000); - - spr_register(env, SPR_7XX_SIAR, "SIAR", - SPR_NOACCESS, SPR_NOACCESS, - &spr_read_generic, SPR_NOACCESS, - 0x00000000); - - spr_register(env, SPR_7XX_UMMCR0, "UMMCR0", - &spr_read_ureg, SPR_NOACCESS, - &spr_read_ureg, SPR_NOACCESS, - 0x00000000); - - spr_register(env, SPR_7XX_UMMCR1, "UMMCR1", - &spr_read_ureg, SPR_NOACCESS, - &spr_read_ureg, SPR_NOACCESS, - 0x00000000); - - spr_register(env, SPR_7XX_UPMC1, "UPMC1", - &spr_read_ureg, SPR_NOACCESS, - &spr_read_ureg, SPR_NOACCESS, - 0x00000000); - - spr_register(env, SPR_7XX_UPMC2, "UPMC2", - &spr_read_ureg, SPR_NOACCESS, - &spr_read_ureg, SPR_NOACCESS, - 0x00000000); - - spr_register(env, SPR_7XX_UPMC3, "UPMC3", - &spr_read_ureg, SPR_NOACCESS, - &spr_read_ureg, SPR_NOACCESS, - 0x00000000); - - spr_register(env, SPR_7XX_UPMC4, "UPMC4", - &spr_read_ureg, SPR_NOACCESS, - &spr_read_ureg, SPR_NOACCESS, - 0x00000000); - - spr_register(env, SPR_7XX_USIAR, "USIAR", - &spr_read_ureg, SPR_NOACCESS, - &spr_read_ureg, SPR_NOACCESS, - 0x00000000); - /* External access control */ - spr_register(env, SPR_EAR, "EAR", - SPR_NOACCESS, SPR_NOACCESS, - &spr_read_generic, &spr_write_generic, - 0x00000000); - - /* Hardware implementation registers */ - spr_register(env, SPR_HID0, "HID0", - SPR_NOACCESS, SPR_NOACCESS, - &spr_read_generic, &spr_write_generic, - 0x00000000); - - spr_register(env, SPR_HID1, "HID1", - SPR_NOACCESS, SPR_NOACCESS, - &spr_read_generic, &spr_write_generic, - 0x00000000); -} - #ifdef TARGET_PPC64 static void register_amr_sprs(CPUPPCState *env) { @@ -947,100 +790,6 @@ static void init_excp_BookE(CPUPPCState *env) #endif } -static void init_excp_7x0(CPUPPCState *env) -{ -#if !defined(CONFIG_USER_ONLY) - env->excp_vectors[POWERPC_EXCP_RESET] = 0x00000100; - env->excp_vectors[POWERPC_EXCP_MCHECK] = 0x00000200; - env->excp_vectors[POWERPC_EXCP_DSI] = 0x00000300; - env->excp_vectors[POWERPC_EXCP_ISI] = 0x00000400; - env->excp_vectors[POWERPC_EXCP_EXTERNAL] = 0x00000500; - env->excp_vectors[POWERPC_EXCP_ALIGN] = 0x00000600; - env->excp_vectors[POWERPC_EXCP_PROGRAM] = 0x00000700; - env->excp_vectors[POWERPC_EXCP_FPU] = 0x00000800; - env->excp_vectors[POWERPC_EXCP_DECR] = 0x00000900; - env->excp_vectors[POWERPC_EXCP_SYSCALL] = 0x00000C00; - env->excp_vectors[POWERPC_EXCP_TRACE] = 0x00000D00; - env->excp_vectors[POWERPC_EXCP_PERFM] = 0x00000F00; - env->excp_vectors[POWERPC_EXCP_IABR] = 0x00001300; - env->excp_vectors[POWERPC_EXCP_SMI] = 0x00001400; - env->excp_vectors[POWERPC_EXCP_THERM] = 0x00001700; - /* Hardware reset vector */ - env->hreset_vector = 0x00000100UL; -#endif -} - -static void init_excp_750cl(CPUPPCState *env) -{ -#if !defined(CONFIG_USER_ONLY) - env->excp_vectors[POWERPC_EXCP_RESET] = 0x00000100; - env->excp_vectors[POWERPC_EXCP_MCHECK] = 0x00000200; - env->excp_vectors[POWERPC_EXCP_DSI] = 0x00000300; - env->excp_vectors[POWERPC_EXCP_ISI] = 0x00000400; - env->excp_vectors[POWERPC_EXCP_EXTERNAL] = 0x00000500; - env->excp_vectors[POWERPC_EXCP_ALIGN] = 0x00000600; - env->excp_vectors[POWERPC_EXCP_PROGRAM] = 0x00000700; - env->excp_vectors[POWERPC_EXCP_FPU] = 0x00000800; - env->excp_vectors[POWERPC_EXCP_DECR] = 0x00000900; - env->excp_vectors[POWERPC_EXCP_SYSCALL] = 0x00000C00; - env->excp_vectors[POWERPC_EXCP_TRACE] = 0x00000D00; - env->excp_vectors[POWERPC_EXCP_PERFM] = 0x00000F00; - env->excp_vectors[POWERPC_EXCP_IABR] = 0x00001300; - env->excp_vectors[POWERPC_EXCP_SMI] = 0x00001400; - /* Hardware reset vector */ - env->hreset_vector = 0x00000100UL; -#endif -} - -static void init_excp_750cx(CPUPPCState *env) -{ -#if !defined(CONFIG_USER_ONLY) - env->excp_vectors[POWERPC_EXCP_RESET] = 0x00000100; - env->excp_vectors[POWERPC_EXCP_MCHECK] = 0x00000200; - env->excp_vectors[POWERPC_EXCP_DSI] = 0x00000300; - env->excp_vectors[POWERPC_EXCP_ISI] = 0x00000400; - env->excp_vectors[POWERPC_EXCP_EXTERNAL] = 0x00000500; - env->excp_vectors[POWERPC_EXCP_ALIGN] = 0x00000600; - env->excp_vectors[POWERPC_EXCP_PROGRAM] = 0x00000700; - env->excp_vectors[POWERPC_EXCP_FPU] = 0x00000800; - env->excp_vectors[POWERPC_EXCP_DECR] = 0x00000900; - env->excp_vectors[POWERPC_EXCP_SYSCALL] = 0x00000C00; - env->excp_vectors[POWERPC_EXCP_TRACE] = 0x00000D00; - env->excp_vectors[POWERPC_EXCP_PERFM] = 0x00000F00; - env->excp_vectors[POWERPC_EXCP_IABR] = 0x00001300; - env->excp_vectors[POWERPC_EXCP_THERM] = 0x00001700; - /* Hardware reset vector */ - env->hreset_vector = 0x00000100UL; -#endif -} - -/* XXX: Check if this is correct */ -static void init_excp_7x5(CPUPPCState *env) -{ -#if !defined(CONFIG_USER_ONLY) - env->excp_vectors[POWERPC_EXCP_RESET] = 0x00000100; - env->excp_vectors[POWERPC_EXCP_MCHECK] = 0x00000200; - env->excp_vectors[POWERPC_EXCP_DSI] = 0x00000300; - env->excp_vectors[POWERPC_EXCP_ISI] = 0x00000400; - env->excp_vectors[POWERPC_EXCP_EXTERNAL] = 0x00000500; - env->excp_vectors[POWERPC_EXCP_ALIGN] = 0x00000600; - env->excp_vectors[POWERPC_EXCP_PROGRAM] = 0x00000700; - env->excp_vectors[POWERPC_EXCP_FPU] = 0x00000800; - env->excp_vectors[POWERPC_EXCP_DECR] = 0x00000900; - env->excp_vectors[POWERPC_EXCP_SYSCALL] = 0x00000C00; - env->excp_vectors[POWERPC_EXCP_TRACE] = 0x00000D00; - env->excp_vectors[POWERPC_EXCP_PERFM] = 0x00000F00; - env->excp_vectors[POWERPC_EXCP_IFTLB] = 0x00001000; - env->excp_vectors[POWERPC_EXCP_DLTLB] = 0x00001100; - env->excp_vectors[POWERPC_EXCP_DSTLB] = 0x00001200; - env->excp_vectors[POWERPC_EXCP_IABR] = 0x00001300; - env->excp_vectors[POWERPC_EXCP_SMI] = 0x00001400; - env->excp_vectors[POWERPC_EXCP_THERM] = 0x00001700; - /* Hardware reset vector */ - env->hreset_vector = 0x00000100UL; -#endif -} - static void init_excp_7400(CPUPPCState *env) { #if !defined(CONFIG_USER_ONLY) @@ -2102,628 +1851,6 @@ POWERPC_FAMILY(e6500)(ObjectClass *oc, void *data) #endif -static void init_proc_740(CPUPPCState *env) -{ - register_non_embedded_sprs(env); - register_sdr1_sprs(env); - register_7xx_sprs(env); - /* Thermal management */ - register_thrm_sprs(env); - - /* Memory management */ - register_low_BATs(env); - init_excp_7x0(env); - env->dcache_line_size = 32; - env->icache_line_size = 32; - /* Allocate hardware IRQ controller */ - ppc6xx_irq_init(env_archcpu(env)); -} - -POWERPC_FAMILY(740)(ObjectClass *oc, void *data) -{ - DeviceClass *dc = DEVICE_CLASS(oc); - PowerPCCPUClass *pcc = POWERPC_CPU_CLASS(oc); - - dc->desc = "PowerPC 740"; - pcc->init_proc = init_proc_740; - pcc->check_pow = check_pow_hid0; - pcc->insns_flags = PPC_INSNS_BASE | PPC_STRING | PPC_MFTB | - PPC_FLOAT | PPC_FLOAT_FSEL | PPC_FLOAT_FRES | - PPC_FLOAT_FRSQRTE | PPC_FLOAT_STFIWX | - PPC_CACHE | PPC_CACHE_ICBI | PPC_CACHE_DCBZ | - PPC_MEM_SYNC | PPC_MEM_EIEIO | - PPC_MEM_TLBIE | PPC_MEM_TLBSYNC | - PPC_SEGMENT | PPC_EXTERN; - pcc->msr_mask = (1ull << MSR_POW) | - (1ull << MSR_ILE) | - (1ull << MSR_EE) | - (1ull << MSR_PR) | - (1ull << MSR_FP) | - (1ull << MSR_ME) | - (1ull << MSR_FE0) | - (1ull << MSR_SE) | - (1ull << MSR_DE) | - (1ull << MSR_FE1) | - (1ull << MSR_EP) | - (1ull << MSR_IR) | - (1ull << MSR_DR) | - (1ull << MSR_PMM) | - (1ull << MSR_RI) | - (1ull << MSR_LE); - pcc->mmu_model = POWERPC_MMU_32B; - pcc->excp_model = POWERPC_EXCP_7xx; - pcc->bus_model = PPC_FLAGS_INPUT_6xx; - pcc->bfd_mach = bfd_mach_ppc_750; - pcc->flags = POWERPC_FLAG_SE | POWERPC_FLAG_BE | - POWERPC_FLAG_PMM | POWERPC_FLAG_BUS_CLK; -} - -static void init_proc_750(CPUPPCState *env) -{ - register_non_embedded_sprs(env); - register_sdr1_sprs(env); - register_7xx_sprs(env); - - spr_register(env, SPR_L2CR, "L2CR", - SPR_NOACCESS, SPR_NOACCESS, - &spr_read_generic, spr_access_nop, - 0x00000000); - /* Thermal management */ - register_thrm_sprs(env); - - /* Memory management */ - register_low_BATs(env); - /* - * XXX: high BATs are also present but are known to be bugged on - * die version 1.x - */ - init_excp_7x0(env); - env->dcache_line_size = 32; - env->icache_line_size = 32; - /* Allocate hardware IRQ controller */ - ppc6xx_irq_init(env_archcpu(env)); -} - -POWERPC_FAMILY(750)(ObjectClass *oc, void *data) -{ - DeviceClass *dc = DEVICE_CLASS(oc); - PowerPCCPUClass *pcc = POWERPC_CPU_CLASS(oc); - - dc->desc = "PowerPC 750"; - pcc->init_proc = init_proc_750; - pcc->check_pow = check_pow_hid0; - pcc->insns_flags = PPC_INSNS_BASE | PPC_STRING | PPC_MFTB | - PPC_FLOAT | PPC_FLOAT_FSEL | PPC_FLOAT_FRES | - PPC_FLOAT_FRSQRTE | PPC_FLOAT_STFIWX | - PPC_CACHE | PPC_CACHE_ICBI | PPC_CACHE_DCBZ | - PPC_MEM_SYNC | PPC_MEM_EIEIO | - PPC_MEM_TLBIE | PPC_MEM_TLBSYNC | - PPC_SEGMENT | PPC_EXTERN; - pcc->msr_mask = (1ull << MSR_POW) | - (1ull << MSR_ILE) | - (1ull << MSR_EE) | - (1ull << MSR_PR) | - (1ull << MSR_FP) | - (1ull << MSR_ME) | - (1ull << MSR_FE0) | - (1ull << MSR_SE) | - (1ull << MSR_DE) | - (1ull << MSR_FE1) | - (1ull << MSR_EP) | - (1ull << MSR_IR) | - (1ull << MSR_DR) | - (1ull << MSR_PMM) | - (1ull << MSR_RI) | - (1ull << MSR_LE); - pcc->mmu_model = POWERPC_MMU_32B; - pcc->excp_model = POWERPC_EXCP_7xx; - pcc->bus_model = PPC_FLAGS_INPUT_6xx; - pcc->bfd_mach = bfd_mach_ppc_750; - pcc->flags = POWERPC_FLAG_SE | POWERPC_FLAG_BE | - POWERPC_FLAG_PMM | POWERPC_FLAG_BUS_CLK; -} - -static void init_proc_750cl(CPUPPCState *env) -{ - register_non_embedded_sprs(env); - register_sdr1_sprs(env); - register_7xx_sprs(env); - - spr_register(env, SPR_L2CR, "L2CR", - SPR_NOACCESS, SPR_NOACCESS, - &spr_read_generic, spr_access_nop, - 0x00000000); - /* Thermal management */ - /* Those registers are fake on 750CL */ - spr_register(env, SPR_THRM1, "THRM1", - SPR_NOACCESS, SPR_NOACCESS, - &spr_read_generic, &spr_write_generic, - 0x00000000); - spr_register(env, SPR_THRM2, "THRM2", - SPR_NOACCESS, SPR_NOACCESS, - &spr_read_generic, &spr_write_generic, - 0x00000000); - spr_register(env, SPR_THRM3, "THRM3", - SPR_NOACCESS, SPR_NOACCESS, - &spr_read_generic, &spr_write_generic, - 0x00000000); - - spr_register(env, SPR_750_TDCL, "TDCL", - SPR_NOACCESS, SPR_NOACCESS, - &spr_read_generic, &spr_write_generic, - 0x00000000); - spr_register(env, SPR_750_TDCH, "TDCH", - SPR_NOACCESS, SPR_NOACCESS, - &spr_read_generic, &spr_write_generic, - 0x00000000); - /* DMA */ - spr_register(env, SPR_750_WPAR, "WPAR", - SPR_NOACCESS, SPR_NOACCESS, - &spr_read_generic, &spr_write_generic, - 0x00000000); - spr_register(env, SPR_750_DMAL, "DMAL", - SPR_NOACCESS, SPR_NOACCESS, - &spr_read_generic, &spr_write_generic, - 0x00000000); - spr_register(env, SPR_750_DMAU, "DMAU", - SPR_NOACCESS, SPR_NOACCESS, - &spr_read_generic, &spr_write_generic, - 0x00000000); - /* Hardware implementation registers */ - spr_register(env, SPR_750CL_HID2, "HID2", - SPR_NOACCESS, SPR_NOACCESS, - &spr_read_generic, &spr_write_generic, - 0x00000000); - - spr_register(env, SPR_750CL_HID4, "HID4", - SPR_NOACCESS, SPR_NOACCESS, - &spr_read_generic, &spr_write_generic, - 0x00000000); - /* Quantization registers */ - spr_register(env, SPR_750_GQR0, "GQR0", - SPR_NOACCESS, SPR_NOACCESS, - &spr_read_generic, &spr_write_generic, - 0x00000000); - - spr_register(env, SPR_750_GQR1, "GQR1", - SPR_NOACCESS, SPR_NOACCESS, - &spr_read_generic, &spr_write_generic, - 0x00000000); - - spr_register(env, SPR_750_GQR2, "GQR2", - SPR_NOACCESS, SPR_NOACCESS, - &spr_read_generic, &spr_write_generic, - 0x00000000); - - spr_register(env, SPR_750_GQR3, "GQR3", - SPR_NOACCESS, SPR_NOACCESS, - &spr_read_generic, &spr_write_generic, - 0x00000000); - - spr_register(env, SPR_750_GQR4, "GQR4", - SPR_NOACCESS, SPR_NOACCESS, - &spr_read_generic, &spr_write_generic, - 0x00000000); - - spr_register(env, SPR_750_GQR5, "GQR5", - SPR_NOACCESS, SPR_NOACCESS, - &spr_read_generic, &spr_write_generic, - 0x00000000); - - spr_register(env, SPR_750_GQR6, "GQR6", - SPR_NOACCESS, SPR_NOACCESS, - &spr_read_generic, &spr_write_generic, - 0x00000000); - - spr_register(env, SPR_750_GQR7, "GQR7", - SPR_NOACCESS, SPR_NOACCESS, - &spr_read_generic, &spr_write_generic, - 0x00000000); - /* Memory management */ - register_low_BATs(env); - /* PowerPC 750cl has 8 DBATs and 8 IBATs */ - register_high_BATs(env); - init_excp_750cl(env); - env->dcache_line_size = 32; - env->icache_line_size = 32; - /* Allocate hardware IRQ controller */ - ppc6xx_irq_init(env_archcpu(env)); -} - -POWERPC_FAMILY(750cl)(ObjectClass *oc, void *data) -{ - DeviceClass *dc = DEVICE_CLASS(oc); - PowerPCCPUClass *pcc = POWERPC_CPU_CLASS(oc); - - dc->desc = "PowerPC 750 CL"; - pcc->init_proc = init_proc_750cl; - pcc->check_pow = check_pow_hid0; - /* - * XXX: not implemented: - * cache lock instructions: - * dcbz_l - * floating point paired instructions - * psq_lux - * psq_lx - * psq_stux - * psq_stx - * ps_abs - * ps_add - * ps_cmpo0 - * ps_cmpo1 - * ps_cmpu0 - * ps_cmpu1 - * ps_div - * ps_madd - * ps_madds0 - * ps_madds1 - * ps_merge00 - * ps_merge01 - * ps_merge10 - * ps_merge11 - * ps_mr - * ps_msub - * ps_mul - * ps_muls0 - * ps_muls1 - * ps_nabs - * ps_neg - * ps_nmadd - * ps_nmsub - * ps_res - * ps_rsqrte - * ps_sel - * ps_sub - * ps_sum0 - * ps_sum1 - */ - pcc->insns_flags = PPC_INSNS_BASE | PPC_STRING | PPC_MFTB | - PPC_FLOAT | PPC_FLOAT_FSEL | PPC_FLOAT_FRES | - PPC_FLOAT_FRSQRTE | PPC_FLOAT_STFIWX | - PPC_CACHE | PPC_CACHE_ICBI | PPC_CACHE_DCBZ | - PPC_MEM_SYNC | PPC_MEM_EIEIO | - PPC_MEM_TLBIE | PPC_MEM_TLBSYNC | - PPC_SEGMENT | PPC_EXTERN; - pcc->msr_mask = (1ull << MSR_POW) | - (1ull << MSR_ILE) | - (1ull << MSR_EE) | - (1ull << MSR_PR) | - (1ull << MSR_FP) | - (1ull << MSR_ME) | - (1ull << MSR_FE0) | - (1ull << MSR_SE) | - (1ull << MSR_DE) | - (1ull << MSR_FE1) | - (1ull << MSR_EP) | - (1ull << MSR_IR) | - (1ull << MSR_DR) | - (1ull << MSR_PMM) | - (1ull << MSR_RI) | - (1ull << MSR_LE); - pcc->mmu_model = POWERPC_MMU_32B; - pcc->excp_model = POWERPC_EXCP_7xx; - pcc->bus_model = PPC_FLAGS_INPUT_6xx; - pcc->bfd_mach = bfd_mach_ppc_750; - pcc->flags = POWERPC_FLAG_SE | POWERPC_FLAG_BE | - POWERPC_FLAG_PMM | POWERPC_FLAG_BUS_CLK; -} - -static void init_proc_750cx(CPUPPCState *env) -{ - register_non_embedded_sprs(env); - register_sdr1_sprs(env); - register_7xx_sprs(env); - - spr_register(env, SPR_L2CR, "L2CR", - SPR_NOACCESS, SPR_NOACCESS, - &spr_read_generic, spr_access_nop, - 0x00000000); - /* Thermal management */ - register_thrm_sprs(env); - - spr_register(env, SPR_SDA, "SDA", - SPR_NOACCESS, SPR_NOACCESS, - &spr_read_generic, &spr_write_generic, - 0x00000000); - - /* Memory management */ - register_low_BATs(env); - /* PowerPC 750cx has 8 DBATs and 8 IBATs */ - register_high_BATs(env); - init_excp_750cx(env); - env->dcache_line_size = 32; - env->icache_line_size = 32; - /* Allocate hardware IRQ controller */ - ppc6xx_irq_init(env_archcpu(env)); -} - -POWERPC_FAMILY(750cx)(ObjectClass *oc, void *data) -{ - DeviceClass *dc = DEVICE_CLASS(oc); - PowerPCCPUClass *pcc = POWERPC_CPU_CLASS(oc); - - dc->desc = "PowerPC 750CX"; - pcc->init_proc = init_proc_750cx; - pcc->check_pow = check_pow_hid0; - pcc->insns_flags = PPC_INSNS_BASE | PPC_STRING | PPC_MFTB | - PPC_FLOAT | PPC_FLOAT_FSEL | PPC_FLOAT_FRES | - PPC_FLOAT_FRSQRTE | PPC_FLOAT_STFIWX | - PPC_CACHE | PPC_CACHE_ICBI | PPC_CACHE_DCBZ | - PPC_MEM_SYNC | PPC_MEM_EIEIO | - PPC_MEM_TLBIE | PPC_MEM_TLBSYNC | - PPC_SEGMENT | PPC_EXTERN; - pcc->msr_mask = (1ull << MSR_POW) | - (1ull << MSR_ILE) | - (1ull << MSR_EE) | - (1ull << MSR_PR) | - (1ull << MSR_FP) | - (1ull << MSR_ME) | - (1ull << MSR_FE0) | - (1ull << MSR_SE) | - (1ull << MSR_DE) | - (1ull << MSR_FE1) | - (1ull << MSR_EP) | - (1ull << MSR_IR) | - (1ull << MSR_DR) | - (1ull << MSR_PMM) | - (1ull << MSR_RI) | - (1ull << MSR_LE); - pcc->mmu_model = POWERPC_MMU_32B; - pcc->excp_model = POWERPC_EXCP_7xx; - pcc->bus_model = PPC_FLAGS_INPUT_6xx; - pcc->bfd_mach = bfd_mach_ppc_750; - pcc->flags = POWERPC_FLAG_SE | POWERPC_FLAG_BE | - POWERPC_FLAG_PMM | POWERPC_FLAG_BUS_CLK; -} - -static void init_proc_750fx(CPUPPCState *env) -{ - register_non_embedded_sprs(env); - register_sdr1_sprs(env); - register_7xx_sprs(env); - - spr_register(env, SPR_L2CR, "L2CR", - SPR_NOACCESS, SPR_NOACCESS, - &spr_read_generic, spr_access_nop, - 0x00000000); - /* Thermal management */ - register_thrm_sprs(env); - - spr_register(env, SPR_750_THRM4, "THRM4", - SPR_NOACCESS, SPR_NOACCESS, - &spr_read_generic, &spr_write_generic, - 0x00000000); - /* Hardware implementation registers */ - spr_register(env, SPR_750FX_HID2, "HID2", - SPR_NOACCESS, SPR_NOACCESS, - &spr_read_generic, &spr_write_generic, - 0x00000000); - /* Memory management */ - register_low_BATs(env); - /* PowerPC 750fx & 750gx has 8 DBATs and 8 IBATs */ - register_high_BATs(env); - init_excp_7x0(env); - env->dcache_line_size = 32; - env->icache_line_size = 32; - /* Allocate hardware IRQ controller */ - ppc6xx_irq_init(env_archcpu(env)); -} - -POWERPC_FAMILY(750fx)(ObjectClass *oc, void *data) -{ - DeviceClass *dc = DEVICE_CLASS(oc); - PowerPCCPUClass *pcc = POWERPC_CPU_CLASS(oc); - - dc->desc = "PowerPC 750FX"; - pcc->init_proc = init_proc_750fx; - pcc->check_pow = check_pow_hid0; - pcc->insns_flags = PPC_INSNS_BASE | PPC_STRING | PPC_MFTB | - PPC_FLOAT | PPC_FLOAT_FSEL | PPC_FLOAT_FRES | - PPC_FLOAT_FRSQRTE | PPC_FLOAT_STFIWX | - PPC_CACHE | PPC_CACHE_ICBI | PPC_CACHE_DCBZ | - PPC_MEM_SYNC | PPC_MEM_EIEIO | - PPC_MEM_TLBIE | PPC_MEM_TLBSYNC | - PPC_SEGMENT | PPC_EXTERN; - pcc->msr_mask = (1ull << MSR_POW) | - (1ull << MSR_ILE) | - (1ull << MSR_EE) | - (1ull << MSR_PR) | - (1ull << MSR_FP) | - (1ull << MSR_ME) | - (1ull << MSR_FE0) | - (1ull << MSR_SE) | - (1ull << MSR_DE) | - (1ull << MSR_FE1) | - (1ull << MSR_EP) | - (1ull << MSR_IR) | - (1ull << MSR_DR) | - (1ull << MSR_PMM) | - (1ull << MSR_RI) | - (1ull << MSR_LE); - pcc->mmu_model = POWERPC_MMU_32B; - pcc->excp_model = POWERPC_EXCP_7xx; - pcc->bus_model = PPC_FLAGS_INPUT_6xx; - pcc->bfd_mach = bfd_mach_ppc_750; - pcc->flags = POWERPC_FLAG_SE | POWERPC_FLAG_BE | - POWERPC_FLAG_PMM | POWERPC_FLAG_BUS_CLK; -} - -static void init_proc_750gx(CPUPPCState *env) -{ - register_non_embedded_sprs(env); - register_sdr1_sprs(env); - register_7xx_sprs(env); - - spr_register(env, SPR_L2CR, "L2CR", - SPR_NOACCESS, SPR_NOACCESS, - &spr_read_generic, spr_access_nop, - 0x00000000); - /* Thermal management */ - register_thrm_sprs(env); - - spr_register(env, SPR_750_THRM4, "THRM4", - SPR_NOACCESS, SPR_NOACCESS, - &spr_read_generic, &spr_write_generic, - 0x00000000); - /* Hardware implementation registers */ - spr_register(env, SPR_750FX_HID2, "HID2", - SPR_NOACCESS, SPR_NOACCESS, - &spr_read_generic, &spr_write_generic, - 0x00000000); - /* Memory management */ - register_low_BATs(env); - /* PowerPC 750fx & 750gx has 8 DBATs and 8 IBATs */ - register_high_BATs(env); - init_excp_7x0(env); - env->dcache_line_size = 32; - env->icache_line_size = 32; - /* Allocate hardware IRQ controller */ - ppc6xx_irq_init(env_archcpu(env)); -} - -POWERPC_FAMILY(750gx)(ObjectClass *oc, void *data) -{ - DeviceClass *dc = DEVICE_CLASS(oc); - PowerPCCPUClass *pcc = POWERPC_CPU_CLASS(oc); - - dc->desc = "PowerPC 750GX"; - pcc->init_proc = init_proc_750gx; - pcc->check_pow = check_pow_hid0; - pcc->insns_flags = PPC_INSNS_BASE | PPC_STRING | PPC_MFTB | - PPC_FLOAT | PPC_FLOAT_FSEL | PPC_FLOAT_FRES | - PPC_FLOAT_FRSQRTE | PPC_FLOAT_STFIWX | - PPC_CACHE | PPC_CACHE_ICBI | PPC_CACHE_DCBZ | - PPC_MEM_SYNC | PPC_MEM_EIEIO | - PPC_MEM_TLBIE | PPC_MEM_TLBSYNC | - PPC_SEGMENT | PPC_EXTERN; - pcc->msr_mask = (1ull << MSR_POW) | - (1ull << MSR_ILE) | - (1ull << MSR_EE) | - (1ull << MSR_PR) | - (1ull << MSR_FP) | - (1ull << MSR_ME) | - (1ull << MSR_FE0) | - (1ull << MSR_SE) | - (1ull << MSR_DE) | - (1ull << MSR_FE1) | - (1ull << MSR_EP) | - (1ull << MSR_IR) | - (1ull << MSR_DR) | - (1ull << MSR_PMM) | - (1ull << MSR_RI) | - (1ull << MSR_LE); - pcc->mmu_model = POWERPC_MMU_32B; - pcc->excp_model = POWERPC_EXCP_7xx; - pcc->bus_model = PPC_FLAGS_INPUT_6xx; - pcc->bfd_mach = bfd_mach_ppc_750; - pcc->flags = POWERPC_FLAG_SE | POWERPC_FLAG_BE | - POWERPC_FLAG_PMM | POWERPC_FLAG_BUS_CLK; -} - -static void init_proc_745(CPUPPCState *env) -{ - register_non_embedded_sprs(env); - register_sdr1_sprs(env); - register_7xx_sprs(env); - register_745_sprs(env); - /* Thermal management */ - register_thrm_sprs(env); - - /* Memory management */ - register_low_BATs(env); - register_high_BATs(env); - register_6xx_7xx_soft_tlb(env, 64, 2); - init_excp_7x5(env); - env->dcache_line_size = 32; - env->icache_line_size = 32; - /* Allocate hardware IRQ controller */ - ppc6xx_irq_init(env_archcpu(env)); -} - -POWERPC_FAMILY(745)(ObjectClass *oc, void *data) -{ - DeviceClass *dc = DEVICE_CLASS(oc); - PowerPCCPUClass *pcc = POWERPC_CPU_CLASS(oc); - - dc->desc = "PowerPC 745"; - pcc->init_proc = init_proc_745; - pcc->check_pow = check_pow_hid0; - pcc->insns_flags = PPC_INSNS_BASE | PPC_STRING | PPC_MFTB | - PPC_FLOAT | PPC_FLOAT_FSEL | PPC_FLOAT_FRES | - PPC_FLOAT_FRSQRTE | PPC_FLOAT_STFIWX | - PPC_CACHE | PPC_CACHE_ICBI | PPC_CACHE_DCBZ | - PPC_MEM_SYNC | PPC_MEM_EIEIO | - PPC_MEM_TLBIE | PPC_MEM_TLBSYNC | PPC_6xx_TLB | - PPC_SEGMENT | PPC_EXTERN; - pcc->msr_mask = (1ull << MSR_POW) | - (1ull << MSR_ILE) | - (1ull << MSR_EE) | - (1ull << MSR_PR) | - (1ull << MSR_FP) | - (1ull << MSR_ME) | - (1ull << MSR_FE0) | - (1ull << MSR_SE) | - (1ull << MSR_DE) | - (1ull << MSR_FE1) | - (1ull << MSR_EP) | - (1ull << MSR_IR) | - (1ull << MSR_DR) | - (1ull << MSR_PMM) | - (1ull << MSR_RI) | - (1ull << MSR_LE); - pcc->mmu_model = POWERPC_MMU_SOFT_6xx; - pcc->excp_model = POWERPC_EXCP_7xx; - pcc->bus_model = PPC_FLAGS_INPUT_6xx; - pcc->bfd_mach = bfd_mach_ppc_750; - pcc->flags = POWERPC_FLAG_SE | POWERPC_FLAG_BE | - POWERPC_FLAG_PMM | POWERPC_FLAG_BUS_CLK; -} - -static void init_proc_755(CPUPPCState *env) -{ - init_proc_745(env); - register_755_sprs(env); -} - -POWERPC_FAMILY(755)(ObjectClass *oc, void *data) -{ - DeviceClass *dc = DEVICE_CLASS(oc); - PowerPCCPUClass *pcc = POWERPC_CPU_CLASS(oc); - - dc->desc = "PowerPC 755"; - pcc->init_proc = init_proc_755; - pcc->check_pow = check_pow_hid0; - pcc->insns_flags = PPC_INSNS_BASE | PPC_STRING | PPC_MFTB | - PPC_FLOAT | PPC_FLOAT_FSEL | PPC_FLOAT_FRES | - PPC_FLOAT_FRSQRTE | PPC_FLOAT_STFIWX | - PPC_CACHE | PPC_CACHE_ICBI | PPC_CACHE_DCBZ | - PPC_MEM_SYNC | PPC_MEM_EIEIO | - PPC_MEM_TLBIE | PPC_MEM_TLBSYNC | PPC_6xx_TLB | - PPC_SEGMENT | PPC_EXTERN; - pcc->msr_mask = (1ull << MSR_POW) | - (1ull << MSR_ILE) | - (1ull << MSR_EE) | - (1ull << MSR_PR) | - (1ull << MSR_FP) | - (1ull << MSR_ME) | - (1ull << MSR_FE0) | - (1ull << MSR_SE) | - (1ull << MSR_DE) | - (1ull << MSR_FE1) | - (1ull << MSR_EP) | - (1ull << MSR_IR) | - (1ull << MSR_DR) | - (1ull << MSR_PMM) | - (1ull << MSR_RI) | - (1ull << MSR_LE); - pcc->mmu_model = POWERPC_MMU_SOFT_6xx; - pcc->excp_model = POWERPC_EXCP_7xx; - pcc->bus_model = PPC_FLAGS_INPUT_6xx; - pcc->bfd_mach = bfd_mach_ppc_750; - pcc->flags = POWERPC_FLAG_SE | POWERPC_FLAG_BE | - POWERPC_FLAG_PMM | POWERPC_FLAG_BUS_CLK; -} - static void init_proc_7400(CPUPPCState *env) { register_non_embedded_sprs(env); diff --git a/target/ppc/meson.build b/target/ppc/meson.build index f4ded2ecdc..f665802d5e 100644 --- a/target/ppc/meson.build +++ b/target/ppc/meson.build @@ -5,6 +5,7 @@ ppc_ss.add(files( 'cpu_init.c', 'cpu_40x.c', 'cpu_6xx.c', + 'cpu_7xx.c', 'excp_helper.c', 'gdbstub.c', 'helper_regs.c', From patchwork Tue Mar 1 13:56:09 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Fabiano Rosas X-Patchwork-Id: 12764748 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 12410C433EF for ; Tue, 1 Mar 2022 13:59:42 +0000 (UTC) Received: from localhost ([::1]:51952 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1nP32T-0000u1-MZ for qemu-devel@archiver.kernel.org; Tue, 01 Mar 2022 08:59:41 -0500 Received: from eggs.gnu.org ([209.51.188.92]:33286) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1nP2zm-0005xB-6s; Tue, 01 Mar 2022 08:56:54 -0500 Received: from mx0a-001b2d01.pphosted.com ([148.163.156.1]:8878) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1nP2zi-00023t-3X; Tue, 01 Mar 2022 08:56:53 -0500 Received: from pps.filterd (m0098396.ppops.net [127.0.0.1]) by mx0a-001b2d01.pphosted.com (8.16.1.2/8.16.1.2) with SMTP id 221DhbgZ024619; Tue, 1 Mar 2022 13:56:43 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=typ68s94trfFbZw4LrpwiVud+345gkPCG4USD76bDec=; b=AK1LjvO97eIGchujh+wU+DM8I8vXoBipp26vSeV68OCs1QR5mRr7Gmr2w4xztMLaVhLT JNm4oi5Zj30zw4surjRnLAjciqF1LagNrH7jr23rHu5tI1BTSJVVU4eWWbqE8rXSIciy sYHLKYu0s0Dmx3eQjCyCVQHElGyqp67DomfG4PjTJp61tkuVEFVk6fymqDvdqC1sFmQ+ eNy9H9dIA1m2G0nR7IhCnwFvx3hY0EHuoqxETnPb/iXhMIdLsyk44zHeyAzRIM4AdNtu W1AWHOZM9qjXk7QMHn9YmU5u6JQbSyG78LJh5NX0ufoVeznZe+IaZfdMUwDnIcvbqWoG cQ== Received: from pps.reinject (localhost [127.0.0.1]) by mx0a-001b2d01.pphosted.com with ESMTP id 3ehmmh08b9-1 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NOT); Tue, 01 Mar 2022 13:56:43 +0000 Received: from m0098396.ppops.net (m0098396.ppops.net [127.0.0.1]) by pps.reinject (8.16.0.43/8.16.0.43) with SMTP id 221DrDNR026013; Tue, 1 Mar 2022 13:56:42 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 3ehmmh08ad-1 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NOT); Tue, 01 Mar 2022 13:56:42 +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 221Du2fH010374; Tue, 1 Mar 2022 13:56:41 GMT Received: from b03cxnp08028.gho.boulder.ibm.com (b03cxnp08028.gho.boulder.ibm.com [9.17.130.20]) by ppma05wdc.us.ibm.com with ESMTP id 3efbua50q3-1 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NOT); Tue, 01 Mar 2022 13:56:40 +0000 Received: from b03ledav005.gho.boulder.ibm.com (b03ledav005.gho.boulder.ibm.com [9.17.130.236]) by b03cxnp08028.gho.boulder.ibm.com (8.14.9/8.14.9/NCO v10.0) with ESMTP id 221DuejU28115372 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-GCM-SHA384 bits=256 verify=OK); Tue, 1 Mar 2022 13:56:40 GMT Received: from b03ledav005.gho.boulder.ibm.com (unknown [127.0.0.1]) by IMSVA (Postfix) with ESMTP id E574FBE056; Tue, 1 Mar 2022 13:56:39 +0000 (GMT) Received: from b03ledav005.gho.boulder.ibm.com (unknown [127.0.0.1]) by IMSVA (Postfix) with ESMTP id 5B249BE053; Tue, 1 Mar 2022 13:56:38 +0000 (GMT) Received: from farosas.linux.ibm.com.com (unknown [9.211.51.129]) by b03ledav005.gho.boulder.ibm.com (Postfix) with ESMTP; Tue, 1 Mar 2022 13:56:38 +0000 (GMT) From: Fabiano Rosas To: qemu-devel@nongnu.org Subject: [PATCH 06/17] target/ppc: Move 74xx CPUs code to their own file Date: Tue, 1 Mar 2022 10:56:09 -0300 Message-Id: <20220301135620.2411952-7-farosas@linux.ibm.com> X-Mailer: git-send-email 2.34.1 In-Reply-To: <20220301135620.2411952-1-farosas@linux.ibm.com> References: <20220301135620.2411952-1-farosas@linux.ibm.com> MIME-Version: 1.0 X-TM-AS-GCONF: 00 X-Proofpoint-GUID: Cyu3hc8OQJoWi9GLyb5zSVuEd5fodt4f X-Proofpoint-ORIG-GUID: k6g3nkYeWoovE-UxcCmzqclQ1DrCTX3- X-Proofpoint-Virus-Version: vendor=baseguard engine=ICAP:2.0.205,Aquarius:18.0.816,Hydra:6.0.425,FMLib:17.11.64.514 definitions=2022-03-01_07,2022-02-26_01,2022-02-23_01 X-Proofpoint-Spam-Details: rule=outbound_notspam policy=outbound score=0 mlxlogscore=999 adultscore=0 priorityscore=1501 suspectscore=0 malwarescore=0 bulkscore=0 mlxscore=0 spamscore=0 lowpriorityscore=0 clxscore=1015 phishscore=0 impostorscore=0 classifier=spam adjust=0 reason=mlx scancount=1 engine=8.12.0-2201110000 definitions=main-2203010074 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_H5=0.001, RCVD_IN_MSPIKE_WL=0.001, SPF_HELO_NONE=0.001, SPF_PASS=-0.001, T_SCC_BODY_TEXT_LINE=-0.01 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" Affects the 7400, 7410, 7440, 7450, 7445, 7455, 7457 and e600. This moves init_proc, init_excp and register_*sprs functions that are related to the 74xx CPUs into a separate file. - the inclusion of sysemu/hw_accel.h is because of the DABR definition that comes from linux-headers kvm.h; - I'm copying check_pow_hid0 instead of moving it to avoid having to keep it exposed in a header file; - I'm also copying vscr_init to avoid having to include fpu/softfloat.h (due to set_float_rounding_mode) from elsewhere. Signed-off-by: Fabiano Rosas --- target/ppc/cpu_74xx.c | 1167 ++++++++++++++++++++++++++++++++++++++++ target/ppc/cpu_init.c | 1136 -------------------------------------- target/ppc/meson.build | 1 + 3 files changed, 1168 insertions(+), 1136 deletions(-) create mode 100644 target/ppc/cpu_74xx.c diff --git a/target/ppc/cpu_74xx.c b/target/ppc/cpu_74xx.c new file mode 100644 index 0000000000..cc530cc405 --- /dev/null +++ b/target/ppc/cpu_74xx.c @@ -0,0 +1,1167 @@ +/* + * CPU initialization for PowerPC 74xx CPUs + * + * Copyright IBM Corp. 2022 + * + * This work is licensed under the terms of the GNU GPL, version 2 or later. + * See the COPYING file in the top-level directory. + */ + +#include "qemu/osdep.h" +#include "sysemu/hw_accel.h" +#include "hw/ppc/ppc.h" +#include "fpu/softfloat.h" +#include "cpu.h" +#include "spr_common.h" + +static int check_pow_hid0(CPUPPCState *env) +{ + if (env->spr[SPR_HID0] & 0x00E00000) { + return 1; + } + + return 0; +} + +static int check_pow_hid0_74xx(CPUPPCState *env) +{ + if (env->spr[SPR_HID0] & 0x00600000) { + return 1; + } + + return 0; +} + +static inline void vscr_init(CPUPPCState *env, uint32_t val) +{ + /* Altivec always uses round-to-nearest */ + set_float_rounding_mode(float_round_nearest_even, &env->vec_status); + ppc_store_vscr(env, val); +} + +static void register_74xx_sprs(CPUPPCState *env) +{ + /* Breakpoints */ + spr_register_kvm(env, SPR_DABR, "DABR", + SPR_NOACCESS, SPR_NOACCESS, + &spr_read_generic, &spr_write_generic, + KVM_REG_PPC_DABR, 0x00000000); + + spr_register(env, SPR_IABR, "IABR", + SPR_NOACCESS, SPR_NOACCESS, + &spr_read_generic, &spr_write_generic, + 0x00000000); + /* Cache management */ + spr_register(env, SPR_ICTC, "ICTC", + SPR_NOACCESS, SPR_NOACCESS, + &spr_read_generic, &spr_write_generic, + 0x00000000); + /* Performance monitors */ + spr_register(env, SPR_7XX_MMCR0, "MMCR0", + SPR_NOACCESS, SPR_NOACCESS, + &spr_read_generic, &spr_write_generic, + 0x00000000); + + spr_register(env, SPR_7XX_MMCR1, "MMCR1", + SPR_NOACCESS, SPR_NOACCESS, + &spr_read_generic, &spr_write_generic, + 0x00000000); + + spr_register(env, SPR_7XX_PMC1, "PMC1", + SPR_NOACCESS, SPR_NOACCESS, + &spr_read_generic, &spr_write_generic, + 0x00000000); + + spr_register(env, SPR_7XX_PMC2, "PMC2", + SPR_NOACCESS, SPR_NOACCESS, + &spr_read_generic, &spr_write_generic, + 0x00000000); + + spr_register(env, SPR_7XX_PMC3, "PMC3", + SPR_NOACCESS, SPR_NOACCESS, + &spr_read_generic, &spr_write_generic, + 0x00000000); + + spr_register(env, SPR_7XX_PMC4, "PMC4", + SPR_NOACCESS, SPR_NOACCESS, + &spr_read_generic, &spr_write_generic, + 0x00000000); + + spr_register(env, SPR_7XX_SIAR, "SIAR", + SPR_NOACCESS, SPR_NOACCESS, + &spr_read_generic, SPR_NOACCESS, + 0x00000000); + + spr_register(env, SPR_7XX_UMMCR0, "UMMCR0", + &spr_read_ureg, SPR_NOACCESS, + &spr_read_ureg, SPR_NOACCESS, + 0x00000000); + + spr_register(env, SPR_7XX_UMMCR1, "UMMCR1", + &spr_read_ureg, SPR_NOACCESS, + &spr_read_ureg, SPR_NOACCESS, + 0x00000000); + + spr_register(env, SPR_7XX_UPMC1, "UPMC1", + &spr_read_ureg, SPR_NOACCESS, + &spr_read_ureg, SPR_NOACCESS, + 0x00000000); + + spr_register(env, SPR_7XX_UPMC2, "UPMC2", + &spr_read_ureg, SPR_NOACCESS, + &spr_read_ureg, SPR_NOACCESS, + 0x00000000); + + spr_register(env, SPR_7XX_UPMC3, "UPMC3", + &spr_read_ureg, SPR_NOACCESS, + &spr_read_ureg, SPR_NOACCESS, + 0x00000000); + + spr_register(env, SPR_7XX_UPMC4, "UPMC4", + &spr_read_ureg, SPR_NOACCESS, + &spr_read_ureg, SPR_NOACCESS, + 0x00000000); + + spr_register(env, SPR_7XX_USIAR, "USIAR", + &spr_read_ureg, SPR_NOACCESS, + &spr_read_ureg, SPR_NOACCESS, + 0x00000000); + /* External access control */ + spr_register(env, SPR_EAR, "EAR", + SPR_NOACCESS, SPR_NOACCESS, + &spr_read_generic, &spr_write_generic, + 0x00000000); + + /* Processor identification */ + spr_register(env, SPR_PIR, "PIR", + SPR_NOACCESS, SPR_NOACCESS, + &spr_read_generic, &spr_write_pir, + 0x00000000); + + spr_register(env, SPR_74XX_MMCR2, "MMCR2", + SPR_NOACCESS, SPR_NOACCESS, + &spr_read_generic, &spr_write_generic, + 0x00000000); + + spr_register(env, SPR_74XX_UMMCR2, "UMMCR2", + &spr_read_ureg, SPR_NOACCESS, + &spr_read_ureg, SPR_NOACCESS, + 0x00000000); + + spr_register(env, SPR_BAMR, "BAMR", + SPR_NOACCESS, SPR_NOACCESS, + &spr_read_generic, &spr_write_generic, + 0x00000000); + + spr_register(env, SPR_MSSCR0, "MSSCR0", + SPR_NOACCESS, SPR_NOACCESS, + &spr_read_generic, &spr_write_generic, + 0x00000000); + /* Hardware implementation registers */ + spr_register(env, SPR_HID0, "HID0", + SPR_NOACCESS, SPR_NOACCESS, + &spr_read_generic, &spr_write_generic, + 0x00000000); + + spr_register(env, SPR_HID1, "HID1", + SPR_NOACCESS, SPR_NOACCESS, + &spr_read_generic, &spr_write_generic, + 0x00000000); + /* Altivec */ + spr_register(env, SPR_VRSAVE, "VRSAVE", + &spr_read_generic, &spr_write_generic, + &spr_read_generic, &spr_write_generic, + 0x00000000); + + spr_register(env, SPR_L2CR, "L2CR", + SPR_NOACCESS, SPR_NOACCESS, + &spr_read_generic, spr_access_nop, + 0x00000000); +} + +static void register_l3_ctrl(CPUPPCState *env) +{ + /* L3CR */ + spr_register(env, SPR_L3CR, "L3CR", + SPR_NOACCESS, SPR_NOACCESS, + &spr_read_generic, &spr_write_generic, + 0x00000000); + /* L3ITCR0 */ + spr_register(env, SPR_L3ITCR0, "L3ITCR0", + SPR_NOACCESS, SPR_NOACCESS, + &spr_read_generic, &spr_write_generic, + 0x00000000); + /* L3PM */ + spr_register(env, SPR_L3PM, "L3PM", + SPR_NOACCESS, SPR_NOACCESS, + &spr_read_generic, &spr_write_generic, + 0x00000000); +} + +static void init_excp_7400(CPUPPCState *env) +{ +#if !defined(CONFIG_USER_ONLY) + env->excp_vectors[POWERPC_EXCP_RESET] = 0x00000100; + env->excp_vectors[POWERPC_EXCP_MCHECK] = 0x00000200; + env->excp_vectors[POWERPC_EXCP_DSI] = 0x00000300; + env->excp_vectors[POWERPC_EXCP_ISI] = 0x00000400; + env->excp_vectors[POWERPC_EXCP_EXTERNAL] = 0x00000500; + env->excp_vectors[POWERPC_EXCP_ALIGN] = 0x00000600; + env->excp_vectors[POWERPC_EXCP_PROGRAM] = 0x00000700; + env->excp_vectors[POWERPC_EXCP_FPU] = 0x00000800; + env->excp_vectors[POWERPC_EXCP_DECR] = 0x00000900; + env->excp_vectors[POWERPC_EXCP_SYSCALL] = 0x00000C00; + env->excp_vectors[POWERPC_EXCP_TRACE] = 0x00000D00; + env->excp_vectors[POWERPC_EXCP_PERFM] = 0x00000F00; + env->excp_vectors[POWERPC_EXCP_VPU] = 0x00000F20; + env->excp_vectors[POWERPC_EXCP_IABR] = 0x00001300; + env->excp_vectors[POWERPC_EXCP_SMI] = 0x00001400; + env->excp_vectors[POWERPC_EXCP_VPUA] = 0x00001600; + env->excp_vectors[POWERPC_EXCP_THERM] = 0x00001700; + /* Hardware reset vector */ + env->hreset_vector = 0x00000100UL; +#endif +} + +static void init_excp_7450(CPUPPCState *env) +{ +#if !defined(CONFIG_USER_ONLY) + env->excp_vectors[POWERPC_EXCP_RESET] = 0x00000100; + env->excp_vectors[POWERPC_EXCP_MCHECK] = 0x00000200; + env->excp_vectors[POWERPC_EXCP_DSI] = 0x00000300; + env->excp_vectors[POWERPC_EXCP_ISI] = 0x00000400; + env->excp_vectors[POWERPC_EXCP_EXTERNAL] = 0x00000500; + env->excp_vectors[POWERPC_EXCP_ALIGN] = 0x00000600; + env->excp_vectors[POWERPC_EXCP_PROGRAM] = 0x00000700; + env->excp_vectors[POWERPC_EXCP_FPU] = 0x00000800; + env->excp_vectors[POWERPC_EXCP_DECR] = 0x00000900; + env->excp_vectors[POWERPC_EXCP_SYSCALL] = 0x00000C00; + env->excp_vectors[POWERPC_EXCP_TRACE] = 0x00000D00; + env->excp_vectors[POWERPC_EXCP_PERFM] = 0x00000F00; + env->excp_vectors[POWERPC_EXCP_VPU] = 0x00000F20; + env->excp_vectors[POWERPC_EXCP_IABR] = 0x00001300; + env->excp_vectors[POWERPC_EXCP_SMI] = 0x00001400; + env->excp_vectors[POWERPC_EXCP_VPUA] = 0x00001600; + /* Hardware reset vector */ + env->hreset_vector = 0x00000100UL; +#endif +} + +static void init_proc_7400(CPUPPCState *env) +{ + register_non_embedded_sprs(env); + register_sdr1_sprs(env); + register_74xx_sprs(env); + vscr_init(env, 0x00010000); + + spr_register(env, SPR_UBAMR, "UBAMR", + &spr_read_ureg, SPR_NOACCESS, + &spr_read_ureg, SPR_NOACCESS, + 0x00000000); + + spr_register(env, SPR_MSSCR1, "MSSCR1", + SPR_NOACCESS, SPR_NOACCESS, + &spr_read_generic, &spr_write_generic, + 0x00000000); + /* Thermal management */ + register_thrm_sprs(env); + /* Memory management */ + register_low_BATs(env); + init_excp_7400(env); + env->dcache_line_size = 32; + env->icache_line_size = 32; + /* Allocate hardware IRQ controller */ + ppc6xx_irq_init(env_archcpu(env)); +} + +static void init_proc_7410(CPUPPCState *env) +{ + register_non_embedded_sprs(env); + register_sdr1_sprs(env); + register_74xx_sprs(env); + vscr_init(env, 0x00010000); + + spr_register(env, SPR_UBAMR, "UBAMR", + &spr_read_ureg, SPR_NOACCESS, + &spr_read_ureg, SPR_NOACCESS, + 0x00000000); + /* Thermal management */ + register_thrm_sprs(env); + /* L2PMCR */ + + spr_register(env, SPR_L2PMCR, "L2PMCR", + SPR_NOACCESS, SPR_NOACCESS, + &spr_read_generic, &spr_write_generic, + 0x00000000); + /* LDSTDB */ + + spr_register(env, SPR_LDSTDB, "LDSTDB", + SPR_NOACCESS, SPR_NOACCESS, + &spr_read_generic, &spr_write_generic, + 0x00000000); + /* Memory management */ + register_low_BATs(env); + init_excp_7400(env); + env->dcache_line_size = 32; + env->icache_line_size = 32; + /* Allocate hardware IRQ controller */ + ppc6xx_irq_init(env_archcpu(env)); +} + +static void init_proc_7440(CPUPPCState *env) +{ + register_non_embedded_sprs(env); + register_sdr1_sprs(env); + register_74xx_sprs(env); + vscr_init(env, 0x00010000); + + spr_register(env, SPR_UBAMR, "UBAMR", + &spr_read_ureg, SPR_NOACCESS, + &spr_read_ureg, SPR_NOACCESS, + 0x00000000); + /* LDSTCR */ + spr_register(env, SPR_LDSTCR, "LDSTCR", + SPR_NOACCESS, SPR_NOACCESS, + &spr_read_generic, &spr_write_generic, + 0x00000000); + /* ICTRL */ + spr_register(env, SPR_ICTRL, "ICTRL", + SPR_NOACCESS, SPR_NOACCESS, + &spr_read_generic, &spr_write_generic, + 0x00000000); + /* MSSSR0 */ + spr_register(env, SPR_MSSSR0, "MSSSR0", + SPR_NOACCESS, SPR_NOACCESS, + &spr_read_generic, &spr_write_generic, + 0x00000000); + /* PMC */ + spr_register(env, SPR_7XX_PMC5, "PMC5", + SPR_NOACCESS, SPR_NOACCESS, + &spr_read_generic, &spr_write_generic, + 0x00000000); + + spr_register(env, SPR_7XX_UPMC5, "UPMC5", + &spr_read_ureg, SPR_NOACCESS, + &spr_read_ureg, SPR_NOACCESS, + 0x00000000); + + spr_register(env, SPR_7XX_PMC6, "PMC6", + SPR_NOACCESS, SPR_NOACCESS, + &spr_read_generic, &spr_write_generic, + 0x00000000); + + spr_register(env, SPR_7XX_UPMC6, "UPMC6", + &spr_read_ureg, SPR_NOACCESS, + &spr_read_ureg, SPR_NOACCESS, + 0x00000000); + /* Memory management */ + register_low_BATs(env); + init_excp_7450(env); + env->dcache_line_size = 32; + env->icache_line_size = 32; + /* Allocate hardware IRQ controller */ + ppc6xx_irq_init(env_archcpu(env)); +} + +static void init_proc_7450(CPUPPCState *env) +{ + register_non_embedded_sprs(env); + register_sdr1_sprs(env); + register_74xx_sprs(env); + vscr_init(env, 0x00010000); + /* Level 3 cache control */ + register_l3_ctrl(env); + /* L3ITCR1 */ + spr_register(env, SPR_L3ITCR1, "L3ITCR1", + SPR_NOACCESS, SPR_NOACCESS, + &spr_read_generic, &spr_write_generic, + 0x00000000); + /* L3ITCR2 */ + spr_register(env, SPR_L3ITCR2, "L3ITCR2", + SPR_NOACCESS, SPR_NOACCESS, + &spr_read_generic, &spr_write_generic, + 0x00000000); + /* L3ITCR3 */ + spr_register(env, SPR_L3ITCR3, "L3ITCR3", + SPR_NOACCESS, SPR_NOACCESS, + &spr_read_generic, &spr_write_generic, + 0x00000000); + /* L3OHCR */ + spr_register(env, SPR_L3OHCR, "L3OHCR", + SPR_NOACCESS, SPR_NOACCESS, + &spr_read_generic, &spr_write_generic, + 0x00000000); + + spr_register(env, SPR_UBAMR, "UBAMR", + &spr_read_ureg, SPR_NOACCESS, + &spr_read_ureg, SPR_NOACCESS, + 0x00000000); + /* LDSTCR */ + spr_register(env, SPR_LDSTCR, "LDSTCR", + SPR_NOACCESS, SPR_NOACCESS, + &spr_read_generic, &spr_write_generic, + 0x00000000); + /* ICTRL */ + spr_register(env, SPR_ICTRL, "ICTRL", + SPR_NOACCESS, SPR_NOACCESS, + &spr_read_generic, &spr_write_generic, + 0x00000000); + /* MSSSR0 */ + spr_register(env, SPR_MSSSR0, "MSSSR0", + SPR_NOACCESS, SPR_NOACCESS, + &spr_read_generic, &spr_write_generic, + 0x00000000); + /* PMC */ + spr_register(env, SPR_7XX_PMC5, "PMC5", + SPR_NOACCESS, SPR_NOACCESS, + &spr_read_generic, &spr_write_generic, + 0x00000000); + + spr_register(env, SPR_7XX_UPMC5, "UPMC5", + &spr_read_ureg, SPR_NOACCESS, + &spr_read_ureg, SPR_NOACCESS, + 0x00000000); + + spr_register(env, SPR_7XX_PMC6, "PMC6", + SPR_NOACCESS, SPR_NOACCESS, + &spr_read_generic, &spr_write_generic, + 0x00000000); + + spr_register(env, SPR_7XX_UPMC6, "UPMC6", + &spr_read_ureg, SPR_NOACCESS, + &spr_read_ureg, SPR_NOACCESS, + 0x00000000); + /* Memory management */ + register_low_BATs(env); + init_excp_7450(env); + env->dcache_line_size = 32; + env->icache_line_size = 32; + /* Allocate hardware IRQ controller */ + ppc6xx_irq_init(env_archcpu(env)); +} + +static void init_proc_7445(CPUPPCState *env) +{ + register_non_embedded_sprs(env); + register_sdr1_sprs(env); + register_74xx_sprs(env); + vscr_init(env, 0x00010000); + /* LDSTCR */ + spr_register(env, SPR_LDSTCR, "LDSTCR", + SPR_NOACCESS, SPR_NOACCESS, + &spr_read_generic, &spr_write_generic, + 0x00000000); + /* ICTRL */ + spr_register(env, SPR_ICTRL, "ICTRL", + SPR_NOACCESS, SPR_NOACCESS, + &spr_read_generic, &spr_write_generic, + 0x00000000); + /* MSSSR0 */ + spr_register(env, SPR_MSSSR0, "MSSSR0", + SPR_NOACCESS, SPR_NOACCESS, + &spr_read_generic, &spr_write_generic, + 0x00000000); + /* PMC */ + spr_register(env, SPR_7XX_PMC5, "PMC5", + SPR_NOACCESS, SPR_NOACCESS, + &spr_read_generic, &spr_write_generic, + 0x00000000); + + spr_register(env, SPR_7XX_UPMC5, "UPMC5", + &spr_read_ureg, SPR_NOACCESS, + &spr_read_ureg, SPR_NOACCESS, + 0x00000000); + + spr_register(env, SPR_7XX_PMC6, "PMC6", + SPR_NOACCESS, SPR_NOACCESS, + &spr_read_generic, &spr_write_generic, + 0x00000000); + + spr_register(env, SPR_7XX_UPMC6, "UPMC6", + &spr_read_ureg, SPR_NOACCESS, + &spr_read_ureg, SPR_NOACCESS, + 0x00000000); + /* SPRGs */ + spr_register(env, SPR_SPRG4, "SPRG4", + SPR_NOACCESS, SPR_NOACCESS, + &spr_read_generic, &spr_write_generic, + 0x00000000); + spr_register(env, SPR_USPRG4, "USPRG4", + &spr_read_ureg, SPR_NOACCESS, + &spr_read_ureg, SPR_NOACCESS, + 0x00000000); + spr_register(env, SPR_SPRG5, "SPRG5", + SPR_NOACCESS, SPR_NOACCESS, + &spr_read_generic, &spr_write_generic, + 0x00000000); + spr_register(env, SPR_USPRG5, "USPRG5", + &spr_read_ureg, SPR_NOACCESS, + &spr_read_ureg, SPR_NOACCESS, + 0x00000000); + spr_register(env, SPR_SPRG6, "SPRG6", + SPR_NOACCESS, SPR_NOACCESS, + &spr_read_generic, &spr_write_generic, + 0x00000000); + spr_register(env, SPR_USPRG6, "USPRG6", + &spr_read_ureg, SPR_NOACCESS, + &spr_read_ureg, SPR_NOACCESS, + 0x00000000); + spr_register(env, SPR_SPRG7, "SPRG7", + SPR_NOACCESS, SPR_NOACCESS, + &spr_read_generic, &spr_write_generic, + 0x00000000); + spr_register(env, SPR_USPRG7, "USPRG7", + &spr_read_ureg, SPR_NOACCESS, + &spr_read_ureg, SPR_NOACCESS, + 0x00000000); + /* Memory management */ + register_low_BATs(env); + register_high_BATs(env); + init_excp_7450(env); + env->dcache_line_size = 32; + env->icache_line_size = 32; + /* Allocate hardware IRQ controller */ + ppc6xx_irq_init(env_archcpu(env)); +} + +static void init_proc_7455(CPUPPCState *env) +{ + register_non_embedded_sprs(env); + register_sdr1_sprs(env); + register_74xx_sprs(env); + vscr_init(env, 0x00010000); + /* Level 3 cache control */ + register_l3_ctrl(env); + /* LDSTCR */ + spr_register(env, SPR_LDSTCR, "LDSTCR", + SPR_NOACCESS, SPR_NOACCESS, + &spr_read_generic, &spr_write_generic, + 0x00000000); + /* ICTRL */ + spr_register(env, SPR_ICTRL, "ICTRL", + SPR_NOACCESS, SPR_NOACCESS, + &spr_read_generic, &spr_write_generic, + 0x00000000); + /* MSSSR0 */ + spr_register(env, SPR_MSSSR0, "MSSSR0", + SPR_NOACCESS, SPR_NOACCESS, + &spr_read_generic, &spr_write_generic, + 0x00000000); + /* PMC */ + spr_register(env, SPR_7XX_PMC5, "PMC5", + SPR_NOACCESS, SPR_NOACCESS, + &spr_read_generic, &spr_write_generic, + 0x00000000); + + spr_register(env, SPR_7XX_UPMC5, "UPMC5", + &spr_read_ureg, SPR_NOACCESS, + &spr_read_ureg, SPR_NOACCESS, + 0x00000000); + + spr_register(env, SPR_7XX_PMC6, "PMC6", + SPR_NOACCESS, SPR_NOACCESS, + &spr_read_generic, &spr_write_generic, + 0x00000000); + + spr_register(env, SPR_7XX_UPMC6, "UPMC6", + &spr_read_ureg, SPR_NOACCESS, + &spr_read_ureg, SPR_NOACCESS, + 0x00000000); + /* SPRGs */ + spr_register(env, SPR_SPRG4, "SPRG4", + SPR_NOACCESS, SPR_NOACCESS, + &spr_read_generic, &spr_write_generic, + 0x00000000); + spr_register(env, SPR_USPRG4, "USPRG4", + &spr_read_ureg, SPR_NOACCESS, + &spr_read_ureg, SPR_NOACCESS, + 0x00000000); + spr_register(env, SPR_SPRG5, "SPRG5", + SPR_NOACCESS, SPR_NOACCESS, + &spr_read_generic, &spr_write_generic, + 0x00000000); + spr_register(env, SPR_USPRG5, "USPRG5", + &spr_read_ureg, SPR_NOACCESS, + &spr_read_ureg, SPR_NOACCESS, + 0x00000000); + spr_register(env, SPR_SPRG6, "SPRG6", + SPR_NOACCESS, SPR_NOACCESS, + &spr_read_generic, &spr_write_generic, + 0x00000000); + spr_register(env, SPR_USPRG6, "USPRG6", + &spr_read_ureg, SPR_NOACCESS, + &spr_read_ureg, SPR_NOACCESS, + 0x00000000); + spr_register(env, SPR_SPRG7, "SPRG7", + SPR_NOACCESS, SPR_NOACCESS, + &spr_read_generic, &spr_write_generic, + 0x00000000); + spr_register(env, SPR_USPRG7, "USPRG7", + &spr_read_ureg, SPR_NOACCESS, + &spr_read_ureg, SPR_NOACCESS, + 0x00000000); + /* Memory management */ + register_low_BATs(env); + register_high_BATs(env); + init_excp_7450(env); + env->dcache_line_size = 32; + env->icache_line_size = 32; + /* Allocate hardware IRQ controller */ + ppc6xx_irq_init(env_archcpu(env)); +} + +static void init_proc_7457(CPUPPCState *env) +{ + register_non_embedded_sprs(env); + register_sdr1_sprs(env); + register_74xx_sprs(env); + vscr_init(env, 0x00010000); + /* Level 3 cache control */ + register_l3_ctrl(env); + /* L3ITCR1 */ + spr_register(env, SPR_L3ITCR1, "L3ITCR1", + SPR_NOACCESS, SPR_NOACCESS, + &spr_read_generic, &spr_write_generic, + 0x00000000); + /* L3ITCR2 */ + spr_register(env, SPR_L3ITCR2, "L3ITCR2", + SPR_NOACCESS, SPR_NOACCESS, + &spr_read_generic, &spr_write_generic, + 0x00000000); + /* L3ITCR3 */ + spr_register(env, SPR_L3ITCR3, "L3ITCR3", + SPR_NOACCESS, SPR_NOACCESS, + &spr_read_generic, &spr_write_generic, + 0x00000000); + /* L3OHCR */ + spr_register(env, SPR_L3OHCR, "L3OHCR", + SPR_NOACCESS, SPR_NOACCESS, + &spr_read_generic, &spr_write_generic, + 0x00000000); + /* LDSTCR */ + spr_register(env, SPR_LDSTCR, "LDSTCR", + SPR_NOACCESS, SPR_NOACCESS, + &spr_read_generic, &spr_write_generic, + 0x00000000); + /* ICTRL */ + spr_register(env, SPR_ICTRL, "ICTRL", + SPR_NOACCESS, SPR_NOACCESS, + &spr_read_generic, &spr_write_generic, + 0x00000000); + /* MSSSR0 */ + spr_register(env, SPR_MSSSR0, "MSSSR0", + SPR_NOACCESS, SPR_NOACCESS, + &spr_read_generic, &spr_write_generic, + 0x00000000); + /* PMC */ + spr_register(env, SPR_7XX_PMC5, "PMC5", + SPR_NOACCESS, SPR_NOACCESS, + &spr_read_generic, &spr_write_generic, + 0x00000000); + + spr_register(env, SPR_7XX_UPMC5, "UPMC5", + &spr_read_ureg, SPR_NOACCESS, + &spr_read_ureg, SPR_NOACCESS, + 0x00000000); + + spr_register(env, SPR_7XX_PMC6, "PMC6", + SPR_NOACCESS, SPR_NOACCESS, + &spr_read_generic, &spr_write_generic, + 0x00000000); + + spr_register(env, SPR_7XX_UPMC6, "UPMC6", + &spr_read_ureg, SPR_NOACCESS, + &spr_read_ureg, SPR_NOACCESS, + 0x00000000); + /* SPRGs */ + spr_register(env, SPR_SPRG4, "SPRG4", + SPR_NOACCESS, SPR_NOACCESS, + &spr_read_generic, &spr_write_generic, + 0x00000000); + spr_register(env, SPR_USPRG4, "USPRG4", + &spr_read_ureg, SPR_NOACCESS, + &spr_read_ureg, SPR_NOACCESS, + 0x00000000); + spr_register(env, SPR_SPRG5, "SPRG5", + SPR_NOACCESS, SPR_NOACCESS, + &spr_read_generic, &spr_write_generic, + 0x00000000); + spr_register(env, SPR_USPRG5, "USPRG5", + &spr_read_ureg, SPR_NOACCESS, + &spr_read_ureg, SPR_NOACCESS, + 0x00000000); + spr_register(env, SPR_SPRG6, "SPRG6", + SPR_NOACCESS, SPR_NOACCESS, + &spr_read_generic, &spr_write_generic, + 0x00000000); + spr_register(env, SPR_USPRG6, "USPRG6", + &spr_read_ureg, SPR_NOACCESS, + &spr_read_ureg, SPR_NOACCESS, + 0x00000000); + spr_register(env, SPR_SPRG7, "SPRG7", + SPR_NOACCESS, SPR_NOACCESS, + &spr_read_generic, &spr_write_generic, + 0x00000000); + spr_register(env, SPR_USPRG7, "USPRG7", + &spr_read_ureg, SPR_NOACCESS, + &spr_read_ureg, SPR_NOACCESS, + 0x00000000); + /* Memory management */ + register_low_BATs(env); + register_high_BATs(env); + init_excp_7450(env); + env->dcache_line_size = 32; + env->icache_line_size = 32; + /* Allocate hardware IRQ controller */ + ppc6xx_irq_init(env_archcpu(env)); +} + +static void init_proc_e600(CPUPPCState *env) +{ + register_non_embedded_sprs(env); + register_sdr1_sprs(env); + register_74xx_sprs(env); + vscr_init(env, 0x00010000); + + spr_register(env, SPR_UBAMR, "UBAMR", + &spr_read_ureg, SPR_NOACCESS, + &spr_read_ureg, SPR_NOACCESS, + 0x00000000); + + spr_register(env, SPR_LDSTCR, "LDSTCR", + SPR_NOACCESS, SPR_NOACCESS, + &spr_read_generic, &spr_write_generic, + 0x00000000); + + spr_register(env, SPR_ICTRL, "ICTRL", + SPR_NOACCESS, SPR_NOACCESS, + &spr_read_generic, &spr_write_generic, + 0x00000000); + + spr_register(env, SPR_MSSSR0, "MSSSR0", + SPR_NOACCESS, SPR_NOACCESS, + &spr_read_generic, &spr_write_generic, + 0x00000000); + + spr_register(env, SPR_7XX_PMC5, "PMC5", + SPR_NOACCESS, SPR_NOACCESS, + &spr_read_generic, &spr_write_generic, + 0x00000000); + + spr_register(env, SPR_7XX_UPMC5, "UPMC5", + &spr_read_ureg, SPR_NOACCESS, + &spr_read_ureg, SPR_NOACCESS, + 0x00000000); + + spr_register(env, SPR_7XX_PMC6, "PMC6", + SPR_NOACCESS, SPR_NOACCESS, + &spr_read_generic, &spr_write_generic, + 0x00000000); + + spr_register(env, SPR_7XX_UPMC6, "UPMC6", + &spr_read_ureg, SPR_NOACCESS, + &spr_read_ureg, SPR_NOACCESS, + 0x00000000); + /* SPRGs */ + spr_register(env, SPR_SPRG4, "SPRG4", + SPR_NOACCESS, SPR_NOACCESS, + &spr_read_generic, &spr_write_generic, + 0x00000000); + spr_register(env, SPR_USPRG4, "USPRG4", + &spr_read_ureg, SPR_NOACCESS, + &spr_read_ureg, SPR_NOACCESS, + 0x00000000); + spr_register(env, SPR_SPRG5, "SPRG5", + SPR_NOACCESS, SPR_NOACCESS, + &spr_read_generic, &spr_write_generic, + 0x00000000); + spr_register(env, SPR_USPRG5, "USPRG5", + &spr_read_ureg, SPR_NOACCESS, + &spr_read_ureg, SPR_NOACCESS, + 0x00000000); + spr_register(env, SPR_SPRG6, "SPRG6", + SPR_NOACCESS, SPR_NOACCESS, + &spr_read_generic, &spr_write_generic, + 0x00000000); + spr_register(env, SPR_USPRG6, "USPRG6", + &spr_read_ureg, SPR_NOACCESS, + &spr_read_ureg, SPR_NOACCESS, + 0x00000000); + spr_register(env, SPR_SPRG7, "SPRG7", + SPR_NOACCESS, SPR_NOACCESS, + &spr_read_generic, &spr_write_generic, + 0x00000000); + spr_register(env, SPR_USPRG7, "USPRG7", + &spr_read_ureg, SPR_NOACCESS, + &spr_read_ureg, SPR_NOACCESS, + 0x00000000); + /* Memory management */ + register_low_BATs(env); + register_high_BATs(env); + init_excp_7450(env); + env->dcache_line_size = 32; + env->icache_line_size = 32; + /* Allocate hardware IRQ controller */ + ppc6xx_irq_init(env_archcpu(env)); +} + +POWERPC_FAMILY(7400)(ObjectClass *oc, void *data) +{ + DeviceClass *dc = DEVICE_CLASS(oc); + PowerPCCPUClass *pcc = POWERPC_CPU_CLASS(oc); + + dc->desc = "PowerPC 7400 (aka G4)"; + pcc->init_proc = init_proc_7400; + pcc->check_pow = check_pow_hid0; + pcc->insns_flags = PPC_INSNS_BASE | PPC_STRING | PPC_MFTB | + PPC_FLOAT | PPC_FLOAT_FSEL | PPC_FLOAT_FRES | + PPC_FLOAT_FSQRT | PPC_FLOAT_FRSQRTE | + PPC_FLOAT_STFIWX | + PPC_CACHE | PPC_CACHE_ICBI | + PPC_CACHE_DCBA | PPC_CACHE_DCBZ | + PPC_MEM_SYNC | PPC_MEM_EIEIO | + PPC_MEM_TLBIE | PPC_MEM_TLBSYNC | + PPC_MEM_TLBIA | + PPC_SEGMENT | PPC_EXTERN | + PPC_ALTIVEC; + pcc->msr_mask = (1ull << MSR_VR) | + (1ull << MSR_POW) | + (1ull << MSR_ILE) | + (1ull << MSR_EE) | + (1ull << MSR_PR) | + (1ull << MSR_FP) | + (1ull << MSR_ME) | + (1ull << MSR_FE0) | + (1ull << MSR_SE) | + (1ull << MSR_DE) | + (1ull << MSR_FE1) | + (1ull << MSR_EP) | + (1ull << MSR_IR) | + (1ull << MSR_DR) | + (1ull << MSR_PMM) | + (1ull << MSR_RI) | + (1ull << MSR_LE); + pcc->mmu_model = POWERPC_MMU_32B; + pcc->excp_model = POWERPC_EXCP_74xx; + pcc->bus_model = PPC_FLAGS_INPUT_6xx; + pcc->bfd_mach = bfd_mach_ppc_7400; + pcc->flags = POWERPC_FLAG_VRE | POWERPC_FLAG_SE | + POWERPC_FLAG_BE | POWERPC_FLAG_PMM | + POWERPC_FLAG_BUS_CLK; +} + +POWERPC_FAMILY(7410)(ObjectClass *oc, void *data) +{ + DeviceClass *dc = DEVICE_CLASS(oc); + PowerPCCPUClass *pcc = POWERPC_CPU_CLASS(oc); + + dc->desc = "PowerPC 7410 (aka G4)"; + pcc->init_proc = init_proc_7410; + pcc->check_pow = check_pow_hid0; + pcc->insns_flags = PPC_INSNS_BASE | PPC_STRING | PPC_MFTB | + PPC_FLOAT | PPC_FLOAT_FSEL | PPC_FLOAT_FRES | + PPC_FLOAT_FSQRT | PPC_FLOAT_FRSQRTE | + PPC_FLOAT_STFIWX | + PPC_CACHE | PPC_CACHE_ICBI | + PPC_CACHE_DCBA | PPC_CACHE_DCBZ | + PPC_MEM_SYNC | PPC_MEM_EIEIO | + PPC_MEM_TLBIE | PPC_MEM_TLBSYNC | + PPC_MEM_TLBIA | + PPC_SEGMENT | PPC_EXTERN | + PPC_ALTIVEC; + pcc->msr_mask = (1ull << MSR_VR) | + (1ull << MSR_POW) | + (1ull << MSR_ILE) | + (1ull << MSR_EE) | + (1ull << MSR_PR) | + (1ull << MSR_FP) | + (1ull << MSR_ME) | + (1ull << MSR_FE0) | + (1ull << MSR_SE) | + (1ull << MSR_DE) | + (1ull << MSR_FE1) | + (1ull << MSR_EP) | + (1ull << MSR_IR) | + (1ull << MSR_DR) | + (1ull << MSR_PMM) | + (1ull << MSR_RI) | + (1ull << MSR_LE); + pcc->mmu_model = POWERPC_MMU_32B; + pcc->excp_model = POWERPC_EXCP_74xx; + pcc->bus_model = PPC_FLAGS_INPUT_6xx; + pcc->bfd_mach = bfd_mach_ppc_7400; + pcc->flags = POWERPC_FLAG_VRE | POWERPC_FLAG_SE | + POWERPC_FLAG_BE | POWERPC_FLAG_PMM | + POWERPC_FLAG_BUS_CLK; +} + +POWERPC_FAMILY(7440)(ObjectClass *oc, void *data) +{ + DeviceClass *dc = DEVICE_CLASS(oc); + PowerPCCPUClass *pcc = POWERPC_CPU_CLASS(oc); + + dc->desc = "PowerPC 7440 (aka G4)"; + pcc->init_proc = init_proc_7440; + pcc->check_pow = check_pow_hid0_74xx; + pcc->insns_flags = PPC_INSNS_BASE | PPC_STRING | PPC_MFTB | + PPC_FLOAT | PPC_FLOAT_FSEL | PPC_FLOAT_FRES | + PPC_FLOAT_FSQRT | PPC_FLOAT_FRSQRTE | + PPC_FLOAT_STFIWX | + PPC_CACHE | PPC_CACHE_ICBI | + PPC_CACHE_DCBA | PPC_CACHE_DCBZ | + PPC_MEM_SYNC | PPC_MEM_EIEIO | + PPC_MEM_TLBIE | PPC_MEM_TLBSYNC | + PPC_MEM_TLBIA | + PPC_SEGMENT | PPC_EXTERN | + PPC_ALTIVEC; + pcc->msr_mask = (1ull << MSR_VR) | + (1ull << MSR_POW) | + (1ull << MSR_ILE) | + (1ull << MSR_EE) | + (1ull << MSR_PR) | + (1ull << MSR_FP) | + (1ull << MSR_ME) | + (1ull << MSR_FE0) | + (1ull << MSR_SE) | + (1ull << MSR_DE) | + (1ull << MSR_FE1) | + (1ull << MSR_EP) | + (1ull << MSR_IR) | + (1ull << MSR_DR) | + (1ull << MSR_PMM) | + (1ull << MSR_RI) | + (1ull << MSR_LE); + pcc->mmu_model = POWERPC_MMU_32B; + pcc->excp_model = POWERPC_EXCP_74xx; + pcc->bus_model = PPC_FLAGS_INPUT_6xx; + pcc->bfd_mach = bfd_mach_ppc_7400; + pcc->flags = POWERPC_FLAG_VRE | POWERPC_FLAG_SE | + POWERPC_FLAG_BE | POWERPC_FLAG_PMM | + POWERPC_FLAG_BUS_CLK; +} + +POWERPC_FAMILY(7450)(ObjectClass *oc, void *data) +{ + DeviceClass *dc = DEVICE_CLASS(oc); + PowerPCCPUClass *pcc = POWERPC_CPU_CLASS(oc); + + dc->desc = "PowerPC 7450 (aka G4)"; + pcc->init_proc = init_proc_7450; + pcc->check_pow = check_pow_hid0_74xx; + pcc->insns_flags = PPC_INSNS_BASE | PPC_STRING | PPC_MFTB | + PPC_FLOAT | PPC_FLOAT_FSEL | PPC_FLOAT_FRES | + PPC_FLOAT_FSQRT | PPC_FLOAT_FRSQRTE | + PPC_FLOAT_STFIWX | + PPC_CACHE | PPC_CACHE_ICBI | + PPC_CACHE_DCBA | PPC_CACHE_DCBZ | + PPC_MEM_SYNC | PPC_MEM_EIEIO | + PPC_MEM_TLBIE | PPC_MEM_TLBSYNC | + PPC_MEM_TLBIA | + PPC_SEGMENT | PPC_EXTERN | + PPC_ALTIVEC; + pcc->msr_mask = (1ull << MSR_VR) | + (1ull << MSR_POW) | + (1ull << MSR_ILE) | + (1ull << MSR_EE) | + (1ull << MSR_PR) | + (1ull << MSR_FP) | + (1ull << MSR_ME) | + (1ull << MSR_FE0) | + (1ull << MSR_SE) | + (1ull << MSR_DE) | + (1ull << MSR_FE1) | + (1ull << MSR_EP) | + (1ull << MSR_IR) | + (1ull << MSR_DR) | + (1ull << MSR_PMM) | + (1ull << MSR_RI) | + (1ull << MSR_LE); + pcc->mmu_model = POWERPC_MMU_32B; + pcc->excp_model = POWERPC_EXCP_74xx; + pcc->bus_model = PPC_FLAGS_INPUT_6xx; + pcc->bfd_mach = bfd_mach_ppc_7400; + pcc->flags = POWERPC_FLAG_VRE | POWERPC_FLAG_SE | + POWERPC_FLAG_BE | POWERPC_FLAG_PMM | + POWERPC_FLAG_BUS_CLK; +} + +POWERPC_FAMILY(7445)(ObjectClass *oc, void *data) +{ + DeviceClass *dc = DEVICE_CLASS(oc); + PowerPCCPUClass *pcc = POWERPC_CPU_CLASS(oc); + + dc->desc = "PowerPC 7445 (aka G4)"; + pcc->init_proc = init_proc_7445; + pcc->check_pow = check_pow_hid0_74xx; + pcc->insns_flags = PPC_INSNS_BASE | PPC_STRING | PPC_MFTB | + PPC_FLOAT | PPC_FLOAT_FSEL | PPC_FLOAT_FRES | + PPC_FLOAT_FSQRT | PPC_FLOAT_FRSQRTE | + PPC_FLOAT_STFIWX | + PPC_CACHE | PPC_CACHE_ICBI | + PPC_CACHE_DCBA | PPC_CACHE_DCBZ | + PPC_MEM_SYNC | PPC_MEM_EIEIO | + PPC_MEM_TLBIE | PPC_MEM_TLBSYNC | + PPC_MEM_TLBIA | + PPC_SEGMENT | PPC_EXTERN | + PPC_ALTIVEC; + pcc->msr_mask = (1ull << MSR_VR) | + (1ull << MSR_POW) | + (1ull << MSR_ILE) | + (1ull << MSR_EE) | + (1ull << MSR_PR) | + (1ull << MSR_FP) | + (1ull << MSR_ME) | + (1ull << MSR_FE0) | + (1ull << MSR_SE) | + (1ull << MSR_DE) | + (1ull << MSR_FE1) | + (1ull << MSR_EP) | + (1ull << MSR_IR) | + (1ull << MSR_DR) | + (1ull << MSR_PMM) | + (1ull << MSR_RI) | + (1ull << MSR_LE); + pcc->mmu_model = POWERPC_MMU_32B; + pcc->excp_model = POWERPC_EXCP_74xx; + pcc->bus_model = PPC_FLAGS_INPUT_6xx; + pcc->bfd_mach = bfd_mach_ppc_7400; + pcc->flags = POWERPC_FLAG_VRE | POWERPC_FLAG_SE | + POWERPC_FLAG_BE | POWERPC_FLAG_PMM | + POWERPC_FLAG_BUS_CLK; +} + +POWERPC_FAMILY(7455)(ObjectClass *oc, void *data) +{ + DeviceClass *dc = DEVICE_CLASS(oc); + PowerPCCPUClass *pcc = POWERPC_CPU_CLASS(oc); + + dc->desc = "PowerPC 7455 (aka G4)"; + pcc->init_proc = init_proc_7455; + pcc->check_pow = check_pow_hid0_74xx; + pcc->insns_flags = PPC_INSNS_BASE | PPC_STRING | PPC_MFTB | + PPC_FLOAT | PPC_FLOAT_FSEL | PPC_FLOAT_FRES | + PPC_FLOAT_FSQRT | PPC_FLOAT_FRSQRTE | + PPC_FLOAT_STFIWX | + PPC_CACHE | PPC_CACHE_ICBI | + PPC_CACHE_DCBA | PPC_CACHE_DCBZ | + PPC_MEM_SYNC | PPC_MEM_EIEIO | + PPC_MEM_TLBIE | PPC_MEM_TLBSYNC | + PPC_MEM_TLBIA | + PPC_SEGMENT | PPC_EXTERN | + PPC_ALTIVEC; + pcc->msr_mask = (1ull << MSR_VR) | + (1ull << MSR_POW) | + (1ull << MSR_ILE) | + (1ull << MSR_EE) | + (1ull << MSR_PR) | + (1ull << MSR_FP) | + (1ull << MSR_ME) | + (1ull << MSR_FE0) | + (1ull << MSR_SE) | + (1ull << MSR_DE) | + (1ull << MSR_FE1) | + (1ull << MSR_EP) | + (1ull << MSR_IR) | + (1ull << MSR_DR) | + (1ull << MSR_PMM) | + (1ull << MSR_RI) | + (1ull << MSR_LE); + pcc->mmu_model = POWERPC_MMU_32B; + pcc->excp_model = POWERPC_EXCP_74xx; + pcc->bus_model = PPC_FLAGS_INPUT_6xx; + pcc->bfd_mach = bfd_mach_ppc_7400; + pcc->flags = POWERPC_FLAG_VRE | POWERPC_FLAG_SE | + POWERPC_FLAG_BE | POWERPC_FLAG_PMM | + POWERPC_FLAG_BUS_CLK; +} + +POWERPC_FAMILY(7457)(ObjectClass *oc, void *data) +{ + DeviceClass *dc = DEVICE_CLASS(oc); + PowerPCCPUClass *pcc = POWERPC_CPU_CLASS(oc); + + dc->desc = "PowerPC 7457 (aka G4)"; + pcc->init_proc = init_proc_7457; + pcc->check_pow = check_pow_hid0_74xx; + pcc->insns_flags = PPC_INSNS_BASE | PPC_STRING | PPC_MFTB | + PPC_FLOAT | PPC_FLOAT_FSEL | PPC_FLOAT_FRES | + PPC_FLOAT_FSQRT | PPC_FLOAT_FRSQRTE | + PPC_FLOAT_STFIWX | + PPC_CACHE | PPC_CACHE_ICBI | + PPC_CACHE_DCBA | PPC_CACHE_DCBZ | + PPC_MEM_SYNC | PPC_MEM_EIEIO | + PPC_MEM_TLBIE | PPC_MEM_TLBSYNC | + PPC_MEM_TLBIA | + PPC_SEGMENT | PPC_EXTERN | + PPC_ALTIVEC; + pcc->msr_mask = (1ull << MSR_VR) | + (1ull << MSR_POW) | + (1ull << MSR_ILE) | + (1ull << MSR_EE) | + (1ull << MSR_PR) | + (1ull << MSR_FP) | + (1ull << MSR_ME) | + (1ull << MSR_FE0) | + (1ull << MSR_SE) | + (1ull << MSR_DE) | + (1ull << MSR_FE1) | + (1ull << MSR_EP) | + (1ull << MSR_IR) | + (1ull << MSR_DR) | + (1ull << MSR_PMM) | + (1ull << MSR_RI) | + (1ull << MSR_LE); + pcc->mmu_model = POWERPC_MMU_32B; + pcc->excp_model = POWERPC_EXCP_74xx; + pcc->bus_model = PPC_FLAGS_INPUT_6xx; + pcc->bfd_mach = bfd_mach_ppc_7400; + pcc->flags = POWERPC_FLAG_VRE | POWERPC_FLAG_SE | + POWERPC_FLAG_BE | POWERPC_FLAG_PMM | + POWERPC_FLAG_BUS_CLK; +} + +POWERPC_FAMILY(e600)(ObjectClass *oc, void *data) +{ + DeviceClass *dc = DEVICE_CLASS(oc); + PowerPCCPUClass *pcc = POWERPC_CPU_CLASS(oc); + + dc->desc = "PowerPC e600"; + pcc->init_proc = init_proc_e600; + pcc->check_pow = check_pow_hid0_74xx; + pcc->insns_flags = PPC_INSNS_BASE | PPC_STRING | PPC_MFTB | + PPC_FLOAT | PPC_FLOAT_FSEL | PPC_FLOAT_FRES | + PPC_FLOAT_FSQRT | PPC_FLOAT_FRSQRTE | + PPC_FLOAT_STFIWX | + PPC_CACHE | PPC_CACHE_ICBI | + PPC_CACHE_DCBA | PPC_CACHE_DCBZ | + PPC_MEM_SYNC | PPC_MEM_EIEIO | + PPC_MEM_TLBIE | PPC_MEM_TLBSYNC | + PPC_MEM_TLBIA | + PPC_SEGMENT | PPC_EXTERN | + PPC_ALTIVEC; + pcc->insns_flags2 = PPC_NONE; + pcc->msr_mask = (1ull << MSR_VR) | + (1ull << MSR_POW) | + (1ull << MSR_ILE) | + (1ull << MSR_EE) | + (1ull << MSR_PR) | + (1ull << MSR_FP) | + (1ull << MSR_ME) | + (1ull << MSR_FE0) | + (1ull << MSR_SE) | + (1ull << MSR_DE) | + (1ull << MSR_FE1) | + (1ull << MSR_EP) | + (1ull << MSR_IR) | + (1ull << MSR_DR) | + (1ull << MSR_PMM) | + (1ull << MSR_RI) | + (1ull << MSR_LE); + pcc->mmu_model = POWERPC_MMU_32B; + pcc->excp_model = POWERPC_EXCP_74xx; + pcc->bus_model = PPC_FLAGS_INPUT_6xx; + pcc->bfd_mach = bfd_mach_ppc_7400; + pcc->flags = POWERPC_FLAG_VRE | POWERPC_FLAG_SE | + POWERPC_FLAG_BE | POWERPC_FLAG_PMM | + POWERPC_FLAG_BUS_CLK; +} diff --git a/target/ppc/cpu_init.c b/target/ppc/cpu_init.c index c9a5e020b1..397a93aa4b 100644 --- a/target/ppc/cpu_init.c +++ b/target/ppc/cpu_init.c @@ -102,165 +102,6 @@ static void register_iamr_sprs(CPUPPCState *env) } #endif /* TARGET_PPC64 */ -static void register_74xx_sprs(CPUPPCState *env) -{ - /* Breakpoints */ - spr_register_kvm(env, SPR_DABR, "DABR", - SPR_NOACCESS, SPR_NOACCESS, - &spr_read_generic, &spr_write_generic, - KVM_REG_PPC_DABR, 0x00000000); - - spr_register(env, SPR_IABR, "IABR", - SPR_NOACCESS, SPR_NOACCESS, - &spr_read_generic, &spr_write_generic, - 0x00000000); - /* Cache management */ - spr_register(env, SPR_ICTC, "ICTC", - SPR_NOACCESS, SPR_NOACCESS, - &spr_read_generic, &spr_write_generic, - 0x00000000); - /* Performance monitors */ - spr_register(env, SPR_7XX_MMCR0, "MMCR0", - SPR_NOACCESS, SPR_NOACCESS, - &spr_read_generic, &spr_write_generic, - 0x00000000); - - spr_register(env, SPR_7XX_MMCR1, "MMCR1", - SPR_NOACCESS, SPR_NOACCESS, - &spr_read_generic, &spr_write_generic, - 0x00000000); - - spr_register(env, SPR_7XX_PMC1, "PMC1", - SPR_NOACCESS, SPR_NOACCESS, - &spr_read_generic, &spr_write_generic, - 0x00000000); - - spr_register(env, SPR_7XX_PMC2, "PMC2", - SPR_NOACCESS, SPR_NOACCESS, - &spr_read_generic, &spr_write_generic, - 0x00000000); - - spr_register(env, SPR_7XX_PMC3, "PMC3", - SPR_NOACCESS, SPR_NOACCESS, - &spr_read_generic, &spr_write_generic, - 0x00000000); - - spr_register(env, SPR_7XX_PMC4, "PMC4", - SPR_NOACCESS, SPR_NOACCESS, - &spr_read_generic, &spr_write_generic, - 0x00000000); - - spr_register(env, SPR_7XX_SIAR, "SIAR", - SPR_NOACCESS, SPR_NOACCESS, - &spr_read_generic, SPR_NOACCESS, - 0x00000000); - - spr_register(env, SPR_7XX_UMMCR0, "UMMCR0", - &spr_read_ureg, SPR_NOACCESS, - &spr_read_ureg, SPR_NOACCESS, - 0x00000000); - - spr_register(env, SPR_7XX_UMMCR1, "UMMCR1", - &spr_read_ureg, SPR_NOACCESS, - &spr_read_ureg, SPR_NOACCESS, - 0x00000000); - - spr_register(env, SPR_7XX_UPMC1, "UPMC1", - &spr_read_ureg, SPR_NOACCESS, - &spr_read_ureg, SPR_NOACCESS, - 0x00000000); - - spr_register(env, SPR_7XX_UPMC2, "UPMC2", - &spr_read_ureg, SPR_NOACCESS, - &spr_read_ureg, SPR_NOACCESS, - 0x00000000); - - spr_register(env, SPR_7XX_UPMC3, "UPMC3", - &spr_read_ureg, SPR_NOACCESS, - &spr_read_ureg, SPR_NOACCESS, - 0x00000000); - - spr_register(env, SPR_7XX_UPMC4, "UPMC4", - &spr_read_ureg, SPR_NOACCESS, - &spr_read_ureg, SPR_NOACCESS, - 0x00000000); - - spr_register(env, SPR_7XX_USIAR, "USIAR", - &spr_read_ureg, SPR_NOACCESS, - &spr_read_ureg, SPR_NOACCESS, - 0x00000000); - /* External access control */ - spr_register(env, SPR_EAR, "EAR", - SPR_NOACCESS, SPR_NOACCESS, - &spr_read_generic, &spr_write_generic, - 0x00000000); - - /* Processor identification */ - spr_register(env, SPR_PIR, "PIR", - SPR_NOACCESS, SPR_NOACCESS, - &spr_read_generic, &spr_write_pir, - 0x00000000); - - spr_register(env, SPR_74XX_MMCR2, "MMCR2", - SPR_NOACCESS, SPR_NOACCESS, - &spr_read_generic, &spr_write_generic, - 0x00000000); - - spr_register(env, SPR_74XX_UMMCR2, "UMMCR2", - &spr_read_ureg, SPR_NOACCESS, - &spr_read_ureg, SPR_NOACCESS, - 0x00000000); - - spr_register(env, SPR_BAMR, "BAMR", - SPR_NOACCESS, SPR_NOACCESS, - &spr_read_generic, &spr_write_generic, - 0x00000000); - - spr_register(env, SPR_MSSCR0, "MSSCR0", - SPR_NOACCESS, SPR_NOACCESS, - &spr_read_generic, &spr_write_generic, - 0x00000000); - /* Hardware implementation registers */ - spr_register(env, SPR_HID0, "HID0", - SPR_NOACCESS, SPR_NOACCESS, - &spr_read_generic, &spr_write_generic, - 0x00000000); - - spr_register(env, SPR_HID1, "HID1", - SPR_NOACCESS, SPR_NOACCESS, - &spr_read_generic, &spr_write_generic, - 0x00000000); - /* Altivec */ - spr_register(env, SPR_VRSAVE, "VRSAVE", - &spr_read_generic, &spr_write_generic, - &spr_read_generic, &spr_write_generic, - 0x00000000); - - spr_register(env, SPR_L2CR, "L2CR", - SPR_NOACCESS, SPR_NOACCESS, - &spr_read_generic, spr_access_nop, - 0x00000000); -} - -static void register_l3_ctrl(CPUPPCState *env) -{ - /* L3CR */ - spr_register(env, SPR_L3CR, "L3CR", - SPR_NOACCESS, SPR_NOACCESS, - &spr_read_generic, &spr_write_generic, - 0x00000000); - /* L3ITCR0 */ - spr_register(env, SPR_L3ITCR0, "L3ITCR0", - SPR_NOACCESS, SPR_NOACCESS, - &spr_read_generic, &spr_write_generic, - 0x00000000); - /* L3PM */ - spr_register(env, SPR_L3PM, "L3PM", - SPR_NOACCESS, SPR_NOACCESS, - &spr_read_generic, &spr_write_generic, - 0x00000000); -} - /* PowerPC BookE SPR */ static void register_BookE_sprs(CPUPPCState *env, uint64_t ivor_mask) { @@ -790,55 +631,6 @@ static void init_excp_BookE(CPUPPCState *env) #endif } -static void init_excp_7400(CPUPPCState *env) -{ -#if !defined(CONFIG_USER_ONLY) - env->excp_vectors[POWERPC_EXCP_RESET] = 0x00000100; - env->excp_vectors[POWERPC_EXCP_MCHECK] = 0x00000200; - env->excp_vectors[POWERPC_EXCP_DSI] = 0x00000300; - env->excp_vectors[POWERPC_EXCP_ISI] = 0x00000400; - env->excp_vectors[POWERPC_EXCP_EXTERNAL] = 0x00000500; - env->excp_vectors[POWERPC_EXCP_ALIGN] = 0x00000600; - env->excp_vectors[POWERPC_EXCP_PROGRAM] = 0x00000700; - env->excp_vectors[POWERPC_EXCP_FPU] = 0x00000800; - env->excp_vectors[POWERPC_EXCP_DECR] = 0x00000900; - env->excp_vectors[POWERPC_EXCP_SYSCALL] = 0x00000C00; - env->excp_vectors[POWERPC_EXCP_TRACE] = 0x00000D00; - env->excp_vectors[POWERPC_EXCP_PERFM] = 0x00000F00; - env->excp_vectors[POWERPC_EXCP_VPU] = 0x00000F20; - env->excp_vectors[POWERPC_EXCP_IABR] = 0x00001300; - env->excp_vectors[POWERPC_EXCP_SMI] = 0x00001400; - env->excp_vectors[POWERPC_EXCP_VPUA] = 0x00001600; - env->excp_vectors[POWERPC_EXCP_THERM] = 0x00001700; - /* Hardware reset vector */ - env->hreset_vector = 0x00000100UL; -#endif -} - -static void init_excp_7450(CPUPPCState *env) -{ -#if !defined(CONFIG_USER_ONLY) - env->excp_vectors[POWERPC_EXCP_RESET] = 0x00000100; - env->excp_vectors[POWERPC_EXCP_MCHECK] = 0x00000200; - env->excp_vectors[POWERPC_EXCP_DSI] = 0x00000300; - env->excp_vectors[POWERPC_EXCP_ISI] = 0x00000400; - env->excp_vectors[POWERPC_EXCP_EXTERNAL] = 0x00000500; - env->excp_vectors[POWERPC_EXCP_ALIGN] = 0x00000600; - env->excp_vectors[POWERPC_EXCP_PROGRAM] = 0x00000700; - env->excp_vectors[POWERPC_EXCP_FPU] = 0x00000800; - env->excp_vectors[POWERPC_EXCP_DECR] = 0x00000900; - env->excp_vectors[POWERPC_EXCP_SYSCALL] = 0x00000C00; - env->excp_vectors[POWERPC_EXCP_TRACE] = 0x00000D00; - env->excp_vectors[POWERPC_EXCP_PERFM] = 0x00000F00; - env->excp_vectors[POWERPC_EXCP_VPU] = 0x00000F20; - env->excp_vectors[POWERPC_EXCP_IABR] = 0x00001300; - env->excp_vectors[POWERPC_EXCP_SMI] = 0x00001400; - env->excp_vectors[POWERPC_EXCP_VPUA] = 0x00001600; - /* Hardware reset vector */ - env->hreset_vector = 0x00000100UL; -#endif -} - #if defined(TARGET_PPC64) static void init_excp_970(CPUPPCState *env) { @@ -939,15 +731,6 @@ static int check_pow_hid0(CPUPPCState *env) return 0; } -static int check_pow_hid0_74xx(CPUPPCState *env) -{ - if (env->spr[SPR_HID0] & 0x00600000) { - return 1; - } - - return 0; -} - static void init_proc_440EP(CPUPPCState *env) { register_BookE_sprs(env, 0x000000000000FFFFULL); @@ -1851,925 +1634,6 @@ POWERPC_FAMILY(e6500)(ObjectClass *oc, void *data) #endif -static void init_proc_7400(CPUPPCState *env) -{ - register_non_embedded_sprs(env); - register_sdr1_sprs(env); - register_74xx_sprs(env); - vscr_init(env, 0x00010000); - - spr_register(env, SPR_UBAMR, "UBAMR", - &spr_read_ureg, SPR_NOACCESS, - &spr_read_ureg, SPR_NOACCESS, - 0x00000000); - - spr_register(env, SPR_MSSCR1, "MSSCR1", - SPR_NOACCESS, SPR_NOACCESS, - &spr_read_generic, &spr_write_generic, - 0x00000000); - /* Thermal management */ - register_thrm_sprs(env); - /* Memory management */ - register_low_BATs(env); - init_excp_7400(env); - env->dcache_line_size = 32; - env->icache_line_size = 32; - /* Allocate hardware IRQ controller */ - ppc6xx_irq_init(env_archcpu(env)); -} - -POWERPC_FAMILY(7400)(ObjectClass *oc, void *data) -{ - DeviceClass *dc = DEVICE_CLASS(oc); - PowerPCCPUClass *pcc = POWERPC_CPU_CLASS(oc); - - dc->desc = "PowerPC 7400 (aka G4)"; - pcc->init_proc = init_proc_7400; - pcc->check_pow = check_pow_hid0; - pcc->insns_flags = PPC_INSNS_BASE | PPC_STRING | PPC_MFTB | - PPC_FLOAT | PPC_FLOAT_FSEL | PPC_FLOAT_FRES | - PPC_FLOAT_FSQRT | PPC_FLOAT_FRSQRTE | - PPC_FLOAT_STFIWX | - PPC_CACHE | PPC_CACHE_ICBI | - PPC_CACHE_DCBA | PPC_CACHE_DCBZ | - PPC_MEM_SYNC | PPC_MEM_EIEIO | - PPC_MEM_TLBIE | PPC_MEM_TLBSYNC | - PPC_MEM_TLBIA | - PPC_SEGMENT | PPC_EXTERN | - PPC_ALTIVEC; - pcc->msr_mask = (1ull << MSR_VR) | - (1ull << MSR_POW) | - (1ull << MSR_ILE) | - (1ull << MSR_EE) | - (1ull << MSR_PR) | - (1ull << MSR_FP) | - (1ull << MSR_ME) | - (1ull << MSR_FE0) | - (1ull << MSR_SE) | - (1ull << MSR_DE) | - (1ull << MSR_FE1) | - (1ull << MSR_EP) | - (1ull << MSR_IR) | - (1ull << MSR_DR) | - (1ull << MSR_PMM) | - (1ull << MSR_RI) | - (1ull << MSR_LE); - pcc->mmu_model = POWERPC_MMU_32B; - pcc->excp_model = POWERPC_EXCP_74xx; - pcc->bus_model = PPC_FLAGS_INPUT_6xx; - pcc->bfd_mach = bfd_mach_ppc_7400; - pcc->flags = POWERPC_FLAG_VRE | POWERPC_FLAG_SE | - POWERPC_FLAG_BE | POWERPC_FLAG_PMM | - POWERPC_FLAG_BUS_CLK; -} - -static void init_proc_7410(CPUPPCState *env) -{ - register_non_embedded_sprs(env); - register_sdr1_sprs(env); - register_74xx_sprs(env); - vscr_init(env, 0x00010000); - - spr_register(env, SPR_UBAMR, "UBAMR", - &spr_read_ureg, SPR_NOACCESS, - &spr_read_ureg, SPR_NOACCESS, - 0x00000000); - /* Thermal management */ - register_thrm_sprs(env); - /* L2PMCR */ - - spr_register(env, SPR_L2PMCR, "L2PMCR", - SPR_NOACCESS, SPR_NOACCESS, - &spr_read_generic, &spr_write_generic, - 0x00000000); - /* LDSTDB */ - - spr_register(env, SPR_LDSTDB, "LDSTDB", - SPR_NOACCESS, SPR_NOACCESS, - &spr_read_generic, &spr_write_generic, - 0x00000000); - /* Memory management */ - register_low_BATs(env); - init_excp_7400(env); - env->dcache_line_size = 32; - env->icache_line_size = 32; - /* Allocate hardware IRQ controller */ - ppc6xx_irq_init(env_archcpu(env)); -} - -POWERPC_FAMILY(7410)(ObjectClass *oc, void *data) -{ - DeviceClass *dc = DEVICE_CLASS(oc); - PowerPCCPUClass *pcc = POWERPC_CPU_CLASS(oc); - - dc->desc = "PowerPC 7410 (aka G4)"; - pcc->init_proc = init_proc_7410; - pcc->check_pow = check_pow_hid0; - pcc->insns_flags = PPC_INSNS_BASE | PPC_STRING | PPC_MFTB | - PPC_FLOAT | PPC_FLOAT_FSEL | PPC_FLOAT_FRES | - PPC_FLOAT_FSQRT | PPC_FLOAT_FRSQRTE | - PPC_FLOAT_STFIWX | - PPC_CACHE | PPC_CACHE_ICBI | - PPC_CACHE_DCBA | PPC_CACHE_DCBZ | - PPC_MEM_SYNC | PPC_MEM_EIEIO | - PPC_MEM_TLBIE | PPC_MEM_TLBSYNC | - PPC_MEM_TLBIA | - PPC_SEGMENT | PPC_EXTERN | - PPC_ALTIVEC; - pcc->msr_mask = (1ull << MSR_VR) | - (1ull << MSR_POW) | - (1ull << MSR_ILE) | - (1ull << MSR_EE) | - (1ull << MSR_PR) | - (1ull << MSR_FP) | - (1ull << MSR_ME) | - (1ull << MSR_FE0) | - (1ull << MSR_SE) | - (1ull << MSR_DE) | - (1ull << MSR_FE1) | - (1ull << MSR_EP) | - (1ull << MSR_IR) | - (1ull << MSR_DR) | - (1ull << MSR_PMM) | - (1ull << MSR_RI) | - (1ull << MSR_LE); - pcc->mmu_model = POWERPC_MMU_32B; - pcc->excp_model = POWERPC_EXCP_74xx; - pcc->bus_model = PPC_FLAGS_INPUT_6xx; - pcc->bfd_mach = bfd_mach_ppc_7400; - pcc->flags = POWERPC_FLAG_VRE | POWERPC_FLAG_SE | - POWERPC_FLAG_BE | POWERPC_FLAG_PMM | - POWERPC_FLAG_BUS_CLK; -} - -static void init_proc_7440(CPUPPCState *env) -{ - register_non_embedded_sprs(env); - register_sdr1_sprs(env); - register_74xx_sprs(env); - vscr_init(env, 0x00010000); - - spr_register(env, SPR_UBAMR, "UBAMR", - &spr_read_ureg, SPR_NOACCESS, - &spr_read_ureg, SPR_NOACCESS, - 0x00000000); - /* LDSTCR */ - spr_register(env, SPR_LDSTCR, "LDSTCR", - SPR_NOACCESS, SPR_NOACCESS, - &spr_read_generic, &spr_write_generic, - 0x00000000); - /* ICTRL */ - spr_register(env, SPR_ICTRL, "ICTRL", - SPR_NOACCESS, SPR_NOACCESS, - &spr_read_generic, &spr_write_generic, - 0x00000000); - /* MSSSR0 */ - spr_register(env, SPR_MSSSR0, "MSSSR0", - SPR_NOACCESS, SPR_NOACCESS, - &spr_read_generic, &spr_write_generic, - 0x00000000); - /* PMC */ - spr_register(env, SPR_7XX_PMC5, "PMC5", - SPR_NOACCESS, SPR_NOACCESS, - &spr_read_generic, &spr_write_generic, - 0x00000000); - - spr_register(env, SPR_7XX_UPMC5, "UPMC5", - &spr_read_ureg, SPR_NOACCESS, - &spr_read_ureg, SPR_NOACCESS, - 0x00000000); - - spr_register(env, SPR_7XX_PMC6, "PMC6", - SPR_NOACCESS, SPR_NOACCESS, - &spr_read_generic, &spr_write_generic, - 0x00000000); - - spr_register(env, SPR_7XX_UPMC6, "UPMC6", - &spr_read_ureg, SPR_NOACCESS, - &spr_read_ureg, SPR_NOACCESS, - 0x00000000); - /* Memory management */ - register_low_BATs(env); - init_excp_7450(env); - env->dcache_line_size = 32; - env->icache_line_size = 32; - /* Allocate hardware IRQ controller */ - ppc6xx_irq_init(env_archcpu(env)); -} - -POWERPC_FAMILY(7440)(ObjectClass *oc, void *data) -{ - DeviceClass *dc = DEVICE_CLASS(oc); - PowerPCCPUClass *pcc = POWERPC_CPU_CLASS(oc); - - dc->desc = "PowerPC 7440 (aka G4)"; - pcc->init_proc = init_proc_7440; - pcc->check_pow = check_pow_hid0_74xx; - pcc->insns_flags = PPC_INSNS_BASE | PPC_STRING | PPC_MFTB | - PPC_FLOAT | PPC_FLOAT_FSEL | PPC_FLOAT_FRES | - PPC_FLOAT_FSQRT | PPC_FLOAT_FRSQRTE | - PPC_FLOAT_STFIWX | - PPC_CACHE | PPC_CACHE_ICBI | - PPC_CACHE_DCBA | PPC_CACHE_DCBZ | - PPC_MEM_SYNC | PPC_MEM_EIEIO | - PPC_MEM_TLBIE | PPC_MEM_TLBSYNC | - PPC_MEM_TLBIA | - PPC_SEGMENT | PPC_EXTERN | - PPC_ALTIVEC; - pcc->msr_mask = (1ull << MSR_VR) | - (1ull << MSR_POW) | - (1ull << MSR_ILE) | - (1ull << MSR_EE) | - (1ull << MSR_PR) | - (1ull << MSR_FP) | - (1ull << MSR_ME) | - (1ull << MSR_FE0) | - (1ull << MSR_SE) | - (1ull << MSR_DE) | - (1ull << MSR_FE1) | - (1ull << MSR_EP) | - (1ull << MSR_IR) | - (1ull << MSR_DR) | - (1ull << MSR_PMM) | - (1ull << MSR_RI) | - (1ull << MSR_LE); - pcc->mmu_model = POWERPC_MMU_32B; - pcc->excp_model = POWERPC_EXCP_74xx; - pcc->bus_model = PPC_FLAGS_INPUT_6xx; - pcc->bfd_mach = bfd_mach_ppc_7400; - pcc->flags = POWERPC_FLAG_VRE | POWERPC_FLAG_SE | - POWERPC_FLAG_BE | POWERPC_FLAG_PMM | - POWERPC_FLAG_BUS_CLK; -} - -static void init_proc_7450(CPUPPCState *env) -{ - register_non_embedded_sprs(env); - register_sdr1_sprs(env); - register_74xx_sprs(env); - vscr_init(env, 0x00010000); - /* Level 3 cache control */ - register_l3_ctrl(env); - /* L3ITCR1 */ - spr_register(env, SPR_L3ITCR1, "L3ITCR1", - SPR_NOACCESS, SPR_NOACCESS, - &spr_read_generic, &spr_write_generic, - 0x00000000); - /* L3ITCR2 */ - spr_register(env, SPR_L3ITCR2, "L3ITCR2", - SPR_NOACCESS, SPR_NOACCESS, - &spr_read_generic, &spr_write_generic, - 0x00000000); - /* L3ITCR3 */ - spr_register(env, SPR_L3ITCR3, "L3ITCR3", - SPR_NOACCESS, SPR_NOACCESS, - &spr_read_generic, &spr_write_generic, - 0x00000000); - /* L3OHCR */ - spr_register(env, SPR_L3OHCR, "L3OHCR", - SPR_NOACCESS, SPR_NOACCESS, - &spr_read_generic, &spr_write_generic, - 0x00000000); - - spr_register(env, SPR_UBAMR, "UBAMR", - &spr_read_ureg, SPR_NOACCESS, - &spr_read_ureg, SPR_NOACCESS, - 0x00000000); - /* LDSTCR */ - spr_register(env, SPR_LDSTCR, "LDSTCR", - SPR_NOACCESS, SPR_NOACCESS, - &spr_read_generic, &spr_write_generic, - 0x00000000); - /* ICTRL */ - spr_register(env, SPR_ICTRL, "ICTRL", - SPR_NOACCESS, SPR_NOACCESS, - &spr_read_generic, &spr_write_generic, - 0x00000000); - /* MSSSR0 */ - spr_register(env, SPR_MSSSR0, "MSSSR0", - SPR_NOACCESS, SPR_NOACCESS, - &spr_read_generic, &spr_write_generic, - 0x00000000); - /* PMC */ - spr_register(env, SPR_7XX_PMC5, "PMC5", - SPR_NOACCESS, SPR_NOACCESS, - &spr_read_generic, &spr_write_generic, - 0x00000000); - - spr_register(env, SPR_7XX_UPMC5, "UPMC5", - &spr_read_ureg, SPR_NOACCESS, - &spr_read_ureg, SPR_NOACCESS, - 0x00000000); - - spr_register(env, SPR_7XX_PMC6, "PMC6", - SPR_NOACCESS, SPR_NOACCESS, - &spr_read_generic, &spr_write_generic, - 0x00000000); - - spr_register(env, SPR_7XX_UPMC6, "UPMC6", - &spr_read_ureg, SPR_NOACCESS, - &spr_read_ureg, SPR_NOACCESS, - 0x00000000); - /* Memory management */ - register_low_BATs(env); - init_excp_7450(env); - env->dcache_line_size = 32; - env->icache_line_size = 32; - /* Allocate hardware IRQ controller */ - ppc6xx_irq_init(env_archcpu(env)); -} - -POWERPC_FAMILY(7450)(ObjectClass *oc, void *data) -{ - DeviceClass *dc = DEVICE_CLASS(oc); - PowerPCCPUClass *pcc = POWERPC_CPU_CLASS(oc); - - dc->desc = "PowerPC 7450 (aka G4)"; - pcc->init_proc = init_proc_7450; - pcc->check_pow = check_pow_hid0_74xx; - pcc->insns_flags = PPC_INSNS_BASE | PPC_STRING | PPC_MFTB | - PPC_FLOAT | PPC_FLOAT_FSEL | PPC_FLOAT_FRES | - PPC_FLOAT_FSQRT | PPC_FLOAT_FRSQRTE | - PPC_FLOAT_STFIWX | - PPC_CACHE | PPC_CACHE_ICBI | - PPC_CACHE_DCBA | PPC_CACHE_DCBZ | - PPC_MEM_SYNC | PPC_MEM_EIEIO | - PPC_MEM_TLBIE | PPC_MEM_TLBSYNC | - PPC_MEM_TLBIA | - PPC_SEGMENT | PPC_EXTERN | - PPC_ALTIVEC; - pcc->msr_mask = (1ull << MSR_VR) | - (1ull << MSR_POW) | - (1ull << MSR_ILE) | - (1ull << MSR_EE) | - (1ull << MSR_PR) | - (1ull << MSR_FP) | - (1ull << MSR_ME) | - (1ull << MSR_FE0) | - (1ull << MSR_SE) | - (1ull << MSR_DE) | - (1ull << MSR_FE1) | - (1ull << MSR_EP) | - (1ull << MSR_IR) | - (1ull << MSR_DR) | - (1ull << MSR_PMM) | - (1ull << MSR_RI) | - (1ull << MSR_LE); - pcc->mmu_model = POWERPC_MMU_32B; - pcc->excp_model = POWERPC_EXCP_74xx; - pcc->bus_model = PPC_FLAGS_INPUT_6xx; - pcc->bfd_mach = bfd_mach_ppc_7400; - pcc->flags = POWERPC_FLAG_VRE | POWERPC_FLAG_SE | - POWERPC_FLAG_BE | POWERPC_FLAG_PMM | - POWERPC_FLAG_BUS_CLK; -} - -static void init_proc_7445(CPUPPCState *env) -{ - register_non_embedded_sprs(env); - register_sdr1_sprs(env); - register_74xx_sprs(env); - vscr_init(env, 0x00010000); - /* LDSTCR */ - spr_register(env, SPR_LDSTCR, "LDSTCR", - SPR_NOACCESS, SPR_NOACCESS, - &spr_read_generic, &spr_write_generic, - 0x00000000); - /* ICTRL */ - spr_register(env, SPR_ICTRL, "ICTRL", - SPR_NOACCESS, SPR_NOACCESS, - &spr_read_generic, &spr_write_generic, - 0x00000000); - /* MSSSR0 */ - spr_register(env, SPR_MSSSR0, "MSSSR0", - SPR_NOACCESS, SPR_NOACCESS, - &spr_read_generic, &spr_write_generic, - 0x00000000); - /* PMC */ - spr_register(env, SPR_7XX_PMC5, "PMC5", - SPR_NOACCESS, SPR_NOACCESS, - &spr_read_generic, &spr_write_generic, - 0x00000000); - - spr_register(env, SPR_7XX_UPMC5, "UPMC5", - &spr_read_ureg, SPR_NOACCESS, - &spr_read_ureg, SPR_NOACCESS, - 0x00000000); - - spr_register(env, SPR_7XX_PMC6, "PMC6", - SPR_NOACCESS, SPR_NOACCESS, - &spr_read_generic, &spr_write_generic, - 0x00000000); - - spr_register(env, SPR_7XX_UPMC6, "UPMC6", - &spr_read_ureg, SPR_NOACCESS, - &spr_read_ureg, SPR_NOACCESS, - 0x00000000); - /* SPRGs */ - spr_register(env, SPR_SPRG4, "SPRG4", - SPR_NOACCESS, SPR_NOACCESS, - &spr_read_generic, &spr_write_generic, - 0x00000000); - spr_register(env, SPR_USPRG4, "USPRG4", - &spr_read_ureg, SPR_NOACCESS, - &spr_read_ureg, SPR_NOACCESS, - 0x00000000); - spr_register(env, SPR_SPRG5, "SPRG5", - SPR_NOACCESS, SPR_NOACCESS, - &spr_read_generic, &spr_write_generic, - 0x00000000); - spr_register(env, SPR_USPRG5, "USPRG5", - &spr_read_ureg, SPR_NOACCESS, - &spr_read_ureg, SPR_NOACCESS, - 0x00000000); - spr_register(env, SPR_SPRG6, "SPRG6", - SPR_NOACCESS, SPR_NOACCESS, - &spr_read_generic, &spr_write_generic, - 0x00000000); - spr_register(env, SPR_USPRG6, "USPRG6", - &spr_read_ureg, SPR_NOACCESS, - &spr_read_ureg, SPR_NOACCESS, - 0x00000000); - spr_register(env, SPR_SPRG7, "SPRG7", - SPR_NOACCESS, SPR_NOACCESS, - &spr_read_generic, &spr_write_generic, - 0x00000000); - spr_register(env, SPR_USPRG7, "USPRG7", - &spr_read_ureg, SPR_NOACCESS, - &spr_read_ureg, SPR_NOACCESS, - 0x00000000); - /* Memory management */ - register_low_BATs(env); - register_high_BATs(env); - init_excp_7450(env); - env->dcache_line_size = 32; - env->icache_line_size = 32; - /* Allocate hardware IRQ controller */ - ppc6xx_irq_init(env_archcpu(env)); -} - -POWERPC_FAMILY(7445)(ObjectClass *oc, void *data) -{ - DeviceClass *dc = DEVICE_CLASS(oc); - PowerPCCPUClass *pcc = POWERPC_CPU_CLASS(oc); - - dc->desc = "PowerPC 7445 (aka G4)"; - pcc->init_proc = init_proc_7445; - pcc->check_pow = check_pow_hid0_74xx; - pcc->insns_flags = PPC_INSNS_BASE | PPC_STRING | PPC_MFTB | - PPC_FLOAT | PPC_FLOAT_FSEL | PPC_FLOAT_FRES | - PPC_FLOAT_FSQRT | PPC_FLOAT_FRSQRTE | - PPC_FLOAT_STFIWX | - PPC_CACHE | PPC_CACHE_ICBI | - PPC_CACHE_DCBA | PPC_CACHE_DCBZ | - PPC_MEM_SYNC | PPC_MEM_EIEIO | - PPC_MEM_TLBIE | PPC_MEM_TLBSYNC | - PPC_MEM_TLBIA | - PPC_SEGMENT | PPC_EXTERN | - PPC_ALTIVEC; - pcc->msr_mask = (1ull << MSR_VR) | - (1ull << MSR_POW) | - (1ull << MSR_ILE) | - (1ull << MSR_EE) | - (1ull << MSR_PR) | - (1ull << MSR_FP) | - (1ull << MSR_ME) | - (1ull << MSR_FE0) | - (1ull << MSR_SE) | - (1ull << MSR_DE) | - (1ull << MSR_FE1) | - (1ull << MSR_EP) | - (1ull << MSR_IR) | - (1ull << MSR_DR) | - (1ull << MSR_PMM) | - (1ull << MSR_RI) | - (1ull << MSR_LE); - pcc->mmu_model = POWERPC_MMU_32B; - pcc->excp_model = POWERPC_EXCP_74xx; - pcc->bus_model = PPC_FLAGS_INPUT_6xx; - pcc->bfd_mach = bfd_mach_ppc_7400; - pcc->flags = POWERPC_FLAG_VRE | POWERPC_FLAG_SE | - POWERPC_FLAG_BE | POWERPC_FLAG_PMM | - POWERPC_FLAG_BUS_CLK; -} - -static void init_proc_7455(CPUPPCState *env) -{ - register_non_embedded_sprs(env); - register_sdr1_sprs(env); - register_74xx_sprs(env); - vscr_init(env, 0x00010000); - /* Level 3 cache control */ - register_l3_ctrl(env); - /* LDSTCR */ - spr_register(env, SPR_LDSTCR, "LDSTCR", - SPR_NOACCESS, SPR_NOACCESS, - &spr_read_generic, &spr_write_generic, - 0x00000000); - /* ICTRL */ - spr_register(env, SPR_ICTRL, "ICTRL", - SPR_NOACCESS, SPR_NOACCESS, - &spr_read_generic, &spr_write_generic, - 0x00000000); - /* MSSSR0 */ - spr_register(env, SPR_MSSSR0, "MSSSR0", - SPR_NOACCESS, SPR_NOACCESS, - &spr_read_generic, &spr_write_generic, - 0x00000000); - /* PMC */ - spr_register(env, SPR_7XX_PMC5, "PMC5", - SPR_NOACCESS, SPR_NOACCESS, - &spr_read_generic, &spr_write_generic, - 0x00000000); - - spr_register(env, SPR_7XX_UPMC5, "UPMC5", - &spr_read_ureg, SPR_NOACCESS, - &spr_read_ureg, SPR_NOACCESS, - 0x00000000); - - spr_register(env, SPR_7XX_PMC6, "PMC6", - SPR_NOACCESS, SPR_NOACCESS, - &spr_read_generic, &spr_write_generic, - 0x00000000); - - spr_register(env, SPR_7XX_UPMC6, "UPMC6", - &spr_read_ureg, SPR_NOACCESS, - &spr_read_ureg, SPR_NOACCESS, - 0x00000000); - /* SPRGs */ - spr_register(env, SPR_SPRG4, "SPRG4", - SPR_NOACCESS, SPR_NOACCESS, - &spr_read_generic, &spr_write_generic, - 0x00000000); - spr_register(env, SPR_USPRG4, "USPRG4", - &spr_read_ureg, SPR_NOACCESS, - &spr_read_ureg, SPR_NOACCESS, - 0x00000000); - spr_register(env, SPR_SPRG5, "SPRG5", - SPR_NOACCESS, SPR_NOACCESS, - &spr_read_generic, &spr_write_generic, - 0x00000000); - spr_register(env, SPR_USPRG5, "USPRG5", - &spr_read_ureg, SPR_NOACCESS, - &spr_read_ureg, SPR_NOACCESS, - 0x00000000); - spr_register(env, SPR_SPRG6, "SPRG6", - SPR_NOACCESS, SPR_NOACCESS, - &spr_read_generic, &spr_write_generic, - 0x00000000); - spr_register(env, SPR_USPRG6, "USPRG6", - &spr_read_ureg, SPR_NOACCESS, - &spr_read_ureg, SPR_NOACCESS, - 0x00000000); - spr_register(env, SPR_SPRG7, "SPRG7", - SPR_NOACCESS, SPR_NOACCESS, - &spr_read_generic, &spr_write_generic, - 0x00000000); - spr_register(env, SPR_USPRG7, "USPRG7", - &spr_read_ureg, SPR_NOACCESS, - &spr_read_ureg, SPR_NOACCESS, - 0x00000000); - /* Memory management */ - register_low_BATs(env); - register_high_BATs(env); - init_excp_7450(env); - env->dcache_line_size = 32; - env->icache_line_size = 32; - /* Allocate hardware IRQ controller */ - ppc6xx_irq_init(env_archcpu(env)); -} - -POWERPC_FAMILY(7455)(ObjectClass *oc, void *data) -{ - DeviceClass *dc = DEVICE_CLASS(oc); - PowerPCCPUClass *pcc = POWERPC_CPU_CLASS(oc); - - dc->desc = "PowerPC 7455 (aka G4)"; - pcc->init_proc = init_proc_7455; - pcc->check_pow = check_pow_hid0_74xx; - pcc->insns_flags = PPC_INSNS_BASE | PPC_STRING | PPC_MFTB | - PPC_FLOAT | PPC_FLOAT_FSEL | PPC_FLOAT_FRES | - PPC_FLOAT_FSQRT | PPC_FLOAT_FRSQRTE | - PPC_FLOAT_STFIWX | - PPC_CACHE | PPC_CACHE_ICBI | - PPC_CACHE_DCBA | PPC_CACHE_DCBZ | - PPC_MEM_SYNC | PPC_MEM_EIEIO | - PPC_MEM_TLBIE | PPC_MEM_TLBSYNC | - PPC_MEM_TLBIA | - PPC_SEGMENT | PPC_EXTERN | - PPC_ALTIVEC; - pcc->msr_mask = (1ull << MSR_VR) | - (1ull << MSR_POW) | - (1ull << MSR_ILE) | - (1ull << MSR_EE) | - (1ull << MSR_PR) | - (1ull << MSR_FP) | - (1ull << MSR_ME) | - (1ull << MSR_FE0) | - (1ull << MSR_SE) | - (1ull << MSR_DE) | - (1ull << MSR_FE1) | - (1ull << MSR_EP) | - (1ull << MSR_IR) | - (1ull << MSR_DR) | - (1ull << MSR_PMM) | - (1ull << MSR_RI) | - (1ull << MSR_LE); - pcc->mmu_model = POWERPC_MMU_32B; - pcc->excp_model = POWERPC_EXCP_74xx; - pcc->bus_model = PPC_FLAGS_INPUT_6xx; - pcc->bfd_mach = bfd_mach_ppc_7400; - pcc->flags = POWERPC_FLAG_VRE | POWERPC_FLAG_SE | - POWERPC_FLAG_BE | POWERPC_FLAG_PMM | - POWERPC_FLAG_BUS_CLK; -} - -static void init_proc_7457(CPUPPCState *env) -{ - register_non_embedded_sprs(env); - register_sdr1_sprs(env); - register_74xx_sprs(env); - vscr_init(env, 0x00010000); - /* Level 3 cache control */ - register_l3_ctrl(env); - /* L3ITCR1 */ - spr_register(env, SPR_L3ITCR1, "L3ITCR1", - SPR_NOACCESS, SPR_NOACCESS, - &spr_read_generic, &spr_write_generic, - 0x00000000); - /* L3ITCR2 */ - spr_register(env, SPR_L3ITCR2, "L3ITCR2", - SPR_NOACCESS, SPR_NOACCESS, - &spr_read_generic, &spr_write_generic, - 0x00000000); - /* L3ITCR3 */ - spr_register(env, SPR_L3ITCR3, "L3ITCR3", - SPR_NOACCESS, SPR_NOACCESS, - &spr_read_generic, &spr_write_generic, - 0x00000000); - /* L3OHCR */ - spr_register(env, SPR_L3OHCR, "L3OHCR", - SPR_NOACCESS, SPR_NOACCESS, - &spr_read_generic, &spr_write_generic, - 0x00000000); - /* LDSTCR */ - spr_register(env, SPR_LDSTCR, "LDSTCR", - SPR_NOACCESS, SPR_NOACCESS, - &spr_read_generic, &spr_write_generic, - 0x00000000); - /* ICTRL */ - spr_register(env, SPR_ICTRL, "ICTRL", - SPR_NOACCESS, SPR_NOACCESS, - &spr_read_generic, &spr_write_generic, - 0x00000000); - /* MSSSR0 */ - spr_register(env, SPR_MSSSR0, "MSSSR0", - SPR_NOACCESS, SPR_NOACCESS, - &spr_read_generic, &spr_write_generic, - 0x00000000); - /* PMC */ - spr_register(env, SPR_7XX_PMC5, "PMC5", - SPR_NOACCESS, SPR_NOACCESS, - &spr_read_generic, &spr_write_generic, - 0x00000000); - - spr_register(env, SPR_7XX_UPMC5, "UPMC5", - &spr_read_ureg, SPR_NOACCESS, - &spr_read_ureg, SPR_NOACCESS, - 0x00000000); - - spr_register(env, SPR_7XX_PMC6, "PMC6", - SPR_NOACCESS, SPR_NOACCESS, - &spr_read_generic, &spr_write_generic, - 0x00000000); - - spr_register(env, SPR_7XX_UPMC6, "UPMC6", - &spr_read_ureg, SPR_NOACCESS, - &spr_read_ureg, SPR_NOACCESS, - 0x00000000); - /* SPRGs */ - spr_register(env, SPR_SPRG4, "SPRG4", - SPR_NOACCESS, SPR_NOACCESS, - &spr_read_generic, &spr_write_generic, - 0x00000000); - spr_register(env, SPR_USPRG4, "USPRG4", - &spr_read_ureg, SPR_NOACCESS, - &spr_read_ureg, SPR_NOACCESS, - 0x00000000); - spr_register(env, SPR_SPRG5, "SPRG5", - SPR_NOACCESS, SPR_NOACCESS, - &spr_read_generic, &spr_write_generic, - 0x00000000); - spr_register(env, SPR_USPRG5, "USPRG5", - &spr_read_ureg, SPR_NOACCESS, - &spr_read_ureg, SPR_NOACCESS, - 0x00000000); - spr_register(env, SPR_SPRG6, "SPRG6", - SPR_NOACCESS, SPR_NOACCESS, - &spr_read_generic, &spr_write_generic, - 0x00000000); - spr_register(env, SPR_USPRG6, "USPRG6", - &spr_read_ureg, SPR_NOACCESS, - &spr_read_ureg, SPR_NOACCESS, - 0x00000000); - spr_register(env, SPR_SPRG7, "SPRG7", - SPR_NOACCESS, SPR_NOACCESS, - &spr_read_generic, &spr_write_generic, - 0x00000000); - spr_register(env, SPR_USPRG7, "USPRG7", - &spr_read_ureg, SPR_NOACCESS, - &spr_read_ureg, SPR_NOACCESS, - 0x00000000); - /* Memory management */ - register_low_BATs(env); - register_high_BATs(env); - init_excp_7450(env); - env->dcache_line_size = 32; - env->icache_line_size = 32; - /* Allocate hardware IRQ controller */ - ppc6xx_irq_init(env_archcpu(env)); -} - -POWERPC_FAMILY(7457)(ObjectClass *oc, void *data) -{ - DeviceClass *dc = DEVICE_CLASS(oc); - PowerPCCPUClass *pcc = POWERPC_CPU_CLASS(oc); - - dc->desc = "PowerPC 7457 (aka G4)"; - pcc->init_proc = init_proc_7457; - pcc->check_pow = check_pow_hid0_74xx; - pcc->insns_flags = PPC_INSNS_BASE | PPC_STRING | PPC_MFTB | - PPC_FLOAT | PPC_FLOAT_FSEL | PPC_FLOAT_FRES | - PPC_FLOAT_FSQRT | PPC_FLOAT_FRSQRTE | - PPC_FLOAT_STFIWX | - PPC_CACHE | PPC_CACHE_ICBI | - PPC_CACHE_DCBA | PPC_CACHE_DCBZ | - PPC_MEM_SYNC | PPC_MEM_EIEIO | - PPC_MEM_TLBIE | PPC_MEM_TLBSYNC | - PPC_MEM_TLBIA | - PPC_SEGMENT | PPC_EXTERN | - PPC_ALTIVEC; - pcc->msr_mask = (1ull << MSR_VR) | - (1ull << MSR_POW) | - (1ull << MSR_ILE) | - (1ull << MSR_EE) | - (1ull << MSR_PR) | - (1ull << MSR_FP) | - (1ull << MSR_ME) | - (1ull << MSR_FE0) | - (1ull << MSR_SE) | - (1ull << MSR_DE) | - (1ull << MSR_FE1) | - (1ull << MSR_EP) | - (1ull << MSR_IR) | - (1ull << MSR_DR) | - (1ull << MSR_PMM) | - (1ull << MSR_RI) | - (1ull << MSR_LE); - pcc->mmu_model = POWERPC_MMU_32B; - pcc->excp_model = POWERPC_EXCP_74xx; - pcc->bus_model = PPC_FLAGS_INPUT_6xx; - pcc->bfd_mach = bfd_mach_ppc_7400; - pcc->flags = POWERPC_FLAG_VRE | POWERPC_FLAG_SE | - POWERPC_FLAG_BE | POWERPC_FLAG_PMM | - POWERPC_FLAG_BUS_CLK; -} - -static void init_proc_e600(CPUPPCState *env) -{ - register_non_embedded_sprs(env); - register_sdr1_sprs(env); - register_74xx_sprs(env); - vscr_init(env, 0x00010000); - - spr_register(env, SPR_UBAMR, "UBAMR", - &spr_read_ureg, SPR_NOACCESS, - &spr_read_ureg, SPR_NOACCESS, - 0x00000000); - - spr_register(env, SPR_LDSTCR, "LDSTCR", - SPR_NOACCESS, SPR_NOACCESS, - &spr_read_generic, &spr_write_generic, - 0x00000000); - - spr_register(env, SPR_ICTRL, "ICTRL", - SPR_NOACCESS, SPR_NOACCESS, - &spr_read_generic, &spr_write_generic, - 0x00000000); - - spr_register(env, SPR_MSSSR0, "MSSSR0", - SPR_NOACCESS, SPR_NOACCESS, - &spr_read_generic, &spr_write_generic, - 0x00000000); - - spr_register(env, SPR_7XX_PMC5, "PMC5", - SPR_NOACCESS, SPR_NOACCESS, - &spr_read_generic, &spr_write_generic, - 0x00000000); - - spr_register(env, SPR_7XX_UPMC5, "UPMC5", - &spr_read_ureg, SPR_NOACCESS, - &spr_read_ureg, SPR_NOACCESS, - 0x00000000); - - spr_register(env, SPR_7XX_PMC6, "PMC6", - SPR_NOACCESS, SPR_NOACCESS, - &spr_read_generic, &spr_write_generic, - 0x00000000); - - spr_register(env, SPR_7XX_UPMC6, "UPMC6", - &spr_read_ureg, SPR_NOACCESS, - &spr_read_ureg, SPR_NOACCESS, - 0x00000000); - /* SPRGs */ - spr_register(env, SPR_SPRG4, "SPRG4", - SPR_NOACCESS, SPR_NOACCESS, - &spr_read_generic, &spr_write_generic, - 0x00000000); - spr_register(env, SPR_USPRG4, "USPRG4", - &spr_read_ureg, SPR_NOACCESS, - &spr_read_ureg, SPR_NOACCESS, - 0x00000000); - spr_register(env, SPR_SPRG5, "SPRG5", - SPR_NOACCESS, SPR_NOACCESS, - &spr_read_generic, &spr_write_generic, - 0x00000000); - spr_register(env, SPR_USPRG5, "USPRG5", - &spr_read_ureg, SPR_NOACCESS, - &spr_read_ureg, SPR_NOACCESS, - 0x00000000); - spr_register(env, SPR_SPRG6, "SPRG6", - SPR_NOACCESS, SPR_NOACCESS, - &spr_read_generic, &spr_write_generic, - 0x00000000); - spr_register(env, SPR_USPRG6, "USPRG6", - &spr_read_ureg, SPR_NOACCESS, - &spr_read_ureg, SPR_NOACCESS, - 0x00000000); - spr_register(env, SPR_SPRG7, "SPRG7", - SPR_NOACCESS, SPR_NOACCESS, - &spr_read_generic, &spr_write_generic, - 0x00000000); - spr_register(env, SPR_USPRG7, "USPRG7", - &spr_read_ureg, SPR_NOACCESS, - &spr_read_ureg, SPR_NOACCESS, - 0x00000000); - /* Memory management */ - register_low_BATs(env); - register_high_BATs(env); - init_excp_7450(env); - env->dcache_line_size = 32; - env->icache_line_size = 32; - /* Allocate hardware IRQ controller */ - ppc6xx_irq_init(env_archcpu(env)); -} - -POWERPC_FAMILY(e600)(ObjectClass *oc, void *data) -{ - DeviceClass *dc = DEVICE_CLASS(oc); - PowerPCCPUClass *pcc = POWERPC_CPU_CLASS(oc); - - dc->desc = "PowerPC e600"; - pcc->init_proc = init_proc_e600; - pcc->check_pow = check_pow_hid0_74xx; - pcc->insns_flags = PPC_INSNS_BASE | PPC_STRING | PPC_MFTB | - PPC_FLOAT | PPC_FLOAT_FSEL | PPC_FLOAT_FRES | - PPC_FLOAT_FSQRT | PPC_FLOAT_FRSQRTE | - PPC_FLOAT_STFIWX | - PPC_CACHE | PPC_CACHE_ICBI | - PPC_CACHE_DCBA | PPC_CACHE_DCBZ | - PPC_MEM_SYNC | PPC_MEM_EIEIO | - PPC_MEM_TLBIE | PPC_MEM_TLBSYNC | - PPC_MEM_TLBIA | - PPC_SEGMENT | PPC_EXTERN | - PPC_ALTIVEC; - pcc->insns_flags2 = PPC_NONE; - pcc->msr_mask = (1ull << MSR_VR) | - (1ull << MSR_POW) | - (1ull << MSR_ILE) | - (1ull << MSR_EE) | - (1ull << MSR_PR) | - (1ull << MSR_FP) | - (1ull << MSR_ME) | - (1ull << MSR_FE0) | - (1ull << MSR_SE) | - (1ull << MSR_DE) | - (1ull << MSR_FE1) | - (1ull << MSR_EP) | - (1ull << MSR_IR) | - (1ull << MSR_DR) | - (1ull << MSR_PMM) | - (1ull << MSR_RI) | - (1ull << MSR_LE); - pcc->mmu_model = POWERPC_MMU_32B; - pcc->excp_model = POWERPC_EXCP_74xx; - pcc->bus_model = PPC_FLAGS_INPUT_6xx; - pcc->bfd_mach = bfd_mach_ppc_7400; - pcc->flags = POWERPC_FLAG_VRE | POWERPC_FLAG_SE | - POWERPC_FLAG_BE | POWERPC_FLAG_PMM | - POWERPC_FLAG_BUS_CLK; -} - #if defined(TARGET_PPC64) #if defined(CONFIG_USER_ONLY) #define POWERPC970_HID5_INIT 0x00000080 diff --git a/target/ppc/meson.build b/target/ppc/meson.build index f665802d5e..aae1c2051e 100644 --- a/target/ppc/meson.build +++ b/target/ppc/meson.build @@ -6,6 +6,7 @@ ppc_ss.add(files( 'cpu_40x.c', 'cpu_6xx.c', 'cpu_7xx.c', + 'cpu_74xx.c', 'excp_helper.c', 'gdbstub.c', 'helper_regs.c', From patchwork Tue Mar 1 13:56:10 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Fabiano Rosas X-Patchwork-Id: 12764750 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 AEBC3C433EF for ; Tue, 1 Mar 2022 14:04:09 +0000 (UTC) Received: from localhost ([::1]:60618 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1nP36m-0006ve-MZ for qemu-devel@archiver.kernel.org; Tue, 01 Mar 2022 09:04:08 -0500 Received: from eggs.gnu.org ([209.51.188.92]:33340) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1nP2zq-00066I-4h; Tue, 01 Mar 2022 08:56:58 -0500 Received: from mx0a-001b2d01.pphosted.com ([148.163.156.1]:40476) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1nP2zl-00024G-Ds; Tue, 01 Mar 2022 08:56:57 -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 221C0Vv4018318; Tue, 1 Mar 2022 13:56:47 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=tjzvQXSm0s4giTINa6XLCEvuAGDVSC+pY2sow9C55gQ=; b=hvVx/0TxeUkFDAOw9fOxtqd/Tnwi4WeOTNHsCkBCptR7J3FPMVWlOTjdDrRlwG/aCN0A UZHLZaOwslivb+zQxekyDyvQpryJdUT6CmcSQgT6FnWuaDPfjxtSnanXFaBDLmhYq2w9 MoJPWG5XaS0AdnBklMgXQxag9DLjSCi4N6EJiLD83wDvGRB9HxFza7pzAOadx+n8ZK6F 8ZOUUqP/AGTan9nTajMQv3NftLCDUlRK1tebOnUwYBoSa5JQxAcN9T9e6e2z0qiq+uUi DVZI9v9w4whVjVO/CYNpVljB6RVB1qQJQ435ldLP7++quFF1ABdNYj7LpUeGDaOJjyoN Kg== Received: from pps.reinject (localhost [127.0.0.1]) by mx0a-001b2d01.pphosted.com with ESMTP id 3ehfrufnwv-1 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NOT); Tue, 01 Mar 2022 13:56:46 +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 221CrHhr012477; Tue, 1 Mar 2022 13:56:45 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 3ehfrufnvw-1 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NOT); Tue, 01 Mar 2022 13:56:45 +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 221Dtd21030041; Tue, 1 Mar 2022 13:56:43 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 3efbu9w0v7-1 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NOT); Tue, 01 Mar 2022 13:56:43 +0000 Received: from b03ledav005.gho.boulder.ibm.com (b03ledav005.gho.boulder.ibm.com [9.17.130.236]) by b03cxnp07029.gho.boulder.ibm.com (8.14.9/8.14.9/NCO v10.0) with ESMTP id 221Dug4l34865580 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-GCM-SHA384 bits=256 verify=OK); Tue, 1 Mar 2022 13:56:42 GMT Received: from b03ledav005.gho.boulder.ibm.com (unknown [127.0.0.1]) by IMSVA (Postfix) with ESMTP id DE97CBE05D; Tue, 1 Mar 2022 13:56:41 +0000 (GMT) Received: from b03ledav005.gho.boulder.ibm.com (unknown [127.0.0.1]) by IMSVA (Postfix) with ESMTP id 668CCBE056; Tue, 1 Mar 2022 13:56:40 +0000 (GMT) Received: from farosas.linux.ibm.com.com (unknown [9.211.51.129]) by b03ledav005.gho.boulder.ibm.com (Postfix) with ESMTP; Tue, 1 Mar 2022 13:56:40 +0000 (GMT) From: Fabiano Rosas To: qemu-devel@nongnu.org Subject: [PATCH 07/17] target/ppc: Move BookE CPUs code to their own file Date: Tue, 1 Mar 2022 10:56:10 -0300 Message-Id: <20220301135620.2411952-8-farosas@linux.ibm.com> X-Mailer: git-send-email 2.34.1 In-Reply-To: <20220301135620.2411952-1-farosas@linux.ibm.com> References: <20220301135620.2411952-1-farosas@linux.ibm.com> MIME-Version: 1.0 X-TM-AS-GCONF: 00 X-Proofpoint-ORIG-GUID: 8TQ85L_5mfKDmDHrfUjApLTepjwV5wnt X-Proofpoint-GUID: kMmjRESLti2k5THQrLOyPrjHot7IEWQC X-Proofpoint-Virus-Version: vendor=baseguard engine=ICAP:2.0.205,Aquarius:18.0.816,Hydra:6.0.425,FMLib:17.11.64.514 definitions=2022-03-01_07,2022-02-26_01,2022-02-23_01 X-Proofpoint-Spam-Details: rule=outbound_notspam policy=outbound score=0 mlxscore=0 suspectscore=0 phishscore=0 clxscore=1015 impostorscore=0 malwarescore=0 priorityscore=1501 mlxlogscore=999 lowpriorityscore=0 spamscore=0 adultscore=0 bulkscore=0 classifier=spam adjust=0 reason=mlx scancount=1 engine=8.12.0-2201110000 definitions=main-2203010074 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_H5=0.001, RCVD_IN_MSPIKE_WL=0.001, SPF_HELO_NONE=0.001, SPF_PASS=-0.001, T_SCC_BODY_TEXT_LINE=-0.01 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" Affects the 440EP, 460EX, 440GP, 440x5, e200, e500v1, e500v2, e500mc, e5500 and e6500. This moves init_proc, init_excp and register_*sprs functions that are related to the BookE CPUs into a separate file. - I'm copying check_pow_hid0 instead of moving it to avoid having to keep it exposed in a header file; - Differently from the previous files, this one contains both 32-bit and 64-bit code. Signed-off-by: Fabiano Rosas --- target/ppc/cpu_booke.c | 1422 ++++++++++++++++++++++++++++++++++++++++ target/ppc/cpu_init.c | 1410 --------------------------------------- target/ppc/meson.build | 1 + 3 files changed, 1423 insertions(+), 1410 deletions(-) create mode 100644 target/ppc/cpu_booke.c diff --git a/target/ppc/cpu_booke.c b/target/ppc/cpu_booke.c new file mode 100644 index 0000000000..18e16bd3bf --- /dev/null +++ b/target/ppc/cpu_booke.c @@ -0,0 +1,1422 @@ +/* + * CPU initialization for PowerPC BookE CPUs + * + * Copyright IBM Corp. 2022 + * + * This work is licensed under the terms of the GNU GPL, version 2 or later. + * See the COPYING file in the top-level directory. + */ + +#include "qemu/osdep.h" +#include "hw/ppc/ppc.h" +#include "cpu.h" +#include "spr_common.h" + +static int check_pow_hid0(CPUPPCState *env) +{ + if (env->spr[SPR_HID0] & 0x00E00000) { + return 1; + } + + return 0; +} + +static void register_BookE_sprs(CPUPPCState *env, uint64_t ivor_mask) +{ + const char *ivor_names[64] = { + "IVOR0", "IVOR1", "IVOR2", "IVOR3", + "IVOR4", "IVOR5", "IVOR6", "IVOR7", + "IVOR8", "IVOR9", "IVOR10", "IVOR11", + "IVOR12", "IVOR13", "IVOR14", "IVOR15", + "IVOR16", "IVOR17", "IVOR18", "IVOR19", + "IVOR20", "IVOR21", "IVOR22", "IVOR23", + "IVOR24", "IVOR25", "IVOR26", "IVOR27", + "IVOR28", "IVOR29", "IVOR30", "IVOR31", + "IVOR32", "IVOR33", "IVOR34", "IVOR35", + "IVOR36", "IVOR37", "IVOR38", "IVOR39", + "IVOR40", "IVOR41", "IVOR42", "IVOR43", + "IVOR44", "IVOR45", "IVOR46", "IVOR47", + "IVOR48", "IVOR49", "IVOR50", "IVOR51", + "IVOR52", "IVOR53", "IVOR54", "IVOR55", + "IVOR56", "IVOR57", "IVOR58", "IVOR59", + "IVOR60", "IVOR61", "IVOR62", "IVOR63", + }; +#define SPR_BOOKE_IVORxx (-1) + int ivor_sprn[64] = { + SPR_BOOKE_IVOR0, SPR_BOOKE_IVOR1, SPR_BOOKE_IVOR2, SPR_BOOKE_IVOR3, + SPR_BOOKE_IVOR4, SPR_BOOKE_IVOR5, SPR_BOOKE_IVOR6, SPR_BOOKE_IVOR7, + SPR_BOOKE_IVOR8, SPR_BOOKE_IVOR9, SPR_BOOKE_IVOR10, SPR_BOOKE_IVOR11, + SPR_BOOKE_IVOR12, SPR_BOOKE_IVOR13, SPR_BOOKE_IVOR14, SPR_BOOKE_IVOR15, + SPR_BOOKE_IVORxx, SPR_BOOKE_IVORxx, SPR_BOOKE_IVORxx, SPR_BOOKE_IVORxx, + SPR_BOOKE_IVORxx, SPR_BOOKE_IVORxx, SPR_BOOKE_IVORxx, SPR_BOOKE_IVORxx, + SPR_BOOKE_IVORxx, SPR_BOOKE_IVORxx, SPR_BOOKE_IVORxx, SPR_BOOKE_IVORxx, + SPR_BOOKE_IVORxx, SPR_BOOKE_IVORxx, SPR_BOOKE_IVORxx, SPR_BOOKE_IVORxx, + SPR_BOOKE_IVOR32, SPR_BOOKE_IVOR33, SPR_BOOKE_IVOR34, SPR_BOOKE_IVOR35, + SPR_BOOKE_IVOR36, SPR_BOOKE_IVOR37, SPR_BOOKE_IVOR38, SPR_BOOKE_IVOR39, + SPR_BOOKE_IVOR40, SPR_BOOKE_IVOR41, SPR_BOOKE_IVOR42, SPR_BOOKE_IVORxx, + SPR_BOOKE_IVORxx, SPR_BOOKE_IVORxx, SPR_BOOKE_IVORxx, SPR_BOOKE_IVORxx, + SPR_BOOKE_IVORxx, SPR_BOOKE_IVORxx, SPR_BOOKE_IVORxx, SPR_BOOKE_IVORxx, + SPR_BOOKE_IVORxx, SPR_BOOKE_IVORxx, SPR_BOOKE_IVORxx, SPR_BOOKE_IVORxx, + SPR_BOOKE_IVORxx, SPR_BOOKE_IVORxx, SPR_BOOKE_IVORxx, SPR_BOOKE_IVORxx, + SPR_BOOKE_IVORxx, SPR_BOOKE_IVORxx, SPR_BOOKE_IVORxx, SPR_BOOKE_IVORxx, + }; + int i; + + /* Interrupt processing */ + spr_register(env, SPR_BOOKE_CSRR0, "CSRR0", + SPR_NOACCESS, SPR_NOACCESS, + &spr_read_generic, &spr_write_generic, + 0x00000000); + spr_register(env, SPR_BOOKE_CSRR1, "CSRR1", + SPR_NOACCESS, SPR_NOACCESS, + &spr_read_generic, &spr_write_generic, + 0x00000000); + /* Debug */ + spr_register(env, SPR_BOOKE_IAC1, "IAC1", + SPR_NOACCESS, SPR_NOACCESS, + &spr_read_generic, &spr_write_generic, + 0x00000000); + + spr_register(env, SPR_BOOKE_IAC2, "IAC2", + SPR_NOACCESS, SPR_NOACCESS, + &spr_read_generic, &spr_write_generic, + 0x00000000); + + spr_register(env, SPR_BOOKE_DAC1, "DAC1", + SPR_NOACCESS, SPR_NOACCESS, + &spr_read_generic, &spr_write_generic, + 0x00000000); + + spr_register(env, SPR_BOOKE_DAC2, "DAC2", + SPR_NOACCESS, SPR_NOACCESS, + &spr_read_generic, &spr_write_generic, + 0x00000000); + + spr_register(env, SPR_BOOKE_DBCR0, "DBCR0", + SPR_NOACCESS, SPR_NOACCESS, + &spr_read_generic, &spr_write_40x_dbcr0, + 0x00000000); + + spr_register(env, SPR_BOOKE_DBCR1, "DBCR1", + SPR_NOACCESS, SPR_NOACCESS, + &spr_read_generic, &spr_write_generic, + 0x00000000); + + spr_register(env, SPR_BOOKE_DBCR2, "DBCR2", + SPR_NOACCESS, SPR_NOACCESS, + &spr_read_generic, &spr_write_generic, + 0x00000000); + spr_register(env, SPR_BOOKE_DSRR0, "DSRR0", + SPR_NOACCESS, SPR_NOACCESS, + &spr_read_generic, &spr_write_generic, + 0x00000000); + spr_register(env, SPR_BOOKE_DSRR1, "DSRR1", + SPR_NOACCESS, SPR_NOACCESS, + &spr_read_generic, &spr_write_generic, + 0x00000000); + + spr_register(env, SPR_BOOKE_DBSR, "DBSR", + SPR_NOACCESS, SPR_NOACCESS, + &spr_read_generic, &spr_write_clear, + 0x00000000); + spr_register(env, SPR_BOOKE_DEAR, "DEAR", + SPR_NOACCESS, SPR_NOACCESS, + &spr_read_generic, &spr_write_generic, + 0x00000000); + spr_register(env, SPR_BOOKE_ESR, "ESR", + SPR_NOACCESS, SPR_NOACCESS, + &spr_read_generic, &spr_write_generic, + 0x00000000); + spr_register(env, SPR_BOOKE_IVPR, "IVPR", + SPR_NOACCESS, SPR_NOACCESS, + &spr_read_generic, &spr_write_excp_prefix, + 0x00000000); + /* Exception vectors */ + for (i = 0; i < 64; i++) { + if (ivor_mask & (1ULL << i)) { + if (ivor_sprn[i] == SPR_BOOKE_IVORxx) { + fprintf(stderr, "ERROR: IVOR %d SPR is not defined\n", i); + exit(1); + } + spr_register(env, ivor_sprn[i], ivor_names[i], + SPR_NOACCESS, SPR_NOACCESS, + &spr_read_generic, &spr_write_excp_vector, + 0x00000000); + } + } + spr_register(env, SPR_BOOKE_PID, "PID", + SPR_NOACCESS, SPR_NOACCESS, + &spr_read_generic, &spr_write_booke_pid, + 0x00000000); + spr_register(env, SPR_BOOKE_TCR, "TCR", + SPR_NOACCESS, SPR_NOACCESS, + &spr_read_generic, &spr_write_booke_tcr, + 0x00000000); + spr_register(env, SPR_BOOKE_TSR, "TSR", + SPR_NOACCESS, SPR_NOACCESS, + &spr_read_generic, &spr_write_booke_tsr, + 0x00000000); + /* Timer */ + spr_register(env, SPR_DECR, "DECR", + SPR_NOACCESS, SPR_NOACCESS, + &spr_read_decr, &spr_write_decr, + 0x00000000); + spr_register(env, SPR_BOOKE_DECAR, "DECAR", + SPR_NOACCESS, SPR_NOACCESS, + SPR_NOACCESS, &spr_write_generic, + 0x00000000); + /* SPRGs */ + spr_register(env, SPR_USPRG0, "USPRG0", + &spr_read_generic, &spr_write_generic, + &spr_read_generic, &spr_write_generic, + 0x00000000); + spr_register(env, SPR_SPRG4, "SPRG4", + SPR_NOACCESS, SPR_NOACCESS, + &spr_read_generic, &spr_write_generic, + 0x00000000); + spr_register(env, SPR_SPRG5, "SPRG5", + SPR_NOACCESS, SPR_NOACCESS, + &spr_read_generic, &spr_write_generic, + 0x00000000); + spr_register(env, SPR_SPRG6, "SPRG6", + SPR_NOACCESS, SPR_NOACCESS, + &spr_read_generic, &spr_write_generic, + 0x00000000); + spr_register(env, SPR_SPRG7, "SPRG7", + SPR_NOACCESS, SPR_NOACCESS, + &spr_read_generic, &spr_write_generic, + 0x00000000); + spr_register(env, SPR_BOOKE_SPRG8, "SPRG8", + SPR_NOACCESS, SPR_NOACCESS, + &spr_read_generic, &spr_write_generic, + 0x00000000); + spr_register(env, SPR_BOOKE_SPRG9, "SPRG9", + SPR_NOACCESS, SPR_NOACCESS, + &spr_read_generic, &spr_write_generic, + 0x00000000); +} + +#if !defined(CONFIG_USER_ONLY) +static inline uint32_t register_tlbncfg(uint32_t assoc, uint32_t minsize, + uint32_t maxsize, uint32_t flags, + uint32_t nentries) +{ + return (assoc << TLBnCFG_ASSOC_SHIFT) | + (minsize << TLBnCFG_MINSIZE_SHIFT) | + (maxsize << TLBnCFG_MAXSIZE_SHIFT) | + flags | nentries; +} +#endif /* !CONFIG_USER_ONLY */ + +/* BookE 2.06 storage control registers */ +static void register_BookE206_sprs(CPUPPCState *env, uint32_t mas_mask, + uint32_t *tlbncfg, uint32_t mmucfg) +{ +#if !defined(CONFIG_USER_ONLY) + const char *mas_names[8] = { + "MAS0", "MAS1", "MAS2", "MAS3", "MAS4", "MAS5", "MAS6", "MAS7", + }; + int mas_sprn[8] = { + SPR_BOOKE_MAS0, SPR_BOOKE_MAS1, SPR_BOOKE_MAS2, SPR_BOOKE_MAS3, + SPR_BOOKE_MAS4, SPR_BOOKE_MAS5, SPR_BOOKE_MAS6, SPR_BOOKE_MAS7, + }; + int i; + + /* TLB assist registers */ + for (i = 0; i < 8; i++) { + if (mas_mask & (1 << i)) { + spr_register(env, mas_sprn[i], mas_names[i], + SPR_NOACCESS, SPR_NOACCESS, + &spr_read_generic, + (i == 2 && (env->insns_flags & PPC_64B)) + ? &spr_write_generic : &spr_write_generic32, + 0x00000000); + } + } + if (env->nb_pids > 1) { + spr_register(env, SPR_BOOKE_PID1, "PID1", + SPR_NOACCESS, SPR_NOACCESS, + &spr_read_generic, &spr_write_booke_pid, + 0x00000000); + } + if (env->nb_pids > 2) { + spr_register(env, SPR_BOOKE_PID2, "PID2", + SPR_NOACCESS, SPR_NOACCESS, + &spr_read_generic, &spr_write_booke_pid, + 0x00000000); + } + + spr_register(env, SPR_BOOKE_EPLC, "EPLC", + SPR_NOACCESS, SPR_NOACCESS, + &spr_read_generic, &spr_write_eplc, + 0x00000000); + spr_register(env, SPR_BOOKE_EPSC, "EPSC", + SPR_NOACCESS, SPR_NOACCESS, + &spr_read_generic, &spr_write_epsc, + 0x00000000); + + spr_register(env, SPR_MMUCFG, "MMUCFG", + SPR_NOACCESS, SPR_NOACCESS, + &spr_read_generic, SPR_NOACCESS, + mmucfg); + switch (env->nb_ways) { + case 4: + spr_register(env, SPR_BOOKE_TLB3CFG, "TLB3CFG", + SPR_NOACCESS, SPR_NOACCESS, + &spr_read_generic, SPR_NOACCESS, + tlbncfg[3]); + /* Fallthru */ + case 3: + spr_register(env, SPR_BOOKE_TLB2CFG, "TLB2CFG", + SPR_NOACCESS, SPR_NOACCESS, + &spr_read_generic, SPR_NOACCESS, + tlbncfg[2]); + /* Fallthru */ + case 2: + spr_register(env, SPR_BOOKE_TLB1CFG, "TLB1CFG", + SPR_NOACCESS, SPR_NOACCESS, + &spr_read_generic, SPR_NOACCESS, + tlbncfg[1]); + /* Fallthru */ + case 1: + spr_register(env, SPR_BOOKE_TLB0CFG, "TLB0CFG", + SPR_NOACCESS, SPR_NOACCESS, + &spr_read_generic, SPR_NOACCESS, + tlbncfg[0]); + /* Fallthru */ + case 0: + default: + break; + } +#endif +} + +static void register_440_sprs(CPUPPCState *env) +{ + /* Cache control */ + spr_register(env, SPR_440_DNV0, "DNV0", + SPR_NOACCESS, SPR_NOACCESS, + &spr_read_generic, &spr_write_generic, + 0x00000000); + + spr_register(env, SPR_440_DNV1, "DNV1", + SPR_NOACCESS, SPR_NOACCESS, + &spr_read_generic, &spr_write_generic, + 0x00000000); + + spr_register(env, SPR_440_DNV2, "DNV2", + SPR_NOACCESS, SPR_NOACCESS, + &spr_read_generic, &spr_write_generic, + 0x00000000); + + spr_register(env, SPR_440_DNV3, "DNV3", + SPR_NOACCESS, SPR_NOACCESS, + &spr_read_generic, &spr_write_generic, + 0x00000000); + + spr_register(env, SPR_440_DTV0, "DTV0", + SPR_NOACCESS, SPR_NOACCESS, + &spr_read_generic, &spr_write_generic, + 0x00000000); + + spr_register(env, SPR_440_DTV1, "DTV1", + SPR_NOACCESS, SPR_NOACCESS, + &spr_read_generic, &spr_write_generic, + 0x00000000); + + spr_register(env, SPR_440_DTV2, "DTV2", + SPR_NOACCESS, SPR_NOACCESS, + &spr_read_generic, &spr_write_generic, + 0x00000000); + + spr_register(env, SPR_440_DTV3, "DTV3", + SPR_NOACCESS, SPR_NOACCESS, + &spr_read_generic, &spr_write_generic, + 0x00000000); + + spr_register(env, SPR_440_DVLIM, "DVLIM", + SPR_NOACCESS, SPR_NOACCESS, + &spr_read_generic, &spr_write_generic, + 0x00000000); + + spr_register(env, SPR_440_INV0, "INV0", + SPR_NOACCESS, SPR_NOACCESS, + &spr_read_generic, &spr_write_generic, + 0x00000000); + + spr_register(env, SPR_440_INV1, "INV1", + SPR_NOACCESS, SPR_NOACCESS, + &spr_read_generic, &spr_write_generic, + 0x00000000); + + spr_register(env, SPR_440_INV2, "INV2", + SPR_NOACCESS, SPR_NOACCESS, + &spr_read_generic, &spr_write_generic, + 0x00000000); + + spr_register(env, SPR_440_INV3, "INV3", + SPR_NOACCESS, SPR_NOACCESS, + &spr_read_generic, &spr_write_generic, + 0x00000000); + + spr_register(env, SPR_440_ITV0, "ITV0", + SPR_NOACCESS, SPR_NOACCESS, + &spr_read_generic, &spr_write_generic, + 0x00000000); + + spr_register(env, SPR_440_ITV1, "ITV1", + SPR_NOACCESS, SPR_NOACCESS, + &spr_read_generic, &spr_write_generic, + 0x00000000); + + spr_register(env, SPR_440_ITV2, "ITV2", + SPR_NOACCESS, SPR_NOACCESS, + &spr_read_generic, &spr_write_generic, + 0x00000000); + + spr_register(env, SPR_440_ITV3, "ITV3", + SPR_NOACCESS, SPR_NOACCESS, + &spr_read_generic, &spr_write_generic, + 0x00000000); + + spr_register(env, SPR_440_IVLIM, "IVLIM", + SPR_NOACCESS, SPR_NOACCESS, + &spr_read_generic, &spr_write_generic, + 0x00000000); + /* Cache debug */ + spr_register(env, SPR_BOOKE_DCDBTRH, "DCDBTRH", + SPR_NOACCESS, SPR_NOACCESS, + &spr_read_generic, SPR_NOACCESS, + 0x00000000); + + spr_register(env, SPR_BOOKE_DCDBTRL, "DCDBTRL", + SPR_NOACCESS, SPR_NOACCESS, + &spr_read_generic, SPR_NOACCESS, + 0x00000000); + + spr_register(env, SPR_BOOKE_ICDBDR, "ICDBDR", + SPR_NOACCESS, SPR_NOACCESS, + &spr_read_generic, SPR_NOACCESS, + 0x00000000); + + spr_register(env, SPR_BOOKE_ICDBTRH, "ICDBTRH", + SPR_NOACCESS, SPR_NOACCESS, + &spr_read_generic, SPR_NOACCESS, + 0x00000000); + + spr_register(env, SPR_BOOKE_ICDBTRL, "ICDBTRL", + SPR_NOACCESS, SPR_NOACCESS, + &spr_read_generic, SPR_NOACCESS, + 0x00000000); + + spr_register(env, SPR_440_DBDR, "DBDR", + SPR_NOACCESS, SPR_NOACCESS, + &spr_read_generic, &spr_write_generic, + 0x00000000); + /* Processor control */ + spr_register(env, SPR_4xx_CCR0, "CCR0", + SPR_NOACCESS, SPR_NOACCESS, + &spr_read_generic, &spr_write_generic, + 0x00000000); + spr_register(env, SPR_440_RSTCFG, "RSTCFG", + SPR_NOACCESS, SPR_NOACCESS, + &spr_read_generic, SPR_NOACCESS, + 0x00000000); + /* Storage control */ + spr_register(env, SPR_440_MMUCR, "MMUCR", + SPR_NOACCESS, SPR_NOACCESS, + &spr_read_generic, &spr_write_generic, + 0x00000000); + + /* Processor identification */ + spr_register(env, SPR_BOOKE_PIR, "PIR", + SPR_NOACCESS, SPR_NOACCESS, + &spr_read_generic, &spr_write_pir, + 0x00000000); + + spr_register(env, SPR_BOOKE_IAC3, "IAC3", + SPR_NOACCESS, SPR_NOACCESS, + &spr_read_generic, &spr_write_generic, + 0x00000000); + + spr_register(env, SPR_BOOKE_IAC4, "IAC4", + SPR_NOACCESS, SPR_NOACCESS, + &spr_read_generic, &spr_write_generic, + 0x00000000); + + spr_register(env, SPR_BOOKE_DVC1, "DVC1", + SPR_NOACCESS, SPR_NOACCESS, + &spr_read_generic, &spr_write_generic, + 0x00000000); + + spr_register(env, SPR_BOOKE_DVC2, "DVC2", + SPR_NOACCESS, SPR_NOACCESS, + &spr_read_generic, &spr_write_generic, + 0x00000000); +} + +static void init_excp_e200(CPUPPCState *env, target_ulong ivpr_mask) +{ +#if !defined(CONFIG_USER_ONLY) + env->excp_vectors[POWERPC_EXCP_RESET] = 0x00000FFC; + env->excp_vectors[POWERPC_EXCP_CRITICAL] = 0x00000000; + env->excp_vectors[POWERPC_EXCP_MCHECK] = 0x00000000; + env->excp_vectors[POWERPC_EXCP_DSI] = 0x00000000; + env->excp_vectors[POWERPC_EXCP_ISI] = 0x00000000; + env->excp_vectors[POWERPC_EXCP_EXTERNAL] = 0x00000000; + env->excp_vectors[POWERPC_EXCP_ALIGN] = 0x00000000; + env->excp_vectors[POWERPC_EXCP_PROGRAM] = 0x00000000; + env->excp_vectors[POWERPC_EXCP_FPU] = 0x00000000; + env->excp_vectors[POWERPC_EXCP_SYSCALL] = 0x00000000; + env->excp_vectors[POWERPC_EXCP_APU] = 0x00000000; + env->excp_vectors[POWERPC_EXCP_DECR] = 0x00000000; + env->excp_vectors[POWERPC_EXCP_FIT] = 0x00000000; + env->excp_vectors[POWERPC_EXCP_WDT] = 0x00000000; + env->excp_vectors[POWERPC_EXCP_DTLB] = 0x00000000; + env->excp_vectors[POWERPC_EXCP_ITLB] = 0x00000000; + env->excp_vectors[POWERPC_EXCP_DEBUG] = 0x00000000; + /* + * These two are the same IVOR as POWERPC_EXCP_VPU and + * POWERPC_EXCP_VPUA. We deal with that when dispatching at + * powerpc_excp(). + */ + env->excp_vectors[POWERPC_EXCP_SPEU] = 0x00000000; + env->excp_vectors[POWERPC_EXCP_EFPDI] = 0x00000000; + + env->excp_vectors[POWERPC_EXCP_EFPRI] = 0x00000000; + env->ivor_mask = 0x0000FFF7UL; + env->ivpr_mask = ivpr_mask; + /* Hardware reset vector */ + env->hreset_vector = 0xFFFFFFFCUL; +#endif +} + +static void init_excp_BookE(CPUPPCState *env) +{ +#if !defined(CONFIG_USER_ONLY) + env->excp_vectors[POWERPC_EXCP_CRITICAL] = 0x00000000; + env->excp_vectors[POWERPC_EXCP_MCHECK] = 0x00000000; + env->excp_vectors[POWERPC_EXCP_DSI] = 0x00000000; + env->excp_vectors[POWERPC_EXCP_ISI] = 0x00000000; + env->excp_vectors[POWERPC_EXCP_EXTERNAL] = 0x00000000; + env->excp_vectors[POWERPC_EXCP_ALIGN] = 0x00000000; + env->excp_vectors[POWERPC_EXCP_PROGRAM] = 0x00000000; + env->excp_vectors[POWERPC_EXCP_FPU] = 0x00000000; + env->excp_vectors[POWERPC_EXCP_SYSCALL] = 0x00000000; + env->excp_vectors[POWERPC_EXCP_APU] = 0x00000000; + env->excp_vectors[POWERPC_EXCP_DECR] = 0x00000000; + env->excp_vectors[POWERPC_EXCP_FIT] = 0x00000000; + env->excp_vectors[POWERPC_EXCP_WDT] = 0x00000000; + env->excp_vectors[POWERPC_EXCP_DTLB] = 0x00000000; + env->excp_vectors[POWERPC_EXCP_ITLB] = 0x00000000; + env->excp_vectors[POWERPC_EXCP_DEBUG] = 0x00000000; + env->ivor_mask = 0x0000FFF0UL; + env->ivpr_mask = 0xFFFF0000UL; + /* Hardware reset vector */ + env->hreset_vector = 0xFFFFFFFCUL; +#endif +} + +static void init_proc_440EP(CPUPPCState *env) +{ + register_BookE_sprs(env, 0x000000000000FFFFULL); + register_440_sprs(env); + register_usprgh_sprs(env); + + spr_register(env, SPR_BOOKE_MCSR, "MCSR", + SPR_NOACCESS, SPR_NOACCESS, + &spr_read_generic, &spr_write_generic, + 0x00000000); + spr_register(env, SPR_BOOKE_MCSRR0, "MCSRR0", + SPR_NOACCESS, SPR_NOACCESS, + &spr_read_generic, &spr_write_generic, + 0x00000000); + spr_register(env, SPR_BOOKE_MCSRR1, "MCSRR1", + SPR_NOACCESS, SPR_NOACCESS, + &spr_read_generic, &spr_write_generic, + 0x00000000); + + spr_register(env, SPR_440_CCR1, "CCR1", + SPR_NOACCESS, SPR_NOACCESS, + &spr_read_generic, &spr_write_generic, + 0x00000000); + /* Memory management */ +#if !defined(CONFIG_USER_ONLY) + env->nb_tlb = 64; + env->nb_ways = 1; + env->id_tlbs = 0; + env->tlb_type = TLB_EMB; +#endif + init_excp_BookE(env); + env->dcache_line_size = 32; + env->icache_line_size = 32; + ppc40x_irq_init(env_archcpu(env)); + + SET_FIT_PERIOD(12, 16, 20, 24); + SET_WDT_PERIOD(20, 24, 28, 32); +} + +static void init_proc_440GP(CPUPPCState *env) +{ + register_BookE_sprs(env, 0x000000000000FFFFULL); + register_440_sprs(env); + register_usprgh_sprs(env); + + /* Memory management */ +#if !defined(CONFIG_USER_ONLY) + env->nb_tlb = 64; + env->nb_ways = 1; + env->id_tlbs = 0; + env->tlb_type = TLB_EMB; +#endif + init_excp_BookE(env); + env->dcache_line_size = 32; + env->icache_line_size = 32; + /* XXX: TODO: allocate internal IRQ controller */ + + SET_FIT_PERIOD(12, 16, 20, 24); + SET_WDT_PERIOD(20, 24, 28, 32); +} + +static void init_proc_440x5(CPUPPCState *env) +{ + register_BookE_sprs(env, 0x000000000000FFFFULL); + register_440_sprs(env); + register_usprgh_sprs(env); + + spr_register(env, SPR_BOOKE_MCSR, "MCSR", + SPR_NOACCESS, SPR_NOACCESS, + &spr_read_generic, &spr_write_generic, + 0x00000000); + spr_register(env, SPR_BOOKE_MCSRR0, "MCSRR0", + SPR_NOACCESS, SPR_NOACCESS, + &spr_read_generic, &spr_write_generic, + 0x00000000); + spr_register(env, SPR_BOOKE_MCSRR1, "MCSRR1", + SPR_NOACCESS, SPR_NOACCESS, + &spr_read_generic, &spr_write_generic, + 0x00000000); + + spr_register(env, SPR_440_CCR1, "CCR1", + SPR_NOACCESS, SPR_NOACCESS, + &spr_read_generic, &spr_write_generic, + 0x00000000); + /* Memory management */ +#if !defined(CONFIG_USER_ONLY) + env->nb_tlb = 64; + env->nb_ways = 1; + env->id_tlbs = 0; + env->tlb_type = TLB_EMB; +#endif + init_excp_BookE(env); + env->dcache_line_size = 32; + env->icache_line_size = 32; + ppc40x_irq_init(env_archcpu(env)); + + SET_FIT_PERIOD(12, 16, 20, 24); + SET_WDT_PERIOD(20, 24, 28, 32); +} + +static void init_proc_e200(CPUPPCState *env) +{ + register_BookE_sprs(env, 0x000000070000FFFFULL); + + spr_register(env, SPR_BOOKE_SPEFSCR, "SPEFSCR", + &spr_read_spefscr, &spr_write_spefscr, + &spr_read_spefscr, &spr_write_spefscr, + 0x00000000); + /* Memory management */ + register_BookE206_sprs(env, 0x0000005D, NULL, 0); + register_usprgh_sprs(env); + + spr_register(env, SPR_HID0, "HID0", + SPR_NOACCESS, SPR_NOACCESS, + &spr_read_generic, &spr_write_generic, + 0x00000000); + + spr_register(env, SPR_HID1, "HID1", + SPR_NOACCESS, SPR_NOACCESS, + &spr_read_generic, &spr_write_generic, + 0x00000000); + + spr_register(env, SPR_Exxx_ALTCTXCR, "ALTCTXCR", + SPR_NOACCESS, SPR_NOACCESS, + &spr_read_generic, &spr_write_generic, + 0x00000000); + + spr_register(env, SPR_Exxx_BUCSR, "BUCSR", + SPR_NOACCESS, SPR_NOACCESS, + &spr_read_generic, &spr_write_generic, + 0x00000000); + + spr_register(env, SPR_Exxx_CTXCR, "CTXCR", + SPR_NOACCESS, SPR_NOACCESS, + &spr_read_generic, &spr_write_generic, + 0x00000000); + + spr_register(env, SPR_Exxx_DBCNT, "DBCNT", + SPR_NOACCESS, SPR_NOACCESS, + &spr_read_generic, &spr_write_generic, + 0x00000000); + + spr_register(env, SPR_Exxx_DBCR3, "DBCR3", + SPR_NOACCESS, SPR_NOACCESS, + &spr_read_generic, &spr_write_generic, + 0x00000000); + + spr_register(env, SPR_Exxx_L1CFG0, "L1CFG0", + &spr_read_generic, SPR_NOACCESS, + &spr_read_generic, SPR_NOACCESS, + 0x00000000); + + spr_register(env, SPR_Exxx_L1CSR0, "L1CSR0", + SPR_NOACCESS, SPR_NOACCESS, + &spr_read_generic, &spr_write_generic, + 0x00000000); + + spr_register(env, SPR_Exxx_L1FINV0, "L1FINV0", + SPR_NOACCESS, SPR_NOACCESS, + &spr_read_generic, &spr_write_generic, + 0x00000000); + + spr_register(env, SPR_BOOKE_TLB0CFG, "TLB0CFG", + SPR_NOACCESS, SPR_NOACCESS, + &spr_read_generic, &spr_write_generic, + 0x00000000); + + spr_register(env, SPR_BOOKE_TLB1CFG, "TLB1CFG", + SPR_NOACCESS, SPR_NOACCESS, + &spr_read_generic, &spr_write_generic, + 0x00000000); + + spr_register(env, SPR_BOOKE_IAC3, "IAC3", + SPR_NOACCESS, SPR_NOACCESS, + &spr_read_generic, &spr_write_generic, + 0x00000000); + + spr_register(env, SPR_BOOKE_IAC4, "IAC4", + SPR_NOACCESS, SPR_NOACCESS, + &spr_read_generic, &spr_write_generic, + 0x00000000); + + spr_register(env, SPR_MMUCSR0, "MMUCSR0", + SPR_NOACCESS, SPR_NOACCESS, + &spr_read_generic, &spr_write_generic, + 0x00000000); /* TOFIX */ + spr_register(env, SPR_BOOKE_DSRR0, "DSRR0", + SPR_NOACCESS, SPR_NOACCESS, + &spr_read_generic, &spr_write_generic, + 0x00000000); + spr_register(env, SPR_BOOKE_DSRR1, "DSRR1", + SPR_NOACCESS, SPR_NOACCESS, + &spr_read_generic, &spr_write_generic, + 0x00000000); +#if !defined(CONFIG_USER_ONLY) + env->nb_tlb = 64; + env->nb_ways = 1; + env->id_tlbs = 0; + env->tlb_type = TLB_EMB; +#endif + init_excp_e200(env, 0xFFFF0000UL); + env->dcache_line_size = 32; + env->icache_line_size = 32; + /* XXX: TODO: allocate internal IRQ controller */ +} + +enum fsl_e500_version { + fsl_e500v1, + fsl_e500v2, + fsl_e500mc, + fsl_e5500, + fsl_e6500, +}; + +static void init_proc_e500(CPUPPCState *env, int version) +{ + uint32_t tlbncfg[2]; + uint64_t ivor_mask; + uint64_t ivpr_mask = 0xFFFF0000ULL; + uint32_t l1cfg0 = 0x3800 /* 8 ways */ + | 0x0020; /* 32 kb */ + uint32_t l1cfg1 = 0x3800 /* 8 ways */ + | 0x0020; /* 32 kb */ + uint32_t mmucfg = 0; +#if !defined(CONFIG_USER_ONLY) + int i; +#endif + + /* + * XXX The e500 doesn't implement IVOR7 and IVOR9, but doesn't + * complain when accessing them. + * register_BookE_sprs(env, 0x0000000F0000FD7FULL); + */ + switch (version) { + case fsl_e500v1: + case fsl_e500v2: + default: + ivor_mask = 0x0000000F0000FFFFULL; + break; + case fsl_e500mc: + case fsl_e5500: + ivor_mask = 0x000003FE0000FFFFULL; + break; + case fsl_e6500: + ivor_mask = 0x000003FF0000FFFFULL; + break; + } + register_BookE_sprs(env, ivor_mask); + + spr_register(env, SPR_USPRG3, "USPRG3", + &spr_read_ureg, SPR_NOACCESS, + &spr_read_ureg, SPR_NOACCESS, + 0x00000000); + + /* Processor identification */ + spr_register(env, SPR_BOOKE_PIR, "PIR", + SPR_NOACCESS, SPR_NOACCESS, + &spr_read_generic, &spr_write_pir, + 0x00000000); + + spr_register(env, SPR_BOOKE_SPEFSCR, "SPEFSCR", + &spr_read_spefscr, &spr_write_spefscr, + &spr_read_spefscr, &spr_write_spefscr, + 0x00000000); +#if !defined(CONFIG_USER_ONLY) + /* Memory management */ + env->nb_pids = 3; + env->nb_ways = 2; + env->id_tlbs = 0; + switch (version) { + case fsl_e500v1: + tlbncfg[0] = register_tlbncfg(2, 1, 1, 0, 256); + tlbncfg[1] = register_tlbncfg(16, 1, 9, TLBnCFG_AVAIL | TLBnCFG_IPROT, 16); + break; + case fsl_e500v2: + tlbncfg[0] = register_tlbncfg(4, 1, 1, 0, 512); + tlbncfg[1] = register_tlbncfg(16, 1, 12, TLBnCFG_AVAIL | TLBnCFG_IPROT, 16); + break; + case fsl_e500mc: + case fsl_e5500: + tlbncfg[0] = register_tlbncfg(4, 1, 1, 0, 512); + tlbncfg[1] = register_tlbncfg(64, 1, 12, TLBnCFG_AVAIL | TLBnCFG_IPROT, 64); + break; + case fsl_e6500: + mmucfg = 0x6510B45; + env->nb_pids = 1; + tlbncfg[0] = 0x08052400; + tlbncfg[1] = 0x40028040; + break; + default: + cpu_abort(env_cpu(env), "Unknown CPU: " TARGET_FMT_lx "\n", + env->spr[SPR_PVR]); + } +#endif + /* Cache sizes */ + switch (version) { + case fsl_e500v1: + case fsl_e500v2: + env->dcache_line_size = 32; + env->icache_line_size = 32; + break; + case fsl_e500mc: + case fsl_e5500: + env->dcache_line_size = 64; + env->icache_line_size = 64; + l1cfg0 |= 0x1000000; /* 64 byte cache block size */ + l1cfg1 |= 0x1000000; /* 64 byte cache block size */ + break; + case fsl_e6500: + env->dcache_line_size = 32; + env->icache_line_size = 32; + l1cfg0 |= 0x0F83820; + l1cfg1 |= 0x0B83820; + break; + default: + cpu_abort(env_cpu(env), "Unknown CPU: " TARGET_FMT_lx "\n", + env->spr[SPR_PVR]); + } + register_BookE206_sprs(env, 0x000000DF, tlbncfg, mmucfg); + register_usprgh_sprs(env); + + spr_register(env, SPR_HID0, "HID0", + SPR_NOACCESS, SPR_NOACCESS, + &spr_read_generic, &spr_write_generic, + 0x00000000); + + spr_register(env, SPR_HID1, "HID1", + SPR_NOACCESS, SPR_NOACCESS, + &spr_read_generic, &spr_write_generic, + 0x00000000); + + spr_register(env, SPR_Exxx_BBEAR, "BBEAR", + SPR_NOACCESS, SPR_NOACCESS, + &spr_read_generic, &spr_write_generic, + 0x00000000); + + spr_register(env, SPR_Exxx_BBTAR, "BBTAR", + SPR_NOACCESS, SPR_NOACCESS, + &spr_read_generic, &spr_write_generic, + 0x00000000); + + spr_register(env, SPR_Exxx_MCAR, "MCAR", + SPR_NOACCESS, SPR_NOACCESS, + &spr_read_generic, &spr_write_generic, + 0x00000000); + + spr_register(env, SPR_BOOKE_MCSR, "MCSR", + SPR_NOACCESS, SPR_NOACCESS, + &spr_read_generic, &spr_write_generic, + 0x00000000); + + spr_register(env, SPR_Exxx_NPIDR, "NPIDR", + SPR_NOACCESS, SPR_NOACCESS, + &spr_read_generic, &spr_write_generic, + 0x00000000); + + spr_register(env, SPR_Exxx_BUCSR, "BUCSR", + SPR_NOACCESS, SPR_NOACCESS, + &spr_read_generic, &spr_write_generic, + 0x00000000); + + spr_register(env, SPR_Exxx_L1CFG0, "L1CFG0", + &spr_read_generic, SPR_NOACCESS, + &spr_read_generic, SPR_NOACCESS, + l1cfg0); + spr_register(env, SPR_Exxx_L1CFG1, "L1CFG1", + &spr_read_generic, SPR_NOACCESS, + &spr_read_generic, SPR_NOACCESS, + l1cfg1); + spr_register(env, SPR_Exxx_L1CSR0, "L1CSR0", + SPR_NOACCESS, SPR_NOACCESS, + &spr_read_generic, &spr_write_e500_l1csr0, + 0x00000000); + spr_register(env, SPR_Exxx_L1CSR1, "L1CSR1", + SPR_NOACCESS, SPR_NOACCESS, + &spr_read_generic, &spr_write_e500_l1csr1, + 0x00000000); + if (version != fsl_e500v1 && version != fsl_e500v2) { + spr_register(env, SPR_Exxx_L2CSR0, "L2CSR0", + SPR_NOACCESS, SPR_NOACCESS, + &spr_read_generic, &spr_write_e500_l2csr0, + 0x00000000); + } + spr_register(env, SPR_BOOKE_MCSRR0, "MCSRR0", + SPR_NOACCESS, SPR_NOACCESS, + &spr_read_generic, &spr_write_generic, + 0x00000000); + spr_register(env, SPR_BOOKE_MCSRR1, "MCSRR1", + SPR_NOACCESS, SPR_NOACCESS, + &spr_read_generic, &spr_write_generic, + 0x00000000); + spr_register(env, SPR_MMUCSR0, "MMUCSR0", + SPR_NOACCESS, SPR_NOACCESS, + &spr_read_generic, &spr_write_booke206_mmucsr0, + 0x00000000); + spr_register(env, SPR_BOOKE_EPR, "EPR", + SPR_NOACCESS, SPR_NOACCESS, + &spr_read_generic, SPR_NOACCESS, + 0x00000000); + /* XXX better abstract into Emb.xxx features */ + if ((version == fsl_e5500) || (version == fsl_e6500)) { + spr_register(env, SPR_BOOKE_EPCR, "EPCR", + SPR_NOACCESS, SPR_NOACCESS, + &spr_read_generic, &spr_write_generic, + 0x00000000); + spr_register(env, SPR_BOOKE_MAS7_MAS3, "MAS7_MAS3", + SPR_NOACCESS, SPR_NOACCESS, + &spr_read_mas73, &spr_write_mas73, + 0x00000000); + ivpr_mask = (target_ulong)~0xFFFFULL; + } + + if (version == fsl_e6500) { + /* Thread identification */ + spr_register(env, SPR_TIR, "TIR", + SPR_NOACCESS, SPR_NOACCESS, + &spr_read_generic, SPR_NOACCESS, + 0x00000000); + spr_register(env, SPR_BOOKE_TLB0PS, "TLB0PS", + SPR_NOACCESS, SPR_NOACCESS, + &spr_read_generic, SPR_NOACCESS, + 0x00000004); + spr_register(env, SPR_BOOKE_TLB1PS, "TLB1PS", + SPR_NOACCESS, SPR_NOACCESS, + &spr_read_generic, SPR_NOACCESS, + 0x7FFFFFFC); + } + +#if !defined(CONFIG_USER_ONLY) + env->nb_tlb = 0; + env->tlb_type = TLB_MAS; + for (i = 0; i < BOOKE206_MAX_TLBN; i++) { + env->nb_tlb += booke206_tlb_size(env, i); + } +#endif + + init_excp_e200(env, ivpr_mask); + /* Allocate hardware IRQ controller */ + ppce500_irq_init(env_archcpu(env)); +} + +static void init_proc_e500v1(CPUPPCState *env) +{ + init_proc_e500(env, fsl_e500v1); +} + +static void init_proc_e500v2(CPUPPCState *env) +{ + init_proc_e500(env, fsl_e500v2); +} + +static void init_proc_e500mc(CPUPPCState *env) +{ + init_proc_e500(env, fsl_e500mc); +} + +#ifdef TARGET_PPC64 +static void init_proc_e5500(CPUPPCState *env) +{ + init_proc_e500(env, fsl_e5500); +} + +static void init_proc_e6500(CPUPPCState *env) +{ + init_proc_e500(env, fsl_e6500); +} +#endif + +POWERPC_FAMILY(440EP)(ObjectClass *oc, void *data) +{ + DeviceClass *dc = DEVICE_CLASS(oc); + PowerPCCPUClass *pcc = POWERPC_CPU_CLASS(oc); + + dc->desc = "PowerPC 440 EP"; + pcc->init_proc = init_proc_440EP; + pcc->check_pow = check_pow_nocheck; + pcc->insns_flags = PPC_INSNS_BASE | PPC_STRING | + PPC_FLOAT | PPC_FLOAT_FRES | PPC_FLOAT_FSEL | + PPC_FLOAT_FSQRT | PPC_FLOAT_FRSQRTE | + PPC_FLOAT_STFIWX | + PPC_DCR | PPC_WRTEE | PPC_RFMCI | + PPC_CACHE | PPC_CACHE_ICBI | + PPC_CACHE_DCBZ | PPC_CACHE_DCBA | + PPC_MEM_TLBSYNC | PPC_MFTB | + PPC_BOOKE | PPC_4xx_COMMON | PPC_405_MAC | + PPC_440_SPEC; + pcc->msr_mask = (1ull << MSR_POW) | + (1ull << MSR_CE) | + (1ull << MSR_EE) | + (1ull << MSR_PR) | + (1ull << MSR_FP) | + (1ull << MSR_ME) | + (1ull << MSR_FE0) | + (1ull << MSR_DWE) | + (1ull << MSR_DE) | + (1ull << MSR_FE1) | + (1ull << MSR_IR) | + (1ull << MSR_DR); + pcc->mmu_model = POWERPC_MMU_BOOKE; + pcc->excp_model = POWERPC_EXCP_BOOKE; + pcc->bus_model = PPC_FLAGS_INPUT_BookE; + pcc->bfd_mach = bfd_mach_ppc_403; + pcc->flags = POWERPC_FLAG_CE | POWERPC_FLAG_DWE | + POWERPC_FLAG_DE | POWERPC_FLAG_BUS_CLK; +} + +POWERPC_FAMILY(460EX)(ObjectClass *oc, void *data) +{ + DeviceClass *dc = DEVICE_CLASS(oc); + PowerPCCPUClass *pcc = POWERPC_CPU_CLASS(oc); + + dc->desc = "PowerPC 460 EX"; + pcc->init_proc = init_proc_440EP; + pcc->check_pow = check_pow_nocheck; + pcc->insns_flags = PPC_INSNS_BASE | PPC_STRING | + PPC_FLOAT | PPC_FLOAT_FRES | PPC_FLOAT_FSEL | + PPC_FLOAT_FSQRT | PPC_FLOAT_FRSQRTE | + PPC_FLOAT_STFIWX | + PPC_DCR | PPC_DCRX | PPC_WRTEE | PPC_RFMCI | + PPC_CACHE | PPC_CACHE_ICBI | + PPC_CACHE_DCBZ | PPC_CACHE_DCBA | + PPC_MEM_TLBSYNC | PPC_MFTB | + PPC_BOOKE | PPC_4xx_COMMON | PPC_405_MAC | + PPC_440_SPEC; + pcc->msr_mask = (1ull << MSR_POW) | + (1ull << MSR_CE) | + (1ull << MSR_EE) | + (1ull << MSR_PR) | + (1ull << MSR_FP) | + (1ull << MSR_ME) | + (1ull << MSR_FE0) | + (1ull << MSR_DWE) | + (1ull << MSR_DE) | + (1ull << MSR_FE1) | + (1ull << MSR_IR) | + (1ull << MSR_DR); + pcc->mmu_model = POWERPC_MMU_BOOKE; + pcc->excp_model = POWERPC_EXCP_BOOKE; + pcc->bus_model = PPC_FLAGS_INPUT_BookE; + pcc->bfd_mach = bfd_mach_ppc_403; + pcc->flags = POWERPC_FLAG_CE | POWERPC_FLAG_DWE | + POWERPC_FLAG_DE | POWERPC_FLAG_BUS_CLK; +} + +POWERPC_FAMILY(440GP)(ObjectClass *oc, void *data) +{ + DeviceClass *dc = DEVICE_CLASS(oc); + PowerPCCPUClass *pcc = POWERPC_CPU_CLASS(oc); + + dc->desc = "PowerPC 440 GP"; + pcc->init_proc = init_proc_440GP; + pcc->check_pow = check_pow_nocheck; + pcc->insns_flags = PPC_INSNS_BASE | PPC_STRING | + PPC_DCR | PPC_DCRX | PPC_WRTEE | PPC_MFAPIDI | + PPC_CACHE | PPC_CACHE_ICBI | + PPC_CACHE_DCBZ | PPC_CACHE_DCBA | + PPC_MEM_TLBSYNC | PPC_TLBIVA | PPC_MFTB | + PPC_BOOKE | PPC_4xx_COMMON | PPC_405_MAC | + PPC_440_SPEC; + pcc->msr_mask = (1ull << MSR_POW) | + (1ull << MSR_CE) | + (1ull << MSR_EE) | + (1ull << MSR_PR) | + (1ull << MSR_FP) | + (1ull << MSR_ME) | + (1ull << MSR_FE0) | + (1ull << MSR_DWE) | + (1ull << MSR_DE) | + (1ull << MSR_FE1) | + (1ull << MSR_IR) | + (1ull << MSR_DR); + pcc->mmu_model = POWERPC_MMU_BOOKE; + pcc->excp_model = POWERPC_EXCP_BOOKE; + pcc->bus_model = PPC_FLAGS_INPUT_BookE; + pcc->bfd_mach = bfd_mach_ppc_403; + pcc->flags = POWERPC_FLAG_CE | POWERPC_FLAG_DWE | + POWERPC_FLAG_DE | POWERPC_FLAG_BUS_CLK; +} + +POWERPC_FAMILY(440x5)(ObjectClass *oc, void *data) +{ + DeviceClass *dc = DEVICE_CLASS(oc); + PowerPCCPUClass *pcc = POWERPC_CPU_CLASS(oc); + + dc->desc = "PowerPC 440x5"; + pcc->init_proc = init_proc_440x5; + pcc->check_pow = check_pow_nocheck; + pcc->insns_flags = PPC_INSNS_BASE | PPC_STRING | + PPC_DCR | PPC_WRTEE | PPC_RFMCI | + PPC_CACHE | PPC_CACHE_ICBI | + PPC_CACHE_DCBZ | PPC_CACHE_DCBA | + PPC_MEM_TLBSYNC | PPC_MFTB | + PPC_BOOKE | PPC_4xx_COMMON | PPC_405_MAC | + PPC_440_SPEC; + pcc->msr_mask = (1ull << MSR_POW) | + (1ull << MSR_CE) | + (1ull << MSR_EE) | + (1ull << MSR_PR) | + (1ull << MSR_FP) | + (1ull << MSR_ME) | + (1ull << MSR_FE0) | + (1ull << MSR_DWE) | + (1ull << MSR_DE) | + (1ull << MSR_FE1) | + (1ull << MSR_IR) | + (1ull << MSR_DR); + pcc->mmu_model = POWERPC_MMU_BOOKE; + pcc->excp_model = POWERPC_EXCP_BOOKE; + pcc->bus_model = PPC_FLAGS_INPUT_BookE; + pcc->bfd_mach = bfd_mach_ppc_403; + pcc->flags = POWERPC_FLAG_CE | POWERPC_FLAG_DWE | + POWERPC_FLAG_DE | POWERPC_FLAG_BUS_CLK; +} + +POWERPC_FAMILY(440x5wDFPU)(ObjectClass *oc, void *data) +{ + DeviceClass *dc = DEVICE_CLASS(oc); + PowerPCCPUClass *pcc = POWERPC_CPU_CLASS(oc); + + dc->desc = "PowerPC 440x5 with double precision FPU"; + pcc->init_proc = init_proc_440x5; + pcc->check_pow = check_pow_nocheck; + pcc->insns_flags = PPC_INSNS_BASE | PPC_STRING | + PPC_FLOAT | PPC_FLOAT_FSQRT | + PPC_FLOAT_STFIWX | + PPC_DCR | PPC_WRTEE | PPC_RFMCI | + PPC_CACHE | PPC_CACHE_ICBI | + PPC_CACHE_DCBZ | PPC_CACHE_DCBA | + PPC_MEM_TLBSYNC | PPC_MFTB | + PPC_BOOKE | PPC_4xx_COMMON | PPC_405_MAC | + PPC_440_SPEC; + pcc->insns_flags2 = PPC2_FP_CVT_S64; + pcc->msr_mask = (1ull << MSR_POW) | + (1ull << MSR_CE) | + (1ull << MSR_EE) | + (1ull << MSR_PR) | + (1ull << MSR_FP) | + (1ull << MSR_ME) | + (1ull << MSR_FE0) | + (1ull << MSR_DWE) | + (1ull << MSR_DE) | + (1ull << MSR_FE1) | + (1ull << MSR_IR) | + (1ull << MSR_DR); + pcc->mmu_model = POWERPC_MMU_BOOKE; + pcc->excp_model = POWERPC_EXCP_BOOKE; + pcc->bus_model = PPC_FLAGS_INPUT_BookE; + pcc->bfd_mach = bfd_mach_ppc_403; + pcc->flags = POWERPC_FLAG_CE | POWERPC_FLAG_DWE | + POWERPC_FLAG_DE | POWERPC_FLAG_BUS_CLK; +} + +POWERPC_FAMILY(e200)(ObjectClass *oc, void *data) +{ + DeviceClass *dc = DEVICE_CLASS(oc); + PowerPCCPUClass *pcc = POWERPC_CPU_CLASS(oc); + + dc->desc = "e200 core"; + pcc->init_proc = init_proc_e200; + pcc->check_pow = check_pow_hid0; + /* + * XXX: unimplemented instructions: + * dcblc + * dcbtlst + * dcbtstls + * icblc + * icbtls + * tlbivax + * all SPE multiply-accumulate instructions + */ + pcc->insns_flags = PPC_INSNS_BASE | PPC_ISEL | + PPC_SPE | PPC_SPE_SINGLE | + PPC_WRTEE | PPC_RFDI | + PPC_CACHE | PPC_CACHE_LOCK | PPC_CACHE_ICBI | + PPC_CACHE_DCBZ | PPC_CACHE_DCBA | + PPC_MEM_TLBSYNC | PPC_TLBIVAX | + PPC_BOOKE; + pcc->msr_mask = (1ull << MSR_UCLE) | + (1ull << MSR_SPE) | + (1ull << MSR_POW) | + (1ull << MSR_CE) | + (1ull << MSR_EE) | + (1ull << MSR_PR) | + (1ull << MSR_FP) | + (1ull << MSR_ME) | + (1ull << MSR_FE0) | + (1ull << MSR_DWE) | + (1ull << MSR_DE) | + (1ull << MSR_FE1) | + (1ull << MSR_IR) | + (1ull << MSR_DR); + pcc->mmu_model = POWERPC_MMU_BOOKE206; + pcc->excp_model = POWERPC_EXCP_BOOKE; + pcc->bus_model = PPC_FLAGS_INPUT_BookE; + pcc->bfd_mach = bfd_mach_ppc_860; + pcc->flags = POWERPC_FLAG_SPE | POWERPC_FLAG_CE | + POWERPC_FLAG_UBLE | POWERPC_FLAG_DE | + POWERPC_FLAG_BUS_CLK; +} + +POWERPC_FAMILY(e500v1)(ObjectClass *oc, void *data) +{ + DeviceClass *dc = DEVICE_CLASS(oc); + PowerPCCPUClass *pcc = POWERPC_CPU_CLASS(oc); + + dc->desc = "e500v1 core"; + pcc->init_proc = init_proc_e500v1; + pcc->check_pow = check_pow_hid0; + pcc->insns_flags = PPC_INSNS_BASE | PPC_ISEL | + PPC_SPE | PPC_SPE_SINGLE | + PPC_WRTEE | PPC_RFDI | + PPC_CACHE | PPC_CACHE_LOCK | PPC_CACHE_ICBI | + PPC_CACHE_DCBZ | PPC_CACHE_DCBA | + PPC_MEM_TLBSYNC | PPC_TLBIVAX | PPC_MEM_SYNC; + pcc->insns_flags2 = PPC2_BOOKE206; + pcc->msr_mask = (1ull << MSR_UCLE) | + (1ull << MSR_SPE) | + (1ull << MSR_POW) | + (1ull << MSR_CE) | + (1ull << MSR_EE) | + (1ull << MSR_PR) | + (1ull << MSR_FP) | + (1ull << MSR_ME) | + (1ull << MSR_FE0) | + (1ull << MSR_DWE) | + (1ull << MSR_DE) | + (1ull << MSR_FE1) | + (1ull << MSR_IR) | + (1ull << MSR_DR); + pcc->mmu_model = POWERPC_MMU_BOOKE206; + pcc->excp_model = POWERPC_EXCP_BOOKE; + pcc->bus_model = PPC_FLAGS_INPUT_BookE; + pcc->bfd_mach = bfd_mach_ppc_860; + pcc->flags = POWERPC_FLAG_SPE | POWERPC_FLAG_CE | + POWERPC_FLAG_UBLE | POWERPC_FLAG_DE | + POWERPC_FLAG_BUS_CLK; +} + +POWERPC_FAMILY(e500v2)(ObjectClass *oc, void *data) +{ + DeviceClass *dc = DEVICE_CLASS(oc); + PowerPCCPUClass *pcc = POWERPC_CPU_CLASS(oc); + + dc->desc = "e500v2 core"; + pcc->init_proc = init_proc_e500v2; + pcc->check_pow = check_pow_hid0; + pcc->insns_flags = PPC_INSNS_BASE | PPC_ISEL | + PPC_SPE | PPC_SPE_SINGLE | PPC_SPE_DOUBLE | + PPC_WRTEE | PPC_RFDI | + PPC_CACHE | PPC_CACHE_LOCK | PPC_CACHE_ICBI | + PPC_CACHE_DCBZ | PPC_CACHE_DCBA | + PPC_MEM_TLBSYNC | PPC_TLBIVAX | PPC_MEM_SYNC; + pcc->insns_flags2 = PPC2_BOOKE206; + pcc->msr_mask = (1ull << MSR_UCLE) | + (1ull << MSR_SPE) | + (1ull << MSR_POW) | + (1ull << MSR_CE) | + (1ull << MSR_EE) | + (1ull << MSR_PR) | + (1ull << MSR_FP) | + (1ull << MSR_ME) | + (1ull << MSR_FE0) | + (1ull << MSR_DWE) | + (1ull << MSR_DE) | + (1ull << MSR_FE1) | + (1ull << MSR_IR) | + (1ull << MSR_DR); + pcc->mmu_model = POWERPC_MMU_BOOKE206; + pcc->excp_model = POWERPC_EXCP_BOOKE; + pcc->bus_model = PPC_FLAGS_INPUT_BookE; + pcc->bfd_mach = bfd_mach_ppc_860; + pcc->flags = POWERPC_FLAG_SPE | POWERPC_FLAG_CE | + POWERPC_FLAG_UBLE | POWERPC_FLAG_DE | + POWERPC_FLAG_BUS_CLK; +} + +POWERPC_FAMILY(e500mc)(ObjectClass *oc, void *data) +{ + DeviceClass *dc = DEVICE_CLASS(oc); + PowerPCCPUClass *pcc = POWERPC_CPU_CLASS(oc); + + dc->desc = "e500mc core"; + pcc->init_proc = init_proc_e500mc; + pcc->check_pow = check_pow_none; + pcc->insns_flags = PPC_INSNS_BASE | PPC_ISEL | PPC_MFTB | + PPC_WRTEE | PPC_RFDI | PPC_RFMCI | + PPC_CACHE | PPC_CACHE_LOCK | PPC_CACHE_ICBI | + PPC_CACHE_DCBZ | PPC_CACHE_DCBA | + PPC_FLOAT | PPC_FLOAT_FRES | + PPC_FLOAT_FRSQRTE | PPC_FLOAT_FSEL | + PPC_FLOAT_STFIWX | PPC_WAIT | + PPC_MEM_TLBSYNC | PPC_TLBIVAX | PPC_MEM_SYNC; + pcc->insns_flags2 = PPC2_BOOKE206 | PPC2_PRCNTL; + pcc->msr_mask = (1ull << MSR_GS) | + (1ull << MSR_UCLE) | + (1ull << MSR_CE) | + (1ull << MSR_EE) | + (1ull << MSR_PR) | + (1ull << MSR_FP) | + (1ull << MSR_ME) | + (1ull << MSR_FE0) | + (1ull << MSR_DE) | + (1ull << MSR_FE1) | + (1ull << MSR_IR) | + (1ull << MSR_DR) | + (1ull << MSR_PX) | + (1ull << MSR_RI); + pcc->mmu_model = POWERPC_MMU_BOOKE206; + pcc->excp_model = POWERPC_EXCP_BOOKE; + pcc->bus_model = PPC_FLAGS_INPUT_BookE; + /* FIXME: figure out the correct flag for e500mc */ + pcc->bfd_mach = bfd_mach_ppc_e500; + pcc->flags = POWERPC_FLAG_CE | POWERPC_FLAG_DE | + POWERPC_FLAG_PMM | POWERPC_FLAG_BUS_CLK; +} + +#ifdef TARGET_PPC64 +POWERPC_FAMILY(e5500)(ObjectClass *oc, void *data) +{ + DeviceClass *dc = DEVICE_CLASS(oc); + PowerPCCPUClass *pcc = POWERPC_CPU_CLASS(oc); + + dc->desc = "e5500 core"; + pcc->init_proc = init_proc_e5500; + pcc->check_pow = check_pow_none; + pcc->insns_flags = PPC_INSNS_BASE | PPC_ISEL | PPC_MFTB | + PPC_WRTEE | PPC_RFDI | PPC_RFMCI | + PPC_CACHE | PPC_CACHE_LOCK | PPC_CACHE_ICBI | + PPC_CACHE_DCBZ | PPC_CACHE_DCBA | + PPC_FLOAT | PPC_FLOAT_FRES | + PPC_FLOAT_FRSQRTE | PPC_FLOAT_FSEL | + PPC_FLOAT_STFIWX | PPC_WAIT | + PPC_MEM_TLBSYNC | PPC_TLBIVAX | PPC_MEM_SYNC | + PPC_64B | PPC_POPCNTB | PPC_POPCNTWD; + pcc->insns_flags2 = PPC2_BOOKE206 | PPC2_PRCNTL | PPC2_PERM_ISA206 | + PPC2_FP_CVT_S64; + pcc->msr_mask = (1ull << MSR_CM) | + (1ull << MSR_GS) | + (1ull << MSR_UCLE) | + (1ull << MSR_CE) | + (1ull << MSR_EE) | + (1ull << MSR_PR) | + (1ull << MSR_FP) | + (1ull << MSR_ME) | + (1ull << MSR_FE0) | + (1ull << MSR_DE) | + (1ull << MSR_FE1) | + (1ull << MSR_IR) | + (1ull << MSR_DR) | + (1ull << MSR_PX) | + (1ull << MSR_RI); + pcc->mmu_model = POWERPC_MMU_BOOKE206; + pcc->excp_model = POWERPC_EXCP_BOOKE; + pcc->bus_model = PPC_FLAGS_INPUT_BookE; + /* FIXME: figure out the correct flag for e5500 */ + pcc->bfd_mach = bfd_mach_ppc_e500; + pcc->flags = POWERPC_FLAG_CE | POWERPC_FLAG_DE | + POWERPC_FLAG_PMM | POWERPC_FLAG_BUS_CLK; +} + +POWERPC_FAMILY(e6500)(ObjectClass *oc, void *data) +{ + DeviceClass *dc = DEVICE_CLASS(oc); + PowerPCCPUClass *pcc = POWERPC_CPU_CLASS(oc); + + dc->desc = "e6500 core"; + pcc->init_proc = init_proc_e6500; + pcc->check_pow = check_pow_none; + pcc->insns_flags = PPC_INSNS_BASE | PPC_ISEL | PPC_MFTB | + PPC_WRTEE | PPC_RFDI | PPC_RFMCI | + PPC_CACHE | PPC_CACHE_LOCK | PPC_CACHE_ICBI | + PPC_CACHE_DCBZ | PPC_CACHE_DCBA | + PPC_FLOAT | PPC_FLOAT_FRES | + PPC_FLOAT_FRSQRTE | PPC_FLOAT_FSEL | + PPC_FLOAT_STFIWX | PPC_WAIT | + PPC_MEM_TLBSYNC | PPC_TLBIVAX | PPC_MEM_SYNC | + PPC_64B | PPC_POPCNTB | PPC_POPCNTWD | PPC_ALTIVEC; + pcc->insns_flags2 = PPC2_BOOKE206 | PPC2_PRCNTL | PPC2_PERM_ISA206 | + PPC2_FP_CVT_S64 | PPC2_ATOMIC_ISA206; + pcc->msr_mask = (1ull << MSR_CM) | + (1ull << MSR_GS) | + (1ull << MSR_UCLE) | + (1ull << MSR_CE) | + (1ull << MSR_EE) | + (1ull << MSR_PR) | + (1ull << MSR_FP) | + (1ull << MSR_ME) | + (1ull << MSR_FE0) | + (1ull << MSR_DE) | + (1ull << MSR_FE1) | + (1ull << MSR_IS) | + (1ull << MSR_DS) | + (1ull << MSR_PX) | + (1ull << MSR_RI) | + (1ull << MSR_VR); + pcc->mmu_model = POWERPC_MMU_BOOKE206; + pcc->excp_model = POWERPC_EXCP_BOOKE; + pcc->bus_model = PPC_FLAGS_INPUT_BookE; + pcc->bfd_mach = bfd_mach_ppc_e500; + pcc->flags = POWERPC_FLAG_CE | POWERPC_FLAG_DE | + POWERPC_FLAG_PMM | POWERPC_FLAG_BUS_CLK | POWERPC_FLAG_VRE; +} +#endif diff --git a/target/ppc/cpu_init.c b/target/ppc/cpu_init.c index 397a93aa4b..95e29e5e6b 100644 --- a/target/ppc/cpu_init.c +++ b/target/ppc/cpu_init.c @@ -102,442 +102,6 @@ static void register_iamr_sprs(CPUPPCState *env) } #endif /* TARGET_PPC64 */ -/* PowerPC BookE SPR */ -static void register_BookE_sprs(CPUPPCState *env, uint64_t ivor_mask) -{ - const char *ivor_names[64] = { - "IVOR0", "IVOR1", "IVOR2", "IVOR3", - "IVOR4", "IVOR5", "IVOR6", "IVOR7", - "IVOR8", "IVOR9", "IVOR10", "IVOR11", - "IVOR12", "IVOR13", "IVOR14", "IVOR15", - "IVOR16", "IVOR17", "IVOR18", "IVOR19", - "IVOR20", "IVOR21", "IVOR22", "IVOR23", - "IVOR24", "IVOR25", "IVOR26", "IVOR27", - "IVOR28", "IVOR29", "IVOR30", "IVOR31", - "IVOR32", "IVOR33", "IVOR34", "IVOR35", - "IVOR36", "IVOR37", "IVOR38", "IVOR39", - "IVOR40", "IVOR41", "IVOR42", "IVOR43", - "IVOR44", "IVOR45", "IVOR46", "IVOR47", - "IVOR48", "IVOR49", "IVOR50", "IVOR51", - "IVOR52", "IVOR53", "IVOR54", "IVOR55", - "IVOR56", "IVOR57", "IVOR58", "IVOR59", - "IVOR60", "IVOR61", "IVOR62", "IVOR63", - }; -#define SPR_BOOKE_IVORxx (-1) - int ivor_sprn[64] = { - SPR_BOOKE_IVOR0, SPR_BOOKE_IVOR1, SPR_BOOKE_IVOR2, SPR_BOOKE_IVOR3, - SPR_BOOKE_IVOR4, SPR_BOOKE_IVOR5, SPR_BOOKE_IVOR6, SPR_BOOKE_IVOR7, - SPR_BOOKE_IVOR8, SPR_BOOKE_IVOR9, SPR_BOOKE_IVOR10, SPR_BOOKE_IVOR11, - SPR_BOOKE_IVOR12, SPR_BOOKE_IVOR13, SPR_BOOKE_IVOR14, SPR_BOOKE_IVOR15, - SPR_BOOKE_IVORxx, SPR_BOOKE_IVORxx, SPR_BOOKE_IVORxx, SPR_BOOKE_IVORxx, - SPR_BOOKE_IVORxx, SPR_BOOKE_IVORxx, SPR_BOOKE_IVORxx, SPR_BOOKE_IVORxx, - SPR_BOOKE_IVORxx, SPR_BOOKE_IVORxx, SPR_BOOKE_IVORxx, SPR_BOOKE_IVORxx, - SPR_BOOKE_IVORxx, SPR_BOOKE_IVORxx, SPR_BOOKE_IVORxx, SPR_BOOKE_IVORxx, - SPR_BOOKE_IVOR32, SPR_BOOKE_IVOR33, SPR_BOOKE_IVOR34, SPR_BOOKE_IVOR35, - SPR_BOOKE_IVOR36, SPR_BOOKE_IVOR37, SPR_BOOKE_IVOR38, SPR_BOOKE_IVOR39, - SPR_BOOKE_IVOR40, SPR_BOOKE_IVOR41, SPR_BOOKE_IVOR42, SPR_BOOKE_IVORxx, - SPR_BOOKE_IVORxx, SPR_BOOKE_IVORxx, SPR_BOOKE_IVORxx, SPR_BOOKE_IVORxx, - SPR_BOOKE_IVORxx, SPR_BOOKE_IVORxx, SPR_BOOKE_IVORxx, SPR_BOOKE_IVORxx, - SPR_BOOKE_IVORxx, SPR_BOOKE_IVORxx, SPR_BOOKE_IVORxx, SPR_BOOKE_IVORxx, - SPR_BOOKE_IVORxx, SPR_BOOKE_IVORxx, SPR_BOOKE_IVORxx, SPR_BOOKE_IVORxx, - SPR_BOOKE_IVORxx, SPR_BOOKE_IVORxx, SPR_BOOKE_IVORxx, SPR_BOOKE_IVORxx, - }; - int i; - - /* Interrupt processing */ - spr_register(env, SPR_BOOKE_CSRR0, "CSRR0", - SPR_NOACCESS, SPR_NOACCESS, - &spr_read_generic, &spr_write_generic, - 0x00000000); - spr_register(env, SPR_BOOKE_CSRR1, "CSRR1", - SPR_NOACCESS, SPR_NOACCESS, - &spr_read_generic, &spr_write_generic, - 0x00000000); - /* Debug */ - spr_register(env, SPR_BOOKE_IAC1, "IAC1", - SPR_NOACCESS, SPR_NOACCESS, - &spr_read_generic, &spr_write_generic, - 0x00000000); - - spr_register(env, SPR_BOOKE_IAC2, "IAC2", - SPR_NOACCESS, SPR_NOACCESS, - &spr_read_generic, &spr_write_generic, - 0x00000000); - - spr_register(env, SPR_BOOKE_DAC1, "DAC1", - SPR_NOACCESS, SPR_NOACCESS, - &spr_read_generic, &spr_write_generic, - 0x00000000); - - spr_register(env, SPR_BOOKE_DAC2, "DAC2", - SPR_NOACCESS, SPR_NOACCESS, - &spr_read_generic, &spr_write_generic, - 0x00000000); - - spr_register(env, SPR_BOOKE_DBCR0, "DBCR0", - SPR_NOACCESS, SPR_NOACCESS, - &spr_read_generic, &spr_write_40x_dbcr0, - 0x00000000); - - spr_register(env, SPR_BOOKE_DBCR1, "DBCR1", - SPR_NOACCESS, SPR_NOACCESS, - &spr_read_generic, &spr_write_generic, - 0x00000000); - - spr_register(env, SPR_BOOKE_DBCR2, "DBCR2", - SPR_NOACCESS, SPR_NOACCESS, - &spr_read_generic, &spr_write_generic, - 0x00000000); - spr_register(env, SPR_BOOKE_DSRR0, "DSRR0", - SPR_NOACCESS, SPR_NOACCESS, - &spr_read_generic, &spr_write_generic, - 0x00000000); - spr_register(env, SPR_BOOKE_DSRR1, "DSRR1", - SPR_NOACCESS, SPR_NOACCESS, - &spr_read_generic, &spr_write_generic, - 0x00000000); - - spr_register(env, SPR_BOOKE_DBSR, "DBSR", - SPR_NOACCESS, SPR_NOACCESS, - &spr_read_generic, &spr_write_clear, - 0x00000000); - spr_register(env, SPR_BOOKE_DEAR, "DEAR", - SPR_NOACCESS, SPR_NOACCESS, - &spr_read_generic, &spr_write_generic, - 0x00000000); - spr_register(env, SPR_BOOKE_ESR, "ESR", - SPR_NOACCESS, SPR_NOACCESS, - &spr_read_generic, &spr_write_generic, - 0x00000000); - spr_register(env, SPR_BOOKE_IVPR, "IVPR", - SPR_NOACCESS, SPR_NOACCESS, - &spr_read_generic, &spr_write_excp_prefix, - 0x00000000); - /* Exception vectors */ - for (i = 0; i < 64; i++) { - if (ivor_mask & (1ULL << i)) { - if (ivor_sprn[i] == SPR_BOOKE_IVORxx) { - fprintf(stderr, "ERROR: IVOR %d SPR is not defined\n", i); - exit(1); - } - spr_register(env, ivor_sprn[i], ivor_names[i], - SPR_NOACCESS, SPR_NOACCESS, - &spr_read_generic, &spr_write_excp_vector, - 0x00000000); - } - } - spr_register(env, SPR_BOOKE_PID, "PID", - SPR_NOACCESS, SPR_NOACCESS, - &spr_read_generic, &spr_write_booke_pid, - 0x00000000); - spr_register(env, SPR_BOOKE_TCR, "TCR", - SPR_NOACCESS, SPR_NOACCESS, - &spr_read_generic, &spr_write_booke_tcr, - 0x00000000); - spr_register(env, SPR_BOOKE_TSR, "TSR", - SPR_NOACCESS, SPR_NOACCESS, - &spr_read_generic, &spr_write_booke_tsr, - 0x00000000); - /* Timer */ - spr_register(env, SPR_DECR, "DECR", - SPR_NOACCESS, SPR_NOACCESS, - &spr_read_decr, &spr_write_decr, - 0x00000000); - spr_register(env, SPR_BOOKE_DECAR, "DECAR", - SPR_NOACCESS, SPR_NOACCESS, - SPR_NOACCESS, &spr_write_generic, - 0x00000000); - /* SPRGs */ - spr_register(env, SPR_USPRG0, "USPRG0", - &spr_read_generic, &spr_write_generic, - &spr_read_generic, &spr_write_generic, - 0x00000000); - spr_register(env, SPR_SPRG4, "SPRG4", - SPR_NOACCESS, SPR_NOACCESS, - &spr_read_generic, &spr_write_generic, - 0x00000000); - spr_register(env, SPR_SPRG5, "SPRG5", - SPR_NOACCESS, SPR_NOACCESS, - &spr_read_generic, &spr_write_generic, - 0x00000000); - spr_register(env, SPR_SPRG6, "SPRG6", - SPR_NOACCESS, SPR_NOACCESS, - &spr_read_generic, &spr_write_generic, - 0x00000000); - spr_register(env, SPR_SPRG7, "SPRG7", - SPR_NOACCESS, SPR_NOACCESS, - &spr_read_generic, &spr_write_generic, - 0x00000000); - spr_register(env, SPR_BOOKE_SPRG8, "SPRG8", - SPR_NOACCESS, SPR_NOACCESS, - &spr_read_generic, &spr_write_generic, - 0x00000000); - spr_register(env, SPR_BOOKE_SPRG9, "SPRG9", - SPR_NOACCESS, SPR_NOACCESS, - &spr_read_generic, &spr_write_generic, - 0x00000000); -} - -#if !defined(CONFIG_USER_ONLY) -static inline uint32_t register_tlbncfg(uint32_t assoc, uint32_t minsize, - uint32_t maxsize, uint32_t flags, - uint32_t nentries) -{ - return (assoc << TLBnCFG_ASSOC_SHIFT) | - (minsize << TLBnCFG_MINSIZE_SHIFT) | - (maxsize << TLBnCFG_MAXSIZE_SHIFT) | - flags | nentries; -} -#endif /* !CONFIG_USER_ONLY */ - -/* BookE 2.06 storage control registers */ -static void register_BookE206_sprs(CPUPPCState *env, uint32_t mas_mask, - uint32_t *tlbncfg, uint32_t mmucfg) -{ -#if !defined(CONFIG_USER_ONLY) - const char *mas_names[8] = { - "MAS0", "MAS1", "MAS2", "MAS3", "MAS4", "MAS5", "MAS6", "MAS7", - }; - int mas_sprn[8] = { - SPR_BOOKE_MAS0, SPR_BOOKE_MAS1, SPR_BOOKE_MAS2, SPR_BOOKE_MAS3, - SPR_BOOKE_MAS4, SPR_BOOKE_MAS5, SPR_BOOKE_MAS6, SPR_BOOKE_MAS7, - }; - int i; - - /* TLB assist registers */ - for (i = 0; i < 8; i++) { - if (mas_mask & (1 << i)) { - spr_register(env, mas_sprn[i], mas_names[i], - SPR_NOACCESS, SPR_NOACCESS, - &spr_read_generic, - (i == 2 && (env->insns_flags & PPC_64B)) - ? &spr_write_generic : &spr_write_generic32, - 0x00000000); - } - } - if (env->nb_pids > 1) { - spr_register(env, SPR_BOOKE_PID1, "PID1", - SPR_NOACCESS, SPR_NOACCESS, - &spr_read_generic, &spr_write_booke_pid, - 0x00000000); - } - if (env->nb_pids > 2) { - spr_register(env, SPR_BOOKE_PID2, "PID2", - SPR_NOACCESS, SPR_NOACCESS, - &spr_read_generic, &spr_write_booke_pid, - 0x00000000); - } - - spr_register(env, SPR_BOOKE_EPLC, "EPLC", - SPR_NOACCESS, SPR_NOACCESS, - &spr_read_generic, &spr_write_eplc, - 0x00000000); - spr_register(env, SPR_BOOKE_EPSC, "EPSC", - SPR_NOACCESS, SPR_NOACCESS, - &spr_read_generic, &spr_write_epsc, - 0x00000000); - - spr_register(env, SPR_MMUCFG, "MMUCFG", - SPR_NOACCESS, SPR_NOACCESS, - &spr_read_generic, SPR_NOACCESS, - mmucfg); - switch (env->nb_ways) { - case 4: - spr_register(env, SPR_BOOKE_TLB3CFG, "TLB3CFG", - SPR_NOACCESS, SPR_NOACCESS, - &spr_read_generic, SPR_NOACCESS, - tlbncfg[3]); - /* Fallthru */ - case 3: - spr_register(env, SPR_BOOKE_TLB2CFG, "TLB2CFG", - SPR_NOACCESS, SPR_NOACCESS, - &spr_read_generic, SPR_NOACCESS, - tlbncfg[2]); - /* Fallthru */ - case 2: - spr_register(env, SPR_BOOKE_TLB1CFG, "TLB1CFG", - SPR_NOACCESS, SPR_NOACCESS, - &spr_read_generic, SPR_NOACCESS, - tlbncfg[1]); - /* Fallthru */ - case 1: - spr_register(env, SPR_BOOKE_TLB0CFG, "TLB0CFG", - SPR_NOACCESS, SPR_NOACCESS, - &spr_read_generic, SPR_NOACCESS, - tlbncfg[0]); - /* Fallthru */ - case 0: - default: - break; - } -#endif -} - -/* SPR specific to PowerPC 440 implementation */ -static void register_440_sprs(CPUPPCState *env) -{ - /* Cache control */ - spr_register(env, SPR_440_DNV0, "DNV0", - SPR_NOACCESS, SPR_NOACCESS, - &spr_read_generic, &spr_write_generic, - 0x00000000); - - spr_register(env, SPR_440_DNV1, "DNV1", - SPR_NOACCESS, SPR_NOACCESS, - &spr_read_generic, &spr_write_generic, - 0x00000000); - - spr_register(env, SPR_440_DNV2, "DNV2", - SPR_NOACCESS, SPR_NOACCESS, - &spr_read_generic, &spr_write_generic, - 0x00000000); - - spr_register(env, SPR_440_DNV3, "DNV3", - SPR_NOACCESS, SPR_NOACCESS, - &spr_read_generic, &spr_write_generic, - 0x00000000); - - spr_register(env, SPR_440_DTV0, "DTV0", - SPR_NOACCESS, SPR_NOACCESS, - &spr_read_generic, &spr_write_generic, - 0x00000000); - - spr_register(env, SPR_440_DTV1, "DTV1", - SPR_NOACCESS, SPR_NOACCESS, - &spr_read_generic, &spr_write_generic, - 0x00000000); - - spr_register(env, SPR_440_DTV2, "DTV2", - SPR_NOACCESS, SPR_NOACCESS, - &spr_read_generic, &spr_write_generic, - 0x00000000); - - spr_register(env, SPR_440_DTV3, "DTV3", - SPR_NOACCESS, SPR_NOACCESS, - &spr_read_generic, &spr_write_generic, - 0x00000000); - - spr_register(env, SPR_440_DVLIM, "DVLIM", - SPR_NOACCESS, SPR_NOACCESS, - &spr_read_generic, &spr_write_generic, - 0x00000000); - - spr_register(env, SPR_440_INV0, "INV0", - SPR_NOACCESS, SPR_NOACCESS, - &spr_read_generic, &spr_write_generic, - 0x00000000); - - spr_register(env, SPR_440_INV1, "INV1", - SPR_NOACCESS, SPR_NOACCESS, - &spr_read_generic, &spr_write_generic, - 0x00000000); - - spr_register(env, SPR_440_INV2, "INV2", - SPR_NOACCESS, SPR_NOACCESS, - &spr_read_generic, &spr_write_generic, - 0x00000000); - - spr_register(env, SPR_440_INV3, "INV3", - SPR_NOACCESS, SPR_NOACCESS, - &spr_read_generic, &spr_write_generic, - 0x00000000); - - spr_register(env, SPR_440_ITV0, "ITV0", - SPR_NOACCESS, SPR_NOACCESS, - &spr_read_generic, &spr_write_generic, - 0x00000000); - - spr_register(env, SPR_440_ITV1, "ITV1", - SPR_NOACCESS, SPR_NOACCESS, - &spr_read_generic, &spr_write_generic, - 0x00000000); - - spr_register(env, SPR_440_ITV2, "ITV2", - SPR_NOACCESS, SPR_NOACCESS, - &spr_read_generic, &spr_write_generic, - 0x00000000); - - spr_register(env, SPR_440_ITV3, "ITV3", - SPR_NOACCESS, SPR_NOACCESS, - &spr_read_generic, &spr_write_generic, - 0x00000000); - - spr_register(env, SPR_440_IVLIM, "IVLIM", - SPR_NOACCESS, SPR_NOACCESS, - &spr_read_generic, &spr_write_generic, - 0x00000000); - /* Cache debug */ - spr_register(env, SPR_BOOKE_DCDBTRH, "DCDBTRH", - SPR_NOACCESS, SPR_NOACCESS, - &spr_read_generic, SPR_NOACCESS, - 0x00000000); - - spr_register(env, SPR_BOOKE_DCDBTRL, "DCDBTRL", - SPR_NOACCESS, SPR_NOACCESS, - &spr_read_generic, SPR_NOACCESS, - 0x00000000); - - spr_register(env, SPR_BOOKE_ICDBDR, "ICDBDR", - SPR_NOACCESS, SPR_NOACCESS, - &spr_read_generic, SPR_NOACCESS, - 0x00000000); - - spr_register(env, SPR_BOOKE_ICDBTRH, "ICDBTRH", - SPR_NOACCESS, SPR_NOACCESS, - &spr_read_generic, SPR_NOACCESS, - 0x00000000); - - spr_register(env, SPR_BOOKE_ICDBTRL, "ICDBTRL", - SPR_NOACCESS, SPR_NOACCESS, - &spr_read_generic, SPR_NOACCESS, - 0x00000000); - - spr_register(env, SPR_440_DBDR, "DBDR", - SPR_NOACCESS, SPR_NOACCESS, - &spr_read_generic, &spr_write_generic, - 0x00000000); - /* Processor control */ - spr_register(env, SPR_4xx_CCR0, "CCR0", - SPR_NOACCESS, SPR_NOACCESS, - &spr_read_generic, &spr_write_generic, - 0x00000000); - spr_register(env, SPR_440_RSTCFG, "RSTCFG", - SPR_NOACCESS, SPR_NOACCESS, - &spr_read_generic, SPR_NOACCESS, - 0x00000000); - /* Storage control */ - spr_register(env, SPR_440_MMUCR, "MMUCR", - SPR_NOACCESS, SPR_NOACCESS, - &spr_read_generic, &spr_write_generic, - 0x00000000); - - /* Processor identification */ - spr_register(env, SPR_BOOKE_PIR, "PIR", - SPR_NOACCESS, SPR_NOACCESS, - &spr_read_generic, &spr_write_pir, - 0x00000000); - - spr_register(env, SPR_BOOKE_IAC3, "IAC3", - SPR_NOACCESS, SPR_NOACCESS, - &spr_read_generic, &spr_write_generic, - 0x00000000); - - spr_register(env, SPR_BOOKE_IAC4, "IAC4", - SPR_NOACCESS, SPR_NOACCESS, - &spr_read_generic, &spr_write_generic, - 0x00000000); - - spr_register(env, SPR_BOOKE_DVC1, "DVC1", - SPR_NOACCESS, SPR_NOACCESS, - &spr_read_generic, &spr_write_generic, - 0x00000000); - - spr_register(env, SPR_BOOKE_DVC2, "DVC2", - SPR_NOACCESS, SPR_NOACCESS, - &spr_read_generic, &spr_write_generic, - 0x00000000); -} - /* * AMR => SPR 29 (Power 2.04) * CTRL => SPR 136 (Power 2.04) @@ -569,68 +133,6 @@ static void register_440_sprs(CPUPPCState *env) /*****************************************************************************/ /* Exception vectors models */ -static void init_excp_e200(CPUPPCState *env, target_ulong ivpr_mask) -{ -#if !defined(CONFIG_USER_ONLY) - env->excp_vectors[POWERPC_EXCP_RESET] = 0x00000FFC; - env->excp_vectors[POWERPC_EXCP_CRITICAL] = 0x00000000; - env->excp_vectors[POWERPC_EXCP_MCHECK] = 0x00000000; - env->excp_vectors[POWERPC_EXCP_DSI] = 0x00000000; - env->excp_vectors[POWERPC_EXCP_ISI] = 0x00000000; - env->excp_vectors[POWERPC_EXCP_EXTERNAL] = 0x00000000; - env->excp_vectors[POWERPC_EXCP_ALIGN] = 0x00000000; - env->excp_vectors[POWERPC_EXCP_PROGRAM] = 0x00000000; - env->excp_vectors[POWERPC_EXCP_FPU] = 0x00000000; - env->excp_vectors[POWERPC_EXCP_SYSCALL] = 0x00000000; - env->excp_vectors[POWERPC_EXCP_APU] = 0x00000000; - env->excp_vectors[POWERPC_EXCP_DECR] = 0x00000000; - env->excp_vectors[POWERPC_EXCP_FIT] = 0x00000000; - env->excp_vectors[POWERPC_EXCP_WDT] = 0x00000000; - env->excp_vectors[POWERPC_EXCP_DTLB] = 0x00000000; - env->excp_vectors[POWERPC_EXCP_ITLB] = 0x00000000; - env->excp_vectors[POWERPC_EXCP_DEBUG] = 0x00000000; - /* - * These two are the same IVOR as POWERPC_EXCP_VPU and - * POWERPC_EXCP_VPUA. We deal with that when dispatching at - * powerpc_excp(). - */ - env->excp_vectors[POWERPC_EXCP_SPEU] = 0x00000000; - env->excp_vectors[POWERPC_EXCP_EFPDI] = 0x00000000; - - env->excp_vectors[POWERPC_EXCP_EFPRI] = 0x00000000; - env->ivor_mask = 0x0000FFF7UL; - env->ivpr_mask = ivpr_mask; - /* Hardware reset vector */ - env->hreset_vector = 0xFFFFFFFCUL; -#endif -} - -static void init_excp_BookE(CPUPPCState *env) -{ -#if !defined(CONFIG_USER_ONLY) - env->excp_vectors[POWERPC_EXCP_CRITICAL] = 0x00000000; - env->excp_vectors[POWERPC_EXCP_MCHECK] = 0x00000000; - env->excp_vectors[POWERPC_EXCP_DSI] = 0x00000000; - env->excp_vectors[POWERPC_EXCP_ISI] = 0x00000000; - env->excp_vectors[POWERPC_EXCP_EXTERNAL] = 0x00000000; - env->excp_vectors[POWERPC_EXCP_ALIGN] = 0x00000000; - env->excp_vectors[POWERPC_EXCP_PROGRAM] = 0x00000000; - env->excp_vectors[POWERPC_EXCP_FPU] = 0x00000000; - env->excp_vectors[POWERPC_EXCP_SYSCALL] = 0x00000000; - env->excp_vectors[POWERPC_EXCP_APU] = 0x00000000; - env->excp_vectors[POWERPC_EXCP_DECR] = 0x00000000; - env->excp_vectors[POWERPC_EXCP_FIT] = 0x00000000; - env->excp_vectors[POWERPC_EXCP_WDT] = 0x00000000; - env->excp_vectors[POWERPC_EXCP_DTLB] = 0x00000000; - env->excp_vectors[POWERPC_EXCP_ITLB] = 0x00000000; - env->excp_vectors[POWERPC_EXCP_DEBUG] = 0x00000000; - env->ivor_mask = 0x0000FFF0UL; - env->ivpr_mask = 0xFFFF0000UL; - /* Hardware reset vector */ - env->hreset_vector = 0xFFFFFFFCUL; -#endif -} - #if defined(TARGET_PPC64) static void init_excp_970(CPUPPCState *env) { @@ -722,918 +224,6 @@ static void init_excp_POWER10(CPUPPCState *env) #endif -static int check_pow_hid0(CPUPPCState *env) -{ - if (env->spr[SPR_HID0] & 0x00E00000) { - return 1; - } - - return 0; -} - -static void init_proc_440EP(CPUPPCState *env) -{ - register_BookE_sprs(env, 0x000000000000FFFFULL); - register_440_sprs(env); - register_usprgh_sprs(env); - - spr_register(env, SPR_BOOKE_MCSR, "MCSR", - SPR_NOACCESS, SPR_NOACCESS, - &spr_read_generic, &spr_write_generic, - 0x00000000); - spr_register(env, SPR_BOOKE_MCSRR0, "MCSRR0", - SPR_NOACCESS, SPR_NOACCESS, - &spr_read_generic, &spr_write_generic, - 0x00000000); - spr_register(env, SPR_BOOKE_MCSRR1, "MCSRR1", - SPR_NOACCESS, SPR_NOACCESS, - &spr_read_generic, &spr_write_generic, - 0x00000000); - - spr_register(env, SPR_440_CCR1, "CCR1", - SPR_NOACCESS, SPR_NOACCESS, - &spr_read_generic, &spr_write_generic, - 0x00000000); - /* Memory management */ -#if !defined(CONFIG_USER_ONLY) - env->nb_tlb = 64; - env->nb_ways = 1; - env->id_tlbs = 0; - env->tlb_type = TLB_EMB; -#endif - init_excp_BookE(env); - env->dcache_line_size = 32; - env->icache_line_size = 32; - ppc40x_irq_init(env_archcpu(env)); - - SET_FIT_PERIOD(12, 16, 20, 24); - SET_WDT_PERIOD(20, 24, 28, 32); -} - -POWERPC_FAMILY(440EP)(ObjectClass *oc, void *data) -{ - DeviceClass *dc = DEVICE_CLASS(oc); - PowerPCCPUClass *pcc = POWERPC_CPU_CLASS(oc); - - dc->desc = "PowerPC 440 EP"; - pcc->init_proc = init_proc_440EP; - pcc->check_pow = check_pow_nocheck; - pcc->insns_flags = PPC_INSNS_BASE | PPC_STRING | - PPC_FLOAT | PPC_FLOAT_FRES | PPC_FLOAT_FSEL | - PPC_FLOAT_FSQRT | PPC_FLOAT_FRSQRTE | - PPC_FLOAT_STFIWX | - PPC_DCR | PPC_WRTEE | PPC_RFMCI | - PPC_CACHE | PPC_CACHE_ICBI | - PPC_CACHE_DCBZ | PPC_CACHE_DCBA | - PPC_MEM_TLBSYNC | PPC_MFTB | - PPC_BOOKE | PPC_4xx_COMMON | PPC_405_MAC | - PPC_440_SPEC; - pcc->msr_mask = (1ull << MSR_POW) | - (1ull << MSR_CE) | - (1ull << MSR_EE) | - (1ull << MSR_PR) | - (1ull << MSR_FP) | - (1ull << MSR_ME) | - (1ull << MSR_FE0) | - (1ull << MSR_DWE) | - (1ull << MSR_DE) | - (1ull << MSR_FE1) | - (1ull << MSR_IR) | - (1ull << MSR_DR); - pcc->mmu_model = POWERPC_MMU_BOOKE; - pcc->excp_model = POWERPC_EXCP_BOOKE; - pcc->bus_model = PPC_FLAGS_INPUT_BookE; - pcc->bfd_mach = bfd_mach_ppc_403; - pcc->flags = POWERPC_FLAG_CE | POWERPC_FLAG_DWE | - POWERPC_FLAG_DE | POWERPC_FLAG_BUS_CLK; -} - -POWERPC_FAMILY(460EX)(ObjectClass *oc, void *data) -{ - DeviceClass *dc = DEVICE_CLASS(oc); - PowerPCCPUClass *pcc = POWERPC_CPU_CLASS(oc); - - dc->desc = "PowerPC 460 EX"; - pcc->init_proc = init_proc_440EP; - pcc->check_pow = check_pow_nocheck; - pcc->insns_flags = PPC_INSNS_BASE | PPC_STRING | - PPC_FLOAT | PPC_FLOAT_FRES | PPC_FLOAT_FSEL | - PPC_FLOAT_FSQRT | PPC_FLOAT_FRSQRTE | - PPC_FLOAT_STFIWX | - PPC_DCR | PPC_DCRX | PPC_WRTEE | PPC_RFMCI | - PPC_CACHE | PPC_CACHE_ICBI | - PPC_CACHE_DCBZ | PPC_CACHE_DCBA | - PPC_MEM_TLBSYNC | PPC_MFTB | - PPC_BOOKE | PPC_4xx_COMMON | PPC_405_MAC | - PPC_440_SPEC; - pcc->msr_mask = (1ull << MSR_POW) | - (1ull << MSR_CE) | - (1ull << MSR_EE) | - (1ull << MSR_PR) | - (1ull << MSR_FP) | - (1ull << MSR_ME) | - (1ull << MSR_FE0) | - (1ull << MSR_DWE) | - (1ull << MSR_DE) | - (1ull << MSR_FE1) | - (1ull << MSR_IR) | - (1ull << MSR_DR); - pcc->mmu_model = POWERPC_MMU_BOOKE; - pcc->excp_model = POWERPC_EXCP_BOOKE; - pcc->bus_model = PPC_FLAGS_INPUT_BookE; - pcc->bfd_mach = bfd_mach_ppc_403; - pcc->flags = POWERPC_FLAG_CE | POWERPC_FLAG_DWE | - POWERPC_FLAG_DE | POWERPC_FLAG_BUS_CLK; -} - -static void init_proc_440GP(CPUPPCState *env) -{ - register_BookE_sprs(env, 0x000000000000FFFFULL); - register_440_sprs(env); - register_usprgh_sprs(env); - - /* Memory management */ -#if !defined(CONFIG_USER_ONLY) - env->nb_tlb = 64; - env->nb_ways = 1; - env->id_tlbs = 0; - env->tlb_type = TLB_EMB; -#endif - init_excp_BookE(env); - env->dcache_line_size = 32; - env->icache_line_size = 32; - /* XXX: TODO: allocate internal IRQ controller */ - - SET_FIT_PERIOD(12, 16, 20, 24); - SET_WDT_PERIOD(20, 24, 28, 32); -} - -POWERPC_FAMILY(440GP)(ObjectClass *oc, void *data) -{ - DeviceClass *dc = DEVICE_CLASS(oc); - PowerPCCPUClass *pcc = POWERPC_CPU_CLASS(oc); - - dc->desc = "PowerPC 440 GP"; - pcc->init_proc = init_proc_440GP; - pcc->check_pow = check_pow_nocheck; - pcc->insns_flags = PPC_INSNS_BASE | PPC_STRING | - PPC_DCR | PPC_DCRX | PPC_WRTEE | PPC_MFAPIDI | - PPC_CACHE | PPC_CACHE_ICBI | - PPC_CACHE_DCBZ | PPC_CACHE_DCBA | - PPC_MEM_TLBSYNC | PPC_TLBIVA | PPC_MFTB | - PPC_BOOKE | PPC_4xx_COMMON | PPC_405_MAC | - PPC_440_SPEC; - pcc->msr_mask = (1ull << MSR_POW) | - (1ull << MSR_CE) | - (1ull << MSR_EE) | - (1ull << MSR_PR) | - (1ull << MSR_FP) | - (1ull << MSR_ME) | - (1ull << MSR_FE0) | - (1ull << MSR_DWE) | - (1ull << MSR_DE) | - (1ull << MSR_FE1) | - (1ull << MSR_IR) | - (1ull << MSR_DR); - pcc->mmu_model = POWERPC_MMU_BOOKE; - pcc->excp_model = POWERPC_EXCP_BOOKE; - pcc->bus_model = PPC_FLAGS_INPUT_BookE; - pcc->bfd_mach = bfd_mach_ppc_403; - pcc->flags = POWERPC_FLAG_CE | POWERPC_FLAG_DWE | - POWERPC_FLAG_DE | POWERPC_FLAG_BUS_CLK; -} - -static void init_proc_440x5(CPUPPCState *env) -{ - register_BookE_sprs(env, 0x000000000000FFFFULL); - register_440_sprs(env); - register_usprgh_sprs(env); - - spr_register(env, SPR_BOOKE_MCSR, "MCSR", - SPR_NOACCESS, SPR_NOACCESS, - &spr_read_generic, &spr_write_generic, - 0x00000000); - spr_register(env, SPR_BOOKE_MCSRR0, "MCSRR0", - SPR_NOACCESS, SPR_NOACCESS, - &spr_read_generic, &spr_write_generic, - 0x00000000); - spr_register(env, SPR_BOOKE_MCSRR1, "MCSRR1", - SPR_NOACCESS, SPR_NOACCESS, - &spr_read_generic, &spr_write_generic, - 0x00000000); - - spr_register(env, SPR_440_CCR1, "CCR1", - SPR_NOACCESS, SPR_NOACCESS, - &spr_read_generic, &spr_write_generic, - 0x00000000); - /* Memory management */ -#if !defined(CONFIG_USER_ONLY) - env->nb_tlb = 64; - env->nb_ways = 1; - env->id_tlbs = 0; - env->tlb_type = TLB_EMB; -#endif - init_excp_BookE(env); - env->dcache_line_size = 32; - env->icache_line_size = 32; - ppc40x_irq_init(env_archcpu(env)); - - SET_FIT_PERIOD(12, 16, 20, 24); - SET_WDT_PERIOD(20, 24, 28, 32); -} - -POWERPC_FAMILY(440x5)(ObjectClass *oc, void *data) -{ - DeviceClass *dc = DEVICE_CLASS(oc); - PowerPCCPUClass *pcc = POWERPC_CPU_CLASS(oc); - - dc->desc = "PowerPC 440x5"; - pcc->init_proc = init_proc_440x5; - pcc->check_pow = check_pow_nocheck; - pcc->insns_flags = PPC_INSNS_BASE | PPC_STRING | - PPC_DCR | PPC_WRTEE | PPC_RFMCI | - PPC_CACHE | PPC_CACHE_ICBI | - PPC_CACHE_DCBZ | PPC_CACHE_DCBA | - PPC_MEM_TLBSYNC | PPC_MFTB | - PPC_BOOKE | PPC_4xx_COMMON | PPC_405_MAC | - PPC_440_SPEC; - pcc->msr_mask = (1ull << MSR_POW) | - (1ull << MSR_CE) | - (1ull << MSR_EE) | - (1ull << MSR_PR) | - (1ull << MSR_FP) | - (1ull << MSR_ME) | - (1ull << MSR_FE0) | - (1ull << MSR_DWE) | - (1ull << MSR_DE) | - (1ull << MSR_FE1) | - (1ull << MSR_IR) | - (1ull << MSR_DR); - pcc->mmu_model = POWERPC_MMU_BOOKE; - pcc->excp_model = POWERPC_EXCP_BOOKE; - pcc->bus_model = PPC_FLAGS_INPUT_BookE; - pcc->bfd_mach = bfd_mach_ppc_403; - pcc->flags = POWERPC_FLAG_CE | POWERPC_FLAG_DWE | - POWERPC_FLAG_DE | POWERPC_FLAG_BUS_CLK; -} - -POWERPC_FAMILY(440x5wDFPU)(ObjectClass *oc, void *data) -{ - DeviceClass *dc = DEVICE_CLASS(oc); - PowerPCCPUClass *pcc = POWERPC_CPU_CLASS(oc); - - dc->desc = "PowerPC 440x5 with double precision FPU"; - pcc->init_proc = init_proc_440x5; - pcc->check_pow = check_pow_nocheck; - pcc->insns_flags = PPC_INSNS_BASE | PPC_STRING | - PPC_FLOAT | PPC_FLOAT_FSQRT | - PPC_FLOAT_STFIWX | - PPC_DCR | PPC_WRTEE | PPC_RFMCI | - PPC_CACHE | PPC_CACHE_ICBI | - PPC_CACHE_DCBZ | PPC_CACHE_DCBA | - PPC_MEM_TLBSYNC | PPC_MFTB | - PPC_BOOKE | PPC_4xx_COMMON | PPC_405_MAC | - PPC_440_SPEC; - pcc->insns_flags2 = PPC2_FP_CVT_S64; - pcc->msr_mask = (1ull << MSR_POW) | - (1ull << MSR_CE) | - (1ull << MSR_EE) | - (1ull << MSR_PR) | - (1ull << MSR_FP) | - (1ull << MSR_ME) | - (1ull << MSR_FE0) | - (1ull << MSR_DWE) | - (1ull << MSR_DE) | - (1ull << MSR_FE1) | - (1ull << MSR_IR) | - (1ull << MSR_DR); - pcc->mmu_model = POWERPC_MMU_BOOKE; - pcc->excp_model = POWERPC_EXCP_BOOKE; - pcc->bus_model = PPC_FLAGS_INPUT_BookE; - pcc->bfd_mach = bfd_mach_ppc_403; - pcc->flags = POWERPC_FLAG_CE | POWERPC_FLAG_DWE | - POWERPC_FLAG_DE | POWERPC_FLAG_BUS_CLK; -} - -static void init_proc_e200(CPUPPCState *env) -{ - register_BookE_sprs(env, 0x000000070000FFFFULL); - - spr_register(env, SPR_BOOKE_SPEFSCR, "SPEFSCR", - &spr_read_spefscr, &spr_write_spefscr, - &spr_read_spefscr, &spr_write_spefscr, - 0x00000000); - /* Memory management */ - register_BookE206_sprs(env, 0x0000005D, NULL, 0); - register_usprgh_sprs(env); - - spr_register(env, SPR_HID0, "HID0", - SPR_NOACCESS, SPR_NOACCESS, - &spr_read_generic, &spr_write_generic, - 0x00000000); - - spr_register(env, SPR_HID1, "HID1", - SPR_NOACCESS, SPR_NOACCESS, - &spr_read_generic, &spr_write_generic, - 0x00000000); - - spr_register(env, SPR_Exxx_ALTCTXCR, "ALTCTXCR", - SPR_NOACCESS, SPR_NOACCESS, - &spr_read_generic, &spr_write_generic, - 0x00000000); - - spr_register(env, SPR_Exxx_BUCSR, "BUCSR", - SPR_NOACCESS, SPR_NOACCESS, - &spr_read_generic, &spr_write_generic, - 0x00000000); - - spr_register(env, SPR_Exxx_CTXCR, "CTXCR", - SPR_NOACCESS, SPR_NOACCESS, - &spr_read_generic, &spr_write_generic, - 0x00000000); - - spr_register(env, SPR_Exxx_DBCNT, "DBCNT", - SPR_NOACCESS, SPR_NOACCESS, - &spr_read_generic, &spr_write_generic, - 0x00000000); - - spr_register(env, SPR_Exxx_DBCR3, "DBCR3", - SPR_NOACCESS, SPR_NOACCESS, - &spr_read_generic, &spr_write_generic, - 0x00000000); - - spr_register(env, SPR_Exxx_L1CFG0, "L1CFG0", - &spr_read_generic, SPR_NOACCESS, - &spr_read_generic, SPR_NOACCESS, - 0x00000000); - - spr_register(env, SPR_Exxx_L1CSR0, "L1CSR0", - SPR_NOACCESS, SPR_NOACCESS, - &spr_read_generic, &spr_write_generic, - 0x00000000); - - spr_register(env, SPR_Exxx_L1FINV0, "L1FINV0", - SPR_NOACCESS, SPR_NOACCESS, - &spr_read_generic, &spr_write_generic, - 0x00000000); - - spr_register(env, SPR_BOOKE_TLB0CFG, "TLB0CFG", - SPR_NOACCESS, SPR_NOACCESS, - &spr_read_generic, &spr_write_generic, - 0x00000000); - - spr_register(env, SPR_BOOKE_TLB1CFG, "TLB1CFG", - SPR_NOACCESS, SPR_NOACCESS, - &spr_read_generic, &spr_write_generic, - 0x00000000); - - spr_register(env, SPR_BOOKE_IAC3, "IAC3", - SPR_NOACCESS, SPR_NOACCESS, - &spr_read_generic, &spr_write_generic, - 0x00000000); - - spr_register(env, SPR_BOOKE_IAC4, "IAC4", - SPR_NOACCESS, SPR_NOACCESS, - &spr_read_generic, &spr_write_generic, - 0x00000000); - - spr_register(env, SPR_MMUCSR0, "MMUCSR0", - SPR_NOACCESS, SPR_NOACCESS, - &spr_read_generic, &spr_write_generic, - 0x00000000); /* TOFIX */ - spr_register(env, SPR_BOOKE_DSRR0, "DSRR0", - SPR_NOACCESS, SPR_NOACCESS, - &spr_read_generic, &spr_write_generic, - 0x00000000); - spr_register(env, SPR_BOOKE_DSRR1, "DSRR1", - SPR_NOACCESS, SPR_NOACCESS, - &spr_read_generic, &spr_write_generic, - 0x00000000); -#if !defined(CONFIG_USER_ONLY) - env->nb_tlb = 64; - env->nb_ways = 1; - env->id_tlbs = 0; - env->tlb_type = TLB_EMB; -#endif - init_excp_e200(env, 0xFFFF0000UL); - env->dcache_line_size = 32; - env->icache_line_size = 32; - /* XXX: TODO: allocate internal IRQ controller */ -} - -POWERPC_FAMILY(e200)(ObjectClass *oc, void *data) -{ - DeviceClass *dc = DEVICE_CLASS(oc); - PowerPCCPUClass *pcc = POWERPC_CPU_CLASS(oc); - - dc->desc = "e200 core"; - pcc->init_proc = init_proc_e200; - pcc->check_pow = check_pow_hid0; - /* - * XXX: unimplemented instructions: - * dcblc - * dcbtlst - * dcbtstls - * icblc - * icbtls - * tlbivax - * all SPE multiply-accumulate instructions - */ - pcc->insns_flags = PPC_INSNS_BASE | PPC_ISEL | - PPC_SPE | PPC_SPE_SINGLE | - PPC_WRTEE | PPC_RFDI | - PPC_CACHE | PPC_CACHE_LOCK | PPC_CACHE_ICBI | - PPC_CACHE_DCBZ | PPC_CACHE_DCBA | - PPC_MEM_TLBSYNC | PPC_TLBIVAX | - PPC_BOOKE; - pcc->msr_mask = (1ull << MSR_UCLE) | - (1ull << MSR_SPE) | - (1ull << MSR_POW) | - (1ull << MSR_CE) | - (1ull << MSR_EE) | - (1ull << MSR_PR) | - (1ull << MSR_FP) | - (1ull << MSR_ME) | - (1ull << MSR_FE0) | - (1ull << MSR_DWE) | - (1ull << MSR_DE) | - (1ull << MSR_FE1) | - (1ull << MSR_IR) | - (1ull << MSR_DR); - pcc->mmu_model = POWERPC_MMU_BOOKE206; - pcc->excp_model = POWERPC_EXCP_BOOKE; - pcc->bus_model = PPC_FLAGS_INPUT_BookE; - pcc->bfd_mach = bfd_mach_ppc_860; - pcc->flags = POWERPC_FLAG_SPE | POWERPC_FLAG_CE | - POWERPC_FLAG_UBLE | POWERPC_FLAG_DE | - POWERPC_FLAG_BUS_CLK; -} - -enum fsl_e500_version { - fsl_e500v1, - fsl_e500v2, - fsl_e500mc, - fsl_e5500, - fsl_e6500, -}; - -static void init_proc_e500(CPUPPCState *env, int version) -{ - uint32_t tlbncfg[2]; - uint64_t ivor_mask; - uint64_t ivpr_mask = 0xFFFF0000ULL; - uint32_t l1cfg0 = 0x3800 /* 8 ways */ - | 0x0020; /* 32 kb */ - uint32_t l1cfg1 = 0x3800 /* 8 ways */ - | 0x0020; /* 32 kb */ - uint32_t mmucfg = 0; -#if !defined(CONFIG_USER_ONLY) - int i; -#endif - - /* - * XXX The e500 doesn't implement IVOR7 and IVOR9, but doesn't - * complain when accessing them. - * register_BookE_sprs(env, 0x0000000F0000FD7FULL); - */ - switch (version) { - case fsl_e500v1: - case fsl_e500v2: - default: - ivor_mask = 0x0000000F0000FFFFULL; - break; - case fsl_e500mc: - case fsl_e5500: - ivor_mask = 0x000003FE0000FFFFULL; - break; - case fsl_e6500: - ivor_mask = 0x000003FF0000FFFFULL; - break; - } - register_BookE_sprs(env, ivor_mask); - - spr_register(env, SPR_USPRG3, "USPRG3", - &spr_read_ureg, SPR_NOACCESS, - &spr_read_ureg, SPR_NOACCESS, - 0x00000000); - - /* Processor identification */ - spr_register(env, SPR_BOOKE_PIR, "PIR", - SPR_NOACCESS, SPR_NOACCESS, - &spr_read_generic, &spr_write_pir, - 0x00000000); - - spr_register(env, SPR_BOOKE_SPEFSCR, "SPEFSCR", - &spr_read_spefscr, &spr_write_spefscr, - &spr_read_spefscr, &spr_write_spefscr, - 0x00000000); -#if !defined(CONFIG_USER_ONLY) - /* Memory management */ - env->nb_pids = 3; - env->nb_ways = 2; - env->id_tlbs = 0; - switch (version) { - case fsl_e500v1: - tlbncfg[0] = register_tlbncfg(2, 1, 1, 0, 256); - tlbncfg[1] = register_tlbncfg(16, 1, 9, TLBnCFG_AVAIL | TLBnCFG_IPROT, 16); - break; - case fsl_e500v2: - tlbncfg[0] = register_tlbncfg(4, 1, 1, 0, 512); - tlbncfg[1] = register_tlbncfg(16, 1, 12, TLBnCFG_AVAIL | TLBnCFG_IPROT, 16); - break; - case fsl_e500mc: - case fsl_e5500: - tlbncfg[0] = register_tlbncfg(4, 1, 1, 0, 512); - tlbncfg[1] = register_tlbncfg(64, 1, 12, TLBnCFG_AVAIL | TLBnCFG_IPROT, 64); - break; - case fsl_e6500: - mmucfg = 0x6510B45; - env->nb_pids = 1; - tlbncfg[0] = 0x08052400; - tlbncfg[1] = 0x40028040; - break; - default: - cpu_abort(env_cpu(env), "Unknown CPU: " TARGET_FMT_lx "\n", - env->spr[SPR_PVR]); - } -#endif - /* Cache sizes */ - switch (version) { - case fsl_e500v1: - case fsl_e500v2: - env->dcache_line_size = 32; - env->icache_line_size = 32; - break; - case fsl_e500mc: - case fsl_e5500: - env->dcache_line_size = 64; - env->icache_line_size = 64; - l1cfg0 |= 0x1000000; /* 64 byte cache block size */ - l1cfg1 |= 0x1000000; /* 64 byte cache block size */ - break; - case fsl_e6500: - env->dcache_line_size = 32; - env->icache_line_size = 32; - l1cfg0 |= 0x0F83820; - l1cfg1 |= 0x0B83820; - break; - default: - cpu_abort(env_cpu(env), "Unknown CPU: " TARGET_FMT_lx "\n", - env->spr[SPR_PVR]); - } - register_BookE206_sprs(env, 0x000000DF, tlbncfg, mmucfg); - register_usprgh_sprs(env); - - spr_register(env, SPR_HID0, "HID0", - SPR_NOACCESS, SPR_NOACCESS, - &spr_read_generic, &spr_write_generic, - 0x00000000); - - spr_register(env, SPR_HID1, "HID1", - SPR_NOACCESS, SPR_NOACCESS, - &spr_read_generic, &spr_write_generic, - 0x00000000); - - spr_register(env, SPR_Exxx_BBEAR, "BBEAR", - SPR_NOACCESS, SPR_NOACCESS, - &spr_read_generic, &spr_write_generic, - 0x00000000); - - spr_register(env, SPR_Exxx_BBTAR, "BBTAR", - SPR_NOACCESS, SPR_NOACCESS, - &spr_read_generic, &spr_write_generic, - 0x00000000); - - spr_register(env, SPR_Exxx_MCAR, "MCAR", - SPR_NOACCESS, SPR_NOACCESS, - &spr_read_generic, &spr_write_generic, - 0x00000000); - - spr_register(env, SPR_BOOKE_MCSR, "MCSR", - SPR_NOACCESS, SPR_NOACCESS, - &spr_read_generic, &spr_write_generic, - 0x00000000); - - spr_register(env, SPR_Exxx_NPIDR, "NPIDR", - SPR_NOACCESS, SPR_NOACCESS, - &spr_read_generic, &spr_write_generic, - 0x00000000); - - spr_register(env, SPR_Exxx_BUCSR, "BUCSR", - SPR_NOACCESS, SPR_NOACCESS, - &spr_read_generic, &spr_write_generic, - 0x00000000); - - spr_register(env, SPR_Exxx_L1CFG0, "L1CFG0", - &spr_read_generic, SPR_NOACCESS, - &spr_read_generic, SPR_NOACCESS, - l1cfg0); - spr_register(env, SPR_Exxx_L1CFG1, "L1CFG1", - &spr_read_generic, SPR_NOACCESS, - &spr_read_generic, SPR_NOACCESS, - l1cfg1); - spr_register(env, SPR_Exxx_L1CSR0, "L1CSR0", - SPR_NOACCESS, SPR_NOACCESS, - &spr_read_generic, &spr_write_e500_l1csr0, - 0x00000000); - spr_register(env, SPR_Exxx_L1CSR1, "L1CSR1", - SPR_NOACCESS, SPR_NOACCESS, - &spr_read_generic, &spr_write_e500_l1csr1, - 0x00000000); - if (version != fsl_e500v1 && version != fsl_e500v2) { - spr_register(env, SPR_Exxx_L2CSR0, "L2CSR0", - SPR_NOACCESS, SPR_NOACCESS, - &spr_read_generic, &spr_write_e500_l2csr0, - 0x00000000); - } - spr_register(env, SPR_BOOKE_MCSRR0, "MCSRR0", - SPR_NOACCESS, SPR_NOACCESS, - &spr_read_generic, &spr_write_generic, - 0x00000000); - spr_register(env, SPR_BOOKE_MCSRR1, "MCSRR1", - SPR_NOACCESS, SPR_NOACCESS, - &spr_read_generic, &spr_write_generic, - 0x00000000); - spr_register(env, SPR_MMUCSR0, "MMUCSR0", - SPR_NOACCESS, SPR_NOACCESS, - &spr_read_generic, &spr_write_booke206_mmucsr0, - 0x00000000); - spr_register(env, SPR_BOOKE_EPR, "EPR", - SPR_NOACCESS, SPR_NOACCESS, - &spr_read_generic, SPR_NOACCESS, - 0x00000000); - /* XXX better abstract into Emb.xxx features */ - if ((version == fsl_e5500) || (version == fsl_e6500)) { - spr_register(env, SPR_BOOKE_EPCR, "EPCR", - SPR_NOACCESS, SPR_NOACCESS, - &spr_read_generic, &spr_write_generic, - 0x00000000); - spr_register(env, SPR_BOOKE_MAS7_MAS3, "MAS7_MAS3", - SPR_NOACCESS, SPR_NOACCESS, - &spr_read_mas73, &spr_write_mas73, - 0x00000000); - ivpr_mask = (target_ulong)~0xFFFFULL; - } - - if (version == fsl_e6500) { - /* Thread identification */ - spr_register(env, SPR_TIR, "TIR", - SPR_NOACCESS, SPR_NOACCESS, - &spr_read_generic, SPR_NOACCESS, - 0x00000000); - spr_register(env, SPR_BOOKE_TLB0PS, "TLB0PS", - SPR_NOACCESS, SPR_NOACCESS, - &spr_read_generic, SPR_NOACCESS, - 0x00000004); - spr_register(env, SPR_BOOKE_TLB1PS, "TLB1PS", - SPR_NOACCESS, SPR_NOACCESS, - &spr_read_generic, SPR_NOACCESS, - 0x7FFFFFFC); - } - -#if !defined(CONFIG_USER_ONLY) - env->nb_tlb = 0; - env->tlb_type = TLB_MAS; - for (i = 0; i < BOOKE206_MAX_TLBN; i++) { - env->nb_tlb += booke206_tlb_size(env, i); - } -#endif - - init_excp_e200(env, ivpr_mask); - /* Allocate hardware IRQ controller */ - ppce500_irq_init(env_archcpu(env)); -} - -static void init_proc_e500v1(CPUPPCState *env) -{ - init_proc_e500(env, fsl_e500v1); -} - -POWERPC_FAMILY(e500v1)(ObjectClass *oc, void *data) -{ - DeviceClass *dc = DEVICE_CLASS(oc); - PowerPCCPUClass *pcc = POWERPC_CPU_CLASS(oc); - - dc->desc = "e500v1 core"; - pcc->init_proc = init_proc_e500v1; - pcc->check_pow = check_pow_hid0; - pcc->insns_flags = PPC_INSNS_BASE | PPC_ISEL | - PPC_SPE | PPC_SPE_SINGLE | - PPC_WRTEE | PPC_RFDI | - PPC_CACHE | PPC_CACHE_LOCK | PPC_CACHE_ICBI | - PPC_CACHE_DCBZ | PPC_CACHE_DCBA | - PPC_MEM_TLBSYNC | PPC_TLBIVAX | PPC_MEM_SYNC; - pcc->insns_flags2 = PPC2_BOOKE206; - pcc->msr_mask = (1ull << MSR_UCLE) | - (1ull << MSR_SPE) | - (1ull << MSR_POW) | - (1ull << MSR_CE) | - (1ull << MSR_EE) | - (1ull << MSR_PR) | - (1ull << MSR_FP) | - (1ull << MSR_ME) | - (1ull << MSR_FE0) | - (1ull << MSR_DWE) | - (1ull << MSR_DE) | - (1ull << MSR_FE1) | - (1ull << MSR_IR) | - (1ull << MSR_DR); - pcc->mmu_model = POWERPC_MMU_BOOKE206; - pcc->excp_model = POWERPC_EXCP_BOOKE; - pcc->bus_model = PPC_FLAGS_INPUT_BookE; - pcc->bfd_mach = bfd_mach_ppc_860; - pcc->flags = POWERPC_FLAG_SPE | POWERPC_FLAG_CE | - POWERPC_FLAG_UBLE | POWERPC_FLAG_DE | - POWERPC_FLAG_BUS_CLK; -} - -static void init_proc_e500v2(CPUPPCState *env) -{ - init_proc_e500(env, fsl_e500v2); -} - -POWERPC_FAMILY(e500v2)(ObjectClass *oc, void *data) -{ - DeviceClass *dc = DEVICE_CLASS(oc); - PowerPCCPUClass *pcc = POWERPC_CPU_CLASS(oc); - - dc->desc = "e500v2 core"; - pcc->init_proc = init_proc_e500v2; - pcc->check_pow = check_pow_hid0; - pcc->insns_flags = PPC_INSNS_BASE | PPC_ISEL | - PPC_SPE | PPC_SPE_SINGLE | PPC_SPE_DOUBLE | - PPC_WRTEE | PPC_RFDI | - PPC_CACHE | PPC_CACHE_LOCK | PPC_CACHE_ICBI | - PPC_CACHE_DCBZ | PPC_CACHE_DCBA | - PPC_MEM_TLBSYNC | PPC_TLBIVAX | PPC_MEM_SYNC; - pcc->insns_flags2 = PPC2_BOOKE206; - pcc->msr_mask = (1ull << MSR_UCLE) | - (1ull << MSR_SPE) | - (1ull << MSR_POW) | - (1ull << MSR_CE) | - (1ull << MSR_EE) | - (1ull << MSR_PR) | - (1ull << MSR_FP) | - (1ull << MSR_ME) | - (1ull << MSR_FE0) | - (1ull << MSR_DWE) | - (1ull << MSR_DE) | - (1ull << MSR_FE1) | - (1ull << MSR_IR) | - (1ull << MSR_DR); - pcc->mmu_model = POWERPC_MMU_BOOKE206; - pcc->excp_model = POWERPC_EXCP_BOOKE; - pcc->bus_model = PPC_FLAGS_INPUT_BookE; - pcc->bfd_mach = bfd_mach_ppc_860; - pcc->flags = POWERPC_FLAG_SPE | POWERPC_FLAG_CE | - POWERPC_FLAG_UBLE | POWERPC_FLAG_DE | - POWERPC_FLAG_BUS_CLK; -} - -static void init_proc_e500mc(CPUPPCState *env) -{ - init_proc_e500(env, fsl_e500mc); -} - -POWERPC_FAMILY(e500mc)(ObjectClass *oc, void *data) -{ - DeviceClass *dc = DEVICE_CLASS(oc); - PowerPCCPUClass *pcc = POWERPC_CPU_CLASS(oc); - - dc->desc = "e500mc core"; - pcc->init_proc = init_proc_e500mc; - pcc->check_pow = check_pow_none; - pcc->insns_flags = PPC_INSNS_BASE | PPC_ISEL | PPC_MFTB | - PPC_WRTEE | PPC_RFDI | PPC_RFMCI | - PPC_CACHE | PPC_CACHE_LOCK | PPC_CACHE_ICBI | - PPC_CACHE_DCBZ | PPC_CACHE_DCBA | - PPC_FLOAT | PPC_FLOAT_FRES | - PPC_FLOAT_FRSQRTE | PPC_FLOAT_FSEL | - PPC_FLOAT_STFIWX | PPC_WAIT | - PPC_MEM_TLBSYNC | PPC_TLBIVAX | PPC_MEM_SYNC; - pcc->insns_flags2 = PPC2_BOOKE206 | PPC2_PRCNTL; - pcc->msr_mask = (1ull << MSR_GS) | - (1ull << MSR_UCLE) | - (1ull << MSR_CE) | - (1ull << MSR_EE) | - (1ull << MSR_PR) | - (1ull << MSR_FP) | - (1ull << MSR_ME) | - (1ull << MSR_FE0) | - (1ull << MSR_DE) | - (1ull << MSR_FE1) | - (1ull << MSR_IR) | - (1ull << MSR_DR) | - (1ull << MSR_PX) | - (1ull << MSR_RI); - pcc->mmu_model = POWERPC_MMU_BOOKE206; - pcc->excp_model = POWERPC_EXCP_BOOKE; - pcc->bus_model = PPC_FLAGS_INPUT_BookE; - /* FIXME: figure out the correct flag for e500mc */ - pcc->bfd_mach = bfd_mach_ppc_e500; - pcc->flags = POWERPC_FLAG_CE | POWERPC_FLAG_DE | - POWERPC_FLAG_PMM | POWERPC_FLAG_BUS_CLK; -} - -#ifdef TARGET_PPC64 -static void init_proc_e5500(CPUPPCState *env) -{ - init_proc_e500(env, fsl_e5500); -} - -POWERPC_FAMILY(e5500)(ObjectClass *oc, void *data) -{ - DeviceClass *dc = DEVICE_CLASS(oc); - PowerPCCPUClass *pcc = POWERPC_CPU_CLASS(oc); - - dc->desc = "e5500 core"; - pcc->init_proc = init_proc_e5500; - pcc->check_pow = check_pow_none; - pcc->insns_flags = PPC_INSNS_BASE | PPC_ISEL | PPC_MFTB | - PPC_WRTEE | PPC_RFDI | PPC_RFMCI | - PPC_CACHE | PPC_CACHE_LOCK | PPC_CACHE_ICBI | - PPC_CACHE_DCBZ | PPC_CACHE_DCBA | - PPC_FLOAT | PPC_FLOAT_FRES | - PPC_FLOAT_FRSQRTE | PPC_FLOAT_FSEL | - PPC_FLOAT_STFIWX | PPC_WAIT | - PPC_MEM_TLBSYNC | PPC_TLBIVAX | PPC_MEM_SYNC | - PPC_64B | PPC_POPCNTB | PPC_POPCNTWD; - pcc->insns_flags2 = PPC2_BOOKE206 | PPC2_PRCNTL | PPC2_PERM_ISA206 | - PPC2_FP_CVT_S64; - pcc->msr_mask = (1ull << MSR_CM) | - (1ull << MSR_GS) | - (1ull << MSR_UCLE) | - (1ull << MSR_CE) | - (1ull << MSR_EE) | - (1ull << MSR_PR) | - (1ull << MSR_FP) | - (1ull << MSR_ME) | - (1ull << MSR_FE0) | - (1ull << MSR_DE) | - (1ull << MSR_FE1) | - (1ull << MSR_IR) | - (1ull << MSR_DR) | - (1ull << MSR_PX) | - (1ull << MSR_RI); - pcc->mmu_model = POWERPC_MMU_BOOKE206; - pcc->excp_model = POWERPC_EXCP_BOOKE; - pcc->bus_model = PPC_FLAGS_INPUT_BookE; - /* FIXME: figure out the correct flag for e5500 */ - pcc->bfd_mach = bfd_mach_ppc_e500; - pcc->flags = POWERPC_FLAG_CE | POWERPC_FLAG_DE | - POWERPC_FLAG_PMM | POWERPC_FLAG_BUS_CLK; -} - -static void init_proc_e6500(CPUPPCState *env) -{ - init_proc_e500(env, fsl_e6500); -} - -POWERPC_FAMILY(e6500)(ObjectClass *oc, void *data) -{ - DeviceClass *dc = DEVICE_CLASS(oc); - PowerPCCPUClass *pcc = POWERPC_CPU_CLASS(oc); - - dc->desc = "e6500 core"; - pcc->init_proc = init_proc_e6500; - pcc->check_pow = check_pow_none; - pcc->insns_flags = PPC_INSNS_BASE | PPC_ISEL | PPC_MFTB | - PPC_WRTEE | PPC_RFDI | PPC_RFMCI | - PPC_CACHE | PPC_CACHE_LOCK | PPC_CACHE_ICBI | - PPC_CACHE_DCBZ | PPC_CACHE_DCBA | - PPC_FLOAT | PPC_FLOAT_FRES | - PPC_FLOAT_FRSQRTE | PPC_FLOAT_FSEL | - PPC_FLOAT_STFIWX | PPC_WAIT | - PPC_MEM_TLBSYNC | PPC_TLBIVAX | PPC_MEM_SYNC | - PPC_64B | PPC_POPCNTB | PPC_POPCNTWD | PPC_ALTIVEC; - pcc->insns_flags2 = PPC2_BOOKE206 | PPC2_PRCNTL | PPC2_PERM_ISA206 | - PPC2_FP_CVT_S64 | PPC2_ATOMIC_ISA206; - pcc->msr_mask = (1ull << MSR_CM) | - (1ull << MSR_GS) | - (1ull << MSR_UCLE) | - (1ull << MSR_CE) | - (1ull << MSR_EE) | - (1ull << MSR_PR) | - (1ull << MSR_FP) | - (1ull << MSR_ME) | - (1ull << MSR_FE0) | - (1ull << MSR_DE) | - (1ull << MSR_FE1) | - (1ull << MSR_IS) | - (1ull << MSR_DS) | - (1ull << MSR_PX) | - (1ull << MSR_RI) | - (1ull << MSR_VR); - pcc->mmu_model = POWERPC_MMU_BOOKE206; - pcc->excp_model = POWERPC_EXCP_BOOKE; - pcc->bus_model = PPC_FLAGS_INPUT_BookE; - pcc->bfd_mach = bfd_mach_ppc_e500; - pcc->flags = POWERPC_FLAG_CE | POWERPC_FLAG_DE | - POWERPC_FLAG_PMM | POWERPC_FLAG_BUS_CLK | POWERPC_FLAG_VRE; -} - -#endif - #if defined(TARGET_PPC64) #if defined(CONFIG_USER_ONLY) #define POWERPC970_HID5_INIT 0x00000080 diff --git a/target/ppc/meson.build b/target/ppc/meson.build index aae1c2051e..6383fb8ebd 100644 --- a/target/ppc/meson.build +++ b/target/ppc/meson.build @@ -7,6 +7,7 @@ ppc_ss.add(files( 'cpu_6xx.c', 'cpu_7xx.c', 'cpu_74xx.c', + 'cpu_booke.c', 'excp_helper.c', 'gdbstub.c', 'helper_regs.c', From patchwork Tue Mar 1 13:56:11 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Fabiano Rosas X-Patchwork-Id: 12764755 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 327B6C433F5 for ; Tue, 1 Mar 2022 14:09:22 +0000 (UTC) Received: from localhost ([::1]:44640 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1nP3Bp-000776-0O for qemu-devel@archiver.kernel.org; Tue, 01 Mar 2022 09:09:21 -0500 Received: from eggs.gnu.org ([209.51.188.92]:33354) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1nP2zt-0006F3-3F; Tue, 01 Mar 2022 08:57:01 -0500 Received: from mx0a-001b2d01.pphosted.com ([148.163.156.1]:28320) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1nP2zm-00024T-NF; Tue, 01 Mar 2022 08:57:00 -0500 Received: from pps.filterd (m0098399.ppops.net [127.0.0.1]) by mx0a-001b2d01.pphosted.com (8.16.1.2/8.16.1.2) with SMTP id 221Dl6ks002259; Tue, 1 Mar 2022 13:56:48 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=4GYh6C69+bNBhtSg5j9v1eXHSmh4J6IQ+m19hUarJ6U=; b=FA8hVJEPSw2mykljwEgvTkdvWRsKumsLa/OKQxQqWfkKWHg9FQ1BFxv0Ln+oiVpmQIeg PowYaRUqdaWd5hJzPHUee8MWYrSuqOTJjBAvTc7/kC7VIe9bVwVlnmC1f3fRjPd5j/4Z 6NzKT3b1OBnSXM/UCjeUSCJpA+QVa0c2IonxNnW9Q1wuzSFFB1DqocgO6NOPhweQijxE NIaIk7J5JUazopYgpCQu+iFcHOiRGn/9eLkJxI8aBLA+FAorkTJYNz50fww01J2Pmn8J SCov2jU1olb5G4syzjI5BI+JA9/fWHvfdgpr5DhvZyHUvu1t0cdSBHrCEQBhC/hTcBdF RQ== Received: from pps.reinject (localhost [127.0.0.1]) by mx0a-001b2d01.pphosted.com with ESMTP id 3ehgc6phe8-1 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NOT); Tue, 01 Mar 2022 13:56:47 +0000 Received: from m0098399.ppops.net (m0098399.ppops.net [127.0.0.1]) by pps.reinject (8.16.0.43/8.16.0.43) with SMTP id 221DM0jA031950; Tue, 1 Mar 2022 13:56:47 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 3ehgc6phds-1 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NOT); Tue, 01 Mar 2022 13:56:47 +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 221DtS8Y024025; Tue, 1 Mar 2022 13:56:46 GMT Received: from b03cxnp08026.gho.boulder.ibm.com (b03cxnp08026.gho.boulder.ibm.com [9.17.130.18]) by ppma01dal.us.ibm.com with ESMTP id 3efbuac6mt-1 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NOT); Tue, 01 Mar 2022 13:56:45 +0000 Received: from b03ledav005.gho.boulder.ibm.com (b03ledav005.gho.boulder.ibm.com [9.17.130.236]) by b03cxnp08026.gho.boulder.ibm.com (8.14.9/8.14.9/NCO v10.0) with ESMTP id 221DuiTH35848526 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-GCM-SHA384 bits=256 verify=OK); Tue, 1 Mar 2022 13:56:44 GMT Received: from b03ledav005.gho.boulder.ibm.com (unknown [127.0.0.1]) by IMSVA (Postfix) with ESMTP id 14122BE053; Tue, 1 Mar 2022 13:56:44 +0000 (GMT) Received: from b03ledav005.gho.boulder.ibm.com (unknown [127.0.0.1]) by IMSVA (Postfix) with ESMTP id 5998CBE04F; Tue, 1 Mar 2022 13:56:42 +0000 (GMT) Received: from farosas.linux.ibm.com.com (unknown [9.211.51.129]) by b03ledav005.gho.boulder.ibm.com (Postfix) with ESMTP; Tue, 1 Mar 2022 13:56:42 +0000 (GMT) From: Fabiano Rosas To: qemu-devel@nongnu.org Subject: [PATCH 08/17] target/ppc: Move BookS CPUs to their own file Date: Tue, 1 Mar 2022 10:56:11 -0300 Message-Id: <20220301135620.2411952-9-farosas@linux.ibm.com> X-Mailer: git-send-email 2.34.1 In-Reply-To: <20220301135620.2411952-1-farosas@linux.ibm.com> References: <20220301135620.2411952-1-farosas@linux.ibm.com> MIME-Version: 1.0 X-TM-AS-GCONF: 00 X-Proofpoint-GUID: 6hMg3Ip0ZuzOoSkRb3kg-KQJ6aqTPMHz X-Proofpoint-ORIG-GUID: jpr1vXA7EyFIfOLHQ3C-sgWwKzaU_BeN X-Proofpoint-Virus-Version: vendor=baseguard engine=ICAP:2.0.205,Aquarius:18.0.816,Hydra:6.0.425,FMLib:17.11.64.514 definitions=2022-03-01_07,2022-02-26_01,2022-02-23_01 X-Proofpoint-Spam-Details: rule=outbound_notspam policy=outbound score=0 mlxscore=0 mlxlogscore=999 spamscore=0 malwarescore=0 impostorscore=0 adultscore=0 suspectscore=0 lowpriorityscore=0 phishscore=0 priorityscore=1501 clxscore=1015 bulkscore=0 classifier=spam adjust=0 reason=mlx scancount=1 engine=8.12.0-2201110000 definitions=main-2203010074 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_H5=0.001, RCVD_IN_MSPIKE_WL=0.001, SPF_HELO_NONE=0.001, SPF_PASS=-0.001, T_SCC_BODY_TEXT_LINE=-0.01 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" Affects the 970, POWER5P, POWER7, POWER8, POWER9, POWER10. This moves init_proc, init_excp and register_*sprs functions that are related to the BookS CPUs into a separate file. Other routines that were brought along are: the Radix page size encodings, the PVR match, cpu_has_work and PMU intialization. These are all specific to BookS. The BookS CPUs are all 64-bits so this new file goes under the TARGET_PPC64 config. Signed-off-by: Fabiano Rosas --- target/ppc/cpu_books.c | 1770 ++++++++++++++++++++++++++++++++++++++++ target/ppc/cpu_init.c | 1761 --------------------------------------- target/ppc/meson.build | 1 + 3 files changed, 1771 insertions(+), 1761 deletions(-) create mode 100644 target/ppc/cpu_books.c diff --git a/target/ppc/cpu_books.c b/target/ppc/cpu_books.c new file mode 100644 index 0000000000..01943140a3 --- /dev/null +++ b/target/ppc/cpu_books.c @@ -0,0 +1,1770 @@ +/* + * CPU initialization for PowerPC BookS CPUs + * + * Copyright IBM Corp. 2022 + * + * This work is licensed under the terms of the GNU GPL, version 2 or later. + * See the COPYING file in the top-level directory. + */ + +#include "qemu/osdep.h" +#include "sysemu/hw_accel.h" +#include "sysemu/tcg.h" +#include "hw/ppc/ppc.h" +#include "fpu/softfloat.h" +#include "cpu.h" +#include "spr_common.h" +#include "power8-pmu.h" +#include "cpu-models.h" +#include "mmu-hash64.h" + +#if defined(CONFIG_USER_ONLY) +#define POWERPC970_HID5_INIT 0x00000080 +#else +#define POWERPC970_HID5_INIT 0x00000000 + + +static inline void vscr_init(CPUPPCState *env, uint32_t val) +{ + /* Altivec always uses round-to-nearest */ + set_float_rounding_mode(float_round_nearest_even, &env->vec_status); + ppc_store_vscr(env, val); +} + +#ifdef CONFIG_SOFTMMU +/* + * Radix pg sizes and AP encodings for dt node ibm,processor-radix-AP-encodings + * Encoded as array of int_32s in the form: + * 0bxxxyyyyyyyyyyyyyyyyyyyyyyyyyyyyy + * x -> AP encoding + * y -> radix mode supported page size (encoded as a shift) + */ +static struct ppc_radix_page_info POWER9_radix_page_info = { + .count = 4, + .entries = { + 0x0000000c, /* 4K - enc: 0x0 */ + 0xa0000010, /* 64K - enc: 0x5 */ + 0x20000015, /* 2M - enc: 0x1 */ + 0x4000001e /* 1G - enc: 0x2 */ + } +}; + +/* + * Radix pg sizes and AP encodings for dt node ibm,processor-radix-AP-encodings + * Encoded as array of int_32s in the form: + * 0bxxxyyyyyyyyyyyyyyyyyyyyyyyyyyyyy + * x -> AP encoding + * y -> radix mode supported page size (encoded as a shift) + */ +static struct ppc_radix_page_info POWER10_radix_page_info = { + .count = 4, + .entries = { + 0x0000000c, /* 4K - enc: 0x0 */ + 0xa0000010, /* 64K - enc: 0x5 */ + 0x20000015, /* 2M - enc: 0x1 */ + 0x4000001e /* 1G - enc: 0x2 */ + } +}; +#endif /* CONFIG_SOFTMMU */ + +static bool ppc_pvr_match_power7(PowerPCCPUClass *pcc, uint32_t pvr) +{ + if ((pvr & CPU_POWERPC_POWER_SERVER_MASK) == CPU_POWERPC_POWER7P_BASE) { + return true; + } + if ((pvr & CPU_POWERPC_POWER_SERVER_MASK) == CPU_POWERPC_POWER7_BASE) { + return true; + } + return false; +} + +static bool cpu_has_work_POWER7(CPUState *cs) +{ + PowerPCCPU *cpu = POWERPC_CPU(cs); + CPUPPCState *env = &cpu->env; + + if (cs->halted) { + if (!(cs->interrupt_request & CPU_INTERRUPT_HARD)) { + return false; + } + if ((env->pending_interrupts & (1u << PPC_INTERRUPT_EXT)) && + (env->spr[SPR_LPCR] & LPCR_P7_PECE0)) { + return true; + } + if ((env->pending_interrupts & (1u << PPC_INTERRUPT_DECR)) && + (env->spr[SPR_LPCR] & LPCR_P7_PECE1)) { + return true; + } + if ((env->pending_interrupts & (1u << PPC_INTERRUPT_MCK)) && + (env->spr[SPR_LPCR] & LPCR_P7_PECE2)) { + return true; + } + if ((env->pending_interrupts & (1u << PPC_INTERRUPT_HMI)) && + (env->spr[SPR_LPCR] & LPCR_P7_PECE2)) { + return true; + } + if (env->pending_interrupts & (1u << PPC_INTERRUPT_RESET)) { + return true; + } + return false; + } else { + return msr_ee && (cs->interrupt_request & CPU_INTERRUPT_HARD); + } +} + +static bool ppc_pvr_match_power8(PowerPCCPUClass *pcc, uint32_t pvr) +{ + if ((pvr & CPU_POWERPC_POWER_SERVER_MASK) == CPU_POWERPC_POWER8NVL_BASE) { + return true; + } + if ((pvr & CPU_POWERPC_POWER_SERVER_MASK) == CPU_POWERPC_POWER8E_BASE) { + return true; + } + if ((pvr & CPU_POWERPC_POWER_SERVER_MASK) == CPU_POWERPC_POWER8_BASE) { + return true; + } + return false; +} + +static bool cpu_has_work_POWER8(CPUState *cs) +{ + PowerPCCPU *cpu = POWERPC_CPU(cs); + CPUPPCState *env = &cpu->env; + + if (cs->halted) { + if (!(cs->interrupt_request & CPU_INTERRUPT_HARD)) { + return false; + } + if ((env->pending_interrupts & (1u << PPC_INTERRUPT_EXT)) && + (env->spr[SPR_LPCR] & LPCR_P8_PECE2)) { + return true; + } + if ((env->pending_interrupts & (1u << PPC_INTERRUPT_DECR)) && + (env->spr[SPR_LPCR] & LPCR_P8_PECE3)) { + return true; + } + if ((env->pending_interrupts & (1u << PPC_INTERRUPT_MCK)) && + (env->spr[SPR_LPCR] & LPCR_P8_PECE4)) { + return true; + } + if ((env->pending_interrupts & (1u << PPC_INTERRUPT_HMI)) && + (env->spr[SPR_LPCR] & LPCR_P8_PECE4)) { + return true; + } + if ((env->pending_interrupts & (1u << PPC_INTERRUPT_DOORBELL)) && + (env->spr[SPR_LPCR] & LPCR_P8_PECE0)) { + return true; + } + if ((env->pending_interrupts & (1u << PPC_INTERRUPT_HDOORBELL)) && + (env->spr[SPR_LPCR] & LPCR_P8_PECE1)) { + return true; + } + if (env->pending_interrupts & (1u << PPC_INTERRUPT_RESET)) { + return true; + } + return false; + } else { + return msr_ee && (cs->interrupt_request & CPU_INTERRUPT_HARD); + } +} + +static bool ppc_pvr_match_power9(PowerPCCPUClass *pcc, uint32_t pvr) +{ + if ((pvr & CPU_POWERPC_POWER_SERVER_MASK) == CPU_POWERPC_POWER9_BASE) { + return true; + } + return false; +} + +static bool cpu_has_work_POWER9(CPUState *cs) +{ + PowerPCCPU *cpu = POWERPC_CPU(cs); + CPUPPCState *env = &cpu->env; + + if (cs->halted) { + uint64_t psscr = env->spr[SPR_PSSCR]; + + if (!(cs->interrupt_request & CPU_INTERRUPT_HARD)) { + return false; + } + + /* If EC is clear, just return true on any pending interrupt */ + if (!(psscr & PSSCR_EC)) { + return true; + } + /* External Exception */ + if ((env->pending_interrupts & (1u << PPC_INTERRUPT_EXT)) && + (env->spr[SPR_LPCR] & LPCR_EEE)) { + bool heic = !!(env->spr[SPR_LPCR] & LPCR_HEIC); + if (heic == 0 || !msr_hv || msr_pr) { + return true; + } + } + /* Decrementer Exception */ + if ((env->pending_interrupts & (1u << PPC_INTERRUPT_DECR)) && + (env->spr[SPR_LPCR] & LPCR_DEE)) { + return true; + } + /* Machine Check or Hypervisor Maintenance Exception */ + if ((env->pending_interrupts & (1u << PPC_INTERRUPT_MCK | + 1u << PPC_INTERRUPT_HMI)) && (env->spr[SPR_LPCR] & LPCR_OEE)) { + return true; + } + /* Privileged Doorbell Exception */ + if ((env->pending_interrupts & (1u << PPC_INTERRUPT_DOORBELL)) && + (env->spr[SPR_LPCR] & LPCR_PDEE)) { + return true; + } + /* Hypervisor Doorbell Exception */ + if ((env->pending_interrupts & (1u << PPC_INTERRUPT_HDOORBELL)) && + (env->spr[SPR_LPCR] & LPCR_HDEE)) { + return true; + } + /* Hypervisor virtualization exception */ + if ((env->pending_interrupts & (1u << PPC_INTERRUPT_HVIRT)) && + (env->spr[SPR_LPCR] & LPCR_HVEE)) { + return true; + } + if (env->pending_interrupts & (1u << PPC_INTERRUPT_RESET)) { + return true; + } + return false; + } else { + return msr_ee && (cs->interrupt_request & CPU_INTERRUPT_HARD); + } +} + +static bool ppc_pvr_match_power10(PowerPCCPUClass *pcc, uint32_t pvr) +{ + if ((pvr & CPU_POWERPC_POWER_SERVER_MASK) == CPU_POWERPC_POWER10_BASE) { + return true; + } + return false; +} + +static bool cpu_has_work_POWER10(CPUState *cs) +{ + PowerPCCPU *cpu = POWERPC_CPU(cs); + CPUPPCState *env = &cpu->env; + + if (cs->halted) { + uint64_t psscr = env->spr[SPR_PSSCR]; + + if (!(cs->interrupt_request & CPU_INTERRUPT_HARD)) { + return false; + } + + /* If EC is clear, just return true on any pending interrupt */ + if (!(psscr & PSSCR_EC)) { + return true; + } + /* External Exception */ + if ((env->pending_interrupts & (1u << PPC_INTERRUPT_EXT)) && + (env->spr[SPR_LPCR] & LPCR_EEE)) { + bool heic = !!(env->spr[SPR_LPCR] & LPCR_HEIC); + if (heic == 0 || !msr_hv || msr_pr) { + return true; + } + } + /* Decrementer Exception */ + if ((env->pending_interrupts & (1u << PPC_INTERRUPT_DECR)) && + (env->spr[SPR_LPCR] & LPCR_DEE)) { + return true; + } + /* Machine Check or Hypervisor Maintenance Exception */ + if ((env->pending_interrupts & (1u << PPC_INTERRUPT_MCK | + 1u << PPC_INTERRUPT_HMI)) && (env->spr[SPR_LPCR] & LPCR_OEE)) { + return true; + } + /* Privileged Doorbell Exception */ + if ((env->pending_interrupts & (1u << PPC_INTERRUPT_DOORBELL)) && + (env->spr[SPR_LPCR] & LPCR_PDEE)) { + return true; + } + /* Hypervisor Doorbell Exception */ + if ((env->pending_interrupts & (1u << PPC_INTERRUPT_HDOORBELL)) && + (env->spr[SPR_LPCR] & LPCR_HDEE)) { + return true; + } + /* Hypervisor virtualization exception */ + if ((env->pending_interrupts & (1u << PPC_INTERRUPT_HVIRT)) && + (env->spr[SPR_LPCR] & LPCR_HVEE)) { + return true; + } + if (env->pending_interrupts & (1u << PPC_INTERRUPT_RESET)) { + return true; + } + return false; + } else { + return msr_ee && (cs->interrupt_request & CPU_INTERRUPT_HARD); + } +} + +static void init_excp_970(CPUPPCState *env) +{ +#if !defined(CONFIG_USER_ONLY) + env->excp_vectors[POWERPC_EXCP_RESET] = 0x00000100; + env->excp_vectors[POWERPC_EXCP_MCHECK] = 0x00000200; + env->excp_vectors[POWERPC_EXCP_DSI] = 0x00000300; + env->excp_vectors[POWERPC_EXCP_DSEG] = 0x00000380; + env->excp_vectors[POWERPC_EXCP_ISI] = 0x00000400; + env->excp_vectors[POWERPC_EXCP_ISEG] = 0x00000480; + env->excp_vectors[POWERPC_EXCP_EXTERNAL] = 0x00000500; + env->excp_vectors[POWERPC_EXCP_ALIGN] = 0x00000600; + env->excp_vectors[POWERPC_EXCP_PROGRAM] = 0x00000700; + env->excp_vectors[POWERPC_EXCP_FPU] = 0x00000800; + env->excp_vectors[POWERPC_EXCP_DECR] = 0x00000900; + env->excp_vectors[POWERPC_EXCP_HDECR] = 0x00000980; + env->excp_vectors[POWERPC_EXCP_SYSCALL] = 0x00000C00; + env->excp_vectors[POWERPC_EXCP_TRACE] = 0x00000D00; + env->excp_vectors[POWERPC_EXCP_PERFM] = 0x00000F00; + env->excp_vectors[POWERPC_EXCP_VPU] = 0x00000F20; + env->excp_vectors[POWERPC_EXCP_IABR] = 0x00001300; + env->excp_vectors[POWERPC_EXCP_MAINT] = 0x00001600; + env->excp_vectors[POWERPC_EXCP_VPUA] = 0x00001700; + env->excp_vectors[POWERPC_EXCP_THERM] = 0x00001800; + /* Hardware reset vector */ + env->hreset_vector = 0x0000000000000100ULL; +#endif +} + +static void init_excp_POWER7(CPUPPCState *env) +{ +#if !defined(CONFIG_USER_ONLY) + env->excp_vectors[POWERPC_EXCP_RESET] = 0x00000100; + env->excp_vectors[POWERPC_EXCP_MCHECK] = 0x00000200; + env->excp_vectors[POWERPC_EXCP_DSI] = 0x00000300; + env->excp_vectors[POWERPC_EXCP_DSEG] = 0x00000380; + env->excp_vectors[POWERPC_EXCP_ISI] = 0x00000400; + env->excp_vectors[POWERPC_EXCP_ISEG] = 0x00000480; + env->excp_vectors[POWERPC_EXCP_EXTERNAL] = 0x00000500; + env->excp_vectors[POWERPC_EXCP_ALIGN] = 0x00000600; + env->excp_vectors[POWERPC_EXCP_PROGRAM] = 0x00000700; + env->excp_vectors[POWERPC_EXCP_FPU] = 0x00000800; + env->excp_vectors[POWERPC_EXCP_DECR] = 0x00000900; + env->excp_vectors[POWERPC_EXCP_HDECR] = 0x00000980; + env->excp_vectors[POWERPC_EXCP_SYSCALL] = 0x00000C00; + env->excp_vectors[POWERPC_EXCP_TRACE] = 0x00000D00; + env->excp_vectors[POWERPC_EXCP_HDSI] = 0x00000E00; + env->excp_vectors[POWERPC_EXCP_HISI] = 0x00000E20; + env->excp_vectors[POWERPC_EXCP_HV_EMU] = 0x00000E40; + env->excp_vectors[POWERPC_EXCP_HV_MAINT] = 0x00000E60; + env->excp_vectors[POWERPC_EXCP_PERFM] = 0x00000F00; + env->excp_vectors[POWERPC_EXCP_VPU] = 0x00000F20; + env->excp_vectors[POWERPC_EXCP_VSXU] = 0x00000F40; + /* Hardware reset vector */ + env->hreset_vector = 0x0000000000000100ULL; +#endif +} + +static void init_excp_POWER8(CPUPPCState *env) +{ + init_excp_POWER7(env); + +#if !defined(CONFIG_USER_ONLY) + env->excp_vectors[POWERPC_EXCP_SDOOR] = 0x00000A00; + env->excp_vectors[POWERPC_EXCP_FU] = 0x00000F60; + env->excp_vectors[POWERPC_EXCP_HV_FU] = 0x00000F80; + env->excp_vectors[POWERPC_EXCP_SDOOR_HV] = 0x00000E80; + + /* Userland exceptions without vector value in PowerISA v3.1 */ + env->excp_vectors[POWERPC_EXCP_PERFM_EBB] = 0x0; + env->excp_vectors[POWERPC_EXCP_EXTERNAL_EBB] = 0x0; +#endif +} + +static void init_excp_POWER9(CPUPPCState *env) +{ + init_excp_POWER8(env); + +#if !defined(CONFIG_USER_ONLY) + env->excp_vectors[POWERPC_EXCP_HVIRT] = 0x00000EA0; + env->excp_vectors[POWERPC_EXCP_SYSCALL_VECTORED] = 0x00017000; +#endif +} + +static void init_excp_POWER10(CPUPPCState *env) +{ + init_excp_POWER9(env); +} + +#endif + +static int check_pow_970(CPUPPCState *env) +{ + if (env->spr[SPR_HID0] & (HID0_DEEPNAP | HID0_DOZE | HID0_NAP)) { + return 1; + } + + return 0; +} + +static void register_amr_sprs(CPUPPCState *env) +{ +#ifndef CONFIG_USER_ONLY + /* + * Virtual Page Class Key protection + * + * The AMR is accessible either via SPR 13 or SPR 29. 13 is + * userspace accessible, 29 is privileged. So we only need to set + * the kvm ONE_REG id on one of them, we use 29 + */ + spr_register(env, SPR_UAMR, "UAMR", + &spr_read_generic, &spr_write_amr, + &spr_read_generic, &spr_write_amr, + 0); + spr_register_kvm_hv(env, SPR_AMR, "AMR", + SPR_NOACCESS, SPR_NOACCESS, + &spr_read_generic, &spr_write_amr, + &spr_read_generic, &spr_write_generic, + KVM_REG_PPC_AMR, 0); + spr_register_kvm_hv(env, SPR_UAMOR, "UAMOR", + SPR_NOACCESS, SPR_NOACCESS, + &spr_read_generic, &spr_write_uamor, + &spr_read_generic, &spr_write_generic, + KVM_REG_PPC_UAMOR, 0); + spr_register_hv(env, SPR_AMOR, "AMOR", + SPR_NOACCESS, SPR_NOACCESS, + SPR_NOACCESS, SPR_NOACCESS, + &spr_read_generic, &spr_write_generic, + 0); +#endif /* !CONFIG_USER_ONLY */ +} + +static void register_iamr_sprs(CPUPPCState *env) +{ +#ifndef CONFIG_USER_ONLY + spr_register_kvm_hv(env, SPR_IAMR, "IAMR", + SPR_NOACCESS, SPR_NOACCESS, + &spr_read_generic, &spr_write_iamr, + &spr_read_generic, &spr_write_generic, + KVM_REG_PPC_IAMR, 0); +#endif /* !CONFIG_USER_ONLY */ +} + +static void register_970_hid_sprs(CPUPPCState *env) +{ + /* Hardware implementation registers */ + spr_register(env, SPR_HID0, "HID0", + SPR_NOACCESS, SPR_NOACCESS, + &spr_read_generic, &spr_write_clear, + 0x60000000); + spr_register(env, SPR_HID1, "HID1", + SPR_NOACCESS, SPR_NOACCESS, + &spr_read_generic, &spr_write_generic, + 0x00000000); + spr_register(env, SPR_970_HID5, "HID5", + SPR_NOACCESS, SPR_NOACCESS, + &spr_read_generic, &spr_write_generic, + POWERPC970_HID5_INIT); +} + +static void register_970_hior_sprs(CPUPPCState *env) +{ + spr_register(env, SPR_HIOR, "SPR_HIOR", + SPR_NOACCESS, SPR_NOACCESS, + &spr_read_hior, &spr_write_hior, + 0x00000000); +} + +static void register_book3s_ctrl_sprs(CPUPPCState *env) +{ + spr_register(env, SPR_CTRL, "SPR_CTRL", + SPR_NOACCESS, SPR_NOACCESS, + SPR_NOACCESS, &spr_write_CTRL, + 0x00000000); + spr_register(env, SPR_UCTRL, "SPR_UCTRL", + &spr_read_ureg, SPR_NOACCESS, + &spr_read_ureg, SPR_NOACCESS, + 0x00000000); +} + +static void register_book3s_altivec_sprs(CPUPPCState *env) +{ + if (!(env->insns_flags & PPC_ALTIVEC)) { + return; + } + + spr_register_kvm(env, SPR_VRSAVE, "VRSAVE", + &spr_read_generic, &spr_write_generic, + &spr_read_generic, &spr_write_generic, + KVM_REG_PPC_VRSAVE, 0x00000000); + +} + +static void register_book3s_dbg_sprs(CPUPPCState *env) +{ + /* + * TODO: different specs define different scopes for these, + * will have to address this: + * 970: super/write and super/read + * powerisa 2.03..2.04: hypv/write and super/read. + * powerisa 2.05 and newer: hypv/write and hypv/read. + */ + spr_register_kvm(env, SPR_DABR, "DABR", + SPR_NOACCESS, SPR_NOACCESS, + &spr_read_generic, &spr_write_generic, + KVM_REG_PPC_DABR, 0x00000000); + spr_register_kvm(env, SPR_DABRX, "DABRX", + SPR_NOACCESS, SPR_NOACCESS, + &spr_read_generic, &spr_write_generic, + KVM_REG_PPC_DABRX, 0x00000000); +} + +static void register_book3s_207_dbg_sprs(CPUPPCState *env) +{ + spr_register_kvm_hv(env, SPR_DAWR0, "DAWR0", + SPR_NOACCESS, SPR_NOACCESS, + SPR_NOACCESS, SPR_NOACCESS, + &spr_read_generic, &spr_write_generic, + KVM_REG_PPC_DAWR, 0x00000000); + spr_register_kvm_hv(env, SPR_DAWRX0, "DAWRX0", + SPR_NOACCESS, SPR_NOACCESS, + SPR_NOACCESS, SPR_NOACCESS, + &spr_read_generic, &spr_write_generic, + KVM_REG_PPC_DAWRX, 0x00000000); + spr_register_kvm_hv(env, SPR_CIABR, "CIABR", + SPR_NOACCESS, SPR_NOACCESS, + SPR_NOACCESS, SPR_NOACCESS, + &spr_read_generic, &spr_write_generic, + KVM_REG_PPC_CIABR, 0x00000000); +} + +static void register_970_dbg_sprs(CPUPPCState *env) +{ + /* Breakpoints */ + spr_register(env, SPR_IABR, "IABR", + SPR_NOACCESS, SPR_NOACCESS, + &spr_read_generic, &spr_write_generic, + 0x00000000); +} + +static void register_book3s_pmu_sup_sprs(CPUPPCState *env) +{ + spr_register_kvm(env, SPR_POWER_MMCR0, "MMCR0", + SPR_NOACCESS, SPR_NOACCESS, + &spr_read_generic, &spr_write_MMCR0, + KVM_REG_PPC_MMCR0, 0x80000000); + spr_register_kvm(env, SPR_POWER_MMCR1, "MMCR1", + SPR_NOACCESS, SPR_NOACCESS, + &spr_read_generic, &spr_write_MMCR1, + KVM_REG_PPC_MMCR1, 0x00000000); + spr_register_kvm(env, SPR_POWER_MMCRA, "MMCRA", + SPR_NOACCESS, SPR_NOACCESS, + &spr_read_generic, &spr_write_generic, + KVM_REG_PPC_MMCRA, 0x00000000); + spr_register_kvm(env, SPR_POWER_PMC1, "PMC1", + SPR_NOACCESS, SPR_NOACCESS, + &spr_read_PMC, &spr_write_PMC, + KVM_REG_PPC_PMC1, 0x00000000); + spr_register_kvm(env, SPR_POWER_PMC2, "PMC2", + SPR_NOACCESS, SPR_NOACCESS, + &spr_read_PMC, &spr_write_PMC, + KVM_REG_PPC_PMC2, 0x00000000); + spr_register_kvm(env, SPR_POWER_PMC3, "PMC3", + SPR_NOACCESS, SPR_NOACCESS, + &spr_read_PMC, &spr_write_PMC, + KVM_REG_PPC_PMC3, 0x00000000); + spr_register_kvm(env, SPR_POWER_PMC4, "PMC4", + SPR_NOACCESS, SPR_NOACCESS, + &spr_read_PMC, &spr_write_PMC, + KVM_REG_PPC_PMC4, 0x00000000); + spr_register_kvm(env, SPR_POWER_PMC5, "PMC5", + SPR_NOACCESS, SPR_NOACCESS, + &spr_read_PMC, &spr_write_PMC, + KVM_REG_PPC_PMC5, 0x00000000); + spr_register_kvm(env, SPR_POWER_PMC6, "PMC6", + SPR_NOACCESS, SPR_NOACCESS, + &spr_read_PMC, &spr_write_PMC, + KVM_REG_PPC_PMC6, 0x00000000); + spr_register_kvm(env, SPR_POWER_SIAR, "SIAR", + SPR_NOACCESS, SPR_NOACCESS, + &spr_read_generic, &spr_write_generic, + KVM_REG_PPC_SIAR, 0x00000000); + spr_register_kvm(env, SPR_POWER_SDAR, "SDAR", + SPR_NOACCESS, SPR_NOACCESS, + &spr_read_generic, &spr_write_generic, + KVM_REG_PPC_SDAR, 0x00000000); +} + +static void register_book3s_pmu_user_sprs(CPUPPCState *env) +{ + spr_register(env, SPR_POWER_UMMCR0, "UMMCR0", + &spr_read_MMCR0_ureg, &spr_write_MMCR0_ureg, + &spr_read_ureg, &spr_write_ureg, + 0x80000000); + spr_register(env, SPR_POWER_UMMCR1, "UMMCR1", + &spr_read_ureg, SPR_NOACCESS, + &spr_read_ureg, &spr_write_ureg, + 0x00000000); + spr_register(env, SPR_POWER_UMMCRA, "UMMCRA", + &spr_read_ureg, SPR_NOACCESS, + &spr_read_ureg, &spr_write_ureg, + 0x00000000); + spr_register(env, SPR_POWER_UPMC1, "UPMC1", + &spr_read_PMC14_ureg, &spr_write_PMC14_ureg, + &spr_read_ureg, &spr_write_ureg, + 0x00000000); + spr_register(env, SPR_POWER_UPMC2, "UPMC2", + &spr_read_PMC14_ureg, &spr_write_PMC14_ureg, + &spr_read_ureg, &spr_write_ureg, + 0x00000000); + spr_register(env, SPR_POWER_UPMC3, "UPMC3", + &spr_read_PMC14_ureg, &spr_write_PMC14_ureg, + &spr_read_ureg, &spr_write_ureg, + 0x00000000); + spr_register(env, SPR_POWER_UPMC4, "UPMC4", + &spr_read_PMC14_ureg, &spr_write_PMC14_ureg, + &spr_read_ureg, &spr_write_ureg, + 0x00000000); + spr_register(env, SPR_POWER_UPMC5, "UPMC5", + &spr_read_PMC56_ureg, &spr_write_PMC56_ureg, + &spr_read_ureg, &spr_write_ureg, + 0x00000000); + spr_register(env, SPR_POWER_UPMC6, "UPMC6", + &spr_read_PMC56_ureg, &spr_write_PMC56_ureg, + &spr_read_ureg, &spr_write_ureg, + 0x00000000); + spr_register(env, SPR_POWER_USIAR, "USIAR", + &spr_read_ureg, SPR_NOACCESS, + &spr_read_ureg, &spr_write_ureg, + 0x00000000); + spr_register(env, SPR_POWER_USDAR, "USDAR", + &spr_read_ureg, SPR_NOACCESS, + &spr_read_ureg, &spr_write_ureg, + 0x00000000); +} + +static void register_970_pmu_sup_sprs(CPUPPCState *env) +{ + spr_register_kvm(env, SPR_970_PMC7, "PMC7", + SPR_NOACCESS, SPR_NOACCESS, + &spr_read_generic, &spr_write_generic, + KVM_REG_PPC_PMC7, 0x00000000); + spr_register_kvm(env, SPR_970_PMC8, "PMC8", + SPR_NOACCESS, SPR_NOACCESS, + &spr_read_generic, &spr_write_generic, + KVM_REG_PPC_PMC8, 0x00000000); +} + +static void register_970_pmu_user_sprs(CPUPPCState *env) +{ + spr_register(env, SPR_970_UPMC7, "UPMC7", + &spr_read_ureg, SPR_NOACCESS, + &spr_read_ureg, &spr_write_ureg, + 0x00000000); + spr_register(env, SPR_970_UPMC8, "UPMC8", + &spr_read_ureg, SPR_NOACCESS, + &spr_read_ureg, &spr_write_ureg, + 0x00000000); +} + +static void register_power8_pmu_sup_sprs(CPUPPCState *env) +{ + spr_register_kvm(env, SPR_POWER_MMCR2, "MMCR2", + SPR_NOACCESS, SPR_NOACCESS, + &spr_read_generic, &spr_write_generic, + KVM_REG_PPC_MMCR2, 0x00000000); + spr_register_kvm(env, SPR_POWER_MMCRS, "MMCRS", + SPR_NOACCESS, SPR_NOACCESS, + &spr_read_generic, &spr_write_generic, + KVM_REG_PPC_MMCRS, 0x00000000); + spr_register_kvm(env, SPR_POWER_SIER, "SIER", + SPR_NOACCESS, SPR_NOACCESS, + &spr_read_generic, &spr_write_generic, + KVM_REG_PPC_SIER, 0x00000000); + spr_register_kvm(env, SPR_POWER_SPMC1, "SPMC1", + SPR_NOACCESS, SPR_NOACCESS, + &spr_read_generic, &spr_write_generic, + KVM_REG_PPC_SPMC1, 0x00000000); + spr_register_kvm(env, SPR_POWER_SPMC2, "SPMC2", + SPR_NOACCESS, SPR_NOACCESS, + &spr_read_generic, &spr_write_generic, + KVM_REG_PPC_SPMC2, 0x00000000); + spr_register_kvm(env, SPR_TACR, "TACR", + SPR_NOACCESS, SPR_NOACCESS, + &spr_read_generic, &spr_write_generic, + KVM_REG_PPC_TACR, 0x00000000); + spr_register_kvm(env, SPR_TCSCR, "TCSCR", + SPR_NOACCESS, SPR_NOACCESS, + &spr_read_generic, &spr_write_generic, + KVM_REG_PPC_TCSCR, 0x00000000); + spr_register_kvm(env, SPR_CSIGR, "CSIGR", + SPR_NOACCESS, SPR_NOACCESS, + &spr_read_generic, &spr_write_generic, + KVM_REG_PPC_CSIGR, 0x00000000); +} + +static void register_power8_pmu_user_sprs(CPUPPCState *env) +{ + spr_register(env, SPR_POWER_UMMCR2, "UMMCR2", + &spr_read_MMCR2_ureg, &spr_write_MMCR2_ureg, + &spr_read_ureg, &spr_write_ureg, + 0x00000000); + spr_register(env, SPR_POWER_USIER, "USIER", + &spr_read_generic, SPR_NOACCESS, + &spr_read_generic, &spr_write_generic, + 0x00000000); +} + +static void register_power5p_ear_sprs(CPUPPCState *env) +{ + /* External access control */ + spr_register(env, SPR_EAR, "EAR", + SPR_NOACCESS, SPR_NOACCESS, + &spr_read_generic, &spr_write_generic, + 0x00000000); +} + +static void register_power5p_tb_sprs(CPUPPCState *env) +{ + /* TBU40 (High 40 bits of the Timebase register */ + spr_register_hv(env, SPR_TBU40, "TBU40", + SPR_NOACCESS, SPR_NOACCESS, + SPR_NOACCESS, SPR_NOACCESS, + SPR_NOACCESS, &spr_write_tbu40, + 0x00000000); +} + +static void register_970_lpar_sprs(CPUPPCState *env) +{ +#if !defined(CONFIG_USER_ONLY) + /* + * PPC970: HID4 covers things later controlled by the LPCR and + * RMOR in later CPUs, but with a different encoding. We only + * support the 970 in "Apple mode" which has all hypervisor + * facilities disabled by strapping, so we can basically just + * ignore it + */ + spr_register(env, SPR_970_HID4, "HID4", + SPR_NOACCESS, SPR_NOACCESS, + &spr_read_generic, &spr_write_generic, + 0x00000000); +#endif +} + +static void register_power5p_lpar_sprs(CPUPPCState *env) +{ +#if !defined(CONFIG_USER_ONLY) + /* Logical partitionning */ + spr_register_kvm_hv(env, SPR_LPCR, "LPCR", + SPR_NOACCESS, SPR_NOACCESS, + SPR_NOACCESS, SPR_NOACCESS, + &spr_read_generic, &spr_write_lpcr, + KVM_REG_PPC_LPCR, LPCR_LPES0 | LPCR_LPES1); + spr_register_hv(env, SPR_HDEC, "HDEC", + SPR_NOACCESS, SPR_NOACCESS, + SPR_NOACCESS, SPR_NOACCESS, + &spr_read_hdecr, &spr_write_hdecr, 0); +#endif +} + +static void register_book3s_ids_sprs(CPUPPCState *env) +{ + /* FIXME: Will need to deal with thread vs core only SPRs */ + + /* Processor identification */ + spr_register_hv(env, SPR_PIR, "PIR", + SPR_NOACCESS, SPR_NOACCESS, + &spr_read_generic, SPR_NOACCESS, + &spr_read_generic, NULL, + 0x00000000); + spr_register_hv(env, SPR_HID0, "HID0", + SPR_NOACCESS, SPR_NOACCESS, + SPR_NOACCESS, SPR_NOACCESS, + &spr_read_generic, &spr_write_generic, + 0x00000000); + spr_register_hv(env, SPR_TSCR, "TSCR", + SPR_NOACCESS, SPR_NOACCESS, + SPR_NOACCESS, SPR_NOACCESS, + &spr_read_generic, &spr_write_generic, + 0x00000000); + spr_register_hv(env, SPR_HMER, "HMER", + SPR_NOACCESS, SPR_NOACCESS, + SPR_NOACCESS, SPR_NOACCESS, + &spr_read_generic, &spr_write_hmer, + 0x00000000); + spr_register_hv(env, SPR_HMEER, "HMEER", + SPR_NOACCESS, SPR_NOACCESS, + SPR_NOACCESS, SPR_NOACCESS, + &spr_read_generic, &spr_write_generic, + 0x00000000); + spr_register_hv(env, SPR_TFMR, "TFMR", + SPR_NOACCESS, SPR_NOACCESS, + SPR_NOACCESS, SPR_NOACCESS, + &spr_read_generic, &spr_write_generic, + 0x00000000); + spr_register_hv(env, SPR_LPIDR, "LPIDR", + SPR_NOACCESS, SPR_NOACCESS, + SPR_NOACCESS, SPR_NOACCESS, + &spr_read_generic, &spr_write_lpidr, + 0x00000000); + spr_register_hv(env, SPR_HFSCR, "HFSCR", + SPR_NOACCESS, SPR_NOACCESS, + SPR_NOACCESS, SPR_NOACCESS, + &spr_read_generic, &spr_write_generic, + 0x00000000); + spr_register_hv(env, SPR_MMCRC, "MMCRC", + SPR_NOACCESS, SPR_NOACCESS, + SPR_NOACCESS, SPR_NOACCESS, + &spr_read_generic, &spr_write_generic, + 0x00000000); + spr_register_hv(env, SPR_MMCRH, "MMCRH", + SPR_NOACCESS, SPR_NOACCESS, + SPR_NOACCESS, SPR_NOACCESS, + &spr_read_generic, &spr_write_generic, + 0x00000000); + spr_register_hv(env, SPR_HSPRG0, "HSPRG0", + SPR_NOACCESS, SPR_NOACCESS, + SPR_NOACCESS, SPR_NOACCESS, + &spr_read_generic, &spr_write_generic, + 0x00000000); + spr_register_hv(env, SPR_HSPRG1, "HSPRG1", + SPR_NOACCESS, SPR_NOACCESS, + SPR_NOACCESS, SPR_NOACCESS, + &spr_read_generic, &spr_write_generic, + 0x00000000); + spr_register_hv(env, SPR_HSRR0, "HSRR0", + SPR_NOACCESS, SPR_NOACCESS, + SPR_NOACCESS, SPR_NOACCESS, + &spr_read_generic, &spr_write_generic, + 0x00000000); + spr_register_hv(env, SPR_HSRR1, "HSRR1", + SPR_NOACCESS, SPR_NOACCESS, + SPR_NOACCESS, SPR_NOACCESS, + &spr_read_generic, &spr_write_generic, + 0x00000000); + spr_register_hv(env, SPR_HDAR, "HDAR", + SPR_NOACCESS, SPR_NOACCESS, + SPR_NOACCESS, SPR_NOACCESS, + &spr_read_generic, &spr_write_generic, + 0x00000000); + spr_register_hv(env, SPR_HDSISR, "HDSISR", + SPR_NOACCESS, SPR_NOACCESS, + SPR_NOACCESS, SPR_NOACCESS, + &spr_read_generic, &spr_write_generic, + 0x00000000); + spr_register_hv(env, SPR_HRMOR, "HRMOR", + SPR_NOACCESS, SPR_NOACCESS, + SPR_NOACCESS, SPR_NOACCESS, + &spr_read_generic, &spr_write_generic, + 0x00000000); +} + +static void register_rmor_sprs(CPUPPCState *env) +{ + spr_register_hv(env, SPR_RMOR, "RMOR", + SPR_NOACCESS, SPR_NOACCESS, + SPR_NOACCESS, SPR_NOACCESS, + &spr_read_generic, &spr_write_generic, + 0x00000000); +} + +static void register_power8_ids_sprs(CPUPPCState *env) +{ + /* Thread identification */ + spr_register(env, SPR_TIR, "TIR", + SPR_NOACCESS, SPR_NOACCESS, + &spr_read_generic, SPR_NOACCESS, + 0x00000000); +} + +static void register_book3s_purr_sprs(CPUPPCState *env) +{ +#if !defined(CONFIG_USER_ONLY) + /* PURR & SPURR: Hack - treat these as aliases for the TB for now */ + spr_register_kvm_hv(env, SPR_PURR, "PURR", + &spr_read_purr, SPR_NOACCESS, + &spr_read_purr, SPR_NOACCESS, + &spr_read_purr, &spr_write_purr, + KVM_REG_PPC_PURR, 0x00000000); + spr_register_kvm_hv(env, SPR_SPURR, "SPURR", + &spr_read_purr, SPR_NOACCESS, + &spr_read_purr, SPR_NOACCESS, + &spr_read_purr, &spr_write_purr, + KVM_REG_PPC_SPURR, 0x00000000); +#endif +} + +static void register_power6_dbg_sprs(CPUPPCState *env) +{ +#if !defined(CONFIG_USER_ONLY) + spr_register(env, SPR_CFAR, "SPR_CFAR", + SPR_NOACCESS, SPR_NOACCESS, + &spr_read_cfar, &spr_write_cfar, + 0x00000000); +#endif +} + +static void register_power5p_common_sprs(CPUPPCState *env) +{ + spr_register_kvm(env, SPR_PPR, "PPR", + &spr_read_generic, &spr_write_generic, + &spr_read_generic, &spr_write_generic, + KVM_REG_PPC_PPR, 0x00000000); +} + +static void register_power6_common_sprs(CPUPPCState *env) +{ +#if !defined(CONFIG_USER_ONLY) + spr_register_kvm(env, SPR_DSCR, "SPR_DSCR", + SPR_NOACCESS, SPR_NOACCESS, + &spr_read_generic, &spr_write_generic, + KVM_REG_PPC_DSCR, 0x00000000); +#endif + /* + * Register PCR to report POWERPC_EXCP_PRIV_REG instead of + * POWERPC_EXCP_INVAL_SPR in userspace. Permit hypervisor access. + */ + spr_register_hv(env, SPR_PCR, "PCR", + SPR_NOACCESS, SPR_NOACCESS, + SPR_NOACCESS, SPR_NOACCESS, + &spr_read_generic, &spr_write_pcr, + 0x00000000); +} + +static void register_power8_tce_address_control_sprs(CPUPPCState *env) +{ + spr_register_kvm(env, SPR_TAR, "TAR", + &spr_read_tar, &spr_write_tar, + &spr_read_generic, &spr_write_generic, + KVM_REG_PPC_TAR, 0x00000000); +} + +static void register_power8_tm_sprs(CPUPPCState *env) +{ + spr_register_kvm(env, SPR_TFHAR, "TFHAR", + &spr_read_tm, &spr_write_tm, + &spr_read_tm, &spr_write_tm, + KVM_REG_PPC_TFHAR, 0x00000000); + spr_register_kvm(env, SPR_TFIAR, "TFIAR", + &spr_read_tm, &spr_write_tm, + &spr_read_tm, &spr_write_tm, + KVM_REG_PPC_TFIAR, 0x00000000); + spr_register_kvm(env, SPR_TEXASR, "TEXASR", + &spr_read_tm, &spr_write_tm, + &spr_read_tm, &spr_write_tm, + KVM_REG_PPC_TEXASR, 0x00000000); + spr_register(env, SPR_TEXASRU, "TEXASRU", + &spr_read_tm_upper32, &spr_write_tm_upper32, + &spr_read_tm_upper32, &spr_write_tm_upper32, + 0x00000000); +} + +static void register_power8_ebb_sprs(CPUPPCState *env) +{ + spr_register(env, SPR_BESCRS, "BESCRS", + &spr_read_ebb, &spr_write_ebb, + &spr_read_generic, &spr_write_generic, + 0x00000000); + spr_register(env, SPR_BESCRSU, "BESCRSU", + &spr_read_ebb_upper32, &spr_write_ebb_upper32, + &spr_read_prev_upper32, &spr_write_prev_upper32, + 0x00000000); + spr_register(env, SPR_BESCRR, "BESCRR", + &spr_read_ebb, &spr_write_ebb, + &spr_read_generic, &spr_write_generic, + 0x00000000); + spr_register(env, SPR_BESCRRU, "BESCRRU", + &spr_read_ebb_upper32, &spr_write_ebb_upper32, + &spr_read_prev_upper32, &spr_write_prev_upper32, + 0x00000000); + spr_register_kvm(env, SPR_EBBHR, "EBBHR", + &spr_read_ebb, &spr_write_ebb, + &spr_read_generic, &spr_write_generic, + KVM_REG_PPC_EBBHR, 0x00000000); + spr_register_kvm(env, SPR_EBBRR, "EBBRR", + &spr_read_ebb, &spr_write_ebb, + &spr_read_generic, &spr_write_generic, + KVM_REG_PPC_EBBRR, 0x00000000); + spr_register_kvm(env, SPR_BESCR, "BESCR", + &spr_read_ebb, &spr_write_ebb, + &spr_read_generic, &spr_write_generic, + KVM_REG_PPC_BESCR, 0x00000000); +} + +/* Virtual Time Base */ +static void register_vtb_sprs(CPUPPCState *env) +{ + spr_register_kvm_hv(env, SPR_VTB, "VTB", + SPR_NOACCESS, SPR_NOACCESS, + &spr_read_vtb, SPR_NOACCESS, + &spr_read_vtb, &spr_write_vtb, + KVM_REG_PPC_VTB, 0x00000000); +} + +static void register_power8_fscr_sprs(CPUPPCState *env) +{ +#if defined(CONFIG_USER_ONLY) + target_ulong initval = 1ULL << FSCR_TAR; +#else + target_ulong initval = 0; +#endif + spr_register_kvm(env, SPR_FSCR, "FSCR", + SPR_NOACCESS, SPR_NOACCESS, + &spr_read_generic, &spr_write_generic, + KVM_REG_PPC_FSCR, initval); +} + +static void register_power8_pspb_sprs(CPUPPCState *env) +{ + spr_register_kvm(env, SPR_PSPB, "PSPB", + SPR_NOACCESS, SPR_NOACCESS, + &spr_read_generic, &spr_write_generic32, + KVM_REG_PPC_PSPB, 0); +} + +static void register_power8_dpdes_sprs(CPUPPCState *env) +{ +#if !defined(CONFIG_USER_ONLY) + /* Directed Privileged Door-bell Exception State, used for IPI */ + spr_register_kvm_hv(env, SPR_DPDES, "DPDES", + SPR_NOACCESS, SPR_NOACCESS, + &spr_read_dpdes, SPR_NOACCESS, + &spr_read_dpdes, &spr_write_dpdes, + KVM_REG_PPC_DPDES, 0x00000000); +#endif +} + +static void register_power8_ic_sprs(CPUPPCState *env) +{ +#if !defined(CONFIG_USER_ONLY) + spr_register_hv(env, SPR_IC, "IC", + SPR_NOACCESS, SPR_NOACCESS, + &spr_read_generic, SPR_NOACCESS, + &spr_read_generic, &spr_write_generic, + 0); +#endif +} + +static void register_power8_book4_sprs(CPUPPCState *env) +{ + /* Add a number of P8 book4 registers */ +#if !defined(CONFIG_USER_ONLY) + spr_register_kvm(env, SPR_ACOP, "ACOP", + SPR_NOACCESS, SPR_NOACCESS, + &spr_read_generic, &spr_write_generic, + KVM_REG_PPC_ACOP, 0); + spr_register_kvm(env, SPR_BOOKS_PID, "PID", + SPR_NOACCESS, SPR_NOACCESS, + &spr_read_generic, &spr_write_pidr, + KVM_REG_PPC_PID, 0); + spr_register_kvm(env, SPR_WORT, "WORT", + SPR_NOACCESS, SPR_NOACCESS, + &spr_read_generic, &spr_write_generic, + KVM_REG_PPC_WORT, 0); +#endif +} + +static void register_power7_book4_sprs(CPUPPCState *env) +{ + /* Add a number of P7 book4 registers */ +#if !defined(CONFIG_USER_ONLY) + spr_register_kvm(env, SPR_ACOP, "ACOP", + SPR_NOACCESS, SPR_NOACCESS, + &spr_read_generic, &spr_write_generic, + KVM_REG_PPC_ACOP, 0); + spr_register_kvm(env, SPR_BOOKS_PID, "PID", + SPR_NOACCESS, SPR_NOACCESS, + &spr_read_generic, &spr_write_generic, + KVM_REG_PPC_PID, 0); +#endif +} + +static void register_power8_rpr_sprs(CPUPPCState *env) +{ +#if !defined(CONFIG_USER_ONLY) + spr_register_hv(env, SPR_RPR, "RPR", + SPR_NOACCESS, SPR_NOACCESS, + SPR_NOACCESS, SPR_NOACCESS, + &spr_read_generic, &spr_write_generic, + 0x00000103070F1F3F); +#endif +} + +static void register_power9_mmu_sprs(CPUPPCState *env) +{ +#if !defined(CONFIG_USER_ONLY) + /* Partition Table Control */ + spr_register_kvm_hv(env, SPR_PTCR, "PTCR", + SPR_NOACCESS, SPR_NOACCESS, + SPR_NOACCESS, SPR_NOACCESS, + &spr_read_generic, &spr_write_ptcr, + KVM_REG_PPC_PTCR, 0x00000000); + /* Address Segment Descriptor Register */ + spr_register_hv(env, SPR_ASDR, "ASDR", + SPR_NOACCESS, SPR_NOACCESS, + SPR_NOACCESS, SPR_NOACCESS, + &spr_read_generic, &spr_write_generic, + 0x0000000000000000); +#endif +} + +/* + * Initialize PMU counter overflow timers for Power8 and + * newer Power chips when using TCG. + */ +static void init_tcg_pmu_power8(CPUPPCState *env) +{ + /* Init PMU overflow timers */ + if (tcg_enabled()) { + cpu_ppc_pmu_init(env); + } +} + +static void init_proc_book3s_common(CPUPPCState *env) +{ + register_non_embedded_sprs(env); + register_book3s_altivec_sprs(env); + register_book3s_pmu_sup_sprs(env); + register_book3s_pmu_user_sprs(env); + register_book3s_ctrl_sprs(env); + /* + * Can't find information on what this should be on reset. This + * value is the one used by 74xx processors. + */ + vscr_init(env, 0x00010000); + + spr_register(env, SPR_USPRG3, "USPRG3", + &spr_read_ureg, SPR_NOACCESS, + &spr_read_ureg, SPR_NOACCESS, + 0x00000000); +} + +static void init_proc_970(CPUPPCState *env) +{ + /* Common Registers */ + init_proc_book3s_common(env); + register_sdr1_sprs(env); + register_book3s_dbg_sprs(env); + + /* 970 Specific Registers */ + register_970_hid_sprs(env); + register_970_hior_sprs(env); + register_low_BATs(env); + register_970_pmu_sup_sprs(env); + register_970_pmu_user_sprs(env); + register_970_lpar_sprs(env); + register_970_dbg_sprs(env); + + /* env variables */ + env->dcache_line_size = 128; + env->icache_line_size = 128; + + /* Allocate hardware IRQ controller */ + init_excp_970(env); + ppc970_irq_init(env_archcpu(env)); +} + +static void init_proc_power5plus(CPUPPCState *env) +{ + /* Common Registers */ + init_proc_book3s_common(env); + register_sdr1_sprs(env); + register_book3s_dbg_sprs(env); + + /* POWER5+ Specific Registers */ + register_970_hid_sprs(env); + register_970_hior_sprs(env); + register_low_BATs(env); + register_970_pmu_sup_sprs(env); + register_970_pmu_user_sprs(env); + register_power5p_common_sprs(env); + register_power5p_lpar_sprs(env); + register_power5p_ear_sprs(env); + register_power5p_tb_sprs(env); + + /* env variables */ + env->dcache_line_size = 128; + env->icache_line_size = 128; + + /* Allocate hardware IRQ controller */ + init_excp_970(env); + ppc970_irq_init(env_archcpu(env)); +} + +static void init_proc_POWER7(CPUPPCState *env) +{ + /* Common Registers */ + init_proc_book3s_common(env); + register_sdr1_sprs(env); + register_book3s_dbg_sprs(env); + + /* POWER7 Specific Registers */ + register_book3s_ids_sprs(env); + register_rmor_sprs(env); + register_amr_sprs(env); + register_book3s_purr_sprs(env); + register_power5p_common_sprs(env); + register_power5p_lpar_sprs(env); + register_power5p_ear_sprs(env); + register_power5p_tb_sprs(env); + register_power6_common_sprs(env); + register_power6_dbg_sprs(env); + register_power7_book4_sprs(env); + + /* env variables */ + env->dcache_line_size = 128; + env->icache_line_size = 128; + + /* Allocate hardware IRQ controller */ + init_excp_POWER7(env); + ppcPOWER7_irq_init(env_archcpu(env)); +} + +static void init_proc_POWER8(CPUPPCState *env) +{ + /* Common Registers */ + init_proc_book3s_common(env); + register_sdr1_sprs(env); + register_book3s_207_dbg_sprs(env); + + /* Common TCG PMU */ + init_tcg_pmu_power8(env); + + /* POWER8 Specific Registers */ + register_book3s_ids_sprs(env); + register_rmor_sprs(env); + register_amr_sprs(env); + register_iamr_sprs(env); + register_book3s_purr_sprs(env); + register_power5p_common_sprs(env); + register_power5p_lpar_sprs(env); + register_power5p_ear_sprs(env); + register_power5p_tb_sprs(env); + register_power6_common_sprs(env); + register_power6_dbg_sprs(env); + register_power8_tce_address_control_sprs(env); + register_power8_ids_sprs(env); + register_power8_ebb_sprs(env); + register_power8_fscr_sprs(env); + register_power8_pmu_sup_sprs(env); + register_power8_pmu_user_sprs(env); + register_power8_tm_sprs(env); + register_power8_pspb_sprs(env); + register_power8_dpdes_sprs(env); + register_vtb_sprs(env); + register_power8_ic_sprs(env); + register_power8_book4_sprs(env); + register_power8_rpr_sprs(env); + + /* env variables */ + env->dcache_line_size = 128; + env->icache_line_size = 128; + + /* Allocate hardware IRQ controller */ + init_excp_POWER8(env); + ppcPOWER7_irq_init(env_archcpu(env)); +} + +static void init_proc_POWER9(CPUPPCState *env) +{ + /* Common Registers */ + init_proc_book3s_common(env); + register_book3s_207_dbg_sprs(env); + + /* Common TCG PMU */ + init_tcg_pmu_power8(env); + + /* POWER8 Specific Registers */ + register_book3s_ids_sprs(env); + register_amr_sprs(env); + register_iamr_sprs(env); + register_book3s_purr_sprs(env); + register_power5p_common_sprs(env); + register_power5p_lpar_sprs(env); + register_power5p_ear_sprs(env); + register_power5p_tb_sprs(env); + register_power6_common_sprs(env); + register_power6_dbg_sprs(env); + register_power8_tce_address_control_sprs(env); + register_power8_ids_sprs(env); + register_power8_ebb_sprs(env); + register_power8_fscr_sprs(env); + register_power8_pmu_sup_sprs(env); + register_power8_pmu_user_sprs(env); + register_power8_tm_sprs(env); + register_power8_pspb_sprs(env); + register_power8_dpdes_sprs(env); + register_vtb_sprs(env); + register_power8_ic_sprs(env); + register_power8_book4_sprs(env); + register_power8_rpr_sprs(env); + register_power9_mmu_sprs(env); + + /* POWER9 Specific registers */ + spr_register_kvm(env, SPR_TIDR, "TIDR", NULL, NULL, + spr_read_generic, spr_write_generic, + KVM_REG_PPC_TIDR, 0); + + /* FIXME: Filter fields properly based on privilege level */ + spr_register_kvm_hv(env, SPR_PSSCR, "PSSCR", NULL, NULL, NULL, NULL, + spr_read_generic, spr_write_generic, + KVM_REG_PPC_PSSCR, 0); + + /* env variables */ + env->dcache_line_size = 128; + env->icache_line_size = 128; + + /* Allocate hardware IRQ controller */ + init_excp_POWER9(env); + ppcPOWER9_irq_init(env_archcpu(env)); +} + +static void init_proc_POWER10(CPUPPCState *env) +{ + /* Common Registers */ + init_proc_book3s_common(env); + register_book3s_207_dbg_sprs(env); + + /* Common TCG PMU */ + init_tcg_pmu_power8(env); + + /* POWER8 Specific Registers */ + register_book3s_ids_sprs(env); + register_amr_sprs(env); + register_iamr_sprs(env); + register_book3s_purr_sprs(env); + register_power5p_common_sprs(env); + register_power5p_lpar_sprs(env); + register_power5p_ear_sprs(env); + register_power6_common_sprs(env); + register_power6_dbg_sprs(env); + register_power8_tce_address_control_sprs(env); + register_power8_ids_sprs(env); + register_power8_ebb_sprs(env); + register_power8_fscr_sprs(env); + register_power8_pmu_sup_sprs(env); + register_power8_pmu_user_sprs(env); + register_power8_tm_sprs(env); + register_power8_pspb_sprs(env); + register_vtb_sprs(env); + register_power8_ic_sprs(env); + register_power8_book4_sprs(env); + register_power8_rpr_sprs(env); + register_power9_mmu_sprs(env); + + /* FIXME: Filter fields properly based on privilege level */ + spr_register_kvm_hv(env, SPR_PSSCR, "PSSCR", NULL, NULL, NULL, NULL, + spr_read_generic, spr_write_generic, + KVM_REG_PPC_PSSCR, 0); + + /* env variables */ + env->dcache_line_size = 128; + env->icache_line_size = 128; + + /* Allocate hardware IRQ controller */ + init_excp_POWER10(env); + ppcPOWER9_irq_init(env_archcpu(env)); +} + +POWERPC_FAMILY(970)(ObjectClass *oc, void *data) +{ + DeviceClass *dc = DEVICE_CLASS(oc); + PowerPCCPUClass *pcc = POWERPC_CPU_CLASS(oc); + + dc->desc = "PowerPC 970"; + pcc->init_proc = init_proc_970; + pcc->check_pow = check_pow_970; + pcc->insns_flags = PPC_INSNS_BASE | PPC_STRING | PPC_MFTB | + PPC_FLOAT | PPC_FLOAT_FSEL | PPC_FLOAT_FRES | + PPC_FLOAT_FSQRT | PPC_FLOAT_FRSQRTE | + PPC_FLOAT_STFIWX | + PPC_CACHE | PPC_CACHE_ICBI | PPC_CACHE_DCBZ | + PPC_MEM_SYNC | PPC_MEM_EIEIO | + PPC_MEM_TLBIE | PPC_MEM_TLBSYNC | + PPC_64B | PPC_ALTIVEC | + PPC_SEGMENT_64B | PPC_SLBI; + pcc->insns_flags2 = PPC2_FP_CVT_S64; + pcc->msr_mask = (1ull << MSR_SF) | + (1ull << MSR_VR) | + (1ull << MSR_POW) | + (1ull << MSR_EE) | + (1ull << MSR_PR) | + (1ull << MSR_FP) | + (1ull << MSR_ME) | + (1ull << MSR_FE0) | + (1ull << MSR_SE) | + (1ull << MSR_DE) | + (1ull << MSR_FE1) | + (1ull << MSR_IR) | + (1ull << MSR_DR) | + (1ull << MSR_PMM) | + (1ull << MSR_RI); + pcc->mmu_model = POWERPC_MMU_64B; +#if defined(CONFIG_SOFTMMU) + pcc->hash64_opts = &ppc_hash64_opts_basic; +#endif + pcc->excp_model = POWERPC_EXCP_970; + pcc->bus_model = PPC_FLAGS_INPUT_970; + pcc->bfd_mach = bfd_mach_ppc64; + pcc->flags = POWERPC_FLAG_VRE | POWERPC_FLAG_SE | + POWERPC_FLAG_BE | POWERPC_FLAG_PMM | + POWERPC_FLAG_BUS_CLK; + pcc->l1_dcache_size = 0x8000; + pcc->l1_icache_size = 0x10000; +} + +POWERPC_FAMILY(POWER5P)(ObjectClass *oc, void *data) +{ + DeviceClass *dc = DEVICE_CLASS(oc); + PowerPCCPUClass *pcc = POWERPC_CPU_CLASS(oc); + + dc->fw_name = "PowerPC,POWER5"; + dc->desc = "POWER5+"; + pcc->init_proc = init_proc_power5plus; + pcc->check_pow = check_pow_970; + pcc->insns_flags = PPC_INSNS_BASE | PPC_STRING | PPC_MFTB | + PPC_FLOAT | PPC_FLOAT_FSEL | PPC_FLOAT_FRES | + PPC_FLOAT_FSQRT | PPC_FLOAT_FRSQRTE | + PPC_FLOAT_STFIWX | + PPC_FLOAT_EXT | + PPC_CACHE | PPC_CACHE_ICBI | PPC_CACHE_DCBZ | + PPC_MEM_SYNC | PPC_MEM_EIEIO | + PPC_MEM_TLBIE | PPC_MEM_TLBSYNC | + PPC_64B | + PPC_POPCNTB | + PPC_SEGMENT_64B | PPC_SLBI; + pcc->insns_flags2 = PPC2_FP_CVT_S64; + pcc->msr_mask = (1ull << MSR_SF) | + (1ull << MSR_VR) | + (1ull << MSR_POW) | + (1ull << MSR_EE) | + (1ull << MSR_PR) | + (1ull << MSR_FP) | + (1ull << MSR_ME) | + (1ull << MSR_FE0) | + (1ull << MSR_SE) | + (1ull << MSR_DE) | + (1ull << MSR_FE1) | + (1ull << MSR_IR) | + (1ull << MSR_DR) | + (1ull << MSR_PMM) | + (1ull << MSR_RI); + pcc->lpcr_mask = LPCR_RMLS | LPCR_ILE | LPCR_LPES0 | LPCR_LPES1 | + LPCR_RMI | LPCR_HDICE; + pcc->mmu_model = POWERPC_MMU_2_03; +#if defined(CONFIG_SOFTMMU) + pcc->hash64_opts = &ppc_hash64_opts_basic; + pcc->lrg_decr_bits = 32; +#endif + pcc->excp_model = POWERPC_EXCP_970; + pcc->bus_model = PPC_FLAGS_INPUT_970; + pcc->bfd_mach = bfd_mach_ppc64; + pcc->flags = POWERPC_FLAG_VRE | POWERPC_FLAG_SE | + POWERPC_FLAG_BE | POWERPC_FLAG_PMM | + POWERPC_FLAG_BUS_CLK; + pcc->l1_dcache_size = 0x8000; + pcc->l1_icache_size = 0x10000; +} + +POWERPC_FAMILY(POWER7)(ObjectClass *oc, void *data) +{ + DeviceClass *dc = DEVICE_CLASS(oc); + PowerPCCPUClass *pcc = POWERPC_CPU_CLASS(oc); + CPUClass *cc = CPU_CLASS(oc); + + dc->fw_name = "PowerPC,POWER7"; + dc->desc = "POWER7"; + pcc->pvr_match = ppc_pvr_match_power7; + pcc->pcr_mask = PCR_VEC_DIS | PCR_VSX_DIS | PCR_COMPAT_2_05; + pcc->pcr_supported = PCR_COMPAT_2_06 | PCR_COMPAT_2_05; + pcc->init_proc = init_proc_POWER7; + pcc->check_pow = check_pow_nocheck; + cc->has_work = cpu_has_work_POWER7; + pcc->insns_flags = PPC_INSNS_BASE | PPC_ISEL | PPC_STRING | PPC_MFTB | + PPC_FLOAT | PPC_FLOAT_FSEL | PPC_FLOAT_FRES | + PPC_FLOAT_FSQRT | PPC_FLOAT_FRSQRTE | + PPC_FLOAT_FRSQRTES | + PPC_FLOAT_STFIWX | + PPC_FLOAT_EXT | + PPC_CACHE | PPC_CACHE_ICBI | PPC_CACHE_DCBZ | + PPC_MEM_SYNC | PPC_MEM_EIEIO | + PPC_MEM_TLBIE | PPC_MEM_TLBSYNC | + PPC_64B | PPC_64H | PPC_64BX | PPC_ALTIVEC | + PPC_SEGMENT_64B | PPC_SLBI | + PPC_POPCNTB | PPC_POPCNTWD | + PPC_CILDST; + pcc->insns_flags2 = PPC2_VSX | PPC2_DFP | PPC2_DBRX | PPC2_ISA205 | + PPC2_PERM_ISA206 | PPC2_DIVE_ISA206 | + PPC2_ATOMIC_ISA206 | PPC2_FP_CVT_ISA206 | + PPC2_FP_TST_ISA206 | PPC2_FP_CVT_S64 | + PPC2_PM_ISA206; + pcc->msr_mask = (1ull << MSR_SF) | + (1ull << MSR_VR) | + (1ull << MSR_VSX) | + (1ull << MSR_EE) | + (1ull << MSR_PR) | + (1ull << MSR_FP) | + (1ull << MSR_ME) | + (1ull << MSR_FE0) | + (1ull << MSR_SE) | + (1ull << MSR_DE) | + (1ull << MSR_FE1) | + (1ull << MSR_IR) | + (1ull << MSR_DR) | + (1ull << MSR_PMM) | + (1ull << MSR_RI) | + (1ull << MSR_LE); + pcc->lpcr_mask = LPCR_VPM0 | LPCR_VPM1 | LPCR_ISL | LPCR_DPFD | + LPCR_VRMASD | LPCR_RMLS | LPCR_ILE | + LPCR_P7_PECE0 | LPCR_P7_PECE1 | LPCR_P7_PECE2 | + LPCR_MER | LPCR_TC | + LPCR_LPES0 | LPCR_LPES1 | LPCR_HDICE; + pcc->lpcr_pm = LPCR_P7_PECE0 | LPCR_P7_PECE1 | LPCR_P7_PECE2; + pcc->mmu_model = POWERPC_MMU_2_06; +#if defined(CONFIG_SOFTMMU) + pcc->hash64_opts = &ppc_hash64_opts_POWER7; + pcc->lrg_decr_bits = 32; +#endif + pcc->excp_model = POWERPC_EXCP_POWER7; + pcc->bus_model = PPC_FLAGS_INPUT_POWER7; + pcc->bfd_mach = bfd_mach_ppc64; + pcc->flags = POWERPC_FLAG_VRE | POWERPC_FLAG_SE | + POWERPC_FLAG_BE | POWERPC_FLAG_PMM | + POWERPC_FLAG_BUS_CLK | POWERPC_FLAG_CFAR | + POWERPC_FLAG_VSX; + pcc->l1_dcache_size = 0x8000; + pcc->l1_icache_size = 0x8000; +} + +POWERPC_FAMILY(POWER8)(ObjectClass *oc, void *data) +{ + DeviceClass *dc = DEVICE_CLASS(oc); + PowerPCCPUClass *pcc = POWERPC_CPU_CLASS(oc); + CPUClass *cc = CPU_CLASS(oc); + + dc->fw_name = "PowerPC,POWER8"; + dc->desc = "POWER8"; + pcc->pvr_match = ppc_pvr_match_power8; + pcc->pcr_mask = PCR_TM_DIS | PCR_COMPAT_2_06 | PCR_COMPAT_2_05; + pcc->pcr_supported = PCR_COMPAT_2_07 | PCR_COMPAT_2_06 | PCR_COMPAT_2_05; + pcc->init_proc = init_proc_POWER8; + pcc->check_pow = check_pow_nocheck; + cc->has_work = cpu_has_work_POWER8; + pcc->insns_flags = PPC_INSNS_BASE | PPC_ISEL | PPC_STRING | PPC_MFTB | + PPC_FLOAT | PPC_FLOAT_FSEL | PPC_FLOAT_FRES | + PPC_FLOAT_FSQRT | PPC_FLOAT_FRSQRTE | + PPC_FLOAT_FRSQRTES | + PPC_FLOAT_STFIWX | + PPC_FLOAT_EXT | + PPC_CACHE | PPC_CACHE_ICBI | PPC_CACHE_DCBZ | + PPC_MEM_SYNC | PPC_MEM_EIEIO | + PPC_MEM_TLBIE | PPC_MEM_TLBSYNC | + PPC_64B | PPC_64H | PPC_64BX | PPC_ALTIVEC | + PPC_SEGMENT_64B | PPC_SLBI | + PPC_POPCNTB | PPC_POPCNTWD | + PPC_CILDST; + pcc->insns_flags2 = PPC2_VSX | PPC2_VSX207 | PPC2_DFP | PPC2_DBRX | + PPC2_PERM_ISA206 | PPC2_DIVE_ISA206 | + PPC2_ATOMIC_ISA206 | PPC2_FP_CVT_ISA206 | + PPC2_FP_TST_ISA206 | PPC2_BCTAR_ISA207 | + PPC2_LSQ_ISA207 | PPC2_ALTIVEC_207 | + PPC2_ISA205 | PPC2_ISA207S | PPC2_FP_CVT_S64 | + PPC2_TM | PPC2_PM_ISA206; + pcc->msr_mask = (1ull << MSR_SF) | + (1ull << MSR_HV) | + (1ull << MSR_TM) | + (1ull << MSR_VR) | + (1ull << MSR_VSX) | + (1ull << MSR_EE) | + (1ull << MSR_PR) | + (1ull << MSR_FP) | + (1ull << MSR_ME) | + (1ull << MSR_FE0) | + (1ull << MSR_SE) | + (1ull << MSR_DE) | + (1ull << MSR_FE1) | + (1ull << MSR_IR) | + (1ull << MSR_DR) | + (1ull << MSR_PMM) | + (1ull << MSR_RI) | + (1ull << MSR_TS0) | + (1ull << MSR_TS1) | + (1ull << MSR_LE); + pcc->lpcr_mask = LPCR_VPM0 | LPCR_VPM1 | LPCR_ISL | LPCR_KBV | + LPCR_DPFD | LPCR_VRMASD | LPCR_RMLS | LPCR_ILE | + LPCR_AIL | LPCR_ONL | LPCR_P8_PECE0 | LPCR_P8_PECE1 | + LPCR_P8_PECE2 | LPCR_P8_PECE3 | LPCR_P8_PECE4 | + LPCR_MER | LPCR_TC | LPCR_LPES0 | LPCR_HDICE; + pcc->lpcr_pm = LPCR_P8_PECE0 | LPCR_P8_PECE1 | LPCR_P8_PECE2 | + LPCR_P8_PECE3 | LPCR_P8_PECE4; + pcc->mmu_model = POWERPC_MMU_2_07; +#if defined(CONFIG_SOFTMMU) + pcc->hash64_opts = &ppc_hash64_opts_POWER7; + pcc->lrg_decr_bits = 32; + pcc->n_host_threads = 8; +#endif + pcc->excp_model = POWERPC_EXCP_POWER8; + pcc->bus_model = PPC_FLAGS_INPUT_POWER7; + pcc->bfd_mach = bfd_mach_ppc64; + pcc->flags = POWERPC_FLAG_VRE | POWERPC_FLAG_SE | + POWERPC_FLAG_BE | POWERPC_FLAG_PMM | + POWERPC_FLAG_BUS_CLK | POWERPC_FLAG_CFAR | + POWERPC_FLAG_VSX | POWERPC_FLAG_TM; + pcc->l1_dcache_size = 0x8000; + pcc->l1_icache_size = 0x8000; +} + +POWERPC_FAMILY(POWER9)(ObjectClass *oc, void *data) +{ + DeviceClass *dc = DEVICE_CLASS(oc); + PowerPCCPUClass *pcc = POWERPC_CPU_CLASS(oc); + CPUClass *cc = CPU_CLASS(oc); + + dc->fw_name = "PowerPC,POWER9"; + dc->desc = "POWER9"; + pcc->pvr_match = ppc_pvr_match_power9; + pcc->pcr_mask = PCR_COMPAT_2_05 | PCR_COMPAT_2_06 | PCR_COMPAT_2_07; + pcc->pcr_supported = PCR_COMPAT_3_00 | PCR_COMPAT_2_07 | PCR_COMPAT_2_06 | + PCR_COMPAT_2_05; + pcc->init_proc = init_proc_POWER9; + pcc->check_pow = check_pow_nocheck; + cc->has_work = cpu_has_work_POWER9; + pcc->insns_flags = PPC_INSNS_BASE | PPC_ISEL | PPC_STRING | PPC_MFTB | + PPC_FLOAT | PPC_FLOAT_FSEL | PPC_FLOAT_FRES | + PPC_FLOAT_FSQRT | PPC_FLOAT_FRSQRTE | + PPC_FLOAT_FRSQRTES | + PPC_FLOAT_STFIWX | + PPC_FLOAT_EXT | + PPC_CACHE | PPC_CACHE_ICBI | PPC_CACHE_DCBZ | + PPC_MEM_SYNC | PPC_MEM_EIEIO | + PPC_MEM_TLBSYNC | + PPC_64B | PPC_64H | PPC_64BX | PPC_ALTIVEC | + PPC_SEGMENT_64B | PPC_SLBI | + PPC_POPCNTB | PPC_POPCNTWD | + PPC_CILDST; + pcc->insns_flags2 = PPC2_VSX | PPC2_VSX207 | PPC2_DFP | PPC2_DBRX | + PPC2_PERM_ISA206 | PPC2_DIVE_ISA206 | + PPC2_ATOMIC_ISA206 | PPC2_FP_CVT_ISA206 | + PPC2_FP_TST_ISA206 | PPC2_BCTAR_ISA207 | + PPC2_LSQ_ISA207 | PPC2_ALTIVEC_207 | + PPC2_ISA205 | PPC2_ISA207S | PPC2_FP_CVT_S64 | + PPC2_TM | PPC2_ISA300 | PPC2_PRCNTL; + pcc->msr_mask = (1ull << MSR_SF) | + (1ull << MSR_HV) | + (1ull << MSR_TM) | + (1ull << MSR_VR) | + (1ull << MSR_VSX) | + (1ull << MSR_EE) | + (1ull << MSR_PR) | + (1ull << MSR_FP) | + (1ull << MSR_ME) | + (1ull << MSR_FE0) | + (1ull << MSR_SE) | + (1ull << MSR_DE) | + (1ull << MSR_FE1) | + (1ull << MSR_IR) | + (1ull << MSR_DR) | + (1ull << MSR_PMM) | + (1ull << MSR_RI) | + (1ull << MSR_LE); + pcc->lpcr_mask = LPCR_VPM1 | LPCR_ISL | LPCR_KBV | LPCR_DPFD | + (LPCR_PECE_U_MASK & LPCR_HVEE) | LPCR_ILE | LPCR_AIL | + LPCR_UPRT | LPCR_EVIRT | LPCR_ONL | LPCR_HR | LPCR_LD | + (LPCR_PECE_L_MASK & (LPCR_PDEE | LPCR_HDEE | LPCR_EEE | + LPCR_DEE | LPCR_OEE)) + | LPCR_MER | LPCR_GTSE | LPCR_TC | + LPCR_HEIC | LPCR_LPES0 | LPCR_HVICE | LPCR_HDICE; + pcc->lpcr_pm = LPCR_PDEE | LPCR_HDEE | LPCR_EEE | LPCR_DEE | LPCR_OEE; + pcc->mmu_model = POWERPC_MMU_3_00; +#if defined(CONFIG_SOFTMMU) + /* segment page size remain the same */ + pcc->hash64_opts = &ppc_hash64_opts_POWER7; + pcc->radix_page_info = &POWER9_radix_page_info; + pcc->lrg_decr_bits = 56; + pcc->n_host_threads = 4; +#endif + pcc->excp_model = POWERPC_EXCP_POWER9; + pcc->bus_model = PPC_FLAGS_INPUT_POWER9; + pcc->bfd_mach = bfd_mach_ppc64; + pcc->flags = POWERPC_FLAG_VRE | POWERPC_FLAG_SE | + POWERPC_FLAG_BE | POWERPC_FLAG_PMM | + POWERPC_FLAG_BUS_CLK | POWERPC_FLAG_CFAR | + POWERPC_FLAG_VSX | POWERPC_FLAG_TM | POWERPC_FLAG_SCV; + pcc->l1_dcache_size = 0x8000; + pcc->l1_icache_size = 0x8000; +} + +POWERPC_FAMILY(POWER10)(ObjectClass *oc, void *data) +{ + DeviceClass *dc = DEVICE_CLASS(oc); + PowerPCCPUClass *pcc = POWERPC_CPU_CLASS(oc); + CPUClass *cc = CPU_CLASS(oc); + + dc->fw_name = "PowerPC,POWER10"; + dc->desc = "POWER10"; + pcc->pvr_match = ppc_pvr_match_power10; + pcc->pcr_mask = PCR_COMPAT_2_05 | PCR_COMPAT_2_06 | PCR_COMPAT_2_07 | + PCR_COMPAT_3_00; + pcc->pcr_supported = PCR_COMPAT_3_10 | PCR_COMPAT_3_00 | PCR_COMPAT_2_07 | + PCR_COMPAT_2_06 | PCR_COMPAT_2_05; + pcc->init_proc = init_proc_POWER10; + pcc->check_pow = check_pow_nocheck; + cc->has_work = cpu_has_work_POWER10; + pcc->insns_flags = PPC_INSNS_BASE | PPC_ISEL | PPC_STRING | PPC_MFTB | + PPC_FLOAT | PPC_FLOAT_FSEL | PPC_FLOAT_FRES | + PPC_FLOAT_FSQRT | PPC_FLOAT_FRSQRTE | + PPC_FLOAT_FRSQRTES | + PPC_FLOAT_STFIWX | + PPC_FLOAT_EXT | + PPC_CACHE | PPC_CACHE_ICBI | PPC_CACHE_DCBZ | + PPC_MEM_SYNC | PPC_MEM_EIEIO | + PPC_MEM_TLBSYNC | + PPC_64B | PPC_64H | PPC_64BX | PPC_ALTIVEC | + PPC_SEGMENT_64B | PPC_SLBI | + PPC_POPCNTB | PPC_POPCNTWD | + PPC_CILDST; + pcc->insns_flags2 = PPC2_VSX | PPC2_VSX207 | PPC2_DFP | PPC2_DBRX | + PPC2_PERM_ISA206 | PPC2_DIVE_ISA206 | + PPC2_ATOMIC_ISA206 | PPC2_FP_CVT_ISA206 | + PPC2_FP_TST_ISA206 | PPC2_BCTAR_ISA207 | + PPC2_LSQ_ISA207 | PPC2_ALTIVEC_207 | + PPC2_ISA205 | PPC2_ISA207S | PPC2_FP_CVT_S64 | + PPC2_TM | PPC2_ISA300 | PPC2_PRCNTL | PPC2_ISA310; + pcc->msr_mask = (1ull << MSR_SF) | + (1ull << MSR_HV) | + (1ull << MSR_TM) | + (1ull << MSR_VR) | + (1ull << MSR_VSX) | + (1ull << MSR_EE) | + (1ull << MSR_PR) | + (1ull << MSR_FP) | + (1ull << MSR_ME) | + (1ull << MSR_FE0) | + (1ull << MSR_SE) | + (1ull << MSR_DE) | + (1ull << MSR_FE1) | + (1ull << MSR_IR) | + (1ull << MSR_DR) | + (1ull << MSR_PMM) | + (1ull << MSR_RI) | + (1ull << MSR_LE); + pcc->lpcr_mask = LPCR_VPM1 | LPCR_ISL | LPCR_KBV | LPCR_DPFD | + (LPCR_PECE_U_MASK & LPCR_HVEE) | LPCR_ILE | LPCR_AIL | + LPCR_UPRT | LPCR_EVIRT | LPCR_ONL | LPCR_HR | LPCR_LD | + (LPCR_PECE_L_MASK & (LPCR_PDEE | LPCR_HDEE | LPCR_EEE | + LPCR_DEE | LPCR_OEE)) + | LPCR_MER | LPCR_GTSE | LPCR_TC | + LPCR_HEIC | LPCR_LPES0 | LPCR_HVICE | LPCR_HDICE; + /* DD2 adds an extra HAIL bit */ + pcc->lpcr_mask |= LPCR_HAIL; + + pcc->lpcr_pm = LPCR_PDEE | LPCR_HDEE | LPCR_EEE | LPCR_DEE | LPCR_OEE; + pcc->mmu_model = POWERPC_MMU_3_00; +#if defined(CONFIG_SOFTMMU) + /* segment page size remain the same */ + pcc->hash64_opts = &ppc_hash64_opts_POWER7; + pcc->radix_page_info = &POWER10_radix_page_info; + pcc->lrg_decr_bits = 56; +#endif + pcc->excp_model = POWERPC_EXCP_POWER10; + pcc->bus_model = PPC_FLAGS_INPUT_POWER9; + pcc->bfd_mach = bfd_mach_ppc64; + pcc->flags = POWERPC_FLAG_VRE | POWERPC_FLAG_SE | + POWERPC_FLAG_BE | POWERPC_FLAG_PMM | + POWERPC_FLAG_BUS_CLK | POWERPC_FLAG_CFAR | + POWERPC_FLAG_VSX | POWERPC_FLAG_TM | POWERPC_FLAG_SCV; + pcc->l1_dcache_size = 0x8000; + pcc->l1_icache_size = 0x8000; +} diff --git a/target/ppc/cpu_init.c b/target/ppc/cpu_init.c index 95e29e5e6b..f1ddd5a739 100644 --- a/target/ppc/cpu_init.c +++ b/target/ppc/cpu_init.c @@ -36,7 +36,6 @@ #include "qapi/visitor.h" #include "hw/qdev-properties.h" #include "hw/ppc/ppc.h" -#include "mmu-book3s-v3.h" #include "qemu/cutils.h" #include "disas/capstone.h" #include "fpu/softfloat.h" @@ -50,58 +49,6 @@ /* #define PPC_DEBUG_SPR */ /* #define USE_APPLE_GDB */ -static inline void vscr_init(CPUPPCState *env, uint32_t val) -{ - /* Altivec always uses round-to-nearest */ - set_float_rounding_mode(float_round_nearest_even, &env->vec_status); - ppc_store_vscr(env, val); -} - -#ifdef TARGET_PPC64 -static void register_amr_sprs(CPUPPCState *env) -{ -#ifndef CONFIG_USER_ONLY - /* - * Virtual Page Class Key protection - * - * The AMR is accessible either via SPR 13 or SPR 29. 13 is - * userspace accessible, 29 is privileged. So we only need to set - * the kvm ONE_REG id on one of them, we use 29 - */ - spr_register(env, SPR_UAMR, "UAMR", - &spr_read_generic, &spr_write_amr, - &spr_read_generic, &spr_write_amr, - 0); - spr_register_kvm_hv(env, SPR_AMR, "AMR", - SPR_NOACCESS, SPR_NOACCESS, - &spr_read_generic, &spr_write_amr, - &spr_read_generic, &spr_write_generic, - KVM_REG_PPC_AMR, 0); - spr_register_kvm_hv(env, SPR_UAMOR, "UAMOR", - SPR_NOACCESS, SPR_NOACCESS, - &spr_read_generic, &spr_write_uamor, - &spr_read_generic, &spr_write_generic, - KVM_REG_PPC_UAMOR, 0); - spr_register_hv(env, SPR_AMOR, "AMOR", - SPR_NOACCESS, SPR_NOACCESS, - SPR_NOACCESS, SPR_NOACCESS, - &spr_read_generic, &spr_write_generic, - 0); -#endif /* !CONFIG_USER_ONLY */ -} - -static void register_iamr_sprs(CPUPPCState *env) -{ -#ifndef CONFIG_USER_ONLY - spr_register_kvm_hv(env, SPR_IAMR, "IAMR", - SPR_NOACCESS, SPR_NOACCESS, - &spr_read_generic, &spr_write_iamr, - &spr_read_generic, &spr_write_generic, - KVM_REG_PPC_IAMR, 0); -#endif /* !CONFIG_USER_ONLY */ -} -#endif /* TARGET_PPC64 */ - /* * AMR => SPR 29 (Power 2.04) * CTRL => SPR 136 (Power 2.04) @@ -133,1711 +80,6 @@ static void register_iamr_sprs(CPUPPCState *env) /*****************************************************************************/ /* Exception vectors models */ -#if defined(TARGET_PPC64) -static void init_excp_970(CPUPPCState *env) -{ -#if !defined(CONFIG_USER_ONLY) - env->excp_vectors[POWERPC_EXCP_RESET] = 0x00000100; - env->excp_vectors[POWERPC_EXCP_MCHECK] = 0x00000200; - env->excp_vectors[POWERPC_EXCP_DSI] = 0x00000300; - env->excp_vectors[POWERPC_EXCP_DSEG] = 0x00000380; - env->excp_vectors[POWERPC_EXCP_ISI] = 0x00000400; - env->excp_vectors[POWERPC_EXCP_ISEG] = 0x00000480; - env->excp_vectors[POWERPC_EXCP_EXTERNAL] = 0x00000500; - env->excp_vectors[POWERPC_EXCP_ALIGN] = 0x00000600; - env->excp_vectors[POWERPC_EXCP_PROGRAM] = 0x00000700; - env->excp_vectors[POWERPC_EXCP_FPU] = 0x00000800; - env->excp_vectors[POWERPC_EXCP_DECR] = 0x00000900; - env->excp_vectors[POWERPC_EXCP_HDECR] = 0x00000980; - env->excp_vectors[POWERPC_EXCP_SYSCALL] = 0x00000C00; - env->excp_vectors[POWERPC_EXCP_TRACE] = 0x00000D00; - env->excp_vectors[POWERPC_EXCP_PERFM] = 0x00000F00; - env->excp_vectors[POWERPC_EXCP_VPU] = 0x00000F20; - env->excp_vectors[POWERPC_EXCP_IABR] = 0x00001300; - env->excp_vectors[POWERPC_EXCP_MAINT] = 0x00001600; - env->excp_vectors[POWERPC_EXCP_VPUA] = 0x00001700; - env->excp_vectors[POWERPC_EXCP_THERM] = 0x00001800; - /* Hardware reset vector */ - env->hreset_vector = 0x0000000000000100ULL; -#endif -} - -static void init_excp_POWER7(CPUPPCState *env) -{ -#if !defined(CONFIG_USER_ONLY) - env->excp_vectors[POWERPC_EXCP_RESET] = 0x00000100; - env->excp_vectors[POWERPC_EXCP_MCHECK] = 0x00000200; - env->excp_vectors[POWERPC_EXCP_DSI] = 0x00000300; - env->excp_vectors[POWERPC_EXCP_DSEG] = 0x00000380; - env->excp_vectors[POWERPC_EXCP_ISI] = 0x00000400; - env->excp_vectors[POWERPC_EXCP_ISEG] = 0x00000480; - env->excp_vectors[POWERPC_EXCP_EXTERNAL] = 0x00000500; - env->excp_vectors[POWERPC_EXCP_ALIGN] = 0x00000600; - env->excp_vectors[POWERPC_EXCP_PROGRAM] = 0x00000700; - env->excp_vectors[POWERPC_EXCP_FPU] = 0x00000800; - env->excp_vectors[POWERPC_EXCP_DECR] = 0x00000900; - env->excp_vectors[POWERPC_EXCP_HDECR] = 0x00000980; - env->excp_vectors[POWERPC_EXCP_SYSCALL] = 0x00000C00; - env->excp_vectors[POWERPC_EXCP_TRACE] = 0x00000D00; - env->excp_vectors[POWERPC_EXCP_HDSI] = 0x00000E00; - env->excp_vectors[POWERPC_EXCP_HISI] = 0x00000E20; - env->excp_vectors[POWERPC_EXCP_HV_EMU] = 0x00000E40; - env->excp_vectors[POWERPC_EXCP_HV_MAINT] = 0x00000E60; - env->excp_vectors[POWERPC_EXCP_PERFM] = 0x00000F00; - env->excp_vectors[POWERPC_EXCP_VPU] = 0x00000F20; - env->excp_vectors[POWERPC_EXCP_VSXU] = 0x00000F40; - /* Hardware reset vector */ - env->hreset_vector = 0x0000000000000100ULL; -#endif -} - -static void init_excp_POWER8(CPUPPCState *env) -{ - init_excp_POWER7(env); - -#if !defined(CONFIG_USER_ONLY) - env->excp_vectors[POWERPC_EXCP_SDOOR] = 0x00000A00; - env->excp_vectors[POWERPC_EXCP_FU] = 0x00000F60; - env->excp_vectors[POWERPC_EXCP_HV_FU] = 0x00000F80; - env->excp_vectors[POWERPC_EXCP_SDOOR_HV] = 0x00000E80; - - /* Userland exceptions without vector value in PowerISA v3.1 */ - env->excp_vectors[POWERPC_EXCP_PERFM_EBB] = 0x0; - env->excp_vectors[POWERPC_EXCP_EXTERNAL_EBB] = 0x0; -#endif -} - -static void init_excp_POWER9(CPUPPCState *env) -{ - init_excp_POWER8(env); - -#if !defined(CONFIG_USER_ONLY) - env->excp_vectors[POWERPC_EXCP_HVIRT] = 0x00000EA0; - env->excp_vectors[POWERPC_EXCP_SYSCALL_VECTORED] = 0x00017000; -#endif -} - -static void init_excp_POWER10(CPUPPCState *env) -{ - init_excp_POWER9(env); -} - -#endif - -#if defined(TARGET_PPC64) -#if defined(CONFIG_USER_ONLY) -#define POWERPC970_HID5_INIT 0x00000080 -#else -#define POWERPC970_HID5_INIT 0x00000000 -#endif - -static int check_pow_970(CPUPPCState *env) -{ - if (env->spr[SPR_HID0] & (HID0_DEEPNAP | HID0_DOZE | HID0_NAP)) { - return 1; - } - - return 0; -} - -static void register_970_hid_sprs(CPUPPCState *env) -{ - /* Hardware implementation registers */ - spr_register(env, SPR_HID0, "HID0", - SPR_NOACCESS, SPR_NOACCESS, - &spr_read_generic, &spr_write_clear, - 0x60000000); - spr_register(env, SPR_HID1, "HID1", - SPR_NOACCESS, SPR_NOACCESS, - &spr_read_generic, &spr_write_generic, - 0x00000000); - spr_register(env, SPR_970_HID5, "HID5", - SPR_NOACCESS, SPR_NOACCESS, - &spr_read_generic, &spr_write_generic, - POWERPC970_HID5_INIT); -} - -static void register_970_hior_sprs(CPUPPCState *env) -{ - spr_register(env, SPR_HIOR, "SPR_HIOR", - SPR_NOACCESS, SPR_NOACCESS, - &spr_read_hior, &spr_write_hior, - 0x00000000); -} - -static void register_book3s_ctrl_sprs(CPUPPCState *env) -{ - spr_register(env, SPR_CTRL, "SPR_CTRL", - SPR_NOACCESS, SPR_NOACCESS, - SPR_NOACCESS, &spr_write_CTRL, - 0x00000000); - spr_register(env, SPR_UCTRL, "SPR_UCTRL", - &spr_read_ureg, SPR_NOACCESS, - &spr_read_ureg, SPR_NOACCESS, - 0x00000000); -} - -static void register_book3s_altivec_sprs(CPUPPCState *env) -{ - if (!(env->insns_flags & PPC_ALTIVEC)) { - return; - } - - spr_register_kvm(env, SPR_VRSAVE, "VRSAVE", - &spr_read_generic, &spr_write_generic, - &spr_read_generic, &spr_write_generic, - KVM_REG_PPC_VRSAVE, 0x00000000); - -} - -static void register_book3s_dbg_sprs(CPUPPCState *env) -{ - /* - * TODO: different specs define different scopes for these, - * will have to address this: - * 970: super/write and super/read - * powerisa 2.03..2.04: hypv/write and super/read. - * powerisa 2.05 and newer: hypv/write and hypv/read. - */ - spr_register_kvm(env, SPR_DABR, "DABR", - SPR_NOACCESS, SPR_NOACCESS, - &spr_read_generic, &spr_write_generic, - KVM_REG_PPC_DABR, 0x00000000); - spr_register_kvm(env, SPR_DABRX, "DABRX", - SPR_NOACCESS, SPR_NOACCESS, - &spr_read_generic, &spr_write_generic, - KVM_REG_PPC_DABRX, 0x00000000); -} - -static void register_book3s_207_dbg_sprs(CPUPPCState *env) -{ - spr_register_kvm_hv(env, SPR_DAWR0, "DAWR0", - SPR_NOACCESS, SPR_NOACCESS, - SPR_NOACCESS, SPR_NOACCESS, - &spr_read_generic, &spr_write_generic, - KVM_REG_PPC_DAWR, 0x00000000); - spr_register_kvm_hv(env, SPR_DAWRX0, "DAWRX0", - SPR_NOACCESS, SPR_NOACCESS, - SPR_NOACCESS, SPR_NOACCESS, - &spr_read_generic, &spr_write_generic, - KVM_REG_PPC_DAWRX, 0x00000000); - spr_register_kvm_hv(env, SPR_CIABR, "CIABR", - SPR_NOACCESS, SPR_NOACCESS, - SPR_NOACCESS, SPR_NOACCESS, - &spr_read_generic, &spr_write_generic, - KVM_REG_PPC_CIABR, 0x00000000); -} - -static void register_970_dbg_sprs(CPUPPCState *env) -{ - /* Breakpoints */ - spr_register(env, SPR_IABR, "IABR", - SPR_NOACCESS, SPR_NOACCESS, - &spr_read_generic, &spr_write_generic, - 0x00000000); -} - -static void register_book3s_pmu_sup_sprs(CPUPPCState *env) -{ - spr_register_kvm(env, SPR_POWER_MMCR0, "MMCR0", - SPR_NOACCESS, SPR_NOACCESS, - &spr_read_generic, &spr_write_MMCR0, - KVM_REG_PPC_MMCR0, 0x80000000); - spr_register_kvm(env, SPR_POWER_MMCR1, "MMCR1", - SPR_NOACCESS, SPR_NOACCESS, - &spr_read_generic, &spr_write_MMCR1, - KVM_REG_PPC_MMCR1, 0x00000000); - spr_register_kvm(env, SPR_POWER_MMCRA, "MMCRA", - SPR_NOACCESS, SPR_NOACCESS, - &spr_read_generic, &spr_write_generic, - KVM_REG_PPC_MMCRA, 0x00000000); - spr_register_kvm(env, SPR_POWER_PMC1, "PMC1", - SPR_NOACCESS, SPR_NOACCESS, - &spr_read_PMC, &spr_write_PMC, - KVM_REG_PPC_PMC1, 0x00000000); - spr_register_kvm(env, SPR_POWER_PMC2, "PMC2", - SPR_NOACCESS, SPR_NOACCESS, - &spr_read_PMC, &spr_write_PMC, - KVM_REG_PPC_PMC2, 0x00000000); - spr_register_kvm(env, SPR_POWER_PMC3, "PMC3", - SPR_NOACCESS, SPR_NOACCESS, - &spr_read_PMC, &spr_write_PMC, - KVM_REG_PPC_PMC3, 0x00000000); - spr_register_kvm(env, SPR_POWER_PMC4, "PMC4", - SPR_NOACCESS, SPR_NOACCESS, - &spr_read_PMC, &spr_write_PMC, - KVM_REG_PPC_PMC4, 0x00000000); - spr_register_kvm(env, SPR_POWER_PMC5, "PMC5", - SPR_NOACCESS, SPR_NOACCESS, - &spr_read_PMC, &spr_write_PMC, - KVM_REG_PPC_PMC5, 0x00000000); - spr_register_kvm(env, SPR_POWER_PMC6, "PMC6", - SPR_NOACCESS, SPR_NOACCESS, - &spr_read_PMC, &spr_write_PMC, - KVM_REG_PPC_PMC6, 0x00000000); - spr_register_kvm(env, SPR_POWER_SIAR, "SIAR", - SPR_NOACCESS, SPR_NOACCESS, - &spr_read_generic, &spr_write_generic, - KVM_REG_PPC_SIAR, 0x00000000); - spr_register_kvm(env, SPR_POWER_SDAR, "SDAR", - SPR_NOACCESS, SPR_NOACCESS, - &spr_read_generic, &spr_write_generic, - KVM_REG_PPC_SDAR, 0x00000000); -} - -static void register_book3s_pmu_user_sprs(CPUPPCState *env) -{ - spr_register(env, SPR_POWER_UMMCR0, "UMMCR0", - &spr_read_MMCR0_ureg, &spr_write_MMCR0_ureg, - &spr_read_ureg, &spr_write_ureg, - 0x80000000); - spr_register(env, SPR_POWER_UMMCR1, "UMMCR1", - &spr_read_ureg, SPR_NOACCESS, - &spr_read_ureg, &spr_write_ureg, - 0x00000000); - spr_register(env, SPR_POWER_UMMCRA, "UMMCRA", - &spr_read_ureg, SPR_NOACCESS, - &spr_read_ureg, &spr_write_ureg, - 0x00000000); - spr_register(env, SPR_POWER_UPMC1, "UPMC1", - &spr_read_PMC14_ureg, &spr_write_PMC14_ureg, - &spr_read_ureg, &spr_write_ureg, - 0x00000000); - spr_register(env, SPR_POWER_UPMC2, "UPMC2", - &spr_read_PMC14_ureg, &spr_write_PMC14_ureg, - &spr_read_ureg, &spr_write_ureg, - 0x00000000); - spr_register(env, SPR_POWER_UPMC3, "UPMC3", - &spr_read_PMC14_ureg, &spr_write_PMC14_ureg, - &spr_read_ureg, &spr_write_ureg, - 0x00000000); - spr_register(env, SPR_POWER_UPMC4, "UPMC4", - &spr_read_PMC14_ureg, &spr_write_PMC14_ureg, - &spr_read_ureg, &spr_write_ureg, - 0x00000000); - spr_register(env, SPR_POWER_UPMC5, "UPMC5", - &spr_read_PMC56_ureg, &spr_write_PMC56_ureg, - &spr_read_ureg, &spr_write_ureg, - 0x00000000); - spr_register(env, SPR_POWER_UPMC6, "UPMC6", - &spr_read_PMC56_ureg, &spr_write_PMC56_ureg, - &spr_read_ureg, &spr_write_ureg, - 0x00000000); - spr_register(env, SPR_POWER_USIAR, "USIAR", - &spr_read_ureg, SPR_NOACCESS, - &spr_read_ureg, &spr_write_ureg, - 0x00000000); - spr_register(env, SPR_POWER_USDAR, "USDAR", - &spr_read_ureg, SPR_NOACCESS, - &spr_read_ureg, &spr_write_ureg, - 0x00000000); -} - -static void register_970_pmu_sup_sprs(CPUPPCState *env) -{ - spr_register_kvm(env, SPR_970_PMC7, "PMC7", - SPR_NOACCESS, SPR_NOACCESS, - &spr_read_generic, &spr_write_generic, - KVM_REG_PPC_PMC7, 0x00000000); - spr_register_kvm(env, SPR_970_PMC8, "PMC8", - SPR_NOACCESS, SPR_NOACCESS, - &spr_read_generic, &spr_write_generic, - KVM_REG_PPC_PMC8, 0x00000000); -} - -static void register_970_pmu_user_sprs(CPUPPCState *env) -{ - spr_register(env, SPR_970_UPMC7, "UPMC7", - &spr_read_ureg, SPR_NOACCESS, - &spr_read_ureg, &spr_write_ureg, - 0x00000000); - spr_register(env, SPR_970_UPMC8, "UPMC8", - &spr_read_ureg, SPR_NOACCESS, - &spr_read_ureg, &spr_write_ureg, - 0x00000000); -} - -static void register_power8_pmu_sup_sprs(CPUPPCState *env) -{ - spr_register_kvm(env, SPR_POWER_MMCR2, "MMCR2", - SPR_NOACCESS, SPR_NOACCESS, - &spr_read_generic, &spr_write_generic, - KVM_REG_PPC_MMCR2, 0x00000000); - spr_register_kvm(env, SPR_POWER_MMCRS, "MMCRS", - SPR_NOACCESS, SPR_NOACCESS, - &spr_read_generic, &spr_write_generic, - KVM_REG_PPC_MMCRS, 0x00000000); - spr_register_kvm(env, SPR_POWER_SIER, "SIER", - SPR_NOACCESS, SPR_NOACCESS, - &spr_read_generic, &spr_write_generic, - KVM_REG_PPC_SIER, 0x00000000); - spr_register_kvm(env, SPR_POWER_SPMC1, "SPMC1", - SPR_NOACCESS, SPR_NOACCESS, - &spr_read_generic, &spr_write_generic, - KVM_REG_PPC_SPMC1, 0x00000000); - spr_register_kvm(env, SPR_POWER_SPMC2, "SPMC2", - SPR_NOACCESS, SPR_NOACCESS, - &spr_read_generic, &spr_write_generic, - KVM_REG_PPC_SPMC2, 0x00000000); - spr_register_kvm(env, SPR_TACR, "TACR", - SPR_NOACCESS, SPR_NOACCESS, - &spr_read_generic, &spr_write_generic, - KVM_REG_PPC_TACR, 0x00000000); - spr_register_kvm(env, SPR_TCSCR, "TCSCR", - SPR_NOACCESS, SPR_NOACCESS, - &spr_read_generic, &spr_write_generic, - KVM_REG_PPC_TCSCR, 0x00000000); - spr_register_kvm(env, SPR_CSIGR, "CSIGR", - SPR_NOACCESS, SPR_NOACCESS, - &spr_read_generic, &spr_write_generic, - KVM_REG_PPC_CSIGR, 0x00000000); -} - -static void register_power8_pmu_user_sprs(CPUPPCState *env) -{ - spr_register(env, SPR_POWER_UMMCR2, "UMMCR2", - &spr_read_MMCR2_ureg, &spr_write_MMCR2_ureg, - &spr_read_ureg, &spr_write_ureg, - 0x00000000); - spr_register(env, SPR_POWER_USIER, "USIER", - &spr_read_generic, SPR_NOACCESS, - &spr_read_generic, &spr_write_generic, - 0x00000000); -} - -static void register_power5p_ear_sprs(CPUPPCState *env) -{ - /* External access control */ - spr_register(env, SPR_EAR, "EAR", - SPR_NOACCESS, SPR_NOACCESS, - &spr_read_generic, &spr_write_generic, - 0x00000000); -} - -static void register_power5p_tb_sprs(CPUPPCState *env) -{ - /* TBU40 (High 40 bits of the Timebase register */ - spr_register_hv(env, SPR_TBU40, "TBU40", - SPR_NOACCESS, SPR_NOACCESS, - SPR_NOACCESS, SPR_NOACCESS, - SPR_NOACCESS, &spr_write_tbu40, - 0x00000000); -} - -static void register_970_lpar_sprs(CPUPPCState *env) -{ -#if !defined(CONFIG_USER_ONLY) - /* - * PPC970: HID4 covers things later controlled by the LPCR and - * RMOR in later CPUs, but with a different encoding. We only - * support the 970 in "Apple mode" which has all hypervisor - * facilities disabled by strapping, so we can basically just - * ignore it - */ - spr_register(env, SPR_970_HID4, "HID4", - SPR_NOACCESS, SPR_NOACCESS, - &spr_read_generic, &spr_write_generic, - 0x00000000); -#endif -} - -static void register_power5p_lpar_sprs(CPUPPCState *env) -{ -#if !defined(CONFIG_USER_ONLY) - /* Logical partitionning */ - spr_register_kvm_hv(env, SPR_LPCR, "LPCR", - SPR_NOACCESS, SPR_NOACCESS, - SPR_NOACCESS, SPR_NOACCESS, - &spr_read_generic, &spr_write_lpcr, - KVM_REG_PPC_LPCR, LPCR_LPES0 | LPCR_LPES1); - spr_register_hv(env, SPR_HDEC, "HDEC", - SPR_NOACCESS, SPR_NOACCESS, - SPR_NOACCESS, SPR_NOACCESS, - &spr_read_hdecr, &spr_write_hdecr, 0); -#endif -} - -static void register_book3s_ids_sprs(CPUPPCState *env) -{ - /* FIXME: Will need to deal with thread vs core only SPRs */ - - /* Processor identification */ - spr_register_hv(env, SPR_PIR, "PIR", - SPR_NOACCESS, SPR_NOACCESS, - &spr_read_generic, SPR_NOACCESS, - &spr_read_generic, NULL, - 0x00000000); - spr_register_hv(env, SPR_HID0, "HID0", - SPR_NOACCESS, SPR_NOACCESS, - SPR_NOACCESS, SPR_NOACCESS, - &spr_read_generic, &spr_write_generic, - 0x00000000); - spr_register_hv(env, SPR_TSCR, "TSCR", - SPR_NOACCESS, SPR_NOACCESS, - SPR_NOACCESS, SPR_NOACCESS, - &spr_read_generic, &spr_write_generic, - 0x00000000); - spr_register_hv(env, SPR_HMER, "HMER", - SPR_NOACCESS, SPR_NOACCESS, - SPR_NOACCESS, SPR_NOACCESS, - &spr_read_generic, &spr_write_hmer, - 0x00000000); - spr_register_hv(env, SPR_HMEER, "HMEER", - SPR_NOACCESS, SPR_NOACCESS, - SPR_NOACCESS, SPR_NOACCESS, - &spr_read_generic, &spr_write_generic, - 0x00000000); - spr_register_hv(env, SPR_TFMR, "TFMR", - SPR_NOACCESS, SPR_NOACCESS, - SPR_NOACCESS, SPR_NOACCESS, - &spr_read_generic, &spr_write_generic, - 0x00000000); - spr_register_hv(env, SPR_LPIDR, "LPIDR", - SPR_NOACCESS, SPR_NOACCESS, - SPR_NOACCESS, SPR_NOACCESS, - &spr_read_generic, &spr_write_lpidr, - 0x00000000); - spr_register_hv(env, SPR_HFSCR, "HFSCR", - SPR_NOACCESS, SPR_NOACCESS, - SPR_NOACCESS, SPR_NOACCESS, - &spr_read_generic, &spr_write_generic, - 0x00000000); - spr_register_hv(env, SPR_MMCRC, "MMCRC", - SPR_NOACCESS, SPR_NOACCESS, - SPR_NOACCESS, SPR_NOACCESS, - &spr_read_generic, &spr_write_generic, - 0x00000000); - spr_register_hv(env, SPR_MMCRH, "MMCRH", - SPR_NOACCESS, SPR_NOACCESS, - SPR_NOACCESS, SPR_NOACCESS, - &spr_read_generic, &spr_write_generic, - 0x00000000); - spr_register_hv(env, SPR_HSPRG0, "HSPRG0", - SPR_NOACCESS, SPR_NOACCESS, - SPR_NOACCESS, SPR_NOACCESS, - &spr_read_generic, &spr_write_generic, - 0x00000000); - spr_register_hv(env, SPR_HSPRG1, "HSPRG1", - SPR_NOACCESS, SPR_NOACCESS, - SPR_NOACCESS, SPR_NOACCESS, - &spr_read_generic, &spr_write_generic, - 0x00000000); - spr_register_hv(env, SPR_HSRR0, "HSRR0", - SPR_NOACCESS, SPR_NOACCESS, - SPR_NOACCESS, SPR_NOACCESS, - &spr_read_generic, &spr_write_generic, - 0x00000000); - spr_register_hv(env, SPR_HSRR1, "HSRR1", - SPR_NOACCESS, SPR_NOACCESS, - SPR_NOACCESS, SPR_NOACCESS, - &spr_read_generic, &spr_write_generic, - 0x00000000); - spr_register_hv(env, SPR_HDAR, "HDAR", - SPR_NOACCESS, SPR_NOACCESS, - SPR_NOACCESS, SPR_NOACCESS, - &spr_read_generic, &spr_write_generic, - 0x00000000); - spr_register_hv(env, SPR_HDSISR, "HDSISR", - SPR_NOACCESS, SPR_NOACCESS, - SPR_NOACCESS, SPR_NOACCESS, - &spr_read_generic, &spr_write_generic, - 0x00000000); - spr_register_hv(env, SPR_HRMOR, "HRMOR", - SPR_NOACCESS, SPR_NOACCESS, - SPR_NOACCESS, SPR_NOACCESS, - &spr_read_generic, &spr_write_generic, - 0x00000000); -} - -static void register_rmor_sprs(CPUPPCState *env) -{ - spr_register_hv(env, SPR_RMOR, "RMOR", - SPR_NOACCESS, SPR_NOACCESS, - SPR_NOACCESS, SPR_NOACCESS, - &spr_read_generic, &spr_write_generic, - 0x00000000); -} - -static void register_power8_ids_sprs(CPUPPCState *env) -{ - /* Thread identification */ - spr_register(env, SPR_TIR, "TIR", - SPR_NOACCESS, SPR_NOACCESS, - &spr_read_generic, SPR_NOACCESS, - 0x00000000); -} - -static void register_book3s_purr_sprs(CPUPPCState *env) -{ -#if !defined(CONFIG_USER_ONLY) - /* PURR & SPURR: Hack - treat these as aliases for the TB for now */ - spr_register_kvm_hv(env, SPR_PURR, "PURR", - &spr_read_purr, SPR_NOACCESS, - &spr_read_purr, SPR_NOACCESS, - &spr_read_purr, &spr_write_purr, - KVM_REG_PPC_PURR, 0x00000000); - spr_register_kvm_hv(env, SPR_SPURR, "SPURR", - &spr_read_purr, SPR_NOACCESS, - &spr_read_purr, SPR_NOACCESS, - &spr_read_purr, &spr_write_purr, - KVM_REG_PPC_SPURR, 0x00000000); -#endif -} - -static void register_power6_dbg_sprs(CPUPPCState *env) -{ -#if !defined(CONFIG_USER_ONLY) - spr_register(env, SPR_CFAR, "SPR_CFAR", - SPR_NOACCESS, SPR_NOACCESS, - &spr_read_cfar, &spr_write_cfar, - 0x00000000); -#endif -} - -static void register_power5p_common_sprs(CPUPPCState *env) -{ - spr_register_kvm(env, SPR_PPR, "PPR", - &spr_read_generic, &spr_write_generic, - &spr_read_generic, &spr_write_generic, - KVM_REG_PPC_PPR, 0x00000000); -} - -static void register_power6_common_sprs(CPUPPCState *env) -{ -#if !defined(CONFIG_USER_ONLY) - spr_register_kvm(env, SPR_DSCR, "SPR_DSCR", - SPR_NOACCESS, SPR_NOACCESS, - &spr_read_generic, &spr_write_generic, - KVM_REG_PPC_DSCR, 0x00000000); -#endif - /* - * Register PCR to report POWERPC_EXCP_PRIV_REG instead of - * POWERPC_EXCP_INVAL_SPR in userspace. Permit hypervisor access. - */ - spr_register_hv(env, SPR_PCR, "PCR", - SPR_NOACCESS, SPR_NOACCESS, - SPR_NOACCESS, SPR_NOACCESS, - &spr_read_generic, &spr_write_pcr, - 0x00000000); -} - -static void register_power8_tce_address_control_sprs(CPUPPCState *env) -{ - spr_register_kvm(env, SPR_TAR, "TAR", - &spr_read_tar, &spr_write_tar, - &spr_read_generic, &spr_write_generic, - KVM_REG_PPC_TAR, 0x00000000); -} - -static void register_power8_tm_sprs(CPUPPCState *env) -{ - spr_register_kvm(env, SPR_TFHAR, "TFHAR", - &spr_read_tm, &spr_write_tm, - &spr_read_tm, &spr_write_tm, - KVM_REG_PPC_TFHAR, 0x00000000); - spr_register_kvm(env, SPR_TFIAR, "TFIAR", - &spr_read_tm, &spr_write_tm, - &spr_read_tm, &spr_write_tm, - KVM_REG_PPC_TFIAR, 0x00000000); - spr_register_kvm(env, SPR_TEXASR, "TEXASR", - &spr_read_tm, &spr_write_tm, - &spr_read_tm, &spr_write_tm, - KVM_REG_PPC_TEXASR, 0x00000000); - spr_register(env, SPR_TEXASRU, "TEXASRU", - &spr_read_tm_upper32, &spr_write_tm_upper32, - &spr_read_tm_upper32, &spr_write_tm_upper32, - 0x00000000); -} - -static void register_power8_ebb_sprs(CPUPPCState *env) -{ - spr_register(env, SPR_BESCRS, "BESCRS", - &spr_read_ebb, &spr_write_ebb, - &spr_read_generic, &spr_write_generic, - 0x00000000); - spr_register(env, SPR_BESCRSU, "BESCRSU", - &spr_read_ebb_upper32, &spr_write_ebb_upper32, - &spr_read_prev_upper32, &spr_write_prev_upper32, - 0x00000000); - spr_register(env, SPR_BESCRR, "BESCRR", - &spr_read_ebb, &spr_write_ebb, - &spr_read_generic, &spr_write_generic, - 0x00000000); - spr_register(env, SPR_BESCRRU, "BESCRRU", - &spr_read_ebb_upper32, &spr_write_ebb_upper32, - &spr_read_prev_upper32, &spr_write_prev_upper32, - 0x00000000); - spr_register_kvm(env, SPR_EBBHR, "EBBHR", - &spr_read_ebb, &spr_write_ebb, - &spr_read_generic, &spr_write_generic, - KVM_REG_PPC_EBBHR, 0x00000000); - spr_register_kvm(env, SPR_EBBRR, "EBBRR", - &spr_read_ebb, &spr_write_ebb, - &spr_read_generic, &spr_write_generic, - KVM_REG_PPC_EBBRR, 0x00000000); - spr_register_kvm(env, SPR_BESCR, "BESCR", - &spr_read_ebb, &spr_write_ebb, - &spr_read_generic, &spr_write_generic, - KVM_REG_PPC_BESCR, 0x00000000); -} - -/* Virtual Time Base */ -static void register_vtb_sprs(CPUPPCState *env) -{ - spr_register_kvm_hv(env, SPR_VTB, "VTB", - SPR_NOACCESS, SPR_NOACCESS, - &spr_read_vtb, SPR_NOACCESS, - &spr_read_vtb, &spr_write_vtb, - KVM_REG_PPC_VTB, 0x00000000); -} - -static void register_power8_fscr_sprs(CPUPPCState *env) -{ -#if defined(CONFIG_USER_ONLY) - target_ulong initval = 1ULL << FSCR_TAR; -#else - target_ulong initval = 0; -#endif - spr_register_kvm(env, SPR_FSCR, "FSCR", - SPR_NOACCESS, SPR_NOACCESS, - &spr_read_generic, &spr_write_generic, - KVM_REG_PPC_FSCR, initval); -} - -static void register_power8_pspb_sprs(CPUPPCState *env) -{ - spr_register_kvm(env, SPR_PSPB, "PSPB", - SPR_NOACCESS, SPR_NOACCESS, - &spr_read_generic, &spr_write_generic32, - KVM_REG_PPC_PSPB, 0); -} - -static void register_power8_dpdes_sprs(CPUPPCState *env) -{ -#if !defined(CONFIG_USER_ONLY) - /* Directed Privileged Door-bell Exception State, used for IPI */ - spr_register_kvm_hv(env, SPR_DPDES, "DPDES", - SPR_NOACCESS, SPR_NOACCESS, - &spr_read_dpdes, SPR_NOACCESS, - &spr_read_dpdes, &spr_write_dpdes, - KVM_REG_PPC_DPDES, 0x00000000); -#endif -} - -static void register_power8_ic_sprs(CPUPPCState *env) -{ -#if !defined(CONFIG_USER_ONLY) - spr_register_hv(env, SPR_IC, "IC", - SPR_NOACCESS, SPR_NOACCESS, - &spr_read_generic, SPR_NOACCESS, - &spr_read_generic, &spr_write_generic, - 0); -#endif -} - -static void register_power8_book4_sprs(CPUPPCState *env) -{ - /* Add a number of P8 book4 registers */ -#if !defined(CONFIG_USER_ONLY) - spr_register_kvm(env, SPR_ACOP, "ACOP", - SPR_NOACCESS, SPR_NOACCESS, - &spr_read_generic, &spr_write_generic, - KVM_REG_PPC_ACOP, 0); - spr_register_kvm(env, SPR_BOOKS_PID, "PID", - SPR_NOACCESS, SPR_NOACCESS, - &spr_read_generic, &spr_write_pidr, - KVM_REG_PPC_PID, 0); - spr_register_kvm(env, SPR_WORT, "WORT", - SPR_NOACCESS, SPR_NOACCESS, - &spr_read_generic, &spr_write_generic, - KVM_REG_PPC_WORT, 0); -#endif -} - -static void register_power7_book4_sprs(CPUPPCState *env) -{ - /* Add a number of P7 book4 registers */ -#if !defined(CONFIG_USER_ONLY) - spr_register_kvm(env, SPR_ACOP, "ACOP", - SPR_NOACCESS, SPR_NOACCESS, - &spr_read_generic, &spr_write_generic, - KVM_REG_PPC_ACOP, 0); - spr_register_kvm(env, SPR_BOOKS_PID, "PID", - SPR_NOACCESS, SPR_NOACCESS, - &spr_read_generic, &spr_write_generic, - KVM_REG_PPC_PID, 0); -#endif -} - -static void register_power8_rpr_sprs(CPUPPCState *env) -{ -#if !defined(CONFIG_USER_ONLY) - spr_register_hv(env, SPR_RPR, "RPR", - SPR_NOACCESS, SPR_NOACCESS, - SPR_NOACCESS, SPR_NOACCESS, - &spr_read_generic, &spr_write_generic, - 0x00000103070F1F3F); -#endif -} - -static void register_power9_mmu_sprs(CPUPPCState *env) -{ -#if !defined(CONFIG_USER_ONLY) - /* Partition Table Control */ - spr_register_kvm_hv(env, SPR_PTCR, "PTCR", - SPR_NOACCESS, SPR_NOACCESS, - SPR_NOACCESS, SPR_NOACCESS, - &spr_read_generic, &spr_write_ptcr, - KVM_REG_PPC_PTCR, 0x00000000); - /* Address Segment Descriptor Register */ - spr_register_hv(env, SPR_ASDR, "ASDR", - SPR_NOACCESS, SPR_NOACCESS, - SPR_NOACCESS, SPR_NOACCESS, - &spr_read_generic, &spr_write_generic, - 0x0000000000000000); -#endif -} - -/* - * Initialize PMU counter overflow timers for Power8 and - * newer Power chips when using TCG. - */ -static void init_tcg_pmu_power8(CPUPPCState *env) -{ - /* Init PMU overflow timers */ - if (tcg_enabled()) { - cpu_ppc_pmu_init(env); - } -} - -static void init_proc_book3s_common(CPUPPCState *env) -{ - register_non_embedded_sprs(env); - register_book3s_altivec_sprs(env); - register_book3s_pmu_sup_sprs(env); - register_book3s_pmu_user_sprs(env); - register_book3s_ctrl_sprs(env); - /* - * Can't find information on what this should be on reset. This - * value is the one used by 74xx processors. - */ - vscr_init(env, 0x00010000); - - spr_register(env, SPR_USPRG3, "USPRG3", - &spr_read_ureg, SPR_NOACCESS, - &spr_read_ureg, SPR_NOACCESS, - 0x00000000); -} - -static void init_proc_970(CPUPPCState *env) -{ - /* Common Registers */ - init_proc_book3s_common(env); - register_sdr1_sprs(env); - register_book3s_dbg_sprs(env); - - /* 970 Specific Registers */ - register_970_hid_sprs(env); - register_970_hior_sprs(env); - register_low_BATs(env); - register_970_pmu_sup_sprs(env); - register_970_pmu_user_sprs(env); - register_970_lpar_sprs(env); - register_970_dbg_sprs(env); - - /* env variables */ - env->dcache_line_size = 128; - env->icache_line_size = 128; - - /* Allocate hardware IRQ controller */ - init_excp_970(env); - ppc970_irq_init(env_archcpu(env)); -} - -POWERPC_FAMILY(970)(ObjectClass *oc, void *data) -{ - DeviceClass *dc = DEVICE_CLASS(oc); - PowerPCCPUClass *pcc = POWERPC_CPU_CLASS(oc); - - dc->desc = "PowerPC 970"; - pcc->init_proc = init_proc_970; - pcc->check_pow = check_pow_970; - pcc->insns_flags = PPC_INSNS_BASE | PPC_STRING | PPC_MFTB | - PPC_FLOAT | PPC_FLOAT_FSEL | PPC_FLOAT_FRES | - PPC_FLOAT_FSQRT | PPC_FLOAT_FRSQRTE | - PPC_FLOAT_STFIWX | - PPC_CACHE | PPC_CACHE_ICBI | PPC_CACHE_DCBZ | - PPC_MEM_SYNC | PPC_MEM_EIEIO | - PPC_MEM_TLBIE | PPC_MEM_TLBSYNC | - PPC_64B | PPC_ALTIVEC | - PPC_SEGMENT_64B | PPC_SLBI; - pcc->insns_flags2 = PPC2_FP_CVT_S64; - pcc->msr_mask = (1ull << MSR_SF) | - (1ull << MSR_VR) | - (1ull << MSR_POW) | - (1ull << MSR_EE) | - (1ull << MSR_PR) | - (1ull << MSR_FP) | - (1ull << MSR_ME) | - (1ull << MSR_FE0) | - (1ull << MSR_SE) | - (1ull << MSR_DE) | - (1ull << MSR_FE1) | - (1ull << MSR_IR) | - (1ull << MSR_DR) | - (1ull << MSR_PMM) | - (1ull << MSR_RI); - pcc->mmu_model = POWERPC_MMU_64B; -#if defined(CONFIG_SOFTMMU) - pcc->hash64_opts = &ppc_hash64_opts_basic; -#endif - pcc->excp_model = POWERPC_EXCP_970; - pcc->bus_model = PPC_FLAGS_INPUT_970; - pcc->bfd_mach = bfd_mach_ppc64; - pcc->flags = POWERPC_FLAG_VRE | POWERPC_FLAG_SE | - POWERPC_FLAG_BE | POWERPC_FLAG_PMM | - POWERPC_FLAG_BUS_CLK; - pcc->l1_dcache_size = 0x8000; - pcc->l1_icache_size = 0x10000; -} - -static void init_proc_power5plus(CPUPPCState *env) -{ - /* Common Registers */ - init_proc_book3s_common(env); - register_sdr1_sprs(env); - register_book3s_dbg_sprs(env); - - /* POWER5+ Specific Registers */ - register_970_hid_sprs(env); - register_970_hior_sprs(env); - register_low_BATs(env); - register_970_pmu_sup_sprs(env); - register_970_pmu_user_sprs(env); - register_power5p_common_sprs(env); - register_power5p_lpar_sprs(env); - register_power5p_ear_sprs(env); - register_power5p_tb_sprs(env); - - /* env variables */ - env->dcache_line_size = 128; - env->icache_line_size = 128; - - /* Allocate hardware IRQ controller */ - init_excp_970(env); - ppc970_irq_init(env_archcpu(env)); -} - -POWERPC_FAMILY(POWER5P)(ObjectClass *oc, void *data) -{ - DeviceClass *dc = DEVICE_CLASS(oc); - PowerPCCPUClass *pcc = POWERPC_CPU_CLASS(oc); - - dc->fw_name = "PowerPC,POWER5"; - dc->desc = "POWER5+"; - pcc->init_proc = init_proc_power5plus; - pcc->check_pow = check_pow_970; - pcc->insns_flags = PPC_INSNS_BASE | PPC_STRING | PPC_MFTB | - PPC_FLOAT | PPC_FLOAT_FSEL | PPC_FLOAT_FRES | - PPC_FLOAT_FSQRT | PPC_FLOAT_FRSQRTE | - PPC_FLOAT_STFIWX | - PPC_FLOAT_EXT | - PPC_CACHE | PPC_CACHE_ICBI | PPC_CACHE_DCBZ | - PPC_MEM_SYNC | PPC_MEM_EIEIO | - PPC_MEM_TLBIE | PPC_MEM_TLBSYNC | - PPC_64B | - PPC_POPCNTB | - PPC_SEGMENT_64B | PPC_SLBI; - pcc->insns_flags2 = PPC2_FP_CVT_S64; - pcc->msr_mask = (1ull << MSR_SF) | - (1ull << MSR_VR) | - (1ull << MSR_POW) | - (1ull << MSR_EE) | - (1ull << MSR_PR) | - (1ull << MSR_FP) | - (1ull << MSR_ME) | - (1ull << MSR_FE0) | - (1ull << MSR_SE) | - (1ull << MSR_DE) | - (1ull << MSR_FE1) | - (1ull << MSR_IR) | - (1ull << MSR_DR) | - (1ull << MSR_PMM) | - (1ull << MSR_RI); - pcc->lpcr_mask = LPCR_RMLS | LPCR_ILE | LPCR_LPES0 | LPCR_LPES1 | - LPCR_RMI | LPCR_HDICE; - pcc->mmu_model = POWERPC_MMU_2_03; -#if defined(CONFIG_SOFTMMU) - pcc->hash64_opts = &ppc_hash64_opts_basic; - pcc->lrg_decr_bits = 32; -#endif - pcc->excp_model = POWERPC_EXCP_970; - pcc->bus_model = PPC_FLAGS_INPUT_970; - pcc->bfd_mach = bfd_mach_ppc64; - pcc->flags = POWERPC_FLAG_VRE | POWERPC_FLAG_SE | - POWERPC_FLAG_BE | POWERPC_FLAG_PMM | - POWERPC_FLAG_BUS_CLK; - pcc->l1_dcache_size = 0x8000; - pcc->l1_icache_size = 0x10000; -} - -static void init_proc_POWER7(CPUPPCState *env) -{ - /* Common Registers */ - init_proc_book3s_common(env); - register_sdr1_sprs(env); - register_book3s_dbg_sprs(env); - - /* POWER7 Specific Registers */ - register_book3s_ids_sprs(env); - register_rmor_sprs(env); - register_amr_sprs(env); - register_book3s_purr_sprs(env); - register_power5p_common_sprs(env); - register_power5p_lpar_sprs(env); - register_power5p_ear_sprs(env); - register_power5p_tb_sprs(env); - register_power6_common_sprs(env); - register_power6_dbg_sprs(env); - register_power7_book4_sprs(env); - - /* env variables */ - env->dcache_line_size = 128; - env->icache_line_size = 128; - - /* Allocate hardware IRQ controller */ - init_excp_POWER7(env); - ppcPOWER7_irq_init(env_archcpu(env)); -} - -static bool ppc_pvr_match_power7(PowerPCCPUClass *pcc, uint32_t pvr) -{ - if ((pvr & CPU_POWERPC_POWER_SERVER_MASK) == CPU_POWERPC_POWER7P_BASE) { - return true; - } - if ((pvr & CPU_POWERPC_POWER_SERVER_MASK) == CPU_POWERPC_POWER7_BASE) { - return true; - } - return false; -} - -static bool cpu_has_work_POWER7(CPUState *cs) -{ - PowerPCCPU *cpu = POWERPC_CPU(cs); - CPUPPCState *env = &cpu->env; - - if (cs->halted) { - if (!(cs->interrupt_request & CPU_INTERRUPT_HARD)) { - return false; - } - if ((env->pending_interrupts & (1u << PPC_INTERRUPT_EXT)) && - (env->spr[SPR_LPCR] & LPCR_P7_PECE0)) { - return true; - } - if ((env->pending_interrupts & (1u << PPC_INTERRUPT_DECR)) && - (env->spr[SPR_LPCR] & LPCR_P7_PECE1)) { - return true; - } - if ((env->pending_interrupts & (1u << PPC_INTERRUPT_MCK)) && - (env->spr[SPR_LPCR] & LPCR_P7_PECE2)) { - return true; - } - if ((env->pending_interrupts & (1u << PPC_INTERRUPT_HMI)) && - (env->spr[SPR_LPCR] & LPCR_P7_PECE2)) { - return true; - } - if (env->pending_interrupts & (1u << PPC_INTERRUPT_RESET)) { - return true; - } - return false; - } else { - return msr_ee && (cs->interrupt_request & CPU_INTERRUPT_HARD); - } -} - -POWERPC_FAMILY(POWER7)(ObjectClass *oc, void *data) -{ - DeviceClass *dc = DEVICE_CLASS(oc); - PowerPCCPUClass *pcc = POWERPC_CPU_CLASS(oc); - CPUClass *cc = CPU_CLASS(oc); - - dc->fw_name = "PowerPC,POWER7"; - dc->desc = "POWER7"; - pcc->pvr_match = ppc_pvr_match_power7; - pcc->pcr_mask = PCR_VEC_DIS | PCR_VSX_DIS | PCR_COMPAT_2_05; - pcc->pcr_supported = PCR_COMPAT_2_06 | PCR_COMPAT_2_05; - pcc->init_proc = init_proc_POWER7; - pcc->check_pow = check_pow_nocheck; - cc->has_work = cpu_has_work_POWER7; - pcc->insns_flags = PPC_INSNS_BASE | PPC_ISEL | PPC_STRING | PPC_MFTB | - PPC_FLOAT | PPC_FLOAT_FSEL | PPC_FLOAT_FRES | - PPC_FLOAT_FSQRT | PPC_FLOAT_FRSQRTE | - PPC_FLOAT_FRSQRTES | - PPC_FLOAT_STFIWX | - PPC_FLOAT_EXT | - PPC_CACHE | PPC_CACHE_ICBI | PPC_CACHE_DCBZ | - PPC_MEM_SYNC | PPC_MEM_EIEIO | - PPC_MEM_TLBIE | PPC_MEM_TLBSYNC | - PPC_64B | PPC_64H | PPC_64BX | PPC_ALTIVEC | - PPC_SEGMENT_64B | PPC_SLBI | - PPC_POPCNTB | PPC_POPCNTWD | - PPC_CILDST; - pcc->insns_flags2 = PPC2_VSX | PPC2_DFP | PPC2_DBRX | PPC2_ISA205 | - PPC2_PERM_ISA206 | PPC2_DIVE_ISA206 | - PPC2_ATOMIC_ISA206 | PPC2_FP_CVT_ISA206 | - PPC2_FP_TST_ISA206 | PPC2_FP_CVT_S64 | - PPC2_PM_ISA206; - pcc->msr_mask = (1ull << MSR_SF) | - (1ull << MSR_VR) | - (1ull << MSR_VSX) | - (1ull << MSR_EE) | - (1ull << MSR_PR) | - (1ull << MSR_FP) | - (1ull << MSR_ME) | - (1ull << MSR_FE0) | - (1ull << MSR_SE) | - (1ull << MSR_DE) | - (1ull << MSR_FE1) | - (1ull << MSR_IR) | - (1ull << MSR_DR) | - (1ull << MSR_PMM) | - (1ull << MSR_RI) | - (1ull << MSR_LE); - pcc->lpcr_mask = LPCR_VPM0 | LPCR_VPM1 | LPCR_ISL | LPCR_DPFD | - LPCR_VRMASD | LPCR_RMLS | LPCR_ILE | - LPCR_P7_PECE0 | LPCR_P7_PECE1 | LPCR_P7_PECE2 | - LPCR_MER | LPCR_TC | - LPCR_LPES0 | LPCR_LPES1 | LPCR_HDICE; - pcc->lpcr_pm = LPCR_P7_PECE0 | LPCR_P7_PECE1 | LPCR_P7_PECE2; - pcc->mmu_model = POWERPC_MMU_2_06; -#if defined(CONFIG_SOFTMMU) - pcc->hash64_opts = &ppc_hash64_opts_POWER7; - pcc->lrg_decr_bits = 32; -#endif - pcc->excp_model = POWERPC_EXCP_POWER7; - pcc->bus_model = PPC_FLAGS_INPUT_POWER7; - pcc->bfd_mach = bfd_mach_ppc64; - pcc->flags = POWERPC_FLAG_VRE | POWERPC_FLAG_SE | - POWERPC_FLAG_BE | POWERPC_FLAG_PMM | - POWERPC_FLAG_BUS_CLK | POWERPC_FLAG_CFAR | - POWERPC_FLAG_VSX; - pcc->l1_dcache_size = 0x8000; - pcc->l1_icache_size = 0x8000; -} - -static void init_proc_POWER8(CPUPPCState *env) -{ - /* Common Registers */ - init_proc_book3s_common(env); - register_sdr1_sprs(env); - register_book3s_207_dbg_sprs(env); - - /* Common TCG PMU */ - init_tcg_pmu_power8(env); - - /* POWER8 Specific Registers */ - register_book3s_ids_sprs(env); - register_rmor_sprs(env); - register_amr_sprs(env); - register_iamr_sprs(env); - register_book3s_purr_sprs(env); - register_power5p_common_sprs(env); - register_power5p_lpar_sprs(env); - register_power5p_ear_sprs(env); - register_power5p_tb_sprs(env); - register_power6_common_sprs(env); - register_power6_dbg_sprs(env); - register_power8_tce_address_control_sprs(env); - register_power8_ids_sprs(env); - register_power8_ebb_sprs(env); - register_power8_fscr_sprs(env); - register_power8_pmu_sup_sprs(env); - register_power8_pmu_user_sprs(env); - register_power8_tm_sprs(env); - register_power8_pspb_sprs(env); - register_power8_dpdes_sprs(env); - register_vtb_sprs(env); - register_power8_ic_sprs(env); - register_power8_book4_sprs(env); - register_power8_rpr_sprs(env); - - /* env variables */ - env->dcache_line_size = 128; - env->icache_line_size = 128; - - /* Allocate hardware IRQ controller */ - init_excp_POWER8(env); - ppcPOWER7_irq_init(env_archcpu(env)); -} - -static bool ppc_pvr_match_power8(PowerPCCPUClass *pcc, uint32_t pvr) -{ - if ((pvr & CPU_POWERPC_POWER_SERVER_MASK) == CPU_POWERPC_POWER8NVL_BASE) { - return true; - } - if ((pvr & CPU_POWERPC_POWER_SERVER_MASK) == CPU_POWERPC_POWER8E_BASE) { - return true; - } - if ((pvr & CPU_POWERPC_POWER_SERVER_MASK) == CPU_POWERPC_POWER8_BASE) { - return true; - } - return false; -} - -static bool cpu_has_work_POWER8(CPUState *cs) -{ - PowerPCCPU *cpu = POWERPC_CPU(cs); - CPUPPCState *env = &cpu->env; - - if (cs->halted) { - if (!(cs->interrupt_request & CPU_INTERRUPT_HARD)) { - return false; - } - if ((env->pending_interrupts & (1u << PPC_INTERRUPT_EXT)) && - (env->spr[SPR_LPCR] & LPCR_P8_PECE2)) { - return true; - } - if ((env->pending_interrupts & (1u << PPC_INTERRUPT_DECR)) && - (env->spr[SPR_LPCR] & LPCR_P8_PECE3)) { - return true; - } - if ((env->pending_interrupts & (1u << PPC_INTERRUPT_MCK)) && - (env->spr[SPR_LPCR] & LPCR_P8_PECE4)) { - return true; - } - if ((env->pending_interrupts & (1u << PPC_INTERRUPT_HMI)) && - (env->spr[SPR_LPCR] & LPCR_P8_PECE4)) { - return true; - } - if ((env->pending_interrupts & (1u << PPC_INTERRUPT_DOORBELL)) && - (env->spr[SPR_LPCR] & LPCR_P8_PECE0)) { - return true; - } - if ((env->pending_interrupts & (1u << PPC_INTERRUPT_HDOORBELL)) && - (env->spr[SPR_LPCR] & LPCR_P8_PECE1)) { - return true; - } - if (env->pending_interrupts & (1u << PPC_INTERRUPT_RESET)) { - return true; - } - return false; - } else { - return msr_ee && (cs->interrupt_request & CPU_INTERRUPT_HARD); - } -} - -POWERPC_FAMILY(POWER8)(ObjectClass *oc, void *data) -{ - DeviceClass *dc = DEVICE_CLASS(oc); - PowerPCCPUClass *pcc = POWERPC_CPU_CLASS(oc); - CPUClass *cc = CPU_CLASS(oc); - - dc->fw_name = "PowerPC,POWER8"; - dc->desc = "POWER8"; - pcc->pvr_match = ppc_pvr_match_power8; - pcc->pcr_mask = PCR_TM_DIS | PCR_COMPAT_2_06 | PCR_COMPAT_2_05; - pcc->pcr_supported = PCR_COMPAT_2_07 | PCR_COMPAT_2_06 | PCR_COMPAT_2_05; - pcc->init_proc = init_proc_POWER8; - pcc->check_pow = check_pow_nocheck; - cc->has_work = cpu_has_work_POWER8; - pcc->insns_flags = PPC_INSNS_BASE | PPC_ISEL | PPC_STRING | PPC_MFTB | - PPC_FLOAT | PPC_FLOAT_FSEL | PPC_FLOAT_FRES | - PPC_FLOAT_FSQRT | PPC_FLOAT_FRSQRTE | - PPC_FLOAT_FRSQRTES | - PPC_FLOAT_STFIWX | - PPC_FLOAT_EXT | - PPC_CACHE | PPC_CACHE_ICBI | PPC_CACHE_DCBZ | - PPC_MEM_SYNC | PPC_MEM_EIEIO | - PPC_MEM_TLBIE | PPC_MEM_TLBSYNC | - PPC_64B | PPC_64H | PPC_64BX | PPC_ALTIVEC | - PPC_SEGMENT_64B | PPC_SLBI | - PPC_POPCNTB | PPC_POPCNTWD | - PPC_CILDST; - pcc->insns_flags2 = PPC2_VSX | PPC2_VSX207 | PPC2_DFP | PPC2_DBRX | - PPC2_PERM_ISA206 | PPC2_DIVE_ISA206 | - PPC2_ATOMIC_ISA206 | PPC2_FP_CVT_ISA206 | - PPC2_FP_TST_ISA206 | PPC2_BCTAR_ISA207 | - PPC2_LSQ_ISA207 | PPC2_ALTIVEC_207 | - PPC2_ISA205 | PPC2_ISA207S | PPC2_FP_CVT_S64 | - PPC2_TM | PPC2_PM_ISA206; - pcc->msr_mask = (1ull << MSR_SF) | - (1ull << MSR_HV) | - (1ull << MSR_TM) | - (1ull << MSR_VR) | - (1ull << MSR_VSX) | - (1ull << MSR_EE) | - (1ull << MSR_PR) | - (1ull << MSR_FP) | - (1ull << MSR_ME) | - (1ull << MSR_FE0) | - (1ull << MSR_SE) | - (1ull << MSR_DE) | - (1ull << MSR_FE1) | - (1ull << MSR_IR) | - (1ull << MSR_DR) | - (1ull << MSR_PMM) | - (1ull << MSR_RI) | - (1ull << MSR_TS0) | - (1ull << MSR_TS1) | - (1ull << MSR_LE); - pcc->lpcr_mask = LPCR_VPM0 | LPCR_VPM1 | LPCR_ISL | LPCR_KBV | - LPCR_DPFD | LPCR_VRMASD | LPCR_RMLS | LPCR_ILE | - LPCR_AIL | LPCR_ONL | LPCR_P8_PECE0 | LPCR_P8_PECE1 | - LPCR_P8_PECE2 | LPCR_P8_PECE3 | LPCR_P8_PECE4 | - LPCR_MER | LPCR_TC | LPCR_LPES0 | LPCR_HDICE; - pcc->lpcr_pm = LPCR_P8_PECE0 | LPCR_P8_PECE1 | LPCR_P8_PECE2 | - LPCR_P8_PECE3 | LPCR_P8_PECE4; - pcc->mmu_model = POWERPC_MMU_2_07; -#if defined(CONFIG_SOFTMMU) - pcc->hash64_opts = &ppc_hash64_opts_POWER7; - pcc->lrg_decr_bits = 32; - pcc->n_host_threads = 8; -#endif - pcc->excp_model = POWERPC_EXCP_POWER8; - pcc->bus_model = PPC_FLAGS_INPUT_POWER7; - pcc->bfd_mach = bfd_mach_ppc64; - pcc->flags = POWERPC_FLAG_VRE | POWERPC_FLAG_SE | - POWERPC_FLAG_BE | POWERPC_FLAG_PMM | - POWERPC_FLAG_BUS_CLK | POWERPC_FLAG_CFAR | - POWERPC_FLAG_VSX | POWERPC_FLAG_TM; - pcc->l1_dcache_size = 0x8000; - pcc->l1_icache_size = 0x8000; -} - -#ifdef CONFIG_SOFTMMU -/* - * Radix pg sizes and AP encodings for dt node ibm,processor-radix-AP-encodings - * Encoded as array of int_32s in the form: - * 0bxxxyyyyyyyyyyyyyyyyyyyyyyyyyyyyy - * x -> AP encoding - * y -> radix mode supported page size (encoded as a shift) - */ -static struct ppc_radix_page_info POWER9_radix_page_info = { - .count = 4, - .entries = { - 0x0000000c, /* 4K - enc: 0x0 */ - 0xa0000010, /* 64K - enc: 0x5 */ - 0x20000015, /* 2M - enc: 0x1 */ - 0x4000001e /* 1G - enc: 0x2 */ - } -}; -#endif /* CONFIG_SOFTMMU */ - -static void init_proc_POWER9(CPUPPCState *env) -{ - /* Common Registers */ - init_proc_book3s_common(env); - register_book3s_207_dbg_sprs(env); - - /* Common TCG PMU */ - init_tcg_pmu_power8(env); - - /* POWER8 Specific Registers */ - register_book3s_ids_sprs(env); - register_amr_sprs(env); - register_iamr_sprs(env); - register_book3s_purr_sprs(env); - register_power5p_common_sprs(env); - register_power5p_lpar_sprs(env); - register_power5p_ear_sprs(env); - register_power5p_tb_sprs(env); - register_power6_common_sprs(env); - register_power6_dbg_sprs(env); - register_power8_tce_address_control_sprs(env); - register_power8_ids_sprs(env); - register_power8_ebb_sprs(env); - register_power8_fscr_sprs(env); - register_power8_pmu_sup_sprs(env); - register_power8_pmu_user_sprs(env); - register_power8_tm_sprs(env); - register_power8_pspb_sprs(env); - register_power8_dpdes_sprs(env); - register_vtb_sprs(env); - register_power8_ic_sprs(env); - register_power8_book4_sprs(env); - register_power8_rpr_sprs(env); - register_power9_mmu_sprs(env); - - /* POWER9 Specific registers */ - spr_register_kvm(env, SPR_TIDR, "TIDR", NULL, NULL, - spr_read_generic, spr_write_generic, - KVM_REG_PPC_TIDR, 0); - - /* FIXME: Filter fields properly based on privilege level */ - spr_register_kvm_hv(env, SPR_PSSCR, "PSSCR", NULL, NULL, NULL, NULL, - spr_read_generic, spr_write_generic, - KVM_REG_PPC_PSSCR, 0); - - /* env variables */ - env->dcache_line_size = 128; - env->icache_line_size = 128; - - /* Allocate hardware IRQ controller */ - init_excp_POWER9(env); - ppcPOWER9_irq_init(env_archcpu(env)); -} - -static bool ppc_pvr_match_power9(PowerPCCPUClass *pcc, uint32_t pvr) -{ - if ((pvr & CPU_POWERPC_POWER_SERVER_MASK) == CPU_POWERPC_POWER9_BASE) { - return true; - } - return false; -} - -static bool cpu_has_work_POWER9(CPUState *cs) -{ - PowerPCCPU *cpu = POWERPC_CPU(cs); - CPUPPCState *env = &cpu->env; - - if (cs->halted) { - uint64_t psscr = env->spr[SPR_PSSCR]; - - if (!(cs->interrupt_request & CPU_INTERRUPT_HARD)) { - return false; - } - - /* If EC is clear, just return true on any pending interrupt */ - if (!(psscr & PSSCR_EC)) { - return true; - } - /* External Exception */ - if ((env->pending_interrupts & (1u << PPC_INTERRUPT_EXT)) && - (env->spr[SPR_LPCR] & LPCR_EEE)) { - bool heic = !!(env->spr[SPR_LPCR] & LPCR_HEIC); - if (heic == 0 || !msr_hv || msr_pr) { - return true; - } - } - /* Decrementer Exception */ - if ((env->pending_interrupts & (1u << PPC_INTERRUPT_DECR)) && - (env->spr[SPR_LPCR] & LPCR_DEE)) { - return true; - } - /* Machine Check or Hypervisor Maintenance Exception */ - if ((env->pending_interrupts & (1u << PPC_INTERRUPT_MCK | - 1u << PPC_INTERRUPT_HMI)) && (env->spr[SPR_LPCR] & LPCR_OEE)) { - return true; - } - /* Privileged Doorbell Exception */ - if ((env->pending_interrupts & (1u << PPC_INTERRUPT_DOORBELL)) && - (env->spr[SPR_LPCR] & LPCR_PDEE)) { - return true; - } - /* Hypervisor Doorbell Exception */ - if ((env->pending_interrupts & (1u << PPC_INTERRUPT_HDOORBELL)) && - (env->spr[SPR_LPCR] & LPCR_HDEE)) { - return true; - } - /* Hypervisor virtualization exception */ - if ((env->pending_interrupts & (1u << PPC_INTERRUPT_HVIRT)) && - (env->spr[SPR_LPCR] & LPCR_HVEE)) { - return true; - } - if (env->pending_interrupts & (1u << PPC_INTERRUPT_RESET)) { - return true; - } - return false; - } else { - return msr_ee && (cs->interrupt_request & CPU_INTERRUPT_HARD); - } -} - -POWERPC_FAMILY(POWER9)(ObjectClass *oc, void *data) -{ - DeviceClass *dc = DEVICE_CLASS(oc); - PowerPCCPUClass *pcc = POWERPC_CPU_CLASS(oc); - CPUClass *cc = CPU_CLASS(oc); - - dc->fw_name = "PowerPC,POWER9"; - dc->desc = "POWER9"; - pcc->pvr_match = ppc_pvr_match_power9; - pcc->pcr_mask = PCR_COMPAT_2_05 | PCR_COMPAT_2_06 | PCR_COMPAT_2_07; - pcc->pcr_supported = PCR_COMPAT_3_00 | PCR_COMPAT_2_07 | PCR_COMPAT_2_06 | - PCR_COMPAT_2_05; - pcc->init_proc = init_proc_POWER9; - pcc->check_pow = check_pow_nocheck; - cc->has_work = cpu_has_work_POWER9; - pcc->insns_flags = PPC_INSNS_BASE | PPC_ISEL | PPC_STRING | PPC_MFTB | - PPC_FLOAT | PPC_FLOAT_FSEL | PPC_FLOAT_FRES | - PPC_FLOAT_FSQRT | PPC_FLOAT_FRSQRTE | - PPC_FLOAT_FRSQRTES | - PPC_FLOAT_STFIWX | - PPC_FLOAT_EXT | - PPC_CACHE | PPC_CACHE_ICBI | PPC_CACHE_DCBZ | - PPC_MEM_SYNC | PPC_MEM_EIEIO | - PPC_MEM_TLBSYNC | - PPC_64B | PPC_64H | PPC_64BX | PPC_ALTIVEC | - PPC_SEGMENT_64B | PPC_SLBI | - PPC_POPCNTB | PPC_POPCNTWD | - PPC_CILDST; - pcc->insns_flags2 = PPC2_VSX | PPC2_VSX207 | PPC2_DFP | PPC2_DBRX | - PPC2_PERM_ISA206 | PPC2_DIVE_ISA206 | - PPC2_ATOMIC_ISA206 | PPC2_FP_CVT_ISA206 | - PPC2_FP_TST_ISA206 | PPC2_BCTAR_ISA207 | - PPC2_LSQ_ISA207 | PPC2_ALTIVEC_207 | - PPC2_ISA205 | PPC2_ISA207S | PPC2_FP_CVT_S64 | - PPC2_TM | PPC2_ISA300 | PPC2_PRCNTL; - pcc->msr_mask = (1ull << MSR_SF) | - (1ull << MSR_HV) | - (1ull << MSR_TM) | - (1ull << MSR_VR) | - (1ull << MSR_VSX) | - (1ull << MSR_EE) | - (1ull << MSR_PR) | - (1ull << MSR_FP) | - (1ull << MSR_ME) | - (1ull << MSR_FE0) | - (1ull << MSR_SE) | - (1ull << MSR_DE) | - (1ull << MSR_FE1) | - (1ull << MSR_IR) | - (1ull << MSR_DR) | - (1ull << MSR_PMM) | - (1ull << MSR_RI) | - (1ull << MSR_LE); - pcc->lpcr_mask = LPCR_VPM1 | LPCR_ISL | LPCR_KBV | LPCR_DPFD | - (LPCR_PECE_U_MASK & LPCR_HVEE) | LPCR_ILE | LPCR_AIL | - LPCR_UPRT | LPCR_EVIRT | LPCR_ONL | LPCR_HR | LPCR_LD | - (LPCR_PECE_L_MASK & (LPCR_PDEE | LPCR_HDEE | LPCR_EEE | - LPCR_DEE | LPCR_OEE)) - | LPCR_MER | LPCR_GTSE | LPCR_TC | - LPCR_HEIC | LPCR_LPES0 | LPCR_HVICE | LPCR_HDICE; - pcc->lpcr_pm = LPCR_PDEE | LPCR_HDEE | LPCR_EEE | LPCR_DEE | LPCR_OEE; - pcc->mmu_model = POWERPC_MMU_3_00; -#if defined(CONFIG_SOFTMMU) - /* segment page size remain the same */ - pcc->hash64_opts = &ppc_hash64_opts_POWER7; - pcc->radix_page_info = &POWER9_radix_page_info; - pcc->lrg_decr_bits = 56; - pcc->n_host_threads = 4; -#endif - pcc->excp_model = POWERPC_EXCP_POWER9; - pcc->bus_model = PPC_FLAGS_INPUT_POWER9; - pcc->bfd_mach = bfd_mach_ppc64; - pcc->flags = POWERPC_FLAG_VRE | POWERPC_FLAG_SE | - POWERPC_FLAG_BE | POWERPC_FLAG_PMM | - POWERPC_FLAG_BUS_CLK | POWERPC_FLAG_CFAR | - POWERPC_FLAG_VSX | POWERPC_FLAG_TM | POWERPC_FLAG_SCV; - pcc->l1_dcache_size = 0x8000; - pcc->l1_icache_size = 0x8000; -} - -#ifdef CONFIG_SOFTMMU -/* - * Radix pg sizes and AP encodings for dt node ibm,processor-radix-AP-encodings - * Encoded as array of int_32s in the form: - * 0bxxxyyyyyyyyyyyyyyyyyyyyyyyyyyyyy - * x -> AP encoding - * y -> radix mode supported page size (encoded as a shift) - */ -static struct ppc_radix_page_info POWER10_radix_page_info = { - .count = 4, - .entries = { - 0x0000000c, /* 4K - enc: 0x0 */ - 0xa0000010, /* 64K - enc: 0x5 */ - 0x20000015, /* 2M - enc: 0x1 */ - 0x4000001e /* 1G - enc: 0x2 */ - } -}; -#endif /* CONFIG_SOFTMMU */ - -static void init_proc_POWER10(CPUPPCState *env) -{ - /* Common Registers */ - init_proc_book3s_common(env); - register_book3s_207_dbg_sprs(env); - - /* Common TCG PMU */ - init_tcg_pmu_power8(env); - - /* POWER8 Specific Registers */ - register_book3s_ids_sprs(env); - register_amr_sprs(env); - register_iamr_sprs(env); - register_book3s_purr_sprs(env); - register_power5p_common_sprs(env); - register_power5p_lpar_sprs(env); - register_power5p_ear_sprs(env); - register_power6_common_sprs(env); - register_power6_dbg_sprs(env); - register_power8_tce_address_control_sprs(env); - register_power8_ids_sprs(env); - register_power8_ebb_sprs(env); - register_power8_fscr_sprs(env); - register_power8_pmu_sup_sprs(env); - register_power8_pmu_user_sprs(env); - register_power8_tm_sprs(env); - register_power8_pspb_sprs(env); - register_vtb_sprs(env); - register_power8_ic_sprs(env); - register_power8_book4_sprs(env); - register_power8_rpr_sprs(env); - register_power9_mmu_sprs(env); - - /* FIXME: Filter fields properly based on privilege level */ - spr_register_kvm_hv(env, SPR_PSSCR, "PSSCR", NULL, NULL, NULL, NULL, - spr_read_generic, spr_write_generic, - KVM_REG_PPC_PSSCR, 0); - - /* env variables */ - env->dcache_line_size = 128; - env->icache_line_size = 128; - - /* Allocate hardware IRQ controller */ - init_excp_POWER10(env); - ppcPOWER9_irq_init(env_archcpu(env)); -} - -static bool ppc_pvr_match_power10(PowerPCCPUClass *pcc, uint32_t pvr) -{ - if ((pvr & CPU_POWERPC_POWER_SERVER_MASK) == CPU_POWERPC_POWER10_BASE) { - return true; - } - return false; -} - -static bool cpu_has_work_POWER10(CPUState *cs) -{ - PowerPCCPU *cpu = POWERPC_CPU(cs); - CPUPPCState *env = &cpu->env; - - if (cs->halted) { - uint64_t psscr = env->spr[SPR_PSSCR]; - - if (!(cs->interrupt_request & CPU_INTERRUPT_HARD)) { - return false; - } - - /* If EC is clear, just return true on any pending interrupt */ - if (!(psscr & PSSCR_EC)) { - return true; - } - /* External Exception */ - if ((env->pending_interrupts & (1u << PPC_INTERRUPT_EXT)) && - (env->spr[SPR_LPCR] & LPCR_EEE)) { - bool heic = !!(env->spr[SPR_LPCR] & LPCR_HEIC); - if (heic == 0 || !msr_hv || msr_pr) { - return true; - } - } - /* Decrementer Exception */ - if ((env->pending_interrupts & (1u << PPC_INTERRUPT_DECR)) && - (env->spr[SPR_LPCR] & LPCR_DEE)) { - return true; - } - /* Machine Check or Hypervisor Maintenance Exception */ - if ((env->pending_interrupts & (1u << PPC_INTERRUPT_MCK | - 1u << PPC_INTERRUPT_HMI)) && (env->spr[SPR_LPCR] & LPCR_OEE)) { - return true; - } - /* Privileged Doorbell Exception */ - if ((env->pending_interrupts & (1u << PPC_INTERRUPT_DOORBELL)) && - (env->spr[SPR_LPCR] & LPCR_PDEE)) { - return true; - } - /* Hypervisor Doorbell Exception */ - if ((env->pending_interrupts & (1u << PPC_INTERRUPT_HDOORBELL)) && - (env->spr[SPR_LPCR] & LPCR_HDEE)) { - return true; - } - /* Hypervisor virtualization exception */ - if ((env->pending_interrupts & (1u << PPC_INTERRUPT_HVIRT)) && - (env->spr[SPR_LPCR] & LPCR_HVEE)) { - return true; - } - if (env->pending_interrupts & (1u << PPC_INTERRUPT_RESET)) { - return true; - } - return false; - } else { - return msr_ee && (cs->interrupt_request & CPU_INTERRUPT_HARD); - } -} - -POWERPC_FAMILY(POWER10)(ObjectClass *oc, void *data) -{ - DeviceClass *dc = DEVICE_CLASS(oc); - PowerPCCPUClass *pcc = POWERPC_CPU_CLASS(oc); - CPUClass *cc = CPU_CLASS(oc); - - dc->fw_name = "PowerPC,POWER10"; - dc->desc = "POWER10"; - pcc->pvr_match = ppc_pvr_match_power10; - pcc->pcr_mask = PCR_COMPAT_2_05 | PCR_COMPAT_2_06 | PCR_COMPAT_2_07 | - PCR_COMPAT_3_00; - pcc->pcr_supported = PCR_COMPAT_3_10 | PCR_COMPAT_3_00 | PCR_COMPAT_2_07 | - PCR_COMPAT_2_06 | PCR_COMPAT_2_05; - pcc->init_proc = init_proc_POWER10; - pcc->check_pow = check_pow_nocheck; - cc->has_work = cpu_has_work_POWER10; - pcc->insns_flags = PPC_INSNS_BASE | PPC_ISEL | PPC_STRING | PPC_MFTB | - PPC_FLOAT | PPC_FLOAT_FSEL | PPC_FLOAT_FRES | - PPC_FLOAT_FSQRT | PPC_FLOAT_FRSQRTE | - PPC_FLOAT_FRSQRTES | - PPC_FLOAT_STFIWX | - PPC_FLOAT_EXT | - PPC_CACHE | PPC_CACHE_ICBI | PPC_CACHE_DCBZ | - PPC_MEM_SYNC | PPC_MEM_EIEIO | - PPC_MEM_TLBSYNC | - PPC_64B | PPC_64H | PPC_64BX | PPC_ALTIVEC | - PPC_SEGMENT_64B | PPC_SLBI | - PPC_POPCNTB | PPC_POPCNTWD | - PPC_CILDST; - pcc->insns_flags2 = PPC2_VSX | PPC2_VSX207 | PPC2_DFP | PPC2_DBRX | - PPC2_PERM_ISA206 | PPC2_DIVE_ISA206 | - PPC2_ATOMIC_ISA206 | PPC2_FP_CVT_ISA206 | - PPC2_FP_TST_ISA206 | PPC2_BCTAR_ISA207 | - PPC2_LSQ_ISA207 | PPC2_ALTIVEC_207 | - PPC2_ISA205 | PPC2_ISA207S | PPC2_FP_CVT_S64 | - PPC2_TM | PPC2_ISA300 | PPC2_PRCNTL | PPC2_ISA310; - pcc->msr_mask = (1ull << MSR_SF) | - (1ull << MSR_HV) | - (1ull << MSR_TM) | - (1ull << MSR_VR) | - (1ull << MSR_VSX) | - (1ull << MSR_EE) | - (1ull << MSR_PR) | - (1ull << MSR_FP) | - (1ull << MSR_ME) | - (1ull << MSR_FE0) | - (1ull << MSR_SE) | - (1ull << MSR_DE) | - (1ull << MSR_FE1) | - (1ull << MSR_IR) | - (1ull << MSR_DR) | - (1ull << MSR_PMM) | - (1ull << MSR_RI) | - (1ull << MSR_LE); - pcc->lpcr_mask = LPCR_VPM1 | LPCR_ISL | LPCR_KBV | LPCR_DPFD | - (LPCR_PECE_U_MASK & LPCR_HVEE) | LPCR_ILE | LPCR_AIL | - LPCR_UPRT | LPCR_EVIRT | LPCR_ONL | LPCR_HR | LPCR_LD | - (LPCR_PECE_L_MASK & (LPCR_PDEE | LPCR_HDEE | LPCR_EEE | - LPCR_DEE | LPCR_OEE)) - | LPCR_MER | LPCR_GTSE | LPCR_TC | - LPCR_HEIC | LPCR_LPES0 | LPCR_HVICE | LPCR_HDICE; - /* DD2 adds an extra HAIL bit */ - pcc->lpcr_mask |= LPCR_HAIL; - - pcc->lpcr_pm = LPCR_PDEE | LPCR_HDEE | LPCR_EEE | LPCR_DEE | LPCR_OEE; - pcc->mmu_model = POWERPC_MMU_3_00; -#if defined(CONFIG_SOFTMMU) - /* segment page size remain the same */ - pcc->hash64_opts = &ppc_hash64_opts_POWER7; - pcc->radix_page_info = &POWER10_radix_page_info; - pcc->lrg_decr_bits = 56; -#endif - pcc->excp_model = POWERPC_EXCP_POWER10; - pcc->bus_model = PPC_FLAGS_INPUT_POWER9; - pcc->bfd_mach = bfd_mach_ppc64; - pcc->flags = POWERPC_FLAG_VRE | POWERPC_FLAG_SE | - POWERPC_FLAG_BE | POWERPC_FLAG_PMM | - POWERPC_FLAG_BUS_CLK | POWERPC_FLAG_CFAR | - POWERPC_FLAG_VSX | POWERPC_FLAG_TM | POWERPC_FLAG_SCV; - pcc->l1_dcache_size = 0x8000; - pcc->l1_icache_size = 0x8000; -} - #if !defined(CONFIG_USER_ONLY) void cpu_ppc_set_vhyp(PowerPCCPU *cpu, PPCVirtualHypervisor *vhyp) { @@ -1851,11 +93,8 @@ void cpu_ppc_set_vhyp(PowerPCCPU *cpu, PPCVirtualHypervisor *vhyp) */ env->msr_mask &= ~MSR_HVB; } - #endif /* !defined(CONFIG_USER_ONLY) */ -#endif /* defined(TARGET_PPC64) */ - /*****************************************************************************/ /* Generic CPU instantiation routine */ static void init_ppc_proc(PowerPCCPU *cpu) diff --git a/target/ppc/meson.build b/target/ppc/meson.build index 6383fb8ebd..d32597dd69 100644 --- a/target/ppc/meson.build +++ b/target/ppc/meson.build @@ -57,6 +57,7 @@ ppc_softmmu_ss.add(when: 'TARGET_PPC64', if_true: files( 'mmu-book3s-v3.c', 'mmu-hash64.c', 'mmu-radix64.c', + 'cpu_books.c', )) target_arch += {'ppc': ppc_ss} From patchwork Tue Mar 1 13:56:12 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Fabiano Rosas X-Patchwork-Id: 12764753 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 3DB5BC433F5 for ; Tue, 1 Mar 2022 14:08:06 +0000 (UTC) Received: from localhost ([::1]:40912 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1nP3Ab-0004Zh-1M for qemu-devel@archiver.kernel.org; Tue, 01 Mar 2022 09:08:05 -0500 Received: from eggs.gnu.org ([209.51.188.92]:33344) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1nP2zq-00066q-AL; Tue, 01 Mar 2022 08:56:58 -0500 Received: from mx0a-001b2d01.pphosted.com ([148.163.156.1]:52900) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1nP2zm-00024W-Qb; Tue, 01 Mar 2022 08:56:57 -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 221CHOCx019258; Tue, 1 Mar 2022 13:56:49 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=SC44WGDgEBd+Ke9HzuDNUzlS/puduvghWm/om/7ac7w=; b=fCFhb1+3dkLyrFSJTB454Hu1izcpCXpTXFbn1HcOMJI2lgC8hyCJN+9bRieg/wmEQPDX fmHmrVzW+vsV+gPqLSmugjW1YFg7k4ikssJlCEVhG3YBZvZ9TqT5xemOCfPIz6dVNWps AGVz2EECq6IuRDggewKvMXrsqAhVWHJnefBJEXRH2BUt8CDhNidhi7ou9Pz26oCkpo71 vqvG95kBulxlSUyNSW8g5z7+Z27EyWjS9zzRmpJoM2i1vYf9fFFUhu2waEcdGcAzEVkm 4tqEK3nRMm4OwsdhUln9fOvr81EMhRFSq0HzpQ1QGcuHYfeHTjU+aIFC5okqHjS77e5x 6Q== Received: from pps.reinject (localhost [127.0.0.1]) by mx0a-001b2d01.pphosted.com with ESMTP id 3ehfrufnyr-1 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NOT); Tue, 01 Mar 2022 13:56:49 +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 221DaMx3019532; Tue, 1 Mar 2022 13:56:48 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 3ehfrufnxw-1 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NOT); Tue, 01 Mar 2022 13:56:48 +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 221DtjCI030087; Tue, 1 Mar 2022 13:56:47 GMT Received: from b03cxnp08027.gho.boulder.ibm.com (b03cxnp08027.gho.boulder.ibm.com [9.17.130.19]) by ppma02wdc.us.ibm.com with ESMTP id 3efbu9w0vk-1 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NOT); Tue, 01 Mar 2022 13:56:47 +0000 Received: from b03ledav005.gho.boulder.ibm.com (b03ledav005.gho.boulder.ibm.com [9.17.130.236]) by b03cxnp08027.gho.boulder.ibm.com (8.14.9/8.14.9/NCO v10.0) with ESMTP id 221DukDS18743624 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-GCM-SHA384 bits=256 verify=OK); Tue, 1 Mar 2022 13:56:46 GMT Received: from b03ledav005.gho.boulder.ibm.com (unknown [127.0.0.1]) by IMSVA (Postfix) with ESMTP id E89C5BE058; Tue, 1 Mar 2022 13:56:45 +0000 (GMT) Received: from b03ledav005.gho.boulder.ibm.com (unknown [127.0.0.1]) by IMSVA (Postfix) with ESMTP id 696D8BE054; Tue, 1 Mar 2022 13:56:44 +0000 (GMT) Received: from farosas.linux.ibm.com.com (unknown [9.211.51.129]) by b03ledav005.gho.boulder.ibm.com (Postfix) with ESMTP; Tue, 1 Mar 2022 13:56:44 +0000 (GMT) From: Fabiano Rosas To: qemu-devel@nongnu.org Subject: [PATCH 09/17] target/ppc: Remove leftover comments from cpu_init Date: Tue, 1 Mar 2022 10:56:12 -0300 Message-Id: <20220301135620.2411952-10-farosas@linux.ibm.com> X-Mailer: git-send-email 2.34.1 In-Reply-To: <20220301135620.2411952-1-farosas@linux.ibm.com> References: <20220301135620.2411952-1-farosas@linux.ibm.com> MIME-Version: 1.0 X-TM-AS-GCONF: 00 X-Proofpoint-ORIG-GUID: xoteiXXT3jnuslSNaW61191p6in_lBi9 X-Proofpoint-GUID: _UEDQ5XCOxZ8S2nAYMCrR4ybJkbwFZKm X-Proofpoint-Virus-Version: vendor=baseguard engine=ICAP:2.0.205,Aquarius:18.0.816,Hydra:6.0.425,FMLib:17.11.64.514 definitions=2022-03-01_07,2022-02-26_01,2022-02-23_01 X-Proofpoint-Spam-Details: rule=outbound_notspam policy=outbound score=0 mlxscore=0 suspectscore=0 phishscore=0 clxscore=1015 impostorscore=0 malwarescore=0 priorityscore=1501 mlxlogscore=999 lowpriorityscore=0 spamscore=0 adultscore=0 bulkscore=0 classifier=spam adjust=0 reason=mlx scancount=1 engine=8.12.0-2201110000 definitions=main-2203010074 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_H5=0.001, RCVD_IN_MSPIKE_WL=0.001, SPF_HELO_NONE=0.001, SPF_PASS=-0.001, T_SCC_BODY_TEXT_LINE=-0.01 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 defines are not in use and the comment seems to have lost its purpose, whatever it was. Signed-off-by: Fabiano Rosas --- target/ppc/cpu_init.c | 34 ---------------------------------- 1 file changed, 34 deletions(-) diff --git a/target/ppc/cpu_init.c b/target/ppc/cpu_init.c index f1ddd5a739..7753dfecd3 100644 --- a/target/ppc/cpu_init.c +++ b/target/ppc/cpu_init.c @@ -46,40 +46,6 @@ #include "spr_common.h" #include "power8-pmu.h" -/* #define PPC_DEBUG_SPR */ -/* #define USE_APPLE_GDB */ - -/* - * AMR => SPR 29 (Power 2.04) - * CTRL => SPR 136 (Power 2.04) - * CTRL => SPR 152 (Power 2.04) - * SCOMC => SPR 276 (64 bits ?) - * SCOMD => SPR 277 (64 bits ?) - * TBU40 => SPR 286 (Power 2.04 hypv) - * HSPRG0 => SPR 304 (Power 2.04 hypv) - * HSPRG1 => SPR 305 (Power 2.04 hypv) - * HDSISR => SPR 306 (Power 2.04 hypv) - * HDAR => SPR 307 (Power 2.04 hypv) - * PURR => SPR 309 (Power 2.04 hypv) - * HDEC => SPR 310 (Power 2.04 hypv) - * HIOR => SPR 311 (hypv) - * RMOR => SPR 312 (970) - * HRMOR => SPR 313 (Power 2.04 hypv) - * HSRR0 => SPR 314 (Power 2.04 hypv) - * HSRR1 => SPR 315 (Power 2.04 hypv) - * LPIDR => SPR 317 (970) - * EPR => SPR 702 (Power 2.04 emb) - * perf => 768-783 (Power 2.04) - * perf => 784-799 (Power 2.04) - * PPR => SPR 896 (Power 2.04) - * DABRX => 1015 (Power 2.04 hypv) - * FPECR => SPR 1022 (?) - * ... and more (thermal management, performance counters, ...) - */ - -/*****************************************************************************/ -/* Exception vectors models */ - #if !defined(CONFIG_USER_ONLY) void cpu_ppc_set_vhyp(PowerPCCPU *cpu, PPCVirtualHypervisor *vhyp) { From patchwork Tue Mar 1 13:56:13 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Fabiano Rosas X-Patchwork-Id: 12764752 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 0FEC1C433F5 for ; Tue, 1 Mar 2022 14:06:17 +0000 (UTC) Received: from localhost ([::1]:36374 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1nP38q-0001I7-2K for qemu-devel@archiver.kernel.org; Tue, 01 Mar 2022 09:06:16 -0500 Received: from eggs.gnu.org ([209.51.188.92]:33394) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1nP2zv-0006Hy-2P; Tue, 01 Mar 2022 08:57:03 -0500 Received: from mx0b-001b2d01.pphosted.com ([148.163.158.5]:17768 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 1nP2zt-00025l-8a; Tue, 01 Mar 2022 08:57:02 -0500 Received: from pps.filterd (m0098413.ppops.net [127.0.0.1]) by mx0b-001b2d01.pphosted.com (8.16.1.2/8.16.1.2) with SMTP id 221DgYdp003461; Tue, 1 Mar 2022 13:56:50 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=GXSuQCow1IOeQZcKuP+cHB7qsqoqywsNO2XyyIhEDaA=; b=lL55UhNuZMs1QVrZnlfm2cRSxcMmFDq4zFDPGyxsNIPgx5c5oe9zOHsKb4bnt/Nq4yCc 72DRu+vwZutUQWTx9BGf9M4QH8FaZ25nUWo7DC7SXJH/vk8Xh352Y8c57dYpL2JyYwY3 yitsJdOzBsuKkCS2IORbEgo0JsqUEUWC4iARUwsHCv9Seddcd9kHtCBeWFObeu6feJAk viW8me337sJbGpRfNl428y5jlJyv94iDl3bMftGYks1A6PT1JBniiufopJmv/SZeNCpk +CUrCM4wjIfuIbQ3tX9m5ECVSg47MGMMqaVWdjwD08XCcEQ1oFiMPFQnI7U1dJKELa4e 1A== Received: from pps.reinject (localhost [127.0.0.1]) by mx0b-001b2d01.pphosted.com with ESMTP id 3ehmku09vu-1 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NOT); Tue, 01 Mar 2022 13:56:50 +0000 Received: from m0098413.ppops.net (m0098413.ppops.net [127.0.0.1]) by pps.reinject (8.16.0.43/8.16.0.43) with SMTP id 221Djbd2010723; Tue, 1 Mar 2022 13:56:49 GMT Received: from ppma03wdc.us.ibm.com (ba.79.3fa9.ip4.static.sl-reverse.com [169.63.121.186]) by mx0b-001b2d01.pphosted.com with ESMTP id 3ehmku09vb-1 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NOT); Tue, 01 Mar 2022 13:56:49 +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 221DtRZT030873; Tue, 1 Mar 2022 13:56:49 GMT Received: from b03cxnp08028.gho.boulder.ibm.com (b03cxnp08028.gho.boulder.ibm.com [9.17.130.20]) by ppma03wdc.us.ibm.com with ESMTP id 3efbu9w13j-1 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NOT); Tue, 01 Mar 2022 13:56:49 +0000 Received: from b03ledav005.gho.boulder.ibm.com (b03ledav005.gho.boulder.ibm.com [9.17.130.236]) by b03cxnp08028.gho.boulder.ibm.com (8.14.9/8.14.9/NCO v10.0) with ESMTP id 221DulSq40698354 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-GCM-SHA384 bits=256 verify=OK); Tue, 1 Mar 2022 13:56:48 GMT Received: from b03ledav005.gho.boulder.ibm.com (unknown [127.0.0.1]) by IMSVA (Postfix) with ESMTP id DB8DCBE054; Tue, 1 Mar 2022 13:56:47 +0000 (GMT) Received: from b03ledav005.gho.boulder.ibm.com (unknown [127.0.0.1]) by IMSVA (Postfix) with ESMTP id 58146BE04F; Tue, 1 Mar 2022 13:56:46 +0000 (GMT) Received: from farosas.linux.ibm.com.com (unknown [9.211.51.129]) by b03ledav005.gho.boulder.ibm.com (Postfix) with ESMTP; Tue, 1 Mar 2022 13:56:46 +0000 (GMT) From: Fabiano Rosas To: qemu-devel@nongnu.org Subject: [PATCH 10/17] target/ppc: Expose some excp_helper functions Date: Tue, 1 Mar 2022 10:56:13 -0300 Message-Id: <20220301135620.2411952-11-farosas@linux.ibm.com> X-Mailer: git-send-email 2.34.1 In-Reply-To: <20220301135620.2411952-1-farosas@linux.ibm.com> References: <20220301135620.2411952-1-farosas@linux.ibm.com> MIME-Version: 1.0 X-TM-AS-GCONF: 00 X-Proofpoint-GUID: LfqsVomC7w6OGaM8lKjG175aiYmqYC1X X-Proofpoint-ORIG-GUID: dXlkHLpYtjTGUg4EQ3VMH9Qq-H8Abw0b X-Proofpoint-Virus-Version: vendor=baseguard engine=ICAP:2.0.205,Aquarius:18.0.816,Hydra:6.0.425,FMLib:17.11.64.514 definitions=2022-03-01_07,2022-02-26_01,2022-02-23_01 X-Proofpoint-Spam-Details: rule=outbound_notspam policy=outbound score=0 malwarescore=0 adultscore=0 spamscore=0 clxscore=1015 impostorscore=0 mlxscore=0 priorityscore=1501 bulkscore=0 phishscore=0 suspectscore=0 mlxlogscore=999 lowpriorityscore=0 classifier=spam adjust=0 reason=mlx scancount=1 engine=8.12.0-2201110000 definitions=main-2203010074 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_H5=0.001, RCVD_IN_MSPIKE_WL=0.001, SPF_HELO_NONE=0.001, SPF_PASS=-0.001, T_SCC_BODY_TEXT_LINE=-0.01 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 next patches will move the powerpc_excp_foo functions into the proper cpu_foo.c files. This patch makes visible some functions that are common to all of them. Signed-off-by: Fabiano Rosas --- target/ppc/cpu.h | 5 +++++ target/ppc/excp_helper.c | 8 ++++---- 2 files changed, 9 insertions(+), 4 deletions(-) diff --git a/target/ppc/cpu.h b/target/ppc/cpu.h index 1b687521c7..c7bb10b0bf 100644 --- a/target/ppc/cpu.h +++ b/target/ppc/cpu.h @@ -175,6 +175,11 @@ enum { POWERPC_EXCP_TRAP = 0x40, }; +const char *powerpc_excp_name(int excp); +void powerpc_set_excp_state(PowerPCCPU *cpu, + target_ulong vector, target_ulong msr); +void powerpc_reset_excp_state(PowerPCCPU *cpu); + #define PPC_INPUT(env) ((env)->bus_model) /*****************************************************************************/ diff --git a/target/ppc/excp_helper.c b/target/ppc/excp_helper.c index 2b5b1e00d8..07190d785a 100644 --- a/target/ppc/excp_helper.c +++ b/target/ppc/excp_helper.c @@ -36,7 +36,7 @@ /* Exception processing */ #if !defined(CONFIG_USER_ONLY) -static const char *powerpc_excp_name(int excp) +const char *powerpc_excp_name(int excp) { switch (excp) { case POWERPC_EXCP_CRITICAL: return "CRITICAL"; @@ -335,7 +335,7 @@ static void ppc_excp_apply_ail(PowerPCCPU *cpu, int excp, target_ulong msr, } #endif -static void powerpc_reset_excp_state(PowerPCCPU *cpu) +void powerpc_reset_excp_state(PowerPCCPU *cpu) { CPUState *cs = CPU(cpu); CPUPPCState *env = &cpu->env; @@ -345,8 +345,8 @@ static void powerpc_reset_excp_state(PowerPCCPU *cpu) env->error_code = 0; } -static void powerpc_set_excp_state(PowerPCCPU *cpu, target_ulong vector, - target_ulong msr) +void powerpc_set_excp_state(PowerPCCPU *cpu, target_ulong vector, + target_ulong msr) { CPUPPCState *env = &cpu->env; From patchwork Tue Mar 1 13:56:14 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Fabiano Rosas X-Patchwork-Id: 12764756 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 B9917C433EF for ; Tue, 1 Mar 2022 14:09:38 +0000 (UTC) Received: from localhost ([::1]:45222 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1nP3C5-0007VL-U3 for qemu-devel@archiver.kernel.org; Tue, 01 Mar 2022 09:09:37 -0500 Received: from eggs.gnu.org ([209.51.188.92]:33428) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1nP302-0006Oe-Da; Tue, 01 Mar 2022 08:57:17 -0500 Received: from mx0a-001b2d01.pphosted.com ([148.163.156.1]:52650) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1nP2zw-00026G-Fq; Tue, 01 Mar 2022 08:57:07 -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 221Dkd6W020120; Tue, 1 Mar 2022 13:56:53 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=bzGJ7RpJudcH0P0onPCUTKODIoGHYz+yPiRo+5tA6lk=; b=AnPyv0pK0pfFG6OM91jWkn/rIm+hOgqtt2pljb/Uvxfwq4eiVh4ujCzQKP5n13n/eDKD eOZ6xiBiJl9Toz11FCX6b3sgehleZ/2Zeuk3Oxk6lhUIQ1w7p8LlmcAuQc6T9HETSoiE LLDEJ/qkJGCqUQ7UYudTmoaSE3+n6Z4fhXzXKeLrKT1+Lpg8t5haPKzSVo3jWPecEwo6 ypOPIfdGJANec+dQzByyfdgSnbgef6cOw9qk0/rCInv9TfQ7ZBduf4shQRgfl9LigHjr aRhq4SojSSjsGOlSxavqPNWTkrnLtkOEKJ4xE4I8tQwIlI1YcMw1VNltTb0gHkquEcVx bw== Received: from pps.reinject (localhost [127.0.0.1]) by mx0a-001b2d01.pphosted.com with ESMTP id 3ehmnyg7df-1 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NOT); Tue, 01 Mar 2022 13:56:52 +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 221DlpXF023401; Tue, 1 Mar 2022 13:56:52 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 3ehmnyg7cv-1 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NOT); Tue, 01 Mar 2022 13:56:52 +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 221Du43q026024; Tue, 1 Mar 2022 13:56:51 GMT Received: from b03cxnp07029.gho.boulder.ibm.com (b03cxnp07029.gho.boulder.ibm.com [9.17.130.16]) by ppma02dal.us.ibm.com with ESMTP id 3efbuac5fc-1 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NOT); Tue, 01 Mar 2022 13:56:51 +0000 Received: from b03ledav005.gho.boulder.ibm.com (b03ledav005.gho.boulder.ibm.com [9.17.130.236]) by b03cxnp07029.gho.boulder.ibm.com (8.14.9/8.14.9/NCO v10.0) with ESMTP id 221Dun7c25821664 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-GCM-SHA384 bits=256 verify=OK); Tue, 1 Mar 2022 13:56:50 GMT Received: from b03ledav005.gho.boulder.ibm.com (unknown [127.0.0.1]) by IMSVA (Postfix) with ESMTP id C415ABE04F; Tue, 1 Mar 2022 13:56:49 +0000 (GMT) Received: from b03ledav005.gho.boulder.ibm.com (unknown [127.0.0.1]) by IMSVA (Postfix) with ESMTP id 4C861BE053; Tue, 1 Mar 2022 13:56:48 +0000 (GMT) Received: from farosas.linux.ibm.com.com (unknown [9.211.51.129]) by b03ledav005.gho.boulder.ibm.com (Postfix) with ESMTP; Tue, 1 Mar 2022 13:56:48 +0000 (GMT) From: Fabiano Rosas To: qemu-devel@nongnu.org Subject: [PATCH 11/17] target/ppc: Move powerpc_excp_40x into cpu_40x.c Date: Tue, 1 Mar 2022 10:56:14 -0300 Message-Id: <20220301135620.2411952-12-farosas@linux.ibm.com> X-Mailer: git-send-email 2.34.1 In-Reply-To: <20220301135620.2411952-1-farosas@linux.ibm.com> References: <20220301135620.2411952-1-farosas@linux.ibm.com> MIME-Version: 1.0 X-TM-AS-GCONF: 00 X-Proofpoint-GUID: YNmMiV8kc6VKiUiijAa04Ij8jLDJlOq2 X-Proofpoint-ORIG-GUID: PnMdBF-iDpsSGpw4fg6XF71PNhHmd-Jg X-Proofpoint-Virus-Version: vendor=baseguard engine=ICAP:2.0.205,Aquarius:18.0.816,Hydra:6.0.425,FMLib:17.11.64.514 definitions=2022-03-01_07,2022-02-26_01,2022-02-23_01 X-Proofpoint-Spam-Details: rule=outbound_notspam policy=outbound score=0 malwarescore=0 adultscore=0 mlxlogscore=999 lowpriorityscore=0 bulkscore=0 spamscore=0 phishscore=0 mlxscore=0 priorityscore=1501 suspectscore=0 impostorscore=0 clxscore=1015 classifier=spam adjust=0 reason=mlx scancount=1 engine=8.12.0-2201110000 definitions=main-2203010074 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_H5=0.001, RCVD_IN_MSPIKE_WL=0.001, SPF_HELO_NONE=0.001, SPF_PASS=-0.001, T_SCC_BODY_TEXT_LINE=-0.01 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" This change along with the next few patches which move the powerpc_excp_foo functions into the cpu_foo.c files has the following purposes: - Move the exception dispatching (powerpc_excp) closer to the exception vectors initialization (init_excp); - Make it immediately clear which CPUs are affected by the exception dispatching code; - Move code which is not a TCG helper out of excp_helpers.c. Aside from the obvious, this also helps with separation between TCG and KVM code; excp_helpers could be TCG-only (we're not quite there yet); - We could start thinking about ways of simplifying the init_excp/powerpc_excp relationship since both users of the POWERPC_EXCP vector addresses are now in the same place. Signed-off-by: Fabiano Rosas --- target/ppc/cpu.h | 1 + target/ppc/cpu_40x.c | 150 ++++++++++++++++++++++++++++++++++++++- target/ppc/excp_helper.c | 138 ----------------------------------- 3 files changed, 150 insertions(+), 139 deletions(-) diff --git a/target/ppc/cpu.h b/target/ppc/cpu.h index c7bb10b0bf..ba3740ea92 100644 --- a/target/ppc/cpu.h +++ b/target/ppc/cpu.h @@ -179,6 +179,7 @@ const char *powerpc_excp_name(int excp); void powerpc_set_excp_state(PowerPCCPU *cpu, target_ulong vector, target_ulong msr); void powerpc_reset_excp_state(PowerPCCPU *cpu); +void powerpc_excp_40x(PowerPCCPU *cpu, int excp); #define PPC_INPUT(env) ((env)->bus_model) diff --git a/target/ppc/cpu_40x.c b/target/ppc/cpu_40x.c index 4ed2cbc305..4b7bbeb28c 100644 --- a/target/ppc/cpu_40x.c +++ b/target/ppc/cpu_40x.c @@ -1,5 +1,5 @@ /* - * CPU initialization for PowerPC 40x CPUs + * CPU initialization and exception dispatching for PowerPC 40x CPUs * * Copyright IBM Corp. 2022 * @@ -8,9 +8,157 @@ */ #include "qemu/osdep.h" +#include "qemu/log.h" #include "hw/ppc/ppc.h" #include "cpu.h" #include "spr_common.h" +#include "trace.h" +#include "helper_regs.h" + +#if !defined(CONFIG_USER_ONLY) +void powerpc_excp_40x(PowerPCCPU *cpu, int excp) +{ + CPUState *cs = CPU(cpu); + CPUPPCState *env = &cpu->env; + target_ulong msr, new_msr, vector; + int srr0, srr1; + + /* new srr1 value excluding must-be-zero bits */ + msr = env->msr & ~0x783f0000ULL; + + /* + * new interrupt handler msr preserves existing ME unless + * explicitly overriden. + */ + new_msr = env->msr & (((target_ulong)1 << MSR_ME)); + + /* target registers */ + srr0 = SPR_SRR0; + 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; + } + + 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_CRITICAL: /* Critical input */ + srr0 = SPR_40x_SRR2; + srr1 = SPR_40x_SRR3; + 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); + } + + /* machine check exceptions don't have ME set */ + new_msr &= ~((target_ulong)1 << MSR_ME); + + srr0 = SPR_40x_SRR2; + srr1 = SPR_40x_SRR3; + break; + case POWERPC_EXCP_DSI: /* Data storage exception */ + trace_ppc_excp_dsi(env->spr[SPR_40x_ESR], env->spr[SPR_40x_DEAR]); + break; + case POWERPC_EXCP_ISI: /* Instruction storage exception */ + trace_ppc_excp_isi(msr, env->nip); + break; + case POWERPC_EXCP_EXTERNAL: /* External input */ + break; + case POWERPC_EXCP_ALIGN: /* Alignment exception */ + 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(); + powerpc_reset_excp_state(cpu); + return; + } + env->spr[SPR_40x_ESR] = ESR_FP; + break; + case POWERPC_EXCP_INVAL: + trace_ppc_excp_inval(env->nip); + env->spr[SPR_40x_ESR] = ESR_PIL; + break; + case POWERPC_EXCP_PRIV: + env->spr[SPR_40x_ESR] = ESR_PPR; + break; + case POWERPC_EXCP_TRAP: + env->spr[SPR_40x_ESR] = ESR_PTR; + break; + default: + cpu_abort(cs, "Invalid program exception %d. Aborting\n", + env->error_code); + break; + } + break; + case POWERPC_EXCP_SYSCALL: /* System call exception */ + trace_ppc_syscall(env, 0); + + /* + * We need to correct the NIP which in this case is supposed + * to point to the next instruction + */ + env->nip += 4; + break; + case POWERPC_EXCP_FIT: /* Fixed-interval timer interrupt */ + trace_ppc_excp_print("FIT"); + break; + case POWERPC_EXCP_WDT: /* Watchdog timer interrupt */ + trace_ppc_excp_print("WDT"); + break; + case POWERPC_EXCP_DTLB: /* Data TLB error */ + case POWERPC_EXCP_ITLB: /* Instruction TLB error */ + break; + case POWERPC_EXCP_PIT: /* Programmable interval timer interrupt */ + trace_ppc_excp_print("PIT"); + break; + case POWERPC_EXCP_DEBUG: /* Debug interrupt */ + cpu_abort(cs, "%s exception not implemented\n", + powerpc_excp_name(excp)); + break; + default: + cpu_abort(cs, "Invalid PowerPC exception %d. Aborting\n", excp); + break; + } + + /* Save PC */ + env->spr[srr0] = env->nip; + + /* Save MSR */ + env->spr[srr1] = msr; + + powerpc_set_excp_state(cpu, vector, new_msr); +} +#else +void powerpc_excp_40x(PowerPCCPU *cpu, int excp) +{ + g_assert_not_reached(); +} +#endif /* SPR shared between PowerPC 40x implementations */ static void register_40x_sprs(CPUPPCState *env) diff --git a/target/ppc/excp_helper.c b/target/ppc/excp_helper.c index 07190d785a..3ae3f4cc45 100644 --- a/target/ppc/excp_helper.c +++ b/target/ppc/excp_helper.c @@ -376,144 +376,6 @@ void powerpc_set_excp_state(PowerPCCPU *cpu, target_ulong vector, env->reserve_addr = -1; } -static void powerpc_excp_40x(PowerPCCPU *cpu, int excp) -{ - CPUState *cs = CPU(cpu); - CPUPPCState *env = &cpu->env; - target_ulong msr, new_msr, vector; - int srr0, srr1; - - /* new srr1 value excluding must-be-zero bits */ - msr = env->msr & ~0x783f0000ULL; - - /* - * new interrupt handler msr preserves existing ME unless - * explicitly overriden. - */ - new_msr = env->msr & (((target_ulong)1 << MSR_ME)); - - /* target registers */ - srr0 = SPR_SRR0; - 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; - } - - 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_CRITICAL: /* Critical input */ - srr0 = SPR_40x_SRR2; - srr1 = SPR_40x_SRR3; - 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); - } - - /* machine check exceptions don't have ME set */ - new_msr &= ~((target_ulong)1 << MSR_ME); - - srr0 = SPR_40x_SRR2; - srr1 = SPR_40x_SRR3; - break; - case POWERPC_EXCP_DSI: /* Data storage exception */ - trace_ppc_excp_dsi(env->spr[SPR_40x_ESR], env->spr[SPR_40x_DEAR]); - break; - case POWERPC_EXCP_ISI: /* Instruction storage exception */ - trace_ppc_excp_isi(msr, env->nip); - break; - case POWERPC_EXCP_EXTERNAL: /* External input */ - break; - case POWERPC_EXCP_ALIGN: /* Alignment exception */ - 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(); - powerpc_reset_excp_state(cpu); - return; - } - env->spr[SPR_40x_ESR] = ESR_FP; - break; - case POWERPC_EXCP_INVAL: - trace_ppc_excp_inval(env->nip); - env->spr[SPR_40x_ESR] = ESR_PIL; - break; - case POWERPC_EXCP_PRIV: - env->spr[SPR_40x_ESR] = ESR_PPR; - break; - case POWERPC_EXCP_TRAP: - env->spr[SPR_40x_ESR] = ESR_PTR; - break; - default: - cpu_abort(cs, "Invalid program exception %d. Aborting\n", - env->error_code); - break; - } - break; - case POWERPC_EXCP_SYSCALL: /* System call exception */ - trace_ppc_syscall(env, 0); - - /* - * We need to correct the NIP which in this case is supposed - * to point to the next instruction - */ - env->nip += 4; - break; - case POWERPC_EXCP_FIT: /* Fixed-interval timer interrupt */ - trace_ppc_excp_print("FIT"); - break; - case POWERPC_EXCP_WDT: /* Watchdog timer interrupt */ - trace_ppc_excp_print("WDT"); - break; - case POWERPC_EXCP_DTLB: /* Data TLB error */ - case POWERPC_EXCP_ITLB: /* Instruction TLB error */ - break; - case POWERPC_EXCP_PIT: /* Programmable interval timer interrupt */ - trace_ppc_excp_print("PIT"); - break; - case POWERPC_EXCP_DEBUG: /* Debug interrupt */ - cpu_abort(cs, "%s exception not implemented\n", - powerpc_excp_name(excp)); - break; - default: - cpu_abort(cs, "Invalid PowerPC exception %d. Aborting\n", excp); - break; - } - - /* Save PC */ - env->spr[srr0] = env->nip; - - /* Save MSR */ - env->spr[srr1] = msr; - - powerpc_set_excp_state(cpu, vector, new_msr); -} - static void powerpc_excp_6xx(PowerPCCPU *cpu, int excp) { CPUState *cs = CPU(cpu); From patchwork Tue Mar 1 13:56:15 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Fabiano Rosas X-Patchwork-Id: 12764771 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 4F46DC433FE for ; Tue, 1 Mar 2022 14:17:44 +0000 (UTC) Received: from localhost ([::1]:36386 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1nP3Jv-0004F5-1s for qemu-devel@archiver.kernel.org; Tue, 01 Mar 2022 09:17:43 -0500 Received: from eggs.gnu.org ([209.51.188.92]:35002) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1nP34t-0005xN-KR; Tue, 01 Mar 2022 09:02:11 -0500 Received: from mx0b-001b2d01.pphosted.com ([148.163.158.5]:11230 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 1nP34r-0003NL-6Q; Tue, 01 Mar 2022 09:02:11 -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 221DDTMb013599; Tue, 1 Mar 2022 13:56:55 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=PdUNWxrJWezfPBQxww7zx5EdB5hqXx8jt1rI1u68aCY=; b=DwPvRX86y3CQtHHnov4fDhcWDnVjgxLxOWBM3McNm/86ci9OeL2B0WMG8xIMKI4ed6/s YKWFdwhbli2aMNffVFVyNkuSdxQk36nFpvdAPpJLy5gvcokNNrKY3aIpprF7IzKzNmie g3cEVqOX60kUx0HoZhJ3InfDcG6/rBi09/U6sCAEmCqo3SpErneyq0QwixerKOjwlCn0 SrSv5HlzSSrUp/wV/gyZC/VzT62Kf7DTbFZyFcpg4FscFLo6udKu9+DcMockR+jrsgSy Nnlm20m2a8izYgzLHQzUo0+y8fi8yD2JZL1vhi2CXSBihJstQyo9A96+PUNKxe+xiDvp HQ== Received: from pps.reinject (localhost [127.0.0.1]) by mx0b-001b2d01.pphosted.com with ESMTP id 3ehm6e0xx9-1 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NOT); Tue, 01 Mar 2022 13:56:54 +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 221DFOSK017582; Tue, 1 Mar 2022 13:56:54 GMT Received: from ppma01dal.us.ibm.com (83.d6.3fa9.ip4.static.sl-reverse.com [169.63.214.131]) by mx0b-001b2d01.pphosted.com with ESMTP id 3ehm6e0xww-1 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NOT); Tue, 01 Mar 2022 13:56:54 +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 221DtTr8024028; Tue, 1 Mar 2022 13:56:53 GMT Received: from b03cxnp08026.gho.boulder.ibm.com (b03cxnp08026.gho.boulder.ibm.com [9.17.130.18]) by ppma01dal.us.ibm.com with ESMTP id 3efbuac6ns-1 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NOT); Tue, 01 Mar 2022 13:56:53 +0000 Received: from b03ledav005.gho.boulder.ibm.com (b03ledav005.gho.boulder.ibm.com [9.17.130.236]) by b03cxnp08026.gho.boulder.ibm.com (8.14.9/8.14.9/NCO v10.0) with ESMTP id 221DupCv25821538 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-GCM-SHA384 bits=256 verify=OK); Tue, 1 Mar 2022 13:56:51 GMT Received: from b03ledav005.gho.boulder.ibm.com (unknown [127.0.0.1]) by IMSVA (Postfix) with ESMTP id CA313BE04F; Tue, 1 Mar 2022 13:56:51 +0000 (GMT) Received: from b03ledav005.gho.boulder.ibm.com (unknown [127.0.0.1]) by IMSVA (Postfix) with ESMTP id 3D65FBE056; Tue, 1 Mar 2022 13:56:50 +0000 (GMT) Received: from farosas.linux.ibm.com.com (unknown [9.211.51.129]) by b03ledav005.gho.boulder.ibm.com (Postfix) with ESMTP; Tue, 1 Mar 2022 13:56:49 +0000 (GMT) From: Fabiano Rosas To: qemu-devel@nongnu.org Subject: [PATCH 12/17] target/ppc: Move powerpc_excp_6xx into cpu_6xx.c Date: Tue, 1 Mar 2022 10:56:15 -0300 Message-Id: <20220301135620.2411952-13-farosas@linux.ibm.com> X-Mailer: git-send-email 2.34.1 In-Reply-To: <20220301135620.2411952-1-farosas@linux.ibm.com> References: <20220301135620.2411952-1-farosas@linux.ibm.com> MIME-Version: 1.0 X-TM-AS-GCONF: 00 X-Proofpoint-GUID: G9HWk6-YEnS4Tcbn0TVEkP6yY-IOKgP3 X-Proofpoint-ORIG-GUID: 6Jxh3lTHCj2LlCs2xemdSuNJ9S7jqnWj X-Proofpoint-Virus-Version: vendor=baseguard engine=ICAP:2.0.205,Aquarius:18.0.816,Hydra:6.0.425,FMLib:17.11.64.514 definitions=2022-03-01_07,2022-02-26_01,2022-02-23_01 X-Proofpoint-Spam-Details: rule=outbound_notspam policy=outbound score=0 malwarescore=0 spamscore=0 mlxscore=0 lowpriorityscore=0 bulkscore=0 suspectscore=0 adultscore=0 mlxlogscore=637 impostorscore=0 phishscore=0 clxscore=1015 priorityscore=1501 classifier=spam adjust=0 reason=mlx scancount=1 engine=8.12.0-2201110000 definitions=main-2203010074 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_H5=0.001, RCVD_IN_MSPIKE_WL=0.001, SPF_HELO_NONE=0.001, SPF_PASS=-0.001, T_SCC_BODY_TEXT_LINE=-0.01 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" Signed-off-by: Fabiano Rosas --- target/ppc/cpu.h | 2 + target/ppc/cpu_6xx.c | 188 ++++++++++++++++++++++++++++++++++++++- target/ppc/excp_helper.c | 177 +----------------------------------- 3 files changed, 190 insertions(+), 177 deletions(-) diff --git a/target/ppc/cpu.h b/target/ppc/cpu.h index ba3740ea92..1a5150f712 100644 --- a/target/ppc/cpu.h +++ b/target/ppc/cpu.h @@ -179,7 +179,9 @@ const char *powerpc_excp_name(int excp); void powerpc_set_excp_state(PowerPCCPU *cpu, target_ulong vector, target_ulong msr); void powerpc_reset_excp_state(PowerPCCPU *cpu); +void ppc_excp_debug_sw_tlb(CPUPPCState *env, int excp); void powerpc_excp_40x(PowerPCCPU *cpu, int excp); +void powerpc_excp_6xx(PowerPCCPU *cpu, int excp); #define PPC_INPUT(env) ((env)->bus_model) diff --git a/target/ppc/cpu_6xx.c b/target/ppc/cpu_6xx.c index a909f79e87..b6a4909dbf 100644 --- a/target/ppc/cpu_6xx.c +++ b/target/ppc/cpu_6xx.c @@ -1,5 +1,5 @@ /* - * CPU initialization for PowerPC 6xx CPUs + * CPU initialization and exception dispatching for PowerPC 6xx CPUs * * Copyright IBM Corp. 2022 * @@ -8,10 +8,14 @@ */ #include "qemu/osdep.h" +#include "qemu/log.h" #include "sysemu/hw_accel.h" #include "hw/ppc/ppc.h" #include "cpu.h" #include "spr_common.h" +#include "trace.h" +#include "helper_regs.h" + static int check_pow_hid0(CPUPPCState *env) { @@ -22,6 +26,188 @@ static int check_pow_hid0(CPUPPCState *env) return 0; } +#if !defined(CONFIG_USER_ONLY) +void powerpc_excp_6xx(PowerPCCPU *cpu, int excp) +{ + CPUState *cs = CPU(cpu); + CPUPPCState *env = &cpu->env; + target_ulong msr, new_msr, vector; + + /* new srr1 value excluding must-be-zero bits */ + msr = env->msr & ~0x783f0000ULL; + + /* + * new interrupt handler msr preserves existing ME unless + * explicitly overriden + */ + new_msr = env->msr & ((target_ulong)1 << MSR_ME); + + /* + * Hypervisor emulation assistance interrupt only exists on server + * arch 2.05 server or later. + */ + if (excp == POWERPC_EXCP_HV_EMU) { + excp = POWERPC_EXCP_PROGRAM; + } + + 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_CRITICAL: /* Critical input */ + 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); + } + + /* machine check exceptions don't have ME set */ + new_msr &= ~((target_ulong)1 << MSR_ME); + + break; + case POWERPC_EXCP_DSI: /* Data storage exception */ + 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; + break; + case POWERPC_EXCP_EXTERNAL: /* External input */ + 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; + 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(); + powerpc_reset_excp_state(cpu); + return; + } + + /* + * FP exceptions always have NIP pointing to the faulting + * instruction, so always use store_next and claim we are + * precise in the MSR. + */ + msr |= 0x00100000; + break; + case POWERPC_EXCP_INVAL: + trace_ppc_excp_inval(env->nip); + msr |= 0x00080000; + break; + case POWERPC_EXCP_PRIV: + msr |= 0x00040000; + break; + case POWERPC_EXCP_TRAP: + msr |= 0x00020000; + break; + default: + /* Should never occur */ + cpu_abort(cs, "Invalid program exception %d. Aborting\n", + env->error_code); + break; + } + break; + case POWERPC_EXCP_SYSCALL: /* System call exception */ + trace_ppc_syscall(env, 0); + + /* + * We need to correct the NIP which in this case is supposed + * to point to the next instruction + */ + env->nip += 4; + break; + case POWERPC_EXCP_FPU: /* Floating-point unavailable exception */ + case POWERPC_EXCP_DECR: /* Decrementer exception */ + break; + case POWERPC_EXCP_DTLB: /* Data TLB error */ + case POWERPC_EXCP_ITLB: /* Instruction TLB error */ + break; + case POWERPC_EXCP_RESET: /* System reset exception */ + if (msr_pow) { + cpu_abort(cs, "Trying to deliver power-saving system reset " + "exception %d with no HV support\n", excp); + } + break; + case POWERPC_EXCP_TRACE: /* Trace exception */ + 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 */ + /* Swap temporary saved registers with GPRs */ + if (!(new_msr & ((target_ulong)1 << MSR_TGPR))) { + new_msr |= (target_ulong)1 << MSR_TGPR; + hreg_swap_gpr_tgpr(env); + } + + ppc_excp_debug_sw_tlb(env, excp); + + msr |= env->crf[0] << 28; + 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; + break; + case POWERPC_EXCP_FPA: /* Floating-point assist exception */ + case POWERPC_EXCP_DABR: /* Data address breakpoint */ + case POWERPC_EXCP_IABR: /* Instruction address breakpoint */ + case POWERPC_EXCP_SMI: /* System management interrupt */ + case POWERPC_EXCP_MEXTBR: /* Maskable external breakpoint */ + case POWERPC_EXCP_NMEXTBR: /* Non maskable external breakpoint */ + cpu_abort(cs, "%s exception not implemented\n", + powerpc_excp_name(excp)); + break; + default: + cpu_abort(cs, "Invalid PowerPC exception %d. Aborting\n", excp); + break; + } + + /* + * Sort out endianness of interrupt, this differs depending on the + * CPU, the HV mode, etc... + */ + if (ppc_interrupts_little_endian(cpu, !!(new_msr & MSR_HVB))) { + new_msr |= (target_ulong)1 << MSR_LE; + } + + /* Save PC */ + env->spr[SPR_SRR0] = env->nip; + + /* Save MSR */ + env->spr[SPR_SRR1] = msr; + + powerpc_set_excp_state(cpu, vector, new_msr); +} +#else +void powerpc_excp_6xx(PowerPCCPU *cpu, int excp) +{ + g_assert_not_reached(); +} +#endif + static void register_5xx_8xx_sprs(CPUPPCState *env) { /* Exception processing */ diff --git a/target/ppc/excp_helper.c b/target/ppc/excp_helper.c index 3ae3f4cc45..2cbd7be499 100644 --- a/target/ppc/excp_helper.c +++ b/target/ppc/excp_helper.c @@ -106,7 +106,7 @@ const char *powerpc_excp_name(int excp) } } -static void ppc_excp_debug_sw_tlb(CPUPPCState *env, int excp) +void ppc_excp_debug_sw_tlb(CPUPPCState *env, int excp) { const char *es; target_ulong *miss, *cmp; @@ -376,181 +376,6 @@ void powerpc_set_excp_state(PowerPCCPU *cpu, target_ulong vector, env->reserve_addr = -1; } -static void powerpc_excp_6xx(PowerPCCPU *cpu, int excp) -{ - CPUState *cs = CPU(cpu); - CPUPPCState *env = &cpu->env; - target_ulong msr, new_msr, vector; - - /* new srr1 value excluding must-be-zero bits */ - msr = env->msr & ~0x783f0000ULL; - - /* - * new interrupt handler msr preserves existing ME unless - * explicitly overriden - */ - new_msr = env->msr & ((target_ulong)1 << MSR_ME); - - /* - * Hypervisor emulation assistance interrupt only exists on server - * arch 2.05 server or later. - */ - if (excp == POWERPC_EXCP_HV_EMU) { - excp = POWERPC_EXCP_PROGRAM; - } - - 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_CRITICAL: /* Critical input */ - 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); - } - - /* machine check exceptions don't have ME set */ - new_msr &= ~((target_ulong)1 << MSR_ME); - - break; - case POWERPC_EXCP_DSI: /* Data storage exception */ - 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; - break; - case POWERPC_EXCP_EXTERNAL: /* External input */ - 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; - 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(); - powerpc_reset_excp_state(cpu); - return; - } - - /* - * FP exceptions always have NIP pointing to the faulting - * instruction, so always use store_next and claim we are - * precise in the MSR. - */ - msr |= 0x00100000; - break; - case POWERPC_EXCP_INVAL: - trace_ppc_excp_inval(env->nip); - msr |= 0x00080000; - break; - case POWERPC_EXCP_PRIV: - msr |= 0x00040000; - break; - case POWERPC_EXCP_TRAP: - msr |= 0x00020000; - break; - default: - /* Should never occur */ - cpu_abort(cs, "Invalid program exception %d. Aborting\n", - env->error_code); - break; - } - break; - case POWERPC_EXCP_SYSCALL: /* System call exception */ - trace_ppc_syscall(env, 0); - - /* - * We need to correct the NIP which in this case is supposed - * to point to the next instruction - */ - env->nip += 4; - break; - case POWERPC_EXCP_FPU: /* Floating-point unavailable exception */ - case POWERPC_EXCP_DECR: /* Decrementer exception */ - break; - case POWERPC_EXCP_DTLB: /* Data TLB error */ - case POWERPC_EXCP_ITLB: /* Instruction TLB error */ - break; - case POWERPC_EXCP_RESET: /* System reset exception */ - if (msr_pow) { - cpu_abort(cs, "Trying to deliver power-saving system reset " - "exception %d with no HV support\n", excp); - } - break; - case POWERPC_EXCP_TRACE: /* Trace exception */ - 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 */ - /* Swap temporary saved registers with GPRs */ - if (!(new_msr & ((target_ulong)1 << MSR_TGPR))) { - new_msr |= (target_ulong)1 << MSR_TGPR; - hreg_swap_gpr_tgpr(env); - } - - ppc_excp_debug_sw_tlb(env, excp); - - msr |= env->crf[0] << 28; - 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; - break; - case POWERPC_EXCP_FPA: /* Floating-point assist exception */ - case POWERPC_EXCP_DABR: /* Data address breakpoint */ - case POWERPC_EXCP_IABR: /* Instruction address breakpoint */ - case POWERPC_EXCP_SMI: /* System management interrupt */ - case POWERPC_EXCP_MEXTBR: /* Maskable external breakpoint */ - case POWERPC_EXCP_NMEXTBR: /* Non maskable external breakpoint */ - cpu_abort(cs, "%s exception not implemented\n", - powerpc_excp_name(excp)); - break; - default: - cpu_abort(cs, "Invalid PowerPC exception %d. Aborting\n", excp); - break; - } - - /* - * Sort out endianness of interrupt, this differs depending on the - * CPU, the HV mode, etc... - */ - if (ppc_interrupts_little_endian(cpu, !!(new_msr & MSR_HVB))) { - new_msr |= (target_ulong)1 << MSR_LE; - } - - /* Save PC */ - env->spr[SPR_SRR0] = env->nip; - - /* Save MSR */ - env->spr[SPR_SRR1] = msr; - - powerpc_set_excp_state(cpu, vector, new_msr); -} - static void powerpc_excp_7xx(PowerPCCPU *cpu, int excp) { CPUState *cs = CPU(cpu); From patchwork Tue Mar 1 13:56:16 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Fabiano Rosas X-Patchwork-Id: 12764770 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 C3E45C433EF for ; Tue, 1 Mar 2022 14:14:36 +0000 (UTC) Received: from localhost ([::1]:56748 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1nP3Gt-00079K-VB for qemu-devel@archiver.kernel.org; Tue, 01 Mar 2022 09:14:35 -0500 Received: from eggs.gnu.org ([209.51.188.92]:33412) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1nP2zw-0006KA-Sc; Tue, 01 Mar 2022 08:57:04 -0500 Received: from mx0a-001b2d01.pphosted.com ([148.163.156.1]:46484) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1nP2zu-00025x-BN; Tue, 01 Mar 2022 08:57:04 -0500 Received: from pps.filterd (m0098399.ppops.net [127.0.0.1]) by mx0a-001b2d01.pphosted.com (8.16.1.2/8.16.1.2) with SMTP id 221DlX9l002459; Tue, 1 Mar 2022 13:56:57 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=neJTrP27U39KKV3x/kRwWVk2u76aQVFbMe2ZcFg9wyk=; b=HWZRa39woKai8zI52b325PqffIh1XotnaaQR7GoZvAbhOs30kXGBKhJZfQn9+RWOTUXm oyzDw0pObu+szjr+e0hYvEIR8RLkVH/Sz1cR6s/gKxcWqXVmreKWRR9nFPPhSnlBOcBY uXVrMJ8WHtyutAa1wTQB9m6BmSuqTrs9Nd8E6futh+6iYZNjRXeC9Ua5CLQeCv3M6cwU DxTEMLRfKFrFVPInVoIIU5B0oRMm+UyBM+Ix+rKHCSdbxfXKnd2ahNNH4Qzw6Bd/a5GL Z5Tyk+wAS511F0oM/SxVmK5VawDcardHXeKHtQH8MlHhAZhUxMC5MtBaZiGulSzUvUXF ug== Received: from pps.reinject (localhost [127.0.0.1]) by mx0a-001b2d01.pphosted.com with ESMTP id 3ehgc6phkq-1 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NOT); Tue, 01 Mar 2022 13:56:56 +0000 Received: from m0098399.ppops.net (m0098399.ppops.net [127.0.0.1]) by pps.reinject (8.16.0.43/8.16.0.43) with SMTP id 221DJmb7025741; Tue, 1 Mar 2022 13:56:56 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 3ehgc6phk6-1 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NOT); Tue, 01 Mar 2022 13:56:56 +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 221Du5XE010415; Tue, 1 Mar 2022 13:56:54 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 3efbua50rh-1 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NOT); Tue, 01 Mar 2022 13:56:54 +0000 Received: from b03ledav005.gho.boulder.ibm.com (b03ledav005.gho.boulder.ibm.com [9.17.130.236]) by b03cxnp08027.gho.boulder.ibm.com (8.14.9/8.14.9/NCO v10.0) with ESMTP id 221DurxT17040002 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-GCM-SHA384 bits=256 verify=OK); Tue, 1 Mar 2022 13:56:53 GMT Received: from b03ledav005.gho.boulder.ibm.com (unknown [127.0.0.1]) by IMSVA (Postfix) with ESMTP id BD431BE053; Tue, 1 Mar 2022 13:56:53 +0000 (GMT) Received: from b03ledav005.gho.boulder.ibm.com (unknown [127.0.0.1]) by IMSVA (Postfix) with ESMTP id 304DDBE056; Tue, 1 Mar 2022 13:56:52 +0000 (GMT) Received: from farosas.linux.ibm.com.com (unknown [9.211.51.129]) by b03ledav005.gho.boulder.ibm.com (Postfix) with ESMTP; Tue, 1 Mar 2022 13:56:51 +0000 (GMT) From: Fabiano Rosas To: qemu-devel@nongnu.org Subject: [PATCH 13/17] target/ppc: Move powerpc_excp_7xx into cpu_7xx.c Date: Tue, 1 Mar 2022 10:56:16 -0300 Message-Id: <20220301135620.2411952-14-farosas@linux.ibm.com> X-Mailer: git-send-email 2.34.1 In-Reply-To: <20220301135620.2411952-1-farosas@linux.ibm.com> References: <20220301135620.2411952-1-farosas@linux.ibm.com> MIME-Version: 1.0 X-TM-AS-GCONF: 00 X-Proofpoint-GUID: Txk4oWsPROBP6t-IfVToxB_CO8RiaRdm X-Proofpoint-ORIG-GUID: HKfBFqVWbpcIhhN9eB3oh2E8FWen5HUJ X-Proofpoint-Virus-Version: vendor=baseguard engine=ICAP:2.0.205,Aquarius:18.0.816,Hydra:6.0.425,FMLib:17.11.64.514 definitions=2022-03-01_07,2022-02-26_01,2022-02-23_01 X-Proofpoint-Spam-Details: rule=outbound_notspam policy=outbound score=0 mlxscore=0 mlxlogscore=906 spamscore=0 malwarescore=0 impostorscore=0 adultscore=0 suspectscore=0 lowpriorityscore=0 phishscore=0 priorityscore=1501 clxscore=1015 bulkscore=0 classifier=spam adjust=0 reason=mlx scancount=1 engine=8.12.0-2201110000 definitions=main-2203010074 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_H5=0.001, RCVD_IN_MSPIKE_WL=0.001, SPF_HELO_NONE=0.001, SPF_PASS=-0.001, T_SCC_BODY_TEXT_LINE=-0.01 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" Signed-off-by: Fabiano Rosas --- target/ppc/cpu.h | 1 + target/ppc/cpu_7xx.c | 193 ++++++++++++++++++++++++++++++++++++++- target/ppc/excp_helper.c | 181 ------------------------------------ 3 files changed, 193 insertions(+), 182 deletions(-) diff --git a/target/ppc/cpu.h b/target/ppc/cpu.h index 1a5150f712..10920464ad 100644 --- a/target/ppc/cpu.h +++ b/target/ppc/cpu.h @@ -182,6 +182,7 @@ void powerpc_reset_excp_state(PowerPCCPU *cpu); void ppc_excp_debug_sw_tlb(CPUPPCState *env, int excp); void powerpc_excp_40x(PowerPCCPU *cpu, int excp); void powerpc_excp_6xx(PowerPCCPU *cpu, int excp); +void powerpc_excp_7xx(PowerPCCPU *cpu, int excp); #define PPC_INPUT(env) ((env)->bus_model) diff --git a/target/ppc/cpu_7xx.c b/target/ppc/cpu_7xx.c index 423f4cb97a..6f99521aba 100644 --- a/target/ppc/cpu_7xx.c +++ b/target/ppc/cpu_7xx.c @@ -1,5 +1,5 @@ /* - * CPU initialization for PowerPC 7xx CPUs + * CPU initialization and exception dispatching for PowerPC 7xx CPUs * * Copyright IBM Corp. 2022 * @@ -8,10 +8,201 @@ */ #include "qemu/osdep.h" +#include "qemu/log.h" #include "sysemu/hw_accel.h" #include "hw/ppc/ppc.h" #include "cpu.h" #include "spr_common.h" +#include "trace.h" +#include "helper_regs.h" + +#if !defined(CONFIG_USER_ONLY) +void powerpc_excp_7xx(PowerPCCPU *cpu, int excp) +{ + CPUState *cs = CPU(cpu); + CPUPPCState *env = &cpu->env; + target_ulong msr, new_msr, vector; + + /* new srr1 value excluding must-be-zero bits */ + msr = env->msr & ~0x783f0000ULL; + + /* + * new interrupt handler msr preserves existing ME unless + * explicitly overriden + */ + new_msr = env->msr & ((target_ulong)1 << MSR_ME); + + /* + * Hypervisor emulation assistance interrupt only exists on server + * arch 2.05 server or later. + */ + if (excp == POWERPC_EXCP_HV_EMU) { + excp = POWERPC_EXCP_PROGRAM; + } + + 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_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); + } + + /* machine check exceptions don't have ME set */ + new_msr &= ~((target_ulong)1 << MSR_ME); + + break; + case POWERPC_EXCP_DSI: /* Data storage exception */ + 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; + break; + case POWERPC_EXCP_EXTERNAL: /* External input */ + 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; + 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(); + powerpc_reset_excp_state(cpu); + return; + } + + /* + * FP exceptions always have NIP pointing to the faulting + * instruction, so always use store_next and claim we are + * precise in the MSR. + */ + msr |= 0x00100000; + break; + case POWERPC_EXCP_INVAL: + trace_ppc_excp_inval(env->nip); + msr |= 0x00080000; + break; + case POWERPC_EXCP_PRIV: + msr |= 0x00040000; + break; + case POWERPC_EXCP_TRAP: + msr |= 0x00020000; + break; + default: + /* Should never occur */ + cpu_abort(cs, "Invalid program exception %d. Aborting\n", + env->error_code); + break; + } + break; + case POWERPC_EXCP_SYSCALL: /* System call exception */ + { + int lev = env->error_code; + + trace_ppc_syscall(env, lev); + + /* + * We need to correct the NIP which in this case is supposed + * to point to the next instruction + */ + env->nip += 4; + + /* + * The Virtual Open Firmware (VOF) relies on the 'sc 1' + * instruction to communicate with QEMU. The pegasos2 machine + * uses VOF and the 7xx CPUs, so although the 7xx don't have + * HV mode, we need to keep hypercall support. + */ + if (lev == 1 && cpu->vhyp) { + PPCVirtualHypervisorClass *vhc = + PPC_VIRTUAL_HYPERVISOR_GET_CLASS(cpu->vhyp); + vhc->hypercall(cpu->vhyp, cpu); + return; + } + + break; + } + case POWERPC_EXCP_FPU: /* Floating-point unavailable exception */ + case POWERPC_EXCP_DECR: /* Decrementer exception */ + break; + case POWERPC_EXCP_RESET: /* System reset exception */ + if (msr_pow) { + cpu_abort(cs, "Trying to deliver power-saving system reset " + "exception %d with no HV support\n", excp); + } + break; + case POWERPC_EXCP_TRACE: /* Trace exception */ + 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_excp_debug_sw_tlb(env, excp); + + msr |= env->crf[0] << 28; + 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; + + break; + case POWERPC_EXCP_IABR: /* Instruction address breakpoint */ + case POWERPC_EXCP_SMI: /* System management interrupt */ + case POWERPC_EXCP_THERM: /* Thermal interrupt */ + case POWERPC_EXCP_PERFM: /* Embedded performance monitor interrupt */ + cpu_abort(cs, "%s exception not implemented\n", + powerpc_excp_name(excp)); + break; + default: + cpu_abort(cs, "Invalid PowerPC exception %d. Aborting\n", excp); + break; + } + + /* + * Sort out endianness of interrupt, this differs depending on the + * CPU, the HV mode, etc... + */ + if (ppc_interrupts_little_endian(cpu, !!(new_msr & MSR_HVB))) { + new_msr |= (target_ulong)1 << MSR_LE; + } + + /* Save PC */ + env->spr[SPR_SRR0] = env->nip; + + /* Save MSR */ + env->spr[SPR_SRR1] = msr; + + powerpc_set_excp_state(cpu, vector, new_msr); +} +#else +void powerpc_excp_7xx(PowerPCCPU *cpu, int excp) +{ + g_assert_not_reached(); +} +#endif static int check_pow_hid0(CPUPPCState *env) { diff --git a/target/ppc/excp_helper.c b/target/ppc/excp_helper.c index 2cbd7be499..1306dcedcf 100644 --- a/target/ppc/excp_helper.c +++ b/target/ppc/excp_helper.c @@ -376,187 +376,6 @@ void powerpc_set_excp_state(PowerPCCPU *cpu, target_ulong vector, env->reserve_addr = -1; } -static void powerpc_excp_7xx(PowerPCCPU *cpu, int excp) -{ - CPUState *cs = CPU(cpu); - CPUPPCState *env = &cpu->env; - target_ulong msr, new_msr, vector; - - /* new srr1 value excluding must-be-zero bits */ - msr = env->msr & ~0x783f0000ULL; - - /* - * new interrupt handler msr preserves existing ME unless - * explicitly overriden - */ - new_msr = env->msr & ((target_ulong)1 << MSR_ME); - - /* - * Hypervisor emulation assistance interrupt only exists on server - * arch 2.05 server or later. - */ - if (excp == POWERPC_EXCP_HV_EMU) { - excp = POWERPC_EXCP_PROGRAM; - } - - 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_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); - } - - /* machine check exceptions don't have ME set */ - new_msr &= ~((target_ulong)1 << MSR_ME); - - break; - case POWERPC_EXCP_DSI: /* Data storage exception */ - 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; - break; - case POWERPC_EXCP_EXTERNAL: /* External input */ - 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; - 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(); - powerpc_reset_excp_state(cpu); - return; - } - - /* - * FP exceptions always have NIP pointing to the faulting - * instruction, so always use store_next and claim we are - * precise in the MSR. - */ - msr |= 0x00100000; - break; - case POWERPC_EXCP_INVAL: - trace_ppc_excp_inval(env->nip); - msr |= 0x00080000; - break; - case POWERPC_EXCP_PRIV: - msr |= 0x00040000; - break; - case POWERPC_EXCP_TRAP: - msr |= 0x00020000; - break; - default: - /* Should never occur */ - cpu_abort(cs, "Invalid program exception %d. Aborting\n", - env->error_code); - break; - } - break; - case POWERPC_EXCP_SYSCALL: /* System call exception */ - { - int lev = env->error_code; - - trace_ppc_syscall(env, lev); - - /* - * We need to correct the NIP which in this case is supposed - * to point to the next instruction - */ - env->nip += 4; - - /* - * The Virtual Open Firmware (VOF) relies on the 'sc 1' - * instruction to communicate with QEMU. The pegasos2 machine - * uses VOF and the 7xx CPUs, so although the 7xx don't have - * HV mode, we need to keep hypercall support. - */ - if (lev == 1 && cpu->vhyp) { - PPCVirtualHypervisorClass *vhc = - PPC_VIRTUAL_HYPERVISOR_GET_CLASS(cpu->vhyp); - vhc->hypercall(cpu->vhyp, cpu); - return; - } - - break; - } - case POWERPC_EXCP_FPU: /* Floating-point unavailable exception */ - case POWERPC_EXCP_DECR: /* Decrementer exception */ - break; - case POWERPC_EXCP_RESET: /* System reset exception */ - if (msr_pow) { - cpu_abort(cs, "Trying to deliver power-saving system reset " - "exception %d with no HV support\n", excp); - } - break; - case POWERPC_EXCP_TRACE: /* Trace exception */ - 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_excp_debug_sw_tlb(env, excp); - - msr |= env->crf[0] << 28; - 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; - - break; - case POWERPC_EXCP_IABR: /* Instruction address breakpoint */ - case POWERPC_EXCP_SMI: /* System management interrupt */ - case POWERPC_EXCP_THERM: /* Thermal interrupt */ - case POWERPC_EXCP_PERFM: /* Embedded performance monitor interrupt */ - cpu_abort(cs, "%s exception not implemented\n", - powerpc_excp_name(excp)); - break; - default: - cpu_abort(cs, "Invalid PowerPC exception %d. Aborting\n", excp); - break; - } - - /* - * Sort out endianness of interrupt, this differs depending on the - * CPU, the HV mode, etc... - */ - if (ppc_interrupts_little_endian(cpu, !!(new_msr & MSR_HVB))) { - new_msr |= (target_ulong)1 << MSR_LE; - } - - /* Save PC */ - env->spr[SPR_SRR0] = env->nip; - - /* Save MSR */ - env->spr[SPR_SRR1] = msr; - - powerpc_set_excp_state(cpu, vector, new_msr); -} - static void powerpc_excp_74xx(PowerPCCPU *cpu, int excp) { CPUState *cs = CPU(cpu); From patchwork Tue Mar 1 13:56:17 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Fabiano Rosas X-Patchwork-Id: 12764758 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 A0A95C433F5 for ; Tue, 1 Mar 2022 14:11:58 +0000 (UTC) Received: from localhost ([::1]:50266 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1nP3EL-0002hQ-Js for qemu-devel@archiver.kernel.org; Tue, 01 Mar 2022 09:11:57 -0500 Received: from eggs.gnu.org ([209.51.188.92]:33462) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1nP307-0006Oy-U2; Tue, 01 Mar 2022 08:57:17 -0500 Received: from mx0b-001b2d01.pphosted.com ([148.163.158.5]:52390 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 1nP302-00026p-EQ; Tue, 01 Mar 2022 08:57:13 -0500 Received: from pps.filterd (m0098419.ppops.net [127.0.0.1]) by mx0b-001b2d01.pphosted.com (8.16.1.2/8.16.1.2) with SMTP id 221CpZ4D013912; Tue, 1 Mar 2022 13:56:57 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=8Zs83GwgmPkgBsRA9eR7M9871igkOoflBfu+hTiv4Z4=; b=Lk0IDwiGkl8dry/C5oFeGKr0oVyoaNWXAwf1SpGl5UecqXIInxZwxYuyinzQJIQjmqjC QrMuIDjNNIYusuhY859tbmhbcxvQrM3cf8XNvBjzuNo8tnrCNc1CreCeD9YFrfqSMjLB Lxyx1POiviMAe7K8JWjNSM08a9gOJuRT0s+uBzNftnFu6+X5lDiUJXCzAOJYMO6YOSf2 gAZHNQyuW3v/XU7B4lPpktgX7CRkANspW99DGWRBz+K1aSnQ+GgyNOSvatPufCU63UqV eXZGJWMQjaBDmkjyjsD7IKPyF2sKKdTTPK+/rFVH8MV6PmTX0l9HIhn/ZWH5QUD6KgQh Fg== Received: from pps.reinject (localhost [127.0.0.1]) by mx0b-001b2d01.pphosted.com with ESMTP id 3ehkv5hgmf-1 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NOT); Tue, 01 Mar 2022 13:56:57 +0000 Received: from m0098419.ppops.net (m0098419.ppops.net [127.0.0.1]) by pps.reinject (8.16.0.43/8.16.0.43) with SMTP id 221DWSov025880; Tue, 1 Mar 2022 13:56:57 GMT Received: from ppma01wdc.us.ibm.com (fd.55.37a9.ip4.static.sl-reverse.com [169.55.85.253]) by mx0b-001b2d01.pphosted.com with ESMTP id 3ehkv5hgm1-1 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NOT); Tue, 01 Mar 2022 13:56:57 +0000 Received: from pps.filterd (ppma01wdc.us.ibm.com [127.0.0.1]) by ppma01wdc.us.ibm.com (8.16.1.2/8.16.1.2) with SMTP id 221DtVuc003473; Tue, 1 Mar 2022 13:56:56 GMT Received: from b03cxnp07027.gho.boulder.ibm.com (b03cxnp07027.gho.boulder.ibm.com [9.17.130.14]) by ppma01wdc.us.ibm.com with ESMTP id 3efbu9my9d-1 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NOT); Tue, 01 Mar 2022 13:56:56 +0000 Received: from b03ledav005.gho.boulder.ibm.com (b03ledav005.gho.boulder.ibm.com [9.17.130.236]) by b03cxnp07027.gho.boulder.ibm.com (8.14.9/8.14.9/NCO v10.0) with ESMTP id 221DutHJ27722058 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-GCM-SHA384 bits=256 verify=OK); Tue, 1 Mar 2022 13:56:55 GMT Received: from b03ledav005.gho.boulder.ibm.com (unknown [127.0.0.1]) by IMSVA (Postfix) with ESMTP id 93056BE05D; Tue, 1 Mar 2022 13:56:55 +0000 (GMT) Received: from b03ledav005.gho.boulder.ibm.com (unknown [127.0.0.1]) by IMSVA (Postfix) with ESMTP id 3014BBE053; Tue, 1 Mar 2022 13:56:54 +0000 (GMT) Received: from farosas.linux.ibm.com.com (unknown [9.211.51.129]) by b03ledav005.gho.boulder.ibm.com (Postfix) with ESMTP; Tue, 1 Mar 2022 13:56:53 +0000 (GMT) From: Fabiano Rosas To: qemu-devel@nongnu.org Subject: [PATCH 14/17] target/ppc: Move powerpc_excp_74xx into cpu_74xx.c Date: Tue, 1 Mar 2022 10:56:17 -0300 Message-Id: <20220301135620.2411952-15-farosas@linux.ibm.com> X-Mailer: git-send-email 2.34.1 In-Reply-To: <20220301135620.2411952-1-farosas@linux.ibm.com> References: <20220301135620.2411952-1-farosas@linux.ibm.com> MIME-Version: 1.0 X-TM-AS-GCONF: 00 X-Proofpoint-ORIG-GUID: 1Y5yE9QXujzyNAIvuVdjw-Y269C1r1Me X-Proofpoint-GUID: 3KhblOlkclsk9X0AVwxqZgbb2nIeetUa X-Proofpoint-Virus-Version: vendor=baseguard engine=ICAP:2.0.205,Aquarius:18.0.816,Hydra:6.0.425,FMLib:17.11.64.514 definitions=2022-03-01_07,2022-02-26_01,2022-02-23_01 X-Proofpoint-Spam-Details: rule=outbound_notspam policy=outbound score=0 clxscore=1015 phishscore=0 bulkscore=0 adultscore=0 lowpriorityscore=0 mlxscore=0 impostorscore=0 priorityscore=1501 spamscore=0 suspectscore=0 mlxlogscore=925 malwarescore=0 classifier=spam adjust=0 reason=mlx scancount=1 engine=8.12.0-2201110000 definitions=main-2203010074 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_H5=0.001, RCVD_IN_MSPIKE_WL=0.001, SPF_HELO_NONE=0.001, SPF_PASS=-0.001, T_SCC_BODY_TEXT_LINE=-0.01 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" Signed-off-by: Fabiano Rosas --- target/ppc/cpu.h | 1 + target/ppc/cpu_74xx.c | 185 ++++++++++++++++++++++++++++++++++++++- target/ppc/excp_helper.c | 173 ------------------------------------ 3 files changed, 185 insertions(+), 174 deletions(-) diff --git a/target/ppc/cpu.h b/target/ppc/cpu.h index 10920464ad..614a92954c 100644 --- a/target/ppc/cpu.h +++ b/target/ppc/cpu.h @@ -183,6 +183,7 @@ void ppc_excp_debug_sw_tlb(CPUPPCState *env, int excp); void powerpc_excp_40x(PowerPCCPU *cpu, int excp); void powerpc_excp_6xx(PowerPCCPU *cpu, int excp); void powerpc_excp_7xx(PowerPCCPU *cpu, int excp); +void powerpc_excp_74xx(PowerPCCPU *cpu, int excp); #define PPC_INPUT(env) ((env)->bus_model) diff --git a/target/ppc/cpu_74xx.c b/target/ppc/cpu_74xx.c index cc530cc405..07715cadb5 100644 --- a/target/ppc/cpu_74xx.c +++ b/target/ppc/cpu_74xx.c @@ -1,5 +1,5 @@ /* - * CPU initialization for PowerPC 74xx CPUs + * CPU initialization and exception dispatching for PowerPC 74xx CPUs * * Copyright IBM Corp. 2022 * @@ -8,11 +8,14 @@ */ #include "qemu/osdep.h" +#include "qemu/log.h" #include "sysemu/hw_accel.h" #include "hw/ppc/ppc.h" #include "fpu/softfloat.h" #include "cpu.h" #include "spr_common.h" +#include "trace.h" +#include "helper_regs.h" static int check_pow_hid0(CPUPPCState *env) { @@ -32,6 +35,186 @@ static int check_pow_hid0_74xx(CPUPPCState *env) return 0; } +#if !defined(CONFIG_USER_ONLY) +void powerpc_excp_74xx(PowerPCCPU *cpu, int excp) +{ + CPUState *cs = CPU(cpu); + CPUPPCState *env = &cpu->env; + target_ulong msr, new_msr, vector; + + /* new srr1 value excluding must-be-zero bits */ + msr = env->msr & ~0x783f0000ULL; + + /* + * new interrupt handler msr preserves existing ME unless + * explicitly overriden + */ + new_msr = env->msr & ((target_ulong)1 << MSR_ME); + + /* + * Hypervisor emulation assistance interrupt only exists on server + * arch 2.05 server or later. + */ + if (excp == POWERPC_EXCP_HV_EMU) { + excp = POWERPC_EXCP_PROGRAM; + } + + 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_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); + } + + /* machine check exceptions don't have ME set */ + new_msr &= ~((target_ulong)1 << MSR_ME); + + break; + case POWERPC_EXCP_DSI: /* Data storage exception */ + 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; + break; + case POWERPC_EXCP_EXTERNAL: /* External input */ + 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; + 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(); + powerpc_reset_excp_state(cpu); + return; + } + + /* + * FP exceptions always have NIP pointing to the faulting + * instruction, so always use store_next and claim we are + * precise in the MSR. + */ + msr |= 0x00100000; + break; + case POWERPC_EXCP_INVAL: + trace_ppc_excp_inval(env->nip); + msr |= 0x00080000; + break; + case POWERPC_EXCP_PRIV: + msr |= 0x00040000; + break; + case POWERPC_EXCP_TRAP: + msr |= 0x00020000; + break; + default: + /* Should never occur */ + cpu_abort(cs, "Invalid program exception %d. Aborting\n", + env->error_code); + break; + } + break; + case POWERPC_EXCP_SYSCALL: /* System call exception */ + { + int lev = env->error_code; + + trace_ppc_syscall(env, lev); + + /* + * We need to correct the NIP which in this case is supposed + * to point to the next instruction + */ + env->nip += 4; + + /* + * The Virtual Open Firmware (VOF) relies on the 'sc 1' + * instruction to communicate with QEMU. The pegasos2 machine + * uses VOF and the 74xx CPUs, so although the 74xx don't have + * HV mode, we need to keep hypercall support. + */ + if ((lev == 1) && cpu->vhyp) { + PPCVirtualHypervisorClass *vhc = + PPC_VIRTUAL_HYPERVISOR_GET_CLASS(cpu->vhyp); + vhc->hypercall(cpu->vhyp, cpu); + return; + } + + break; + } + case POWERPC_EXCP_FPU: /* Floating-point unavailable exception */ + case POWERPC_EXCP_DECR: /* Decrementer exception */ + break; + case POWERPC_EXCP_RESET: /* System reset exception */ + if (msr_pow) { + cpu_abort(cs, "Trying to deliver power-saving system reset " + "exception %d with no HV support\n", excp); + } + break; + case POWERPC_EXCP_TRACE: /* Trace exception */ + break; + case POWERPC_EXCP_VPU: /* Vector unavailable exception */ + break; + case POWERPC_EXCP_IABR: /* Instruction address breakpoint */ + case POWERPC_EXCP_SMI: /* System management interrupt */ + case POWERPC_EXCP_THERM: /* Thermal interrupt */ + case POWERPC_EXCP_PERFM: /* Embedded performance monitor interrupt */ + case POWERPC_EXCP_VPUA: /* Vector assist exception */ + cpu_abort(cs, "%s exception not implemented\n", + powerpc_excp_name(excp)); + break; + default: + cpu_abort(cs, "Invalid PowerPC exception %d. Aborting\n", excp); + break; + } + + /* + * Sort out endianness of interrupt, this differs depending on the + * CPU, the HV mode, etc... + */ + if (ppc_interrupts_little_endian(cpu, !!(new_msr & MSR_HVB))) { + new_msr |= (target_ulong)1 << MSR_LE; + } + + /* Save PC */ + env->spr[SPR_SRR0] = env->nip; + + /* Save MSR */ + env->spr[SPR_SRR1] = msr; + + powerpc_set_excp_state(cpu, vector, new_msr); +} +#else +void powerpc_excp_74xx(PowerPCCPU *cpu, int excp) +{ + g_assert_not_reached(); +} +#endif + static inline void vscr_init(CPUPPCState *env, uint32_t val) { /* Altivec always uses round-to-nearest */ diff --git a/target/ppc/excp_helper.c b/target/ppc/excp_helper.c index 1306dcedcf..b2b8c991bf 100644 --- a/target/ppc/excp_helper.c +++ b/target/ppc/excp_helper.c @@ -376,179 +376,6 @@ void powerpc_set_excp_state(PowerPCCPU *cpu, target_ulong vector, env->reserve_addr = -1; } -static void powerpc_excp_74xx(PowerPCCPU *cpu, int excp) -{ - CPUState *cs = CPU(cpu); - CPUPPCState *env = &cpu->env; - target_ulong msr, new_msr, vector; - - /* new srr1 value excluding must-be-zero bits */ - msr = env->msr & ~0x783f0000ULL; - - /* - * new interrupt handler msr preserves existing ME unless - * explicitly overriden - */ - new_msr = env->msr & ((target_ulong)1 << MSR_ME); - - /* - * Hypervisor emulation assistance interrupt only exists on server - * arch 2.05 server or later. - */ - if (excp == POWERPC_EXCP_HV_EMU) { - excp = POWERPC_EXCP_PROGRAM; - } - - 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_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); - } - - /* machine check exceptions don't have ME set */ - new_msr &= ~((target_ulong)1 << MSR_ME); - - break; - case POWERPC_EXCP_DSI: /* Data storage exception */ - 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; - break; - case POWERPC_EXCP_EXTERNAL: /* External input */ - 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; - 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(); - powerpc_reset_excp_state(cpu); - return; - } - - /* - * FP exceptions always have NIP pointing to the faulting - * instruction, so always use store_next and claim we are - * precise in the MSR. - */ - msr |= 0x00100000; - break; - case POWERPC_EXCP_INVAL: - trace_ppc_excp_inval(env->nip); - msr |= 0x00080000; - break; - case POWERPC_EXCP_PRIV: - msr |= 0x00040000; - break; - case POWERPC_EXCP_TRAP: - msr |= 0x00020000; - break; - default: - /* Should never occur */ - cpu_abort(cs, "Invalid program exception %d. Aborting\n", - env->error_code); - break; - } - break; - case POWERPC_EXCP_SYSCALL: /* System call exception */ - { - int lev = env->error_code; - - trace_ppc_syscall(env, lev); - - /* - * We need to correct the NIP which in this case is supposed - * to point to the next instruction - */ - env->nip += 4; - - /* - * The Virtual Open Firmware (VOF) relies on the 'sc 1' - * instruction to communicate with QEMU. The pegasos2 machine - * uses VOF and the 74xx CPUs, so although the 74xx don't have - * HV mode, we need to keep hypercall support. - */ - if ((lev == 1) && cpu->vhyp) { - PPCVirtualHypervisorClass *vhc = - PPC_VIRTUAL_HYPERVISOR_GET_CLASS(cpu->vhyp); - vhc->hypercall(cpu->vhyp, cpu); - return; - } - - break; - } - case POWERPC_EXCP_FPU: /* Floating-point unavailable exception */ - case POWERPC_EXCP_DECR: /* Decrementer exception */ - break; - case POWERPC_EXCP_RESET: /* System reset exception */ - if (msr_pow) { - cpu_abort(cs, "Trying to deliver power-saving system reset " - "exception %d with no HV support\n", excp); - } - break; - case POWERPC_EXCP_TRACE: /* Trace exception */ - break; - case POWERPC_EXCP_VPU: /* Vector unavailable exception */ - break; - case POWERPC_EXCP_IABR: /* Instruction address breakpoint */ - case POWERPC_EXCP_SMI: /* System management interrupt */ - case POWERPC_EXCP_THERM: /* Thermal interrupt */ - case POWERPC_EXCP_PERFM: /* Embedded performance monitor interrupt */ - case POWERPC_EXCP_VPUA: /* Vector assist exception */ - cpu_abort(cs, "%s exception not implemented\n", - powerpc_excp_name(excp)); - break; - default: - cpu_abort(cs, "Invalid PowerPC exception %d. Aborting\n", excp); - break; - } - - /* - * Sort out endianness of interrupt, this differs depending on the - * CPU, the HV mode, etc... - */ - if (ppc_interrupts_little_endian(cpu, !!(new_msr & MSR_HVB))) { - new_msr |= (target_ulong)1 << MSR_LE; - } - - /* Save PC */ - env->spr[SPR_SRR0] = env->nip; - - /* Save MSR */ - env->spr[SPR_SRR1] = msr; - - powerpc_set_excp_state(cpu, vector, new_msr); -} - static void powerpc_excp_booke(PowerPCCPU *cpu, int excp) { CPUState *cs = CPU(cpu); From patchwork Tue Mar 1 13:56:18 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Fabiano Rosas X-Patchwork-Id: 12764759 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 9AC49C433F5 for ; Tue, 1 Mar 2022 14:13:14 +0000 (UTC) Received: from localhost ([::1]:53324 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1nP3FZ-0004li-PN for qemu-devel@archiver.kernel.org; Tue, 01 Mar 2022 09:13:13 -0500 Received: from eggs.gnu.org ([209.51.188.92]:33498) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1nP30B-0006R1-7c; Tue, 01 Mar 2022 08:57:20 -0500 Received: from mx0b-001b2d01.pphosted.com ([148.163.158.5]:29150 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 1nP306-00027L-Ql; Tue, 01 Mar 2022 08:57:18 -0500 Received: from pps.filterd (m0098420.ppops.net [127.0.0.1]) by mx0b-001b2d01.pphosted.com (8.16.1.2/8.16.1.2) with SMTP id 221DhEN1008109; Tue, 1 Mar 2022 13:57:00 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=FaE2u7lu+7IDk8y5MUXVWeOleamhhRj4hXNYIrAGviE=; b=sfzMeGBJDNXpIDBUkKzzmCOCoZLQM1zrCLO/Ks6GzGuGASVblnHbDY6HiiKhl3Uc308b tXAT3KVTW1g5yFY83nuJzzL2DOhf7T82XJo6nEhEdYJzpTf+pJqBgU54Xkzp0u2ZAs0L wN6EMO50OcB8rrNmjAiX+KT5s6Bc4fzurokrOYpr2JDw2fInjM+yNf1dD0BQqoXrMbAr cgagNGSIXp84HH1eNMg8crxPOCGd73hrsXIqehfOrU1TWBCTsIRAh6csacjEWxtielnz viM3wzQ5dU3yb2h7hiUO3oB3iF14MvUzfwhrWWpL+ocVl6hPzosj42Bkj5j5jWUEtXsk fw== Received: from pps.reinject (localhost [127.0.0.1]) by mx0b-001b2d01.pphosted.com with ESMTP id 3ehmmbg9mc-1 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NOT); Tue, 01 Mar 2022 13:56:59 +0000 Received: from m0098420.ppops.net (m0098420.ppops.net [127.0.0.1]) by pps.reinject (8.16.0.43/8.16.0.43) with SMTP id 221DlAwd025212; Tue, 1 Mar 2022 13:56:59 GMT Received: from ppma05wdc.us.ibm.com (1b.90.2fa9.ip4.static.sl-reverse.com [169.47.144.27]) by mx0b-001b2d01.pphosted.com with ESMTP id 3ehmmbg9m6-1 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NOT); Tue, 01 Mar 2022 13:56:59 +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 221Du5XH010415; Tue, 1 Mar 2022 13:56:58 GMT Received: from b03cxnp08025.gho.boulder.ibm.com (b03cxnp08025.gho.boulder.ibm.com [9.17.130.17]) by ppma05wdc.us.ibm.com with ESMTP id 3efbua50rv-1 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NOT); Tue, 01 Mar 2022 13:56:58 +0000 Received: from b03ledav005.gho.boulder.ibm.com (b03ledav005.gho.boulder.ibm.com [9.17.130.236]) by b03cxnp08025.gho.boulder.ibm.com (8.14.9/8.14.9/NCO v10.0) with ESMTP id 221DuvO422151432 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-GCM-SHA384 bits=256 verify=OK); Tue, 1 Mar 2022 13:56:57 GMT Received: from b03ledav005.gho.boulder.ibm.com (unknown [127.0.0.1]) by IMSVA (Postfix) with ESMTP id 69909BE059; Tue, 1 Mar 2022 13:56:57 +0000 (GMT) Received: from b03ledav005.gho.boulder.ibm.com (unknown [127.0.0.1]) by IMSVA (Postfix) with ESMTP id E9918BE054; Tue, 1 Mar 2022 13:56:55 +0000 (GMT) Received: from farosas.linux.ibm.com.com (unknown [9.211.51.129]) by b03ledav005.gho.boulder.ibm.com (Postfix) with ESMTP; Tue, 1 Mar 2022 13:56:55 +0000 (GMT) From: Fabiano Rosas To: qemu-devel@nongnu.org Subject: [PATCH 15/17] target/ppc: Move powerpc_excp_booke into cpu_booke.c Date: Tue, 1 Mar 2022 10:56:18 -0300 Message-Id: <20220301135620.2411952-16-farosas@linux.ibm.com> X-Mailer: git-send-email 2.34.1 In-Reply-To: <20220301135620.2411952-1-farosas@linux.ibm.com> References: <20220301135620.2411952-1-farosas@linux.ibm.com> MIME-Version: 1.0 X-TM-AS-GCONF: 00 X-Proofpoint-GUID: Fm1RK6-dILovJKjGrKvfZqau3kSVfDsk X-Proofpoint-ORIG-GUID: GHH5iYrEc2ge4h9XJfGNlCpnhGYoTLJA X-Proofpoint-Virus-Version: vendor=baseguard engine=ICAP:2.0.205,Aquarius:18.0.816,Hydra:6.0.425,FMLib:17.11.64.514 definitions=2022-03-01_07,2022-02-26_01,2022-02-23_01 X-Proofpoint-Spam-Details: rule=outbound_notspam policy=outbound score=0 clxscore=1015 mlxscore=0 malwarescore=0 suspectscore=0 priorityscore=1501 mlxlogscore=997 impostorscore=0 spamscore=0 bulkscore=0 adultscore=0 phishscore=0 lowpriorityscore=0 classifier=spam adjust=0 reason=mlx scancount=1 engine=8.12.0-2201110000 definitions=main-2203010074 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_H5=0.001, RCVD_IN_MSPIKE_WL=0.001, SPF_HELO_NONE=0.001, SPF_PASS=-0.001, T_SCC_BODY_TEXT_LINE=-0.01 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" Signed-off-by: Fabiano Rosas --- target/ppc/cpu.h | 1 + target/ppc/cpu_booke.c | 216 ++++++++++++++++++++++++++++++++++++++- target/ppc/excp_helper.c | 204 ------------------------------------ 3 files changed, 216 insertions(+), 205 deletions(-) diff --git a/target/ppc/cpu.h b/target/ppc/cpu.h index 614a92954c..03ca593095 100644 --- a/target/ppc/cpu.h +++ b/target/ppc/cpu.h @@ -184,6 +184,7 @@ void powerpc_excp_40x(PowerPCCPU *cpu, int excp); void powerpc_excp_6xx(PowerPCCPU *cpu, int excp); void powerpc_excp_7xx(PowerPCCPU *cpu, int excp); void powerpc_excp_74xx(PowerPCCPU *cpu, int excp); +void powerpc_excp_booke(PowerPCCPU *cpu, int excp); #define PPC_INPUT(env) ((env)->bus_model) diff --git a/target/ppc/cpu_booke.c b/target/ppc/cpu_booke.c index 18e16bd3bf..b73cfe224d 100644 --- a/target/ppc/cpu_booke.c +++ b/target/ppc/cpu_booke.c @@ -1,5 +1,5 @@ /* - * CPU initialization for PowerPC BookE CPUs + * CPU initialization and exception dispatching for PowerPC BookE CPUs * * Copyright IBM Corp. 2022 * @@ -8,9 +8,12 @@ */ #include "qemu/osdep.h" +#include "qemu/log.h" #include "hw/ppc/ppc.h" #include "cpu.h" #include "spr_common.h" +#include "trace.h" +#include "helper_regs.h" static int check_pow_hid0(CPUPPCState *env) { @@ -21,6 +24,217 @@ static int check_pow_hid0(CPUPPCState *env) return 0; } +#if !defined(CONFIG_USER_ONLY) +void powerpc_excp_booke(PowerPCCPU *cpu, int excp) +{ + CPUState *cs = CPU(cpu); + CPUPPCState *env = &cpu->env; + target_ulong msr, new_msr, vector; + int srr0, srr1; + + msr = env->msr; + + /* + * new interrupt handler msr preserves existing ME unless + * explicitly overriden + */ + new_msr = env->msr & ((target_ulong)1 << MSR_ME); + + /* target registers */ + srr0 = SPR_SRR0; + 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 (excp == POWERPC_EXCP_VPU) { + excp = POWERPC_EXCP_SPEU; + } +#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_CRITICAL: /* Critical input */ + srr0 = SPR_BOOKE_CSRR0; + srr1 = SPR_BOOKE_CSRR1; + 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); + } + + /* machine check exceptions don't have ME set */ + new_msr &= ~((target_ulong)1 << MSR_ME); + + /* FIXME: choose one or the other based on CPU type */ + srr0 = SPR_BOOKE_MCSRR0; + srr1 = SPR_BOOKE_MCSRR1; + + env->spr[SPR_BOOKE_CSRR0] = env->nip; + env->spr[SPR_BOOKE_CSRR1] = msr; + + break; + case POWERPC_EXCP_DSI: /* Data storage exception */ + trace_ppc_excp_dsi(env->spr[SPR_BOOKE_ESR], env->spr[SPR_BOOKE_DEAR]); + break; + case POWERPC_EXCP_ISI: /* Instruction storage exception */ + trace_ppc_excp_isi(msr, env->nip); + break; + case POWERPC_EXCP_EXTERNAL: /* External input */ + if (env->mpic_proxy) { + /* IACK the IRQ on delivery */ + env->spr[SPR_BOOKE_EPR] = ldl_phys(cs->as, env->mpic_iack); + } + break; + case POWERPC_EXCP_ALIGN: /* Alignment exception */ + 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(); + powerpc_reset_excp_state(cpu); + return; + } + + /* + * FP exceptions always have NIP pointing to the faulting + * instruction, so always use store_next and claim we are + * precise in the MSR. + */ + msr |= 0x00100000; + env->spr[SPR_BOOKE_ESR] = ESR_FP; + break; + case POWERPC_EXCP_INVAL: + trace_ppc_excp_inval(env->nip); + msr |= 0x00080000; + env->spr[SPR_BOOKE_ESR] = ESR_PIL; + break; + case POWERPC_EXCP_PRIV: + msr |= 0x00040000; + env->spr[SPR_BOOKE_ESR] = ESR_PPR; + break; + case POWERPC_EXCP_TRAP: + 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; + } + break; + case POWERPC_EXCP_SYSCALL: /* System call exception */ + trace_ppc_syscall(env, 0); + + /* + * We need to correct the NIP which in this case is supposed + * to point to the next instruction + */ + env->nip += 4; + 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"); + break; + case POWERPC_EXCP_WDT: /* Watchdog timer interrupt */ + trace_ppc_excp_print("WDT"); + srr0 = SPR_BOOKE_CSRR0; + srr1 = SPR_BOOKE_CSRR1; + 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 */ + srr0 = SPR_BOOKE_DSRR0; + srr1 = SPR_BOOKE_DSRR1; + + 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"); + } + break; + case POWERPC_EXCP_SPEU: /* SPE/embedded floating-point unavailable/VPU */ + env->spr[SPR_BOOKE_ESR] = ESR_SPV; + break; + case POWERPC_EXCP_RESET: /* System reset exception */ + if (msr_pow) { + cpu_abort(cs, "Trying to deliver power-saving system reset " + "exception %d with no HV support\n", excp); + } + break; + case POWERPC_EXCP_EFPDI: /* Embedded floating-point data interrupt */ + case POWERPC_EXCP_EFPRI: /* Embedded floating-point round interrupt */ + cpu_abort(cs, "%s exception not implemented\n", + powerpc_excp_name(excp)); + break; + default: + cpu_abort(cs, "Invalid PowerPC exception %d. Aborting\n", excp); + break; + } + +#if defined(TARGET_PPC64) + 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; + } else { + vector = (uint32_t)vector; + } +#endif + + /* Save PC */ + env->spr[srr0] = env->nip; + + /* Save MSR */ + env->spr[srr1] = msr; + + powerpc_set_excp_state(cpu, vector, new_msr); +} +#else +void powerpc_excp_booke(PowerPCCPU *cpu, int excp) +{ + g_assert_not_reached(); +} +#endif + static void register_BookE_sprs(CPUPPCState *env, uint64_t ivor_mask) { const char *ivor_names[64] = { diff --git a/target/ppc/excp_helper.c b/target/ppc/excp_helper.c index b2b8c991bf..a6a721d21c 100644 --- a/target/ppc/excp_helper.c +++ b/target/ppc/excp_helper.c @@ -376,210 +376,6 @@ void powerpc_set_excp_state(PowerPCCPU *cpu, target_ulong vector, env->reserve_addr = -1; } -static void powerpc_excp_booke(PowerPCCPU *cpu, int excp) -{ - CPUState *cs = CPU(cpu); - CPUPPCState *env = &cpu->env; - target_ulong msr, new_msr, vector; - int srr0, srr1; - - msr = env->msr; - - /* - * new interrupt handler msr preserves existing ME unless - * explicitly overriden - */ - new_msr = env->msr & ((target_ulong)1 << MSR_ME); - - /* target registers */ - srr0 = SPR_SRR0; - 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 (excp == POWERPC_EXCP_VPU) { - excp = POWERPC_EXCP_SPEU; - } -#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_CRITICAL: /* Critical input */ - srr0 = SPR_BOOKE_CSRR0; - srr1 = SPR_BOOKE_CSRR1; - 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); - } - - /* machine check exceptions don't have ME set */ - new_msr &= ~((target_ulong)1 << MSR_ME); - - /* FIXME: choose one or the other based on CPU type */ - srr0 = SPR_BOOKE_MCSRR0; - srr1 = SPR_BOOKE_MCSRR1; - - env->spr[SPR_BOOKE_CSRR0] = env->nip; - env->spr[SPR_BOOKE_CSRR1] = msr; - - break; - case POWERPC_EXCP_DSI: /* Data storage exception */ - trace_ppc_excp_dsi(env->spr[SPR_BOOKE_ESR], env->spr[SPR_BOOKE_DEAR]); - break; - case POWERPC_EXCP_ISI: /* Instruction storage exception */ - trace_ppc_excp_isi(msr, env->nip); - break; - case POWERPC_EXCP_EXTERNAL: /* External input */ - if (env->mpic_proxy) { - /* IACK the IRQ on delivery */ - env->spr[SPR_BOOKE_EPR] = ldl_phys(cs->as, env->mpic_iack); - } - break; - case POWERPC_EXCP_ALIGN: /* Alignment exception */ - 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(); - powerpc_reset_excp_state(cpu); - return; - } - - /* - * FP exceptions always have NIP pointing to the faulting - * instruction, so always use store_next and claim we are - * precise in the MSR. - */ - msr |= 0x00100000; - env->spr[SPR_BOOKE_ESR] = ESR_FP; - break; - case POWERPC_EXCP_INVAL: - trace_ppc_excp_inval(env->nip); - msr |= 0x00080000; - env->spr[SPR_BOOKE_ESR] = ESR_PIL; - break; - case POWERPC_EXCP_PRIV: - msr |= 0x00040000; - env->spr[SPR_BOOKE_ESR] = ESR_PPR; - break; - case POWERPC_EXCP_TRAP: - 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; - } - break; - case POWERPC_EXCP_SYSCALL: /* System call exception */ - trace_ppc_syscall(env, 0); - - /* - * We need to correct the NIP which in this case is supposed - * to point to the next instruction - */ - env->nip += 4; - 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"); - break; - case POWERPC_EXCP_WDT: /* Watchdog timer interrupt */ - trace_ppc_excp_print("WDT"); - srr0 = SPR_BOOKE_CSRR0; - srr1 = SPR_BOOKE_CSRR1; - 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 */ - srr0 = SPR_BOOKE_DSRR0; - srr1 = SPR_BOOKE_DSRR1; - - 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"); - } - break; - case POWERPC_EXCP_SPEU: /* SPE/embedded floating-point unavailable/VPU */ - env->spr[SPR_BOOKE_ESR] = ESR_SPV; - break; - case POWERPC_EXCP_RESET: /* System reset exception */ - if (msr_pow) { - cpu_abort(cs, "Trying to deliver power-saving system reset " - "exception %d with no HV support\n", excp); - } - break; - case POWERPC_EXCP_EFPDI: /* Embedded floating-point data interrupt */ - case POWERPC_EXCP_EFPRI: /* Embedded floating-point round interrupt */ - cpu_abort(cs, "%s exception not implemented\n", - powerpc_excp_name(excp)); - break; - default: - cpu_abort(cs, "Invalid PowerPC exception %d. Aborting\n", excp); - break; - } - -#if defined(TARGET_PPC64) - 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; - } else { - vector = (uint32_t)vector; - } -#endif - - /* Save PC */ - env->spr[srr0] = env->nip; - - /* Save MSR */ - env->spr[srr1] = msr; - - powerpc_set_excp_state(cpu, vector, new_msr); -} - /* * When running a nested HV guest under vhyp, external interrupts are * delivered as HVIRT. From patchwork Tue Mar 1 13:56:19 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Fabiano Rosas X-Patchwork-Id: 12764774 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 0A5D5C433EF for ; Tue, 1 Mar 2022 14:21:56 +0000 (UTC) Received: from localhost ([::1]:42798 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1nP3Ny-0000I8-Qh for qemu-devel@archiver.kernel.org; Tue, 01 Mar 2022 09:21:54 -0500 Received: from eggs.gnu.org ([209.51.188.92]:35122) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1nP352-0006Lr-UF; Tue, 01 Mar 2022 09:02:21 -0500 Received: from mx0b-001b2d01.pphosted.com ([148.163.158.5]:56968 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 1nP34v-0003Nw-9S; Tue, 01 Mar 2022 09:02:20 -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 221DDXj1013717; Tue, 1 Mar 2022 13:57:01 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=R4Mkt5Ckuf/Le2nfFwzHs7Ar5I1iszuun5XjvFXoiDE=; b=IY0EswkhFHbMdHdho7pvcAoqaJ7WNBDN06OB61MEClnJXPoQEUn7gOts2XHp5l9hjF4Q aMF+0Ey/zrUDc6ZUAhNmYnfhUgJvAvvrayzXgDOjSwE+ZFm+MUnJNcTFBr/8lEX9EEjd eWDjYBW7wshzyNMfsxLr+fnzO187wmgvmEvjftFdOVKyngIMgSErM5wf7YTReEILuA6Y PgbriLnDkW+ZijcqlcJcIiatAcko1tqpPXheqXZ/KAu7FR3aqCCfkFSVUK9sRRlTZR3F Gu3SD3NPnMpXfLdx7Ii3rU+SSSqhZLI46SBXANNY9h+TSKldGfN+mHoMEMUqJq/tsSH3 Qg== Received: from pps.reinject (localhost [127.0.0.1]) by mx0b-001b2d01.pphosted.com with ESMTP id 3ehm6e0y0q-1 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NOT); Tue, 01 Mar 2022 13:57:01 +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 221DEDfM015330; Tue, 1 Mar 2022 13:57:00 GMT Received: from ppma03wdc.us.ibm.com (ba.79.3fa9.ip4.static.sl-reverse.com [169.63.121.186]) by mx0b-001b2d01.pphosted.com with ESMTP id 3ehm6e0y0d-1 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NOT); Tue, 01 Mar 2022 13:57:00 +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 221DtU0b030890; Tue, 1 Mar 2022 13:57:00 GMT Received: from b03cxnp07028.gho.boulder.ibm.com (b03cxnp07028.gho.boulder.ibm.com [9.17.130.15]) by ppma03wdc.us.ibm.com with ESMTP id 3efbu9w14p-1 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NOT); Tue, 01 Mar 2022 13:57:00 +0000 Received: from b03ledav005.gho.boulder.ibm.com (b03ledav005.gho.boulder.ibm.com [9.17.130.236]) by b03cxnp07028.gho.boulder.ibm.com (8.14.9/8.14.9/NCO v10.0) with ESMTP id 221DuxJ825821628 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-GCM-SHA384 bits=256 verify=OK); Tue, 1 Mar 2022 13:56:59 GMT Received: from b03ledav005.gho.boulder.ibm.com (unknown [127.0.0.1]) by IMSVA (Postfix) with ESMTP id 40C87BE054; Tue, 1 Mar 2022 13:56:59 +0000 (GMT) Received: from b03ledav005.gho.boulder.ibm.com (unknown [127.0.0.1]) by IMSVA (Postfix) with ESMTP id CCD3CBE053; Tue, 1 Mar 2022 13:56:57 +0000 (GMT) Received: from farosas.linux.ibm.com.com (unknown [9.211.51.129]) by b03ledav005.gho.boulder.ibm.com (Postfix) with ESMTP; Tue, 1 Mar 2022 13:56:57 +0000 (GMT) From: Fabiano Rosas To: qemu-devel@nongnu.org Subject: [PATCH 16/17] target/ppc: Move powerpc_excp_books into cpu_books.c Date: Tue, 1 Mar 2022 10:56:19 -0300 Message-Id: <20220301135620.2411952-17-farosas@linux.ibm.com> X-Mailer: git-send-email 2.34.1 In-Reply-To: <20220301135620.2411952-1-farosas@linux.ibm.com> References: <20220301135620.2411952-1-farosas@linux.ibm.com> MIME-Version: 1.0 X-TM-AS-GCONF: 00 X-Proofpoint-GUID: LLWTuzrYlwsBcb3uac7RWsAojVnWfTED X-Proofpoint-ORIG-GUID: HdE0HktzuhmaPA-unjTN8ocLTf1CuJCm X-Proofpoint-Virus-Version: vendor=baseguard engine=ICAP:2.0.205,Aquarius:18.0.816,Hydra:6.0.425,FMLib:17.11.64.514 definitions=2022-03-01_07,2022-02-26_01,2022-02-23_01 X-Proofpoint-Spam-Details: rule=outbound_notspam policy=outbound score=0 malwarescore=0 spamscore=0 mlxscore=0 lowpriorityscore=0 bulkscore=0 suspectscore=0 adultscore=0 mlxlogscore=999 impostorscore=0 phishscore=0 clxscore=1015 priorityscore=1501 classifier=spam adjust=0 reason=mlx scancount=1 engine=8.12.0-2201110000 definitions=main-2203010074 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_H5=0.001, RCVD_IN_MSPIKE_WL=0.001, SPF_HELO_NONE=0.001, SPF_PASS=-0.001, T_SCC_BODY_TEXT_LINE=-0.01 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" Take powerpc_reset_wakeup and ppc_excp_apply_ail along because these are specific to BookS as well. Signed-off-by: Fabiano Rosas --- target/ppc/cpu.h | 1 + target/ppc/cpu_books.c | 525 +++++++++++++++++++++++++++++++++++++- target/ppc/excp_helper.c | 531 +-------------------------------------- 3 files changed, 527 insertions(+), 530 deletions(-) diff --git a/target/ppc/cpu.h b/target/ppc/cpu.h index 03ca593095..30d06d2ef2 100644 --- a/target/ppc/cpu.h +++ b/target/ppc/cpu.h @@ -185,6 +185,7 @@ void powerpc_excp_6xx(PowerPCCPU *cpu, int excp); void powerpc_excp_7xx(PowerPCCPU *cpu, int excp); void powerpc_excp_74xx(PowerPCCPU *cpu, int excp); void powerpc_excp_booke(PowerPCCPU *cpu, int excp); +void powerpc_excp_books(PowerPCCPU *cpu, int excp); #define PPC_INPUT(env) ((env)->bus_model) diff --git a/target/ppc/cpu_books.c b/target/ppc/cpu_books.c index 01943140a3..e776ededda 100644 --- a/target/ppc/cpu_books.c +++ b/target/ppc/cpu_books.c @@ -1,5 +1,5 @@ /* - * CPU initialization for PowerPC BookS CPUs + * CPU initialization and exception dispatching for PowerPC BookS CPUs * * Copyright IBM Corp. 2022 * @@ -8,6 +8,7 @@ */ #include "qemu/osdep.h" +#include "qemu/log.h" #include "sysemu/hw_accel.h" #include "sysemu/tcg.h" #include "hw/ppc/ppc.h" @@ -17,6 +18,8 @@ #include "power8-pmu.h" #include "cpu-models.h" #include "mmu-hash64.h" +#include "trace.h" +#include "helper_regs.h" #if defined(CONFIG_USER_ONLY) #define POWERPC970_HID5_INIT 0x00000080 @@ -24,6 +27,526 @@ #define POWERPC970_HID5_INIT 0x00000000 +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 void ppc_excp_apply_ail(PowerPCCPU *cpu, int excp, target_ulong msr, + target_ulong *new_msr, target_ulong *vector) +{ + PowerPCCPUClass *pcc = POWERPC_CPU_GET_CLASS(cpu); + 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 (!(pcc->lpcr_mask & LPCR_AIL)) { + /* This CPU does not have AIL */ + return; + } + + /* P8 & P9 */ + if (!(pcc->lpcr_mask & LPCR_HAIL)) { + 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; + } + + /* P10 and up */ + } else { + 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; + } + } + + /* + * 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) { + *vector |= 0x0000000000018000ull; + } else if (ail == 3) { + *vector |= 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) { + *vector &= ~0x0000000000017000ull; /* Un-apply the base offset */ + *vector |= 0xc000000000003000ull; /* Apply scv's AIL=3 offset */ + } + } +} + +/* + * When running under vhyp, hcalls are always intercepted and sent to the + * vhc->hypercall handler. + */ +static bool books_vhyp_handles_hcall(PowerPCCPU *cpu) +{ + if (cpu->vhyp) { + return !vhyp_cpu_in_nested(cpu); + } + return false; +} + +/* + * When running a nested KVM HV guest under vhyp, HV exceptions are not + * delivered to the guest (because there is no concept of HV support), but + * rather they are sent tothe vhyp to exit from the L2 back to the L1 and + * return from the H_ENTER_NESTED hypercall. + */ +static bool books_vhyp_handles_hv_excp(PowerPCCPU *cpu) +{ + if (cpu->vhyp) { + return vhyp_cpu_in_nested(cpu); + } + return false; +} + +void powerpc_excp_books(PowerPCCPU *cpu, int excp) +{ + CPUState *cs = CPU(cpu); + CPUPPCState *env = &cpu->env; + target_ulong msr, new_msr, vector; + int srr0, srr1, lev = -1; + + /* new srr1 value excluding must-be-zero bits */ + msr = env->msr & ~0x783f0000ULL; + + /* + * new interrupt handler msr preserves existing HV and ME unless + * explicitly overriden + */ + new_msr = env->msr & (((target_ulong)1 << MSR_ME) | MSR_HVB); + + /* target registers */ + srr0 = SPR_SRR0; + 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); + } + + /* + * We don't want to generate a 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; + } + + 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_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). + */ + new_msr |= (target_ulong)MSR_HVB; + } + + /* machine check exceptions don't have ME set */ + new_msr &= ~((target_ulong)1 << MSR_ME); + + break; + case POWERPC_EXCP_DSI: /* Data storage exception */ + 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; + break; + case POWERPC_EXCP_EXTERNAL: /* External input */ + { + bool lpes0; + + /* + * LPES0 is only taken into consideration if we support HV + * mode for this CPU. + */ + if (!env->has_hv_mode) { + break; + } + + lpes0 = !!(env->spr[SPR_LPCR] & LPCR_LPES0); + + if (!lpes0) { + new_msr |= (target_ulong)MSR_HVB; + new_msr |= env->msr & ((target_ulong)1 << MSR_RI); + srr0 = SPR_HSRR0; + srr1 = SPR_HSRR1; + } + + 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; + 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(); + powerpc_reset_excp_state(cpu); + return; + } + + /* + * FP exceptions always have NIP pointing to the faulting + * instruction, so always use store_next and claim we are + * precise in the MSR. + */ + msr |= 0x00100000; + break; + case POWERPC_EXCP_INVAL: + trace_ppc_excp_inval(env->nip); + msr |= 0x00080000; + break; + case POWERPC_EXCP_PRIV: + msr |= 0x00040000; + break; + case POWERPC_EXCP_TRAP: + msr |= 0x00020000; + break; + default: + /* Should never occur */ + cpu_abort(cs, "Invalid program exception %d. Aborting\n", + env->error_code); + break; + } + break; + case POWERPC_EXCP_SYSCALL: /* System call exception */ + lev = env->error_code; + + trace_ppc_syscall(env, lev); + + /* + * We need to correct the NIP which in this case is supposed + * to point to the next instruction + */ + env->nip += 4; + + /* "PAPR mode" built-in hypercall emulation */ + if ((lev == 1) && books_vhyp_handles_hcall(cpu)) { + PPCVirtualHypervisorClass *vhc = + PPC_VIRTUAL_HYPERVISOR_GET_CLASS(cpu->vhyp); + vhc->hypercall(cpu->vhyp, cpu); + return; + } + if (lev == 1) { + new_msr |= (target_ulong)MSR_HVB; + } + break; + case POWERPC_EXCP_SYSCALL_VECTORED: /* scv exception */ + lev = env->error_code; + trace_ppc_syscall(env, 0); + 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_DECR: /* Decrementer exception */ + 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); + } + 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; + } else { + if (msr_pow) { + cpu_abort(cs, "Trying to deliver power-saving system reset " + "exception %d with no HV support\n", excp); + } + } + 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 */ + msr |= env->error_code; + /* fall through */ + case POWERPC_EXCP_HDECR: /* Hypervisor decrementer exception */ + case POWERPC_EXCP_HDSI: /* Hypervisor data storage exception */ + 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); + break; + case POWERPC_EXCP_VPU: /* Vector unavailable exception */ + case POWERPC_EXCP_VSXU: /* VSX unavailable exception */ + case POWERPC_EXCP_FU: /* Facility unavailable exception */ + env->spr[SPR_FSCR] |= ((target_ulong)env->error_code << 56); + break; + case POWERPC_EXCP_HV_FU: /* Hypervisor Facility Unavailable Exception */ + 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); + break; + case POWERPC_EXCP_PERFM_EBB: /* Performance Monitor EBB Exception */ + case POWERPC_EXCP_EXTERNAL_EBB: /* External EBB Exception */ + env->spr[SPR_BESCR] &= ~BESCR_GE; + + /* + * Save NIP for rfebb insn in SPR_EBBRR. Next nip is + * stored in the EBB Handler SPR_EBBHR. + */ + env->spr[SPR_EBBRR] = env->nip; + powerpc_set_excp_state(cpu, env->spr[SPR_EBBHR], env->msr); + + /* + * This exception is handled in userspace. No need to proceed. + */ + return; + case POWERPC_EXCP_THERM: /* Thermal interrupt */ + case POWERPC_EXCP_PERFM: /* Embedded performance monitor interrupt */ + case POWERPC_EXCP_VPUA: /* Vector assist exception */ + case POWERPC_EXCP_MAINT: /* Maintenance exception */ + case POWERPC_EXCP_SDOOR: /* Doorbell interrupt */ + case POWERPC_EXCP_HV_MAINT: /* Hypervisor Maintenance exception */ + cpu_abort(cs, "%s exception not implemented\n", + powerpc_excp_name(excp)); + break; + default: + cpu_abort(cs, "Invalid PowerPC exception %d. Aborting\n", excp); + break; + } + + /* + * Sort out endianness of interrupt, this differs depending on the + * CPU, the HV mode, etc... + */ + if (ppc_interrupts_little_endian(cpu, !!(new_msr & MSR_HVB))) { + new_msr |= (target_ulong)1 << MSR_LE; + } + + new_msr |= (target_ulong)1 << MSR_SF; + + if (excp != POWERPC_EXCP_SYSCALL_VECTORED) { + /* Save PC */ + env->spr[srr0] = env->nip; + + /* Save MSR */ + env->spr[srr1] = msr; + } + + if ((new_msr & MSR_HVB) && books_vhyp_handles_hv_excp(cpu)) { + PPCVirtualHypervisorClass *vhc = + PPC_VIRTUAL_HYPERVISOR_GET_CLASS(cpu->vhyp); + /* Deliver interrupt to L1 by returning from the H_ENTER_NESTED call */ + vhc->deliver_hv_excp(cpu, excp); + + powerpc_reset_excp_state(cpu); + + } else { + /* Sanity check */ + if (!(env->msr_mask & MSR_HVB) && srr0 == SPR_HSRR0) { + cpu_abort(cs, "Trying to deliver HV exception (HSRR) %d with " + "no HV support\n", excp); + } + + /* This can update new_msr and vector if AIL applies */ + ppc_excp_apply_ail(cpu, excp, msr, &new_msr, &vector); + + powerpc_set_excp_state(cpu, vector, new_msr); + } +} + static inline void vscr_init(CPUPPCState *env, uint32_t val) { /* Altivec always uses round-to-nearest */ diff --git a/target/ppc/excp_helper.c b/target/ppc/excp_helper.c index a6a721d21c..257379871f 100644 --- a/target/ppc/excp_helper.c +++ b/target/ppc/excp_helper.c @@ -138,203 +138,6 @@ void ppc_excp_debug_sw_tlb(CPUPPCState *env, int excp) env->error_code); } -#if defined(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 void ppc_excp_apply_ail(PowerPCCPU *cpu, int excp, target_ulong msr, - target_ulong *new_msr, target_ulong *vector) -{ - PowerPCCPUClass *pcc = POWERPC_CPU_GET_CLASS(cpu); - 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 (!(pcc->lpcr_mask & LPCR_AIL)) { - /* This CPU does not have AIL */ - return; - } - - /* P8 & P9 */ - if (!(pcc->lpcr_mask & LPCR_HAIL)) { - 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; - } - - /* P10 and up */ - } else { - 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; - } - } - - /* - * 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) { - *vector |= 0x0000000000018000ull; - } else if (ail == 3) { - *vector |= 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) { - *vector &= ~0x0000000000017000ull; /* Un-apply the base offset */ - *vector |= 0xc000000000003000ull; /* Apply scv's AIL=3 offset */ - } - } -} -#endif - void powerpc_reset_excp_state(PowerPCCPU *cpu) { CPUState *cs = CPU(cpu); @@ -388,338 +191,6 @@ static bool books_vhyp_promotes_external_to_hvirt(PowerPCCPU *cpu) return false; } -#ifdef TARGET_PPC64 -/* - * When running under vhyp, hcalls are always intercepted and sent to the - * vhc->hypercall handler. - */ -static bool books_vhyp_handles_hcall(PowerPCCPU *cpu) -{ - if (cpu->vhyp) { - return !vhyp_cpu_in_nested(cpu); - } - return false; -} - -/* - * When running a nested KVM HV guest under vhyp, HV exceptions are not - * delivered to the guest (because there is no concept of HV support), but - * rather they are sent tothe vhyp to exit from the L2 back to the L1 and - * return from the H_ENTER_NESTED hypercall. - */ -static bool books_vhyp_handles_hv_excp(PowerPCCPU *cpu) -{ - if (cpu->vhyp) { - return vhyp_cpu_in_nested(cpu); - } - return false; -} - -static void powerpc_excp_books(PowerPCCPU *cpu, int excp) -{ - CPUState *cs = CPU(cpu); - CPUPPCState *env = &cpu->env; - target_ulong msr, new_msr, vector; - int srr0, srr1, lev = -1; - - /* new srr1 value excluding must-be-zero bits */ - msr = env->msr & ~0x783f0000ULL; - - /* - * new interrupt handler msr preserves existing HV and ME unless - * explicitly overriden - */ - new_msr = env->msr & (((target_ulong)1 << MSR_ME) | MSR_HVB); - - /* target registers */ - srr0 = SPR_SRR0; - 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); - } - - /* - * We don't want to generate a 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; - } - - 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_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). - */ - new_msr |= (target_ulong)MSR_HVB; - } - - /* machine check exceptions don't have ME set */ - new_msr &= ~((target_ulong)1 << MSR_ME); - - break; - case POWERPC_EXCP_DSI: /* Data storage exception */ - 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; - break; - case POWERPC_EXCP_EXTERNAL: /* External input */ - { - bool lpes0; - - /* - * LPES0 is only taken into consideration if we support HV - * mode for this CPU. - */ - if (!env->has_hv_mode) { - break; - } - - lpes0 = !!(env->spr[SPR_LPCR] & LPCR_LPES0); - - if (!lpes0) { - new_msr |= (target_ulong)MSR_HVB; - new_msr |= env->msr & ((target_ulong)1 << MSR_RI); - srr0 = SPR_HSRR0; - srr1 = SPR_HSRR1; - } - - 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; - 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(); - powerpc_reset_excp_state(cpu); - return; - } - - /* - * FP exceptions always have NIP pointing to the faulting - * instruction, so always use store_next and claim we are - * precise in the MSR. - */ - msr |= 0x00100000; - break; - case POWERPC_EXCP_INVAL: - trace_ppc_excp_inval(env->nip); - msr |= 0x00080000; - break; - case POWERPC_EXCP_PRIV: - msr |= 0x00040000; - break; - case POWERPC_EXCP_TRAP: - msr |= 0x00020000; - break; - default: - /* Should never occur */ - cpu_abort(cs, "Invalid program exception %d. Aborting\n", - env->error_code); - break; - } - break; - case POWERPC_EXCP_SYSCALL: /* System call exception */ - lev = env->error_code; - - trace_ppc_syscall(env, lev); - - /* - * We need to correct the NIP which in this case is supposed - * to point to the next instruction - */ - env->nip += 4; - - /* "PAPR mode" built-in hypercall emulation */ - if ((lev == 1) && books_vhyp_handles_hcall(cpu)) { - PPCVirtualHypervisorClass *vhc = - PPC_VIRTUAL_HYPERVISOR_GET_CLASS(cpu->vhyp); - vhc->hypercall(cpu->vhyp, cpu); - return; - } - if (lev == 1) { - new_msr |= (target_ulong)MSR_HVB; - } - break; - case POWERPC_EXCP_SYSCALL_VECTORED: /* scv exception */ - lev = env->error_code; - trace_ppc_syscall(env, 0); - 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_DECR: /* Decrementer exception */ - 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); - } - 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; - } else { - if (msr_pow) { - cpu_abort(cs, "Trying to deliver power-saving system reset " - "exception %d with no HV support\n", excp); - } - } - 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 */ - msr |= env->error_code; - /* fall through */ - case POWERPC_EXCP_HDECR: /* Hypervisor decrementer exception */ - case POWERPC_EXCP_HDSI: /* Hypervisor data storage exception */ - 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); - break; - case POWERPC_EXCP_VPU: /* Vector unavailable exception */ - case POWERPC_EXCP_VSXU: /* VSX unavailable exception */ - case POWERPC_EXCP_FU: /* Facility unavailable exception */ - env->spr[SPR_FSCR] |= ((target_ulong)env->error_code << 56); - break; - case POWERPC_EXCP_HV_FU: /* Hypervisor Facility Unavailable Exception */ - 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); - break; - case POWERPC_EXCP_PERFM_EBB: /* Performance Monitor EBB Exception */ - case POWERPC_EXCP_EXTERNAL_EBB: /* External EBB Exception */ - env->spr[SPR_BESCR] &= ~BESCR_GE; - - /* - * Save NIP for rfebb insn in SPR_EBBRR. Next nip is - * stored in the EBB Handler SPR_EBBHR. - */ - env->spr[SPR_EBBRR] = env->nip; - powerpc_set_excp_state(cpu, env->spr[SPR_EBBHR], env->msr); - - /* - * This exception is handled in userspace. No need to proceed. - */ - return; - case POWERPC_EXCP_THERM: /* Thermal interrupt */ - case POWERPC_EXCP_PERFM: /* Embedded performance monitor interrupt */ - case POWERPC_EXCP_VPUA: /* Vector assist exception */ - case POWERPC_EXCP_MAINT: /* Maintenance exception */ - case POWERPC_EXCP_SDOOR: /* Doorbell interrupt */ - case POWERPC_EXCP_HV_MAINT: /* Hypervisor Maintenance exception */ - cpu_abort(cs, "%s exception not implemented\n", - powerpc_excp_name(excp)); - break; - default: - cpu_abort(cs, "Invalid PowerPC exception %d. Aborting\n", excp); - break; - } - - /* - * Sort out endianness of interrupt, this differs depending on the - * CPU, the HV mode, etc... - */ - if (ppc_interrupts_little_endian(cpu, !!(new_msr & MSR_HVB))) { - new_msr |= (target_ulong)1 << MSR_LE; - } - - new_msr |= (target_ulong)1 << MSR_SF; - - if (excp != POWERPC_EXCP_SYSCALL_VECTORED) { - /* Save PC */ - env->spr[srr0] = env->nip; - - /* Save MSR */ - env->spr[srr1] = msr; - } - - if ((new_msr & MSR_HVB) && books_vhyp_handles_hv_excp(cpu)) { - PPCVirtualHypervisorClass *vhc = - PPC_VIRTUAL_HYPERVISOR_GET_CLASS(cpu->vhyp); - /* Deliver interrupt to L1 by returning from the H_ENTER_NESTED call */ - vhc->deliver_hv_excp(cpu, excp); - - powerpc_reset_excp_state(cpu); - - } else { - /* Sanity check */ - if (!(env->msr_mask & MSR_HVB) && srr0 == SPR_HSRR0) { - cpu_abort(cs, "Trying to deliver HV exception (HSRR) %d with " - "no HV support\n", excp); - } - - /* This can update new_msr and vector if AIL applies */ - ppc_excp_apply_ail(cpu, excp, msr, &new_msr, &vector); - - powerpc_set_excp_state(cpu, vector, new_msr); - } -} -#else -static inline void powerpc_excp_books(PowerPCCPU *cpu, int excp) -{ - g_assert_not_reached(); -} -#endif - static void powerpc_excp(PowerPCCPU *cpu, int excp) { CPUState *cs = CPU(cpu); @@ -751,6 +222,7 @@ static void powerpc_excp(PowerPCCPU *cpu, int excp) case POWERPC_EXCP_BOOKE: powerpc_excp_booke(cpu, excp); break; +#if defined(TARGET_PPC64) case POWERPC_EXCP_970: case POWERPC_EXCP_POWER7: case POWERPC_EXCP_POWER8: @@ -758,6 +230,7 @@ static void powerpc_excp(PowerPCCPU *cpu, int excp) case POWERPC_EXCP_POWER10: powerpc_excp_books(cpu, excp); break; +#endif default: g_assert_not_reached(); } From patchwork Tue Mar 1 13:56:20 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Fabiano Rosas X-Patchwork-Id: 12764757 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 CF4E9C433F5 for ; Tue, 1 Mar 2022 14:09:40 +0000 (UTC) Received: from localhost ([::1]:45128 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1nP3C7-0007RE-Un for qemu-devel@archiver.kernel.org; Tue, 01 Mar 2022 09:09:39 -0500 Received: from eggs.gnu.org ([209.51.188.92]:33496) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1nP30B-0006R0-7M; Tue, 01 Mar 2022 08:57:20 -0500 Received: from mx0b-001b2d01.pphosted.com ([148.163.158.5]:39076 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 1nP307-00027r-W1; Tue, 01 Mar 2022 08:57:18 -0500 Received: from pps.filterd (m0098413.ppops.net [127.0.0.1]) by mx0b-001b2d01.pphosted.com (8.16.1.2/8.16.1.2) with SMTP id 221DgPP7003018; Tue, 1 Mar 2022 13:57:03 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=KaprR9n1LG75YBCialneF91syiLGt3SpQXEd2GbKgLg=; b=bRNt/h8lnwqbHgvavNDfLjF15jxZlof4grYSOzNx5up5cYdku/DTyTvTgtBXABFlXSyd MmI8LD6ao1/xP+k8lI8gfuC0OgfNAt8l6PcFshqBnLatOWLMMH/oLv8GiUsWnPBT1ynn Vtr6dboaJJEnoqyP0I7XdDC8QNipC7MXg98aZE+P0C+HuiLXK9n21Xioo1LUI1ZIokXA t1tTTRpSTwtDFy01TmsRxRqxybpPd5f/CXVpeS52HAL6nfgP7JaC1hAOQaOfx3RXZIzV SgGN7iCVBKEaQ2uetBnlEA1QD88Oq++biK1pHMXBNQzSjEB/jTAsGNunYPb/RRexBMOH ZQ== Received: from pps.reinject (localhost [127.0.0.1]) by mx0b-001b2d01.pphosted.com with ESMTP id 3ehmku0a21-1 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NOT); Tue, 01 Mar 2022 13:57:03 +0000 Received: from m0098413.ppops.net (m0098413.ppops.net [127.0.0.1]) by pps.reinject (8.16.0.43/8.16.0.43) with SMTP id 221DgccN003536; Tue, 1 Mar 2022 13:57:03 GMT Received: from ppma04wdc.us.ibm.com (1a.90.2fa9.ip4.static.sl-reverse.com [169.47.144.26]) by mx0b-001b2d01.pphosted.com with ESMTP id 3ehmku0a1t-1 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NOT); Tue, 01 Mar 2022 13:57:03 +0000 Received: from pps.filterd (ppma04wdc.us.ibm.com [127.0.0.1]) by ppma04wdc.us.ibm.com (8.16.1.2/8.16.1.2) with SMTP id 221DtsHf002621; Tue, 1 Mar 2022 13:57:02 GMT Received: from b03cxnp08028.gho.boulder.ibm.com (b03cxnp08028.gho.boulder.ibm.com [9.17.130.20]) by ppma04wdc.us.ibm.com with ESMTP id 3eftrreust-1 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NOT); Tue, 01 Mar 2022 13:57:02 +0000 Received: from b03ledav005.gho.boulder.ibm.com (b03ledav005.gho.boulder.ibm.com [9.17.130.236]) by b03cxnp08028.gho.boulder.ibm.com (8.14.9/8.14.9/NCO v10.0) with ESMTP id 221Dv1Um33095948 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-GCM-SHA384 bits=256 verify=OK); Tue, 1 Mar 2022 13:57:01 GMT Received: from b03ledav005.gho.boulder.ibm.com (unknown [127.0.0.1]) by IMSVA (Postfix) with ESMTP id 2CBAEBE053; Tue, 1 Mar 2022 13:57:01 +0000 (GMT) Received: from b03ledav005.gho.boulder.ibm.com (unknown [127.0.0.1]) by IMSVA (Postfix) with ESMTP id A4054BE04F; Tue, 1 Mar 2022 13:56:59 +0000 (GMT) Received: from farosas.linux.ibm.com.com (unknown [9.211.51.129]) by b03ledav005.gho.boulder.ibm.com (Postfix) with ESMTP; Tue, 1 Mar 2022 13:56:59 +0000 (GMT) From: Fabiano Rosas To: qemu-devel@nongnu.org Subject: [PATCH 17/17] target/ppc: Move powerpc_excp* to the PowerPCCPU Class Date: Tue, 1 Mar 2022 10:56:20 -0300 Message-Id: <20220301135620.2411952-18-farosas@linux.ibm.com> X-Mailer: git-send-email 2.34.1 In-Reply-To: <20220301135620.2411952-1-farosas@linux.ibm.com> References: <20220301135620.2411952-1-farosas@linux.ibm.com> MIME-Version: 1.0 X-TM-AS-GCONF: 00 X-Proofpoint-GUID: iP4OcgDiMN8aIJheLZ_EaTcL2fsQfi60 X-Proofpoint-ORIG-GUID: 4A2x9XvV5R-ZpcomD6Zxew36zh90We88 X-Proofpoint-Virus-Version: vendor=baseguard engine=ICAP:2.0.205,Aquarius:18.0.816,Hydra:6.0.425,FMLib:17.11.64.514 definitions=2022-03-01_07,2022-02-26_01,2022-02-23_01 X-Proofpoint-Spam-Details: rule=outbound_notspam policy=outbound score=0 malwarescore=0 adultscore=0 spamscore=0 clxscore=1015 impostorscore=0 mlxscore=0 priorityscore=1501 bulkscore=0 phishscore=0 suspectscore=0 mlxlogscore=999 lowpriorityscore=0 classifier=spam adjust=0 reason=mlx scancount=1 engine=8.12.0-2201110000 definitions=main-2203010074 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_H5=0.001, RCVD_IN_MSPIKE_WL=0.001, SPF_HELO_NONE=0.001, SPF_PASS=-0.001, T_SCC_BODY_TEXT_LINE=-0.01 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 all the powerpc_excp* functions are in their appropriate C files, we can drop the excp_model switch and just use a QOM class method. This will allow us to remove the excp_model enum once we've figured out the last two remaining usages outside of excp_helper.c Signed-off-by: Fabiano Rosas --- target/ppc/cpu-qom.h | 1 + target/ppc/cpu.h | 6 ------ target/ppc/cpu_40x.c | 5 +++-- target/ppc/cpu_6xx.c | 13 +++++++++++-- target/ppc/cpu_74xx.c | 12 ++++++++++-- target/ppc/cpu_7xx.c | 12 ++++++++++-- target/ppc/cpu_booke.c | 15 +++++++++++++-- target/ppc/cpu_books.c | 8 +++++++- target/ppc/excp_helper.c | 30 ++---------------------------- 9 files changed, 57 insertions(+), 45 deletions(-) diff --git a/target/ppc/cpu-qom.h b/target/ppc/cpu-qom.h index 98facee9fa..1d0fa314c3 100644 --- a/target/ppc/cpu-qom.h +++ b/target/ppc/cpu-qom.h @@ -184,6 +184,7 @@ struct PowerPCCPUClass { int n_host_threads; void (*init_proc)(CPUPPCState *env); int (*check_pow)(CPUPPCState *env); + void (*dispatch_excp)(PowerPCCPU *cpu, int excp); }; #ifndef CONFIG_USER_ONLY diff --git a/target/ppc/cpu.h b/target/ppc/cpu.h index 30d06d2ef2..d21a952ab4 100644 --- a/target/ppc/cpu.h +++ b/target/ppc/cpu.h @@ -180,12 +180,6 @@ void powerpc_set_excp_state(PowerPCCPU *cpu, target_ulong vector, target_ulong msr); void powerpc_reset_excp_state(PowerPCCPU *cpu); void ppc_excp_debug_sw_tlb(CPUPPCState *env, int excp); -void powerpc_excp_40x(PowerPCCPU *cpu, int excp); -void powerpc_excp_6xx(PowerPCCPU *cpu, int excp); -void powerpc_excp_7xx(PowerPCCPU *cpu, int excp); -void powerpc_excp_74xx(PowerPCCPU *cpu, int excp); -void powerpc_excp_booke(PowerPCCPU *cpu, int excp); -void powerpc_excp_books(PowerPCCPU *cpu, int excp); #define PPC_INPUT(env) ((env)->bus_model) diff --git a/target/ppc/cpu_40x.c b/target/ppc/cpu_40x.c index 4b7bbeb28c..241c7e14bd 100644 --- a/target/ppc/cpu_40x.c +++ b/target/ppc/cpu_40x.c @@ -16,7 +16,7 @@ #include "helper_regs.h" #if !defined(CONFIG_USER_ONLY) -void powerpc_excp_40x(PowerPCCPU *cpu, int excp) +static void powerpc_excp_40x(PowerPCCPU *cpu, int excp) { CPUState *cs = CPU(cpu); CPUPPCState *env = &cpu->env; @@ -154,7 +154,7 @@ void powerpc_excp_40x(PowerPCCPU *cpu, int excp) powerpc_set_excp_state(cpu, vector, new_msr); } #else -void powerpc_excp_40x(PowerPCCPU *cpu, int excp) +static void powerpc_excp_40x(PowerPCCPU *cpu, int excp) { g_assert_not_reached(); } @@ -385,6 +385,7 @@ POWERPC_FAMILY(405)(ObjectClass *oc, void *data) dc->desc = "PowerPC 405"; pcc->init_proc = init_proc_405; pcc->check_pow = check_pow_nocheck; + pcc->dispatch_excp = powerpc_excp_40x; pcc->insns_flags = PPC_INSNS_BASE | PPC_STRING | PPC_MFTB | PPC_DCR | PPC_WRTEE | PPC_CACHE | PPC_CACHE_ICBI | PPC_40x_ICBT | diff --git a/target/ppc/cpu_6xx.c b/target/ppc/cpu_6xx.c index b6a4909dbf..b066e96c91 100644 --- a/target/ppc/cpu_6xx.c +++ b/target/ppc/cpu_6xx.c @@ -27,7 +27,7 @@ static int check_pow_hid0(CPUPPCState *env) } #if !defined(CONFIG_USER_ONLY) -void powerpc_excp_6xx(PowerPCCPU *cpu, int excp) +static void powerpc_excp_6xx(PowerPCCPU *cpu, int excp) { CPUState *cs = CPU(cpu); CPUPPCState *env = &cpu->env; @@ -202,7 +202,7 @@ void powerpc_excp_6xx(PowerPCCPU *cpu, int excp) powerpc_set_excp_state(cpu, vector, new_msr); } #else -void powerpc_excp_6xx(PowerPCCPU *cpu, int excp) +static void powerpc_excp_6xx(PowerPCCPU *cpu, int excp) { g_assert_not_reached(); } @@ -1002,6 +1002,7 @@ POWERPC_FAMILY(MPC5xx)(ObjectClass *oc, void *data) dc->desc = "Freescale 5xx cores (aka RCPU)"; pcc->init_proc = init_proc_MPC5xx; pcc->check_pow = check_pow_none; + pcc->dispatch_excp = powerpc_excp_6xx; pcc->insns_flags = PPC_INSNS_BASE | PPC_STRING | PPC_MEM_EIEIO | PPC_MEM_SYNC | PPC_CACHE_ICBI | PPC_FLOAT | PPC_FLOAT_STFIWX | @@ -1034,6 +1035,7 @@ POWERPC_FAMILY(MPC8xx)(ObjectClass *oc, void *data) dc->desc = "Freescale 8xx cores (aka PowerQUICC)"; pcc->init_proc = init_proc_MPC8xx; pcc->check_pow = check_pow_none; + pcc->dispatch_excp = powerpc_excp_6xx; pcc->insns_flags = PPC_INSNS_BASE | PPC_STRING | PPC_MEM_EIEIO | PPC_MEM_SYNC | PPC_CACHE_ICBI | PPC_MFTB; @@ -1065,6 +1067,7 @@ POWERPC_FAMILY(G2)(ObjectClass *oc, void *data) dc->desc = "PowerPC G2"; pcc->init_proc = init_proc_G2; pcc->check_pow = check_pow_hid0; + pcc->dispatch_excp = powerpc_excp_6xx; pcc->insns_flags = PPC_INSNS_BASE | PPC_STRING | PPC_MFTB | PPC_FLOAT | PPC_FLOAT_FSEL | PPC_FLOAT_FRES | PPC_FLOAT_STFIWX | @@ -1103,6 +1106,7 @@ POWERPC_FAMILY(G2LE)(ObjectClass *oc, void *data) dc->desc = "PowerPC G2LE"; pcc->init_proc = init_proc_G2; pcc->check_pow = check_pow_hid0; + pcc->dispatch_excp = powerpc_excp_6xx; pcc->insns_flags = PPC_INSNS_BASE | PPC_STRING | PPC_MFTB | PPC_FLOAT | PPC_FLOAT_FSEL | PPC_FLOAT_FRES | PPC_FLOAT_STFIWX | @@ -1143,6 +1147,7 @@ POWERPC_FAMILY(603)(ObjectClass *oc, void *data) dc->desc = "PowerPC 603"; pcc->init_proc = init_proc_603; pcc->check_pow = check_pow_hid0; + pcc->dispatch_excp = powerpc_excp_6xx; pcc->insns_flags = PPC_INSNS_BASE | PPC_STRING | PPC_MFTB | PPC_FLOAT | PPC_FLOAT_FSEL | PPC_FLOAT_FRES | PPC_FLOAT_FRSQRTE | PPC_FLOAT_STFIWX | @@ -1182,6 +1187,7 @@ POWERPC_FAMILY(603E)(ObjectClass *oc, void *data) dc->desc = "PowerPC 603e"; pcc->init_proc = init_proc_603; pcc->check_pow = check_pow_hid0; + pcc->dispatch_excp = powerpc_excp_6xx; pcc->insns_flags = PPC_INSNS_BASE | PPC_STRING | PPC_MFTB | PPC_FLOAT | PPC_FLOAT_FSEL | PPC_FLOAT_FRES | PPC_FLOAT_FRSQRTE | PPC_FLOAT_STFIWX | @@ -1221,6 +1227,7 @@ POWERPC_FAMILY(e300)(ObjectClass *oc, void *data) dc->desc = "e300 core"; pcc->init_proc = init_proc_e300; pcc->check_pow = check_pow_hid0; + pcc->dispatch_excp = powerpc_excp_6xx; pcc->insns_flags = PPC_INSNS_BASE | PPC_STRING | PPC_MFTB | PPC_FLOAT | PPC_FLOAT_FSEL | PPC_FLOAT_FRES | PPC_FLOAT_STFIWX | @@ -1261,6 +1268,7 @@ POWERPC_FAMILY(604)(ObjectClass *oc, void *data) dc->desc = "PowerPC 604"; pcc->init_proc = init_proc_604; pcc->check_pow = check_pow_nocheck; + pcc->dispatch_excp = powerpc_excp_6xx; pcc->insns_flags = PPC_INSNS_BASE | PPC_STRING | PPC_MFTB | PPC_FLOAT | PPC_FLOAT_FSEL | PPC_FLOAT_FRES | PPC_FLOAT_FRSQRTE | PPC_FLOAT_STFIWX | @@ -1300,6 +1308,7 @@ POWERPC_FAMILY(604E)(ObjectClass *oc, void *data) dc->desc = "PowerPC 604E"; pcc->init_proc = init_proc_604E; pcc->check_pow = check_pow_nocheck; + pcc->dispatch_excp = powerpc_excp_6xx; pcc->insns_flags = PPC_INSNS_BASE | PPC_STRING | PPC_MFTB | PPC_FLOAT | PPC_FLOAT_FSEL | PPC_FLOAT_FRES | PPC_FLOAT_FRSQRTE | PPC_FLOAT_STFIWX | diff --git a/target/ppc/cpu_74xx.c b/target/ppc/cpu_74xx.c index 07715cadb5..0ee53833b0 100644 --- a/target/ppc/cpu_74xx.c +++ b/target/ppc/cpu_74xx.c @@ -36,7 +36,7 @@ static int check_pow_hid0_74xx(CPUPPCState *env) } #if !defined(CONFIG_USER_ONLY) -void powerpc_excp_74xx(PowerPCCPU *cpu, int excp) +static void powerpc_excp_74xx(PowerPCCPU *cpu, int excp) { CPUState *cs = CPU(cpu); CPUPPCState *env = &cpu->env; @@ -209,7 +209,7 @@ void powerpc_excp_74xx(PowerPCCPU *cpu, int excp) powerpc_set_excp_state(cpu, vector, new_msr); } #else -void powerpc_excp_74xx(PowerPCCPU *cpu, int excp) +static void powerpc_excp_74xx(PowerPCCPU *cpu, int excp) { g_assert_not_reached(); } @@ -996,6 +996,7 @@ POWERPC_FAMILY(7400)(ObjectClass *oc, void *data) dc->desc = "PowerPC 7400 (aka G4)"; pcc->init_proc = init_proc_7400; pcc->check_pow = check_pow_hid0; + pcc->dispatch_excp = powerpc_excp_74xx; pcc->insns_flags = PPC_INSNS_BASE | PPC_STRING | PPC_MFTB | PPC_FLOAT | PPC_FLOAT_FSEL | PPC_FLOAT_FRES | PPC_FLOAT_FSQRT | PPC_FLOAT_FRSQRTE | @@ -1041,6 +1042,7 @@ POWERPC_FAMILY(7410)(ObjectClass *oc, void *data) dc->desc = "PowerPC 7410 (aka G4)"; pcc->init_proc = init_proc_7410; pcc->check_pow = check_pow_hid0; + pcc->dispatch_excp = powerpc_excp_74xx; pcc->insns_flags = PPC_INSNS_BASE | PPC_STRING | PPC_MFTB | PPC_FLOAT | PPC_FLOAT_FSEL | PPC_FLOAT_FRES | PPC_FLOAT_FSQRT | PPC_FLOAT_FRSQRTE | @@ -1086,6 +1088,7 @@ POWERPC_FAMILY(7440)(ObjectClass *oc, void *data) dc->desc = "PowerPC 7440 (aka G4)"; pcc->init_proc = init_proc_7440; pcc->check_pow = check_pow_hid0_74xx; + pcc->dispatch_excp = powerpc_excp_74xx; pcc->insns_flags = PPC_INSNS_BASE | PPC_STRING | PPC_MFTB | PPC_FLOAT | PPC_FLOAT_FSEL | PPC_FLOAT_FRES | PPC_FLOAT_FSQRT | PPC_FLOAT_FRSQRTE | @@ -1131,6 +1134,7 @@ POWERPC_FAMILY(7450)(ObjectClass *oc, void *data) dc->desc = "PowerPC 7450 (aka G4)"; pcc->init_proc = init_proc_7450; pcc->check_pow = check_pow_hid0_74xx; + pcc->dispatch_excp = powerpc_excp_74xx; pcc->insns_flags = PPC_INSNS_BASE | PPC_STRING | PPC_MFTB | PPC_FLOAT | PPC_FLOAT_FSEL | PPC_FLOAT_FRES | PPC_FLOAT_FSQRT | PPC_FLOAT_FRSQRTE | @@ -1176,6 +1180,7 @@ POWERPC_FAMILY(7445)(ObjectClass *oc, void *data) dc->desc = "PowerPC 7445 (aka G4)"; pcc->init_proc = init_proc_7445; pcc->check_pow = check_pow_hid0_74xx; + pcc->dispatch_excp = powerpc_excp_74xx; pcc->insns_flags = PPC_INSNS_BASE | PPC_STRING | PPC_MFTB | PPC_FLOAT | PPC_FLOAT_FSEL | PPC_FLOAT_FRES | PPC_FLOAT_FSQRT | PPC_FLOAT_FRSQRTE | @@ -1221,6 +1226,7 @@ POWERPC_FAMILY(7455)(ObjectClass *oc, void *data) dc->desc = "PowerPC 7455 (aka G4)"; pcc->init_proc = init_proc_7455; pcc->check_pow = check_pow_hid0_74xx; + pcc->dispatch_excp = powerpc_excp_74xx; pcc->insns_flags = PPC_INSNS_BASE | PPC_STRING | PPC_MFTB | PPC_FLOAT | PPC_FLOAT_FSEL | PPC_FLOAT_FRES | PPC_FLOAT_FSQRT | PPC_FLOAT_FRSQRTE | @@ -1266,6 +1272,7 @@ POWERPC_FAMILY(7457)(ObjectClass *oc, void *data) dc->desc = "PowerPC 7457 (aka G4)"; pcc->init_proc = init_proc_7457; pcc->check_pow = check_pow_hid0_74xx; + pcc->dispatch_excp = powerpc_excp_74xx; pcc->insns_flags = PPC_INSNS_BASE | PPC_STRING | PPC_MFTB | PPC_FLOAT | PPC_FLOAT_FSEL | PPC_FLOAT_FRES | PPC_FLOAT_FSQRT | PPC_FLOAT_FRSQRTE | @@ -1311,6 +1318,7 @@ POWERPC_FAMILY(e600)(ObjectClass *oc, void *data) dc->desc = "PowerPC e600"; pcc->init_proc = init_proc_e600; pcc->check_pow = check_pow_hid0_74xx; + pcc->dispatch_excp = powerpc_excp_74xx; pcc->insns_flags = PPC_INSNS_BASE | PPC_STRING | PPC_MFTB | PPC_FLOAT | PPC_FLOAT_FSEL | PPC_FLOAT_FRES | PPC_FLOAT_FSQRT | PPC_FLOAT_FRSQRTE | diff --git a/target/ppc/cpu_7xx.c b/target/ppc/cpu_7xx.c index 6f99521aba..03b10906c9 100644 --- a/target/ppc/cpu_7xx.c +++ b/target/ppc/cpu_7xx.c @@ -17,7 +17,7 @@ #include "helper_regs.h" #if !defined(CONFIG_USER_ONLY) -void powerpc_excp_7xx(PowerPCCPU *cpu, int excp) +static void powerpc_excp_7xx(PowerPCCPU *cpu, int excp) { CPUState *cs = CPU(cpu); CPUPPCState *env = &cpu->env; @@ -198,7 +198,7 @@ void powerpc_excp_7xx(PowerPCCPU *cpu, int excp) powerpc_set_excp_state(cpu, vector, new_msr); } #else -void powerpc_excp_7xx(PowerPCCPU *cpu, int excp) +static void powerpc_excp_7xx(PowerPCCPU *cpu, int excp) { g_assert_not_reached(); } @@ -743,6 +743,7 @@ POWERPC_FAMILY(740)(ObjectClass *oc, void *data) dc->desc = "PowerPC 740"; pcc->init_proc = init_proc_740; pcc->check_pow = check_pow_hid0; + pcc->dispatch_excp = powerpc_excp_7xx; pcc->insns_flags = PPC_INSNS_BASE | PPC_STRING | PPC_MFTB | PPC_FLOAT | PPC_FLOAT_FSEL | PPC_FLOAT_FRES | PPC_FLOAT_FRSQRTE | PPC_FLOAT_STFIWX | @@ -782,6 +783,7 @@ POWERPC_FAMILY(750)(ObjectClass *oc, void *data) dc->desc = "PowerPC 750"; pcc->init_proc = init_proc_750; pcc->check_pow = check_pow_hid0; + pcc->dispatch_excp = powerpc_excp_7xx; pcc->insns_flags = PPC_INSNS_BASE | PPC_STRING | PPC_MFTB | PPC_FLOAT | PPC_FLOAT_FSEL | PPC_FLOAT_FRES | PPC_FLOAT_FRSQRTE | PPC_FLOAT_STFIWX | @@ -821,6 +823,7 @@ POWERPC_FAMILY(750cl)(ObjectClass *oc, void *data) dc->desc = "PowerPC 750 CL"; pcc->init_proc = init_proc_750cl; pcc->check_pow = check_pow_hid0; + pcc->dispatch_excp = powerpc_excp_7xx; /* * XXX: not implemented: * cache lock instructions: @@ -899,6 +902,7 @@ POWERPC_FAMILY(750cx)(ObjectClass *oc, void *data) dc->desc = "PowerPC 750CX"; pcc->init_proc = init_proc_750cx; pcc->check_pow = check_pow_hid0; + pcc->dispatch_excp = powerpc_excp_7xx; pcc->insns_flags = PPC_INSNS_BASE | PPC_STRING | PPC_MFTB | PPC_FLOAT | PPC_FLOAT_FSEL | PPC_FLOAT_FRES | PPC_FLOAT_FRSQRTE | PPC_FLOAT_STFIWX | @@ -938,6 +942,7 @@ POWERPC_FAMILY(750fx)(ObjectClass *oc, void *data) dc->desc = "PowerPC 750FX"; pcc->init_proc = init_proc_750fx; pcc->check_pow = check_pow_hid0; + pcc->dispatch_excp = powerpc_excp_7xx; pcc->insns_flags = PPC_INSNS_BASE | PPC_STRING | PPC_MFTB | PPC_FLOAT | PPC_FLOAT_FSEL | PPC_FLOAT_FRES | PPC_FLOAT_FRSQRTE | PPC_FLOAT_STFIWX | @@ -977,6 +982,7 @@ POWERPC_FAMILY(750gx)(ObjectClass *oc, void *data) dc->desc = "PowerPC 750GX"; pcc->init_proc = init_proc_750gx; pcc->check_pow = check_pow_hid0; + pcc->dispatch_excp = powerpc_excp_7xx; pcc->insns_flags = PPC_INSNS_BASE | PPC_STRING | PPC_MFTB | PPC_FLOAT | PPC_FLOAT_FSEL | PPC_FLOAT_FRES | PPC_FLOAT_FRSQRTE | PPC_FLOAT_STFIWX | @@ -1016,6 +1022,7 @@ POWERPC_FAMILY(745)(ObjectClass *oc, void *data) dc->desc = "PowerPC 745"; pcc->init_proc = init_proc_745; pcc->check_pow = check_pow_hid0; + pcc->dispatch_excp = powerpc_excp_7xx; pcc->insns_flags = PPC_INSNS_BASE | PPC_STRING | PPC_MFTB | PPC_FLOAT | PPC_FLOAT_FSEL | PPC_FLOAT_FRES | PPC_FLOAT_FRSQRTE | PPC_FLOAT_STFIWX | @@ -1055,6 +1062,7 @@ POWERPC_FAMILY(755)(ObjectClass *oc, void *data) dc->desc = "PowerPC 755"; pcc->init_proc = init_proc_755; pcc->check_pow = check_pow_hid0; + pcc->dispatch_excp = powerpc_excp_7xx; pcc->insns_flags = PPC_INSNS_BASE | PPC_STRING | PPC_MFTB | PPC_FLOAT | PPC_FLOAT_FSEL | PPC_FLOAT_FRES | PPC_FLOAT_FRSQRTE | PPC_FLOAT_STFIWX | diff --git a/target/ppc/cpu_booke.c b/target/ppc/cpu_booke.c index b73cfe224d..baf0139075 100644 --- a/target/ppc/cpu_booke.c +++ b/target/ppc/cpu_booke.c @@ -25,7 +25,7 @@ static int check_pow_hid0(CPUPPCState *env) } #if !defined(CONFIG_USER_ONLY) -void powerpc_excp_booke(PowerPCCPU *cpu, int excp) +static void powerpc_excp_booke(PowerPCCPU *cpu, int excp) { CPUState *cs = CPU(cpu); CPUPPCState *env = &cpu->env; @@ -229,7 +229,7 @@ void powerpc_excp_booke(PowerPCCPU *cpu, int excp) powerpc_set_excp_state(cpu, vector, new_msr); } #else -void powerpc_excp_booke(PowerPCCPU *cpu, int excp) +static void powerpc_excp_booke(PowerPCCPU *cpu, int excp) { g_assert_not_reached(); } @@ -1207,6 +1207,7 @@ POWERPC_FAMILY(440EP)(ObjectClass *oc, void *data) dc->desc = "PowerPC 440 EP"; pcc->init_proc = init_proc_440EP; pcc->check_pow = check_pow_nocheck; + pcc->dispatch_excp = powerpc_excp_booke; pcc->insns_flags = PPC_INSNS_BASE | PPC_STRING | PPC_FLOAT | PPC_FLOAT_FRES | PPC_FLOAT_FSEL | PPC_FLOAT_FSQRT | PPC_FLOAT_FRSQRTE | @@ -1245,6 +1246,7 @@ POWERPC_FAMILY(460EX)(ObjectClass *oc, void *data) dc->desc = "PowerPC 460 EX"; pcc->init_proc = init_proc_440EP; pcc->check_pow = check_pow_nocheck; + pcc->dispatch_excp = powerpc_excp_booke; pcc->insns_flags = PPC_INSNS_BASE | PPC_STRING | PPC_FLOAT | PPC_FLOAT_FRES | PPC_FLOAT_FSEL | PPC_FLOAT_FSQRT | PPC_FLOAT_FRSQRTE | @@ -1283,6 +1285,7 @@ POWERPC_FAMILY(440GP)(ObjectClass *oc, void *data) dc->desc = "PowerPC 440 GP"; pcc->init_proc = init_proc_440GP; pcc->check_pow = check_pow_nocheck; + pcc->dispatch_excp = powerpc_excp_booke; pcc->insns_flags = PPC_INSNS_BASE | PPC_STRING | PPC_DCR | PPC_DCRX | PPC_WRTEE | PPC_MFAPIDI | PPC_CACHE | PPC_CACHE_ICBI | @@ -1318,6 +1321,7 @@ POWERPC_FAMILY(440x5)(ObjectClass *oc, void *data) dc->desc = "PowerPC 440x5"; pcc->init_proc = init_proc_440x5; pcc->check_pow = check_pow_nocheck; + pcc->dispatch_excp = powerpc_excp_booke; pcc->insns_flags = PPC_INSNS_BASE | PPC_STRING | PPC_DCR | PPC_WRTEE | PPC_RFMCI | PPC_CACHE | PPC_CACHE_ICBI | @@ -1353,6 +1357,7 @@ POWERPC_FAMILY(440x5wDFPU)(ObjectClass *oc, void *data) dc->desc = "PowerPC 440x5 with double precision FPU"; pcc->init_proc = init_proc_440x5; pcc->check_pow = check_pow_nocheck; + pcc->dispatch_excp = powerpc_excp_booke; pcc->insns_flags = PPC_INSNS_BASE | PPC_STRING | PPC_FLOAT | PPC_FLOAT_FSQRT | PPC_FLOAT_STFIWX | @@ -1391,6 +1396,7 @@ POWERPC_FAMILY(e200)(ObjectClass *oc, void *data) dc->desc = "e200 core"; pcc->init_proc = init_proc_e200; pcc->check_pow = check_pow_hid0; + pcc->dispatch_excp = powerpc_excp_booke; /* * XXX: unimplemented instructions: * dcblc @@ -1439,6 +1445,7 @@ POWERPC_FAMILY(e500v1)(ObjectClass *oc, void *data) dc->desc = "e500v1 core"; pcc->init_proc = init_proc_e500v1; pcc->check_pow = check_pow_hid0; + pcc->dispatch_excp = powerpc_excp_booke; pcc->insns_flags = PPC_INSNS_BASE | PPC_ISEL | PPC_SPE | PPC_SPE_SINGLE | PPC_WRTEE | PPC_RFDI | @@ -1477,6 +1484,7 @@ POWERPC_FAMILY(e500v2)(ObjectClass *oc, void *data) dc->desc = "e500v2 core"; pcc->init_proc = init_proc_e500v2; pcc->check_pow = check_pow_hid0; + pcc->dispatch_excp = powerpc_excp_booke; pcc->insns_flags = PPC_INSNS_BASE | PPC_ISEL | PPC_SPE | PPC_SPE_SINGLE | PPC_SPE_DOUBLE | PPC_WRTEE | PPC_RFDI | @@ -1515,6 +1523,7 @@ POWERPC_FAMILY(e500mc)(ObjectClass *oc, void *data) dc->desc = "e500mc core"; pcc->init_proc = init_proc_e500mc; pcc->check_pow = check_pow_none; + pcc->dispatch_excp = powerpc_excp_booke; pcc->insns_flags = PPC_INSNS_BASE | PPC_ISEL | PPC_MFTB | PPC_WRTEE | PPC_RFDI | PPC_RFMCI | PPC_CACHE | PPC_CACHE_LOCK | PPC_CACHE_ICBI | @@ -1556,6 +1565,7 @@ POWERPC_FAMILY(e5500)(ObjectClass *oc, void *data) dc->desc = "e5500 core"; pcc->init_proc = init_proc_e5500; pcc->check_pow = check_pow_none; + pcc->dispatch_excp = powerpc_excp_booke; pcc->insns_flags = PPC_INSNS_BASE | PPC_ISEL | PPC_MFTB | PPC_WRTEE | PPC_RFDI | PPC_RFMCI | PPC_CACHE | PPC_CACHE_LOCK | PPC_CACHE_ICBI | @@ -1599,6 +1609,7 @@ POWERPC_FAMILY(e6500)(ObjectClass *oc, void *data) dc->desc = "e6500 core"; pcc->init_proc = init_proc_e6500; pcc->check_pow = check_pow_none; + pcc->dispatch_excp = powerpc_excp_booke; pcc->insns_flags = PPC_INSNS_BASE | PPC_ISEL | PPC_MFTB | PPC_WRTEE | PPC_RFDI | PPC_RFMCI | PPC_CACHE | PPC_CACHE_LOCK | PPC_CACHE_ICBI | diff --git a/target/ppc/cpu_books.c b/target/ppc/cpu_books.c index e776ededda..27b34df2b0 100644 --- a/target/ppc/cpu_books.c +++ b/target/ppc/cpu_books.c @@ -248,7 +248,7 @@ static bool books_vhyp_handles_hv_excp(PowerPCCPU *cpu) return false; } -void powerpc_excp_books(PowerPCCPU *cpu, int excp) +static void powerpc_excp_books(PowerPCCPU *cpu, int excp) { CPUState *cs = CPU(cpu); CPUPPCState *env = &cpu->env; @@ -1889,6 +1889,7 @@ POWERPC_FAMILY(970)(ObjectClass *oc, void *data) dc->desc = "PowerPC 970"; pcc->init_proc = init_proc_970; pcc->check_pow = check_pow_970; + pcc->dispatch_excp = powerpc_excp_books; pcc->insns_flags = PPC_INSNS_BASE | PPC_STRING | PPC_MFTB | PPC_FLOAT | PPC_FLOAT_FSEL | PPC_FLOAT_FRES | PPC_FLOAT_FSQRT | PPC_FLOAT_FRSQRTE | @@ -1937,6 +1938,7 @@ POWERPC_FAMILY(POWER5P)(ObjectClass *oc, void *data) dc->desc = "POWER5+"; pcc->init_proc = init_proc_power5plus; pcc->check_pow = check_pow_970; + pcc->dispatch_excp = powerpc_excp_books; pcc->insns_flags = PPC_INSNS_BASE | PPC_STRING | PPC_MFTB | PPC_FLOAT | PPC_FLOAT_FSEL | PPC_FLOAT_FRES | PPC_FLOAT_FSQRT | PPC_FLOAT_FRSQRTE | @@ -1994,6 +1996,7 @@ POWERPC_FAMILY(POWER7)(ObjectClass *oc, void *data) pcc->pcr_supported = PCR_COMPAT_2_06 | PCR_COMPAT_2_05; pcc->init_proc = init_proc_POWER7; pcc->check_pow = check_pow_nocheck; + pcc->dispatch_excp = powerpc_excp_books; cc->has_work = cpu_has_work_POWER7; pcc->insns_flags = PPC_INSNS_BASE | PPC_ISEL | PPC_STRING | PPC_MFTB | PPC_FLOAT | PPC_FLOAT_FSEL | PPC_FLOAT_FRES | @@ -2064,6 +2067,7 @@ POWERPC_FAMILY(POWER8)(ObjectClass *oc, void *data) pcc->pcr_supported = PCR_COMPAT_2_07 | PCR_COMPAT_2_06 | PCR_COMPAT_2_05; pcc->init_proc = init_proc_POWER8; pcc->check_pow = check_pow_nocheck; + pcc->dispatch_excp = powerpc_excp_books; cc->has_work = cpu_has_work_POWER8; pcc->insns_flags = PPC_INSNS_BASE | PPC_ISEL | PPC_STRING | PPC_MFTB | PPC_FLOAT | PPC_FLOAT_FSEL | PPC_FLOAT_FRES | @@ -2143,6 +2147,7 @@ POWERPC_FAMILY(POWER9)(ObjectClass *oc, void *data) PCR_COMPAT_2_05; pcc->init_proc = init_proc_POWER9; pcc->check_pow = check_pow_nocheck; + pcc->dispatch_excp = powerpc_excp_books; cc->has_work = cpu_has_work_POWER9; pcc->insns_flags = PPC_INSNS_BASE | PPC_ISEL | PPC_STRING | PPC_MFTB | PPC_FLOAT | PPC_FLOAT_FSEL | PPC_FLOAT_FRES | @@ -2224,6 +2229,7 @@ POWERPC_FAMILY(POWER10)(ObjectClass *oc, void *data) PCR_COMPAT_2_06 | PCR_COMPAT_2_05; pcc->init_proc = init_proc_POWER10; pcc->check_pow = check_pow_nocheck; + pcc->dispatch_excp = powerpc_excp_books; cc->has_work = cpu_has_work_POWER10; pcc->insns_flags = PPC_INSNS_BASE | PPC_ISEL | PPC_STRING | PPC_MFTB | PPC_FLOAT | PPC_FLOAT_FSEL | PPC_FLOAT_FRES | diff --git a/target/ppc/excp_helper.c b/target/ppc/excp_helper.c index 257379871f..6755a0cbba 100644 --- a/target/ppc/excp_helper.c +++ b/target/ppc/excp_helper.c @@ -193,6 +193,7 @@ static bool books_vhyp_promotes_external_to_hvirt(PowerPCCPU *cpu) static void powerpc_excp(PowerPCCPU *cpu, int excp) { + PowerPCCPUClass *pcc = POWERPC_CPU_GET_CLASS(cpu); CPUState *cs = CPU(cpu); CPUPPCState *env = &cpu->env; @@ -206,34 +207,7 @@ static void powerpc_excp(PowerPCCPU *cpu, int excp) trace_ppc_excp(env->nip, powerpc_excp_name(excp), excp, env->error_code); - switch (env->excp_model) { - case POWERPC_EXCP_40x: - powerpc_excp_40x(cpu, excp); - break; - case POWERPC_EXCP_6xx: - powerpc_excp_6xx(cpu, excp); - break; - case POWERPC_EXCP_7xx: - powerpc_excp_7xx(cpu, excp); - break; - case POWERPC_EXCP_74xx: - powerpc_excp_74xx(cpu, excp); - break; - case POWERPC_EXCP_BOOKE: - powerpc_excp_booke(cpu, excp); - break; -#if defined(TARGET_PPC64) - case POWERPC_EXCP_970: - case POWERPC_EXCP_POWER7: - case POWERPC_EXCP_POWER8: - case POWERPC_EXCP_POWER9: - case POWERPC_EXCP_POWER10: - powerpc_excp_books(cpu, excp); - break; -#endif - default: - g_assert_not_reached(); - } + (*pcc->dispatch_excp)(cpu, excp); } void ppc_cpu_do_interrupt(CPUState *cs)