From patchwork Tue May 4 05:52:27 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: David Gibson X-Patchwork-Id: 12237413 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-16.6 required=3.0 tests=BAYES_00,DKIM_INVALID, DKIM_SIGNED,HEADER_FROM_DIFFERENT_DOMAINS,INCLUDES_CR_TRAILER,INCLUDES_PATCH, MAILING_LIST_MULTI,SPF_HELO_NONE,SPF_PASS,USER_AGENT_GIT autolearn=ham autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id A6DE3C433ED for ; Tue, 4 May 2021 05:56:07 +0000 (UTC) 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 mail.kernel.org (Postfix) with ESMTPS id 1CC8C613B3 for ; Tue, 4 May 2021 05:56:06 +0000 (UTC) DMARC-Filter: OpenDMARC Filter v1.3.2 mail.kernel.org 1CC8C613B3 Authentication-Results: mail.kernel.org; dmarc=none (p=none dis=none) header.from=gibson.dropbear.id.au Authentication-Results: mail.kernel.org; spf=pass smtp.mailfrom=qemu-devel-bounces+qemu-devel=archiver.kernel.org@nongnu.org Received: from localhost ([::1]:50058 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1ldo2P-00076y-SU for qemu-devel@archiver.kernel.org; Tue, 04 May 2021 01:56:05 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]:60336) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1ldnzp-00057h-8n; Tue, 04 May 2021 01:53:25 -0400 Received: from ozlabs.org ([203.11.71.1]:56761) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1ldnzm-0004Zz-57; Tue, 04 May 2021 01:53:25 -0400 Received: by ozlabs.org (Postfix, from userid 1007) id 4FZ8CJ2Tvxz9sVt; Tue, 4 May 2021 15:53:16 +1000 (AEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=gibson.dropbear.id.au; s=201602; t=1620107596; bh=c+Av/lwhQMLGG0GJaCIeD3vUOc2wvGqxh/adBaWljAk=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=pTqF1+8ZeGf+62Z/AZScXQBqsePDe8KLJ3t6SbKNES1pgux/TlZ6qG+Ppt43ECLX0 wEcvkETo4TZ4oiJznyX+v69t7I7ZXDwWcawpD3wDb+l5dx6hiQcfmLk8oiCkdhFUq+ k9Ayc+uYDVdk1i/JEImv11GxS6IMrJo3PQzn+2Xo= From: David Gibson To: peter.maydell@linaro.org, groug@kaod.org Subject: [PULL 01/46] hw/ppc/mac_newworld: Restrict RAM to 2 GiB Date: Tue, 4 May 2021 15:52:27 +1000 Message-Id: <20210504055312.306823-2-david@gibson.dropbear.id.au> X-Mailer: git-send-email 2.31.1 In-Reply-To: <20210504055312.306823-1-david@gibson.dropbear.id.au> References: <20210504055312.306823-1-david@gibson.dropbear.id.au> MIME-Version: 1.0 Received-SPF: pass client-ip=203.11.71.1; envelope-from=dgibson@ozlabs.org; helo=ozlabs.org X-Spam_score_int: -17 X-Spam_score: -1.8 X-Spam_bar: - X-Spam_report: (-1.8 / 5.0 requ) BAYES_00=-1.9, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_AU=-0.1, HEADER_FROM_DIFFERENT_DOMAINS=0.25, SPF_HELO_PASS=-0.001, SPF_PASS=-0.001 autolearn=no autolearn_force=no X-Spam_action: no action X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: =?utf-8?q?Philippe_Mathieu-Daud=C3=A9?= , qemu-devel@nongnu.org, qemu-ppc@nongnu.org, =?utf-8?q?H=C3=A5vard_Eidnes?= , David Gibson Errors-To: qemu-devel-bounces+qemu-devel=archiver.kernel.org@nongnu.org Sender: "Qemu-devel" From: Philippe Mathieu-Daudé On Mac99 and newer machines, the Uninorth PCI host bridge maps the PCI hole region at 2GiB, so the RAM area beside 2GiB is not accessible by the CPU. Restrict the memory to 2GiB to avoid problems such the one reported in the buglink. Buglink: https://bugs.launchpad.net/qemu/+bug/1922391 Reported-by: Håvard Eidnes Signed-off-by: Philippe Mathieu-Daudé Message-Id: <20210406084842.2859664-1-f4bug@amsat.org> Reviewed-by: BALATON Zoltan Signed-off-by: David Gibson --- hw/ppc/mac_newworld.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/hw/ppc/mac_newworld.c b/hw/ppc/mac_newworld.c index 2175962846..d88b38e925 100644 --- a/hw/ppc/mac_newworld.c +++ b/hw/ppc/mac_newworld.c @@ -157,6 +157,10 @@ static void ppc_core99_init(MachineState *machine) } /* allocate RAM */ + if (machine->ram_size > 2 * GiB) { + error_report("RAM size more than 2 GiB is not supported"); + exit(1); + } memory_region_add_subregion(get_system_memory(), 0, machine->ram); /* allocate and load firmware ROM */ From patchwork Tue May 4 05:52:28 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: David Gibson X-Patchwork-Id: 12237429 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-16.6 required=3.0 tests=BAYES_00,DKIM_INVALID, DKIM_SIGNED,HEADER_FROM_DIFFERENT_DOMAINS,INCLUDES_CR_TRAILER,INCLUDES_PATCH, MAILING_LIST_MULTI,SPF_HELO_NONE,SPF_PASS,USER_AGENT_GIT autolearn=ham autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id 1C476C433B4 for ; Tue, 4 May 2021 06:04:18 +0000 (UTC) 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 mail.kernel.org (Postfix) with ESMTPS id A06296139A for ; Tue, 4 May 2021 06:04:17 +0000 (UTC) DMARC-Filter: OpenDMARC Filter v1.3.2 mail.kernel.org A06296139A Authentication-Results: mail.kernel.org; dmarc=none (p=none dis=none) header.from=gibson.dropbear.id.au Authentication-Results: mail.kernel.org; spf=pass smtp.mailfrom=qemu-devel-bounces+qemu-devel=archiver.kernel.org@nongnu.org Received: from localhost ([::1]:39950 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1ldoAK-0006cq-Pt for qemu-devel@archiver.kernel.org; Tue, 04 May 2021 02:04:16 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]:60368) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1ldnzr-00058k-F5; Tue, 04 May 2021 01:53:27 -0400 Received: from ozlabs.org ([2401:3900:2:1::2]:47715) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1ldnzn-0004a1-Ja; Tue, 04 May 2021 01:53:27 -0400 Received: by ozlabs.org (Postfix, from userid 1007) id 4FZ8CJ6ZtNz9sW8; Tue, 4 May 2021 15:53:16 +1000 (AEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=gibson.dropbear.id.au; s=201602; t=1620107596; bh=oiyPiLUSEfVDN6Hic2i2vSkbwYSlKuLN7VQdHYLVgoY=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=LyAZ7IzZz10+CT9EWyh/J3F7XAiZUWobA2q3TDeu2JzbfPdYRMpBYcGPm0lO4ArX4 fXwvJ8RPC+M/Pg3+oPLdbfseHTHP8LfM6npDVn32OBvp/wDhJf/JB9n1xvhK3usvnn CzKa0aserH9BDDmI1BnpjDzCY1UP+EyRfw+UcK/Y= From: David Gibson To: peter.maydell@linaro.org, groug@kaod.org Subject: [PULL 02/46] target/ppc: Move helper_regs.h functions out-of-line Date: Tue, 4 May 2021 15:52:28 +1000 Message-Id: <20210504055312.306823-3-david@gibson.dropbear.id.au> X-Mailer: git-send-email 2.31.1 In-Reply-To: <20210504055312.306823-1-david@gibson.dropbear.id.au> References: <20210504055312.306823-1-david@gibson.dropbear.id.au> MIME-Version: 1.0 Received-SPF: pass client-ip=2401:3900:2:1::2; envelope-from=dgibson@ozlabs.org; helo=ozlabs.org X-Spam_score_int: -17 X-Spam_score: -1.8 X-Spam_bar: - X-Spam_report: (-1.8 / 5.0 requ) BAYES_00=-1.9, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_AU=-0.1, HEADER_FROM_DIFFERENT_DOMAINS=0.25, SPF_HELO_PASS=-0.001, SPF_PASS=-0.001 autolearn=no autolearn_force=no X-Spam_action: no action X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: Richard Henderson , David Gibson , qemu-ppc@nongnu.org, qemu-devel@nongnu.org, =?utf-8?q?C=C3=A9dric_Le_Goater?= Errors-To: qemu-devel-bounces+qemu-devel=archiver.kernel.org@nongnu.org Sender: "Qemu-devel" From: Richard Henderson Move the functions to a new file, helper_regs.c. Note int_helper.c was relying on helper_regs.h to indirectly include qemu/log.h. Signed-off-by: Richard Henderson Message-Id: <20210315184615.1985590-2-richard.henderson@linaro.org> Reviewed-by: Cédric Le Goater Signed-off-by: David Gibson --- target/ppc/helper_regs.c | 197 +++++++++++++++++++++++++++++++++++++++ target/ppc/helper_regs.h | 184 ++---------------------------------- target/ppc/int_helper.c | 1 + target/ppc/meson.build | 1 + 4 files changed, 207 insertions(+), 176 deletions(-) create mode 100644 target/ppc/helper_regs.c diff --git a/target/ppc/helper_regs.c b/target/ppc/helper_regs.c new file mode 100644 index 0000000000..5e18232b84 --- /dev/null +++ b/target/ppc/helper_regs.c @@ -0,0 +1,197 @@ +/* + * PowerPC emulation special registers manipulation helpers for qemu. + * + * Copyright (c) 2003-2007 Jocelyn Mayer + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, see . + */ + +#include "qemu/osdep.h" +#include "qemu/main-loop.h" +#include "exec/exec-all.h" +#include "sysemu/kvm.h" +#include "helper_regs.h" + +/* Swap temporary saved registers with GPRs */ +void hreg_swap_gpr_tgpr(CPUPPCState *env) +{ + target_ulong tmp; + + tmp = env->gpr[0]; + env->gpr[0] = env->tgpr[0]; + env->tgpr[0] = tmp; + tmp = env->gpr[1]; + env->gpr[1] = env->tgpr[1]; + env->tgpr[1] = tmp; + tmp = env->gpr[2]; + env->gpr[2] = env->tgpr[2]; + env->tgpr[2] = tmp; + tmp = env->gpr[3]; + env->gpr[3] = env->tgpr[3]; + env->tgpr[3] = tmp; +} + +void hreg_compute_mem_idx(CPUPPCState *env) +{ + /* + * This is our encoding for server processors. The architecture + * specifies that there is no such thing as userspace with + * translation off, however it appears that MacOS does it and some + * 32-bit CPUs support it. Weird... + * + * 0 = Guest User space virtual mode + * 1 = Guest Kernel space virtual mode + * 2 = Guest User space real mode + * 3 = Guest Kernel space real mode + * 4 = HV User space virtual mode + * 5 = HV Kernel space virtual mode + * 6 = HV User space real mode + * 7 = HV Kernel space real mode + * + * For BookE, we need 8 MMU modes as follow: + * + * 0 = AS 0 HV User space + * 1 = AS 0 HV Kernel space + * 2 = AS 1 HV User space + * 3 = AS 1 HV Kernel space + * 4 = AS 0 Guest User space + * 5 = AS 0 Guest Kernel space + * 6 = AS 1 Guest User space + * 7 = AS 1 Guest Kernel space + */ + if (env->mmu_model & POWERPC_MMU_BOOKE) { + env->immu_idx = env->dmmu_idx = msr_pr ? 0 : 1; + env->immu_idx += msr_is ? 2 : 0; + env->dmmu_idx += msr_ds ? 2 : 0; + env->immu_idx += msr_gs ? 4 : 0; + env->dmmu_idx += msr_gs ? 4 : 0; + } else { + env->immu_idx = env->dmmu_idx = msr_pr ? 0 : 1; + env->immu_idx += msr_ir ? 0 : 2; + env->dmmu_idx += msr_dr ? 0 : 2; + env->immu_idx += msr_hv ? 4 : 0; + env->dmmu_idx += msr_hv ? 4 : 0; + } +} + +void hreg_compute_hflags(CPUPPCState *env) +{ + target_ulong hflags_mask; + + /* We 'forget' FE0 & FE1: we'll never generate imprecise exceptions */ + hflags_mask = (1 << MSR_VR) | (1 << MSR_AP) | (1 << MSR_SA) | + (1 << MSR_PR) | (1 << MSR_FP) | (1 << MSR_SE) | (1 << MSR_BE) | + (1 << MSR_LE) | (1 << MSR_VSX) | (1 << MSR_IR) | (1 << MSR_DR); + hflags_mask |= (1ULL << MSR_CM) | (1ULL << MSR_SF) | MSR_HVB; + hreg_compute_mem_idx(env); + env->hflags = env->msr & hflags_mask; + /* Merge with hflags coming from other registers */ + env->hflags |= env->hflags_nmsr; +} + +void cpu_interrupt_exittb(CPUState *cs) +{ + if (!kvm_enabled()) { + return; + } + + if (!qemu_mutex_iothread_locked()) { + qemu_mutex_lock_iothread(); + cpu_interrupt(cs, CPU_INTERRUPT_EXITTB); + qemu_mutex_unlock_iothread(); + } else { + cpu_interrupt(cs, CPU_INTERRUPT_EXITTB); + } +} + +int hreg_store_msr(CPUPPCState *env, target_ulong value, int alter_hv) +{ + int excp; +#if !defined(CONFIG_USER_ONLY) + CPUState *cs = env_cpu(env); +#endif + + excp = 0; + value &= env->msr_mask; +#if !defined(CONFIG_USER_ONLY) + /* Neither mtmsr nor guest state can alter HV */ + if (!alter_hv || !(env->msr & MSR_HVB)) { + value &= ~MSR_HVB; + value |= env->msr & MSR_HVB; + } + if (((value >> MSR_IR) & 1) != msr_ir || + ((value >> MSR_DR) & 1) != msr_dr) { + cpu_interrupt_exittb(cs); + } + if ((env->mmu_model & POWERPC_MMU_BOOKE) && + ((value >> MSR_GS) & 1) != msr_gs) { + cpu_interrupt_exittb(cs); + } + if (unlikely((env->flags & POWERPC_FLAG_TGPR) && + ((value ^ env->msr) & (1 << MSR_TGPR)))) { + /* Swap temporary saved registers with GPRs */ + hreg_swap_gpr_tgpr(env); + } + if (unlikely((value >> MSR_EP) & 1) != msr_ep) { + /* Change the exception prefix on PowerPC 601 */ + env->excp_prefix = ((value >> MSR_EP) & 1) * 0xFFF00000; + } + /* + * If PR=1 then EE, IR and DR must be 1 + * + * Note: We only enforce this on 64-bit server processors. + * It appears that: + * - 32-bit implementations supports PR=1 and EE/DR/IR=0 and MacOS + * exploits it. + * - 64-bit embedded implementations do not need any operation to be + * performed when PR is set. + */ + if (is_book3s_arch2x(env) && ((value >> MSR_PR) & 1)) { + value |= (1 << MSR_EE) | (1 << MSR_DR) | (1 << MSR_IR); + } +#endif + env->msr = value; + hreg_compute_hflags(env); +#if !defined(CONFIG_USER_ONLY) + if (unlikely(msr_pow == 1)) { + if (!env->pending_interrupts && (*env->check_pow)(env)) { + cs->halted = 1; + excp = EXCP_HALTED; + } + } +#endif + + return excp; +} + +#ifndef CONFIG_USER_ONLY +void check_tlb_flush(CPUPPCState *env, bool global) +{ + CPUState *cs = env_cpu(env); + + /* Handle global flushes first */ + if (global && (env->tlb_need_flush & TLB_NEED_GLOBAL_FLUSH)) { + env->tlb_need_flush &= ~TLB_NEED_GLOBAL_FLUSH; + env->tlb_need_flush &= ~TLB_NEED_LOCAL_FLUSH; + tlb_flush_all_cpus_synced(cs); + return; + } + + /* Then handle local ones */ + if (env->tlb_need_flush & TLB_NEED_LOCAL_FLUSH) { + env->tlb_need_flush &= ~TLB_NEED_LOCAL_FLUSH; + tlb_flush(cs); + } +} +#endif diff --git a/target/ppc/helper_regs.h b/target/ppc/helper_regs.h index efcc903427..4148a442b3 100644 --- a/target/ppc/helper_regs.h +++ b/target/ppc/helper_regs.h @@ -20,184 +20,16 @@ #ifndef HELPER_REGS_H #define HELPER_REGS_H -#include "qemu/main-loop.h" -#include "exec/exec-all.h" -#include "sysemu/kvm.h" +void hreg_swap_gpr_tgpr(CPUPPCState *env); +void hreg_compute_mem_idx(CPUPPCState *env); +void hreg_compute_hflags(CPUPPCState *env); +void cpu_interrupt_exittb(CPUState *cs); +int hreg_store_msr(CPUPPCState *env, target_ulong value, int alter_hv); -/* Swap temporary saved registers with GPRs */ -static inline void hreg_swap_gpr_tgpr(CPUPPCState *env) -{ - target_ulong tmp; - - tmp = env->gpr[0]; - env->gpr[0] = env->tgpr[0]; - env->tgpr[0] = tmp; - tmp = env->gpr[1]; - env->gpr[1] = env->tgpr[1]; - env->tgpr[1] = tmp; - tmp = env->gpr[2]; - env->gpr[2] = env->tgpr[2]; - env->tgpr[2] = tmp; - tmp = env->gpr[3]; - env->gpr[3] = env->tgpr[3]; - env->tgpr[3] = tmp; -} - -static inline void hreg_compute_mem_idx(CPUPPCState *env) -{ - /* - * This is our encoding for server processors. The architecture - * specifies that there is no such thing as userspace with - * translation off, however it appears that MacOS does it and some - * 32-bit CPUs support it. Weird... - * - * 0 = Guest User space virtual mode - * 1 = Guest Kernel space virtual mode - * 2 = Guest User space real mode - * 3 = Guest Kernel space real mode - * 4 = HV User space virtual mode - * 5 = HV Kernel space virtual mode - * 6 = HV User space real mode - * 7 = HV Kernel space real mode - * - * For BookE, we need 8 MMU modes as follow: - * - * 0 = AS 0 HV User space - * 1 = AS 0 HV Kernel space - * 2 = AS 1 HV User space - * 3 = AS 1 HV Kernel space - * 4 = AS 0 Guest User space - * 5 = AS 0 Guest Kernel space - * 6 = AS 1 Guest User space - * 7 = AS 1 Guest Kernel space - */ - if (env->mmu_model & POWERPC_MMU_BOOKE) { - env->immu_idx = env->dmmu_idx = msr_pr ? 0 : 1; - env->immu_idx += msr_is ? 2 : 0; - env->dmmu_idx += msr_ds ? 2 : 0; - env->immu_idx += msr_gs ? 4 : 0; - env->dmmu_idx += msr_gs ? 4 : 0; - } else { - env->immu_idx = env->dmmu_idx = msr_pr ? 0 : 1; - env->immu_idx += msr_ir ? 0 : 2; - env->dmmu_idx += msr_dr ? 0 : 2; - env->immu_idx += msr_hv ? 4 : 0; - env->dmmu_idx += msr_hv ? 4 : 0; - } -} - -static inline void hreg_compute_hflags(CPUPPCState *env) -{ - target_ulong hflags_mask; - - /* We 'forget' FE0 & FE1: we'll never generate imprecise exceptions */ - hflags_mask = (1 << MSR_VR) | (1 << MSR_AP) | (1 << MSR_SA) | - (1 << MSR_PR) | (1 << MSR_FP) | (1 << MSR_SE) | (1 << MSR_BE) | - (1 << MSR_LE) | (1 << MSR_VSX) | (1 << MSR_IR) | (1 << MSR_DR); - hflags_mask |= (1ULL << MSR_CM) | (1ULL << MSR_SF) | MSR_HVB; - hreg_compute_mem_idx(env); - env->hflags = env->msr & hflags_mask; - /* Merge with hflags coming from other registers */ - env->hflags |= env->hflags_nmsr; -} - -static inline void cpu_interrupt_exittb(CPUState *cs) -{ - if (!kvm_enabled()) { - return; - } - - if (!qemu_mutex_iothread_locked()) { - qemu_mutex_lock_iothread(); - cpu_interrupt(cs, CPU_INTERRUPT_EXITTB); - qemu_mutex_unlock_iothread(); - } else { - cpu_interrupt(cs, CPU_INTERRUPT_EXITTB); - } -} - -static inline int hreg_store_msr(CPUPPCState *env, target_ulong value, - int alter_hv) -{ - int excp; -#if !defined(CONFIG_USER_ONLY) - CPUState *cs = env_cpu(env); -#endif - - excp = 0; - value &= env->msr_mask; -#if !defined(CONFIG_USER_ONLY) - /* Neither mtmsr nor guest state can alter HV */ - if (!alter_hv || !(env->msr & MSR_HVB)) { - value &= ~MSR_HVB; - value |= env->msr & MSR_HVB; - } - if (((value >> MSR_IR) & 1) != msr_ir || - ((value >> MSR_DR) & 1) != msr_dr) { - cpu_interrupt_exittb(cs); - } - if ((env->mmu_model & POWERPC_MMU_BOOKE) && - ((value >> MSR_GS) & 1) != msr_gs) { - cpu_interrupt_exittb(cs); - } - if (unlikely((env->flags & POWERPC_FLAG_TGPR) && - ((value ^ env->msr) & (1 << MSR_TGPR)))) { - /* Swap temporary saved registers with GPRs */ - hreg_swap_gpr_tgpr(env); - } - if (unlikely((value >> MSR_EP) & 1) != msr_ep) { - /* Change the exception prefix on PowerPC 601 */ - env->excp_prefix = ((value >> MSR_EP) & 1) * 0xFFF00000; - } - /* - * If PR=1 then EE, IR and DR must be 1 - * - * Note: We only enforce this on 64-bit server processors. - * It appears that: - * - 32-bit implementations supports PR=1 and EE/DR/IR=0 and MacOS - * exploits it. - * - 64-bit embedded implementations do not need any operation to be - * performed when PR is set. - */ - if (is_book3s_arch2x(env) && ((value >> MSR_PR) & 1)) { - value |= (1 << MSR_EE) | (1 << MSR_DR) | (1 << MSR_IR); - } -#endif - env->msr = value; - hreg_compute_hflags(env); -#if !defined(CONFIG_USER_ONLY) - if (unlikely(msr_pow == 1)) { - if (!env->pending_interrupts && (*env->check_pow)(env)) { - cs->halted = 1; - excp = EXCP_HALTED; - } - } -#endif - - return excp; -} - -#if !defined(CONFIG_USER_ONLY) -static inline void check_tlb_flush(CPUPPCState *env, bool global) -{ - CPUState *cs = env_cpu(env); - - /* Handle global flushes first */ - if (global && (env->tlb_need_flush & TLB_NEED_GLOBAL_FLUSH)) { - env->tlb_need_flush &= ~TLB_NEED_GLOBAL_FLUSH; - env->tlb_need_flush &= ~TLB_NEED_LOCAL_FLUSH; - tlb_flush_all_cpus_synced(cs); - return; - } - - /* Then handle local ones */ - if (env->tlb_need_flush & TLB_NEED_LOCAL_FLUSH) { - env->tlb_need_flush &= ~TLB_NEED_LOCAL_FLUSH; - tlb_flush(cs); - } -} -#else +#ifdef CONFIG_USER_ONLY static inline void check_tlb_flush(CPUPPCState *env, bool global) { } +#else +void check_tlb_flush(CPUPPCState *env, bool global); #endif #endif /* HELPER_REGS_H */ diff --git a/target/ppc/int_helper.c b/target/ppc/int_helper.c index 429de28494..a44c2d90ea 100644 --- a/target/ppc/int_helper.c +++ b/target/ppc/int_helper.c @@ -22,6 +22,7 @@ #include "internal.h" #include "qemu/host-utils.h" #include "qemu/main-loop.h" +#include "qemu/log.h" #include "exec/helper-proto.h" #include "crypto/aes.h" #include "fpu/softfloat.h" diff --git a/target/ppc/meson.build b/target/ppc/meson.build index bbfef90e08..4079d01ee3 100644 --- a/target/ppc/meson.build +++ b/target/ppc/meson.build @@ -6,6 +6,7 @@ ppc_ss.add(files( 'excp_helper.c', 'fpu_helper.c', 'gdbstub.c', + 'helper_regs.c', 'int_helper.c', 'mem_helper.c', 'misc_helper.c', From patchwork Tue May 4 05:52:29 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: David Gibson X-Patchwork-Id: 12237415 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-16.6 required=3.0 tests=BAYES_00,DKIM_INVALID, DKIM_SIGNED,HEADER_FROM_DIFFERENT_DOMAINS,INCLUDES_CR_TRAILER,INCLUDES_PATCH, MAILING_LIST_MULTI,SPF_HELO_NONE,SPF_PASS,USER_AGENT_GIT autolearn=ham autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id 9E2B3C433ED for ; Tue, 4 May 2021 05:56:10 +0000 (UTC) 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 mail.kernel.org (Postfix) with ESMTPS id 414A761166 for ; Tue, 4 May 2021 05:56:10 +0000 (UTC) DMARC-Filter: OpenDMARC Filter v1.3.2 mail.kernel.org 414A761166 Authentication-Results: mail.kernel.org; dmarc=none (p=none dis=none) header.from=gibson.dropbear.id.au Authentication-Results: mail.kernel.org; spf=pass smtp.mailfrom=qemu-devel-bounces+qemu-devel=archiver.kernel.org@nongnu.org Received: from localhost ([::1]:50304 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1ldo2T-0007Dd-78 for qemu-devel@archiver.kernel.org; Tue, 04 May 2021 01:56:09 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]:60340) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1ldnzp-00057k-EN; Tue, 04 May 2021 01:53:25 -0400 Received: from bilbo.ozlabs.org ([2401:3900:2:1::2]:38887 helo=ozlabs.org) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1ldnzn-0004a2-J6; Tue, 04 May 2021 01:53:25 -0400 Received: by ozlabs.org (Postfix, from userid 1007) id 4FZ8CK01nQz9sW1; Tue, 4 May 2021 15:53:16 +1000 (AEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=gibson.dropbear.id.au; s=201602; t=1620107597; bh=Twg3ixSosYubY2S6kfpWfV4IThjGfpdxnG0ofrjJl5o=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=Wey+sXsWMpXtdyngiL5nCJRjXigGzkg59MtvR79TfxhMUiYwngHSPunLEMkLBc9RY 477Q+iSWgE7KZuDOU/XPjtlKvmI4YvdfGM6+/d4UOQqI9M1VcbTbKzHYHM6LFzg+H5 W173M41ZUFjqCgD3iJPgsoxg6LdNsKjMnYFQLLAo= From: David Gibson To: peter.maydell@linaro.org, groug@kaod.org Subject: [PULL 03/46] target/ppc: Move 601 hflags adjustment to hreg_compute_hflags Date: Tue, 4 May 2021 15:52:29 +1000 Message-Id: <20210504055312.306823-4-david@gibson.dropbear.id.au> X-Mailer: git-send-email 2.31.1 In-Reply-To: <20210504055312.306823-1-david@gibson.dropbear.id.au> References: <20210504055312.306823-1-david@gibson.dropbear.id.au> MIME-Version: 1.0 Received-SPF: pass client-ip=2401:3900:2:1::2; envelope-from=dgibson@ozlabs.org; helo=ozlabs.org X-Spam_score_int: -17 X-Spam_score: -1.8 X-Spam_bar: - X-Spam_report: (-1.8 / 5.0 requ) BAYES_00=-1.9, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_AU=-0.1, HEADER_FROM_DIFFERENT_DOMAINS=0.25, SPF_HELO_PASS=-0.001, SPF_PASS=-0.001 autolearn=no autolearn_force=no X-Spam_action: no action X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: Richard Henderson , David Gibson , qemu-ppc@nongnu.org, qemu-devel@nongnu.org, =?utf-8?q?C=C3=A9dric_Le_Goater?= Errors-To: qemu-devel-bounces+qemu-devel=archiver.kernel.org@nongnu.org Sender: "Qemu-devel" From: Richard Henderson Keep all hflags computation in one place, as this will be especially important later. Introduce a new POWERPC_FLAG_HID0_LE bit to indicate when LE should be taken from HID0. This appears to be set if and only if POWERPC_FLAG_RTC_CLK is set, but we're not short of bits and having both names will avoid confusion. Note that this was the only user of hflags_nmsr, so we can perform a straight assignment rather than mask and set. Signed-off-by: Richard Henderson Message-Id: <20210315184615.1985590-3-richard.henderson@linaro.org> Reviewed-by: Cédric Le Goater Signed-off-by: David Gibson --- target/ppc/cpu.h | 2 ++ target/ppc/helper_regs.c | 13 +++++++++++-- target/ppc/misc_helper.c | 8 +++----- target/ppc/translate_init.c.inc | 4 ++-- 4 files changed, 18 insertions(+), 9 deletions(-) diff --git a/target/ppc/cpu.h b/target/ppc/cpu.h index e73416da68..061d2eed1b 100644 --- a/target/ppc/cpu.h +++ b/target/ppc/cpu.h @@ -581,6 +581,8 @@ enum { POWERPC_FLAG_TM = 0x00100000, /* Has SCV (ISA 3.00) */ POWERPC_FLAG_SCV = 0x00200000, + /* Has HID0 for LE bit (601) */ + POWERPC_FLAG_HID0_LE = 0x00400000, }; /*****************************************************************************/ diff --git a/target/ppc/helper_regs.c b/target/ppc/helper_regs.c index 5e18232b84..95b9aca61f 100644 --- a/target/ppc/helper_regs.c +++ b/target/ppc/helper_regs.c @@ -96,8 +96,17 @@ void hreg_compute_hflags(CPUPPCState *env) hflags_mask |= (1ULL << MSR_CM) | (1ULL << MSR_SF) | MSR_HVB; hreg_compute_mem_idx(env); env->hflags = env->msr & hflags_mask; - /* Merge with hflags coming from other registers */ - env->hflags |= env->hflags_nmsr; + + if (env->flags & POWERPC_FLAG_HID0_LE) { + /* + * Note that MSR_LE is not set in env->msr_mask for this cpu, + * and so will never be set in msr or hflags at this point. + */ + uint32_t le = extract32(env->spr[SPR_HID0], 3, 1); + env->hflags |= le << MSR_LE; + /* Retain for backward compatibility with migration. */ + env->hflags_nmsr = le << MSR_LE; + } } void cpu_interrupt_exittb(CPUState *cs) diff --git a/target/ppc/misc_helper.c b/target/ppc/misc_helper.c index 5d6e0de396..63e3147eb4 100644 --- a/target/ppc/misc_helper.c +++ b/target/ppc/misc_helper.c @@ -194,16 +194,14 @@ void helper_store_hid0_601(CPUPPCState *env, target_ulong val) target_ulong hid0; hid0 = env->spr[SPR_HID0]; + env->spr[SPR_HID0] = (uint32_t)val; + if ((val ^ hid0) & 0x00000008) { /* Change current endianness */ - env->hflags &= ~(1 << MSR_LE); - env->hflags_nmsr &= ~(1 << MSR_LE); - env->hflags_nmsr |= (1 << MSR_LE) & (((val >> 3) & 1) << MSR_LE); - env->hflags |= env->hflags_nmsr; + hreg_compute_hflags(env); qemu_log("%s: set endianness to %c => " TARGET_FMT_lx "\n", __func__, val & 0x8 ? 'l' : 'b', env->hflags); } - env->spr[SPR_HID0] = (uint32_t)val; } void helper_store_403_pbr(CPUPPCState *env, uint32_t num, target_ulong value) diff --git a/target/ppc/translate_init.c.inc b/target/ppc/translate_init.c.inc index c03a7c4f52..049d76cfd1 100644 --- a/target/ppc/translate_init.c.inc +++ b/target/ppc/translate_init.c.inc @@ -5441,7 +5441,7 @@ POWERPC_FAMILY(601)(ObjectClass *oc, void *data) pcc->excp_model = POWERPC_EXCP_601; pcc->bus_model = PPC_FLAGS_INPUT_6xx; pcc->bfd_mach = bfd_mach_ppc_601; - pcc->flags = POWERPC_FLAG_SE | POWERPC_FLAG_RTC_CLK; + pcc->flags = POWERPC_FLAG_SE | POWERPC_FLAG_RTC_CLK | POWERPC_FLAG_HID0_LE; } #define POWERPC_MSRR_601v (0x0000000000001040ULL) @@ -5485,7 +5485,7 @@ POWERPC_FAMILY(601v)(ObjectClass *oc, void *data) #endif pcc->bus_model = PPC_FLAGS_INPUT_6xx; pcc->bfd_mach = bfd_mach_ppc_601; - pcc->flags = POWERPC_FLAG_SE | POWERPC_FLAG_RTC_CLK; + pcc->flags = POWERPC_FLAG_SE | POWERPC_FLAG_RTC_CLK | POWERPC_FLAG_HID0_LE; } static void init_proc_602(CPUPPCState *env) From patchwork Tue May 4 05:52:30 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: David Gibson X-Patchwork-Id: 12237417 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-16.6 required=3.0 tests=BAYES_00,DKIM_INVALID, DKIM_SIGNED,HEADER_FROM_DIFFERENT_DOMAINS,INCLUDES_CR_TRAILER,INCLUDES_PATCH, MAILING_LIST_MULTI,SPF_HELO_NONE,SPF_PASS,USER_AGENT_GIT autolearn=ham autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id 02BFEC433B4 for ; Tue, 4 May 2021 05:56:34 +0000 (UTC) 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 mail.kernel.org (Postfix) with ESMTPS id 9929060C3D for ; Tue, 4 May 2021 05:56:33 +0000 (UTC) DMARC-Filter: OpenDMARC Filter v1.3.2 mail.kernel.org 9929060C3D Authentication-Results: mail.kernel.org; dmarc=none (p=none dis=none) header.from=gibson.dropbear.id.au Authentication-Results: mail.kernel.org; spf=pass smtp.mailfrom=qemu-devel-bounces+qemu-devel=archiver.kernel.org@nongnu.org Received: from localhost ([::1]:51080 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1ldo2q-0007YU-MJ for qemu-devel@archiver.kernel.org; Tue, 04 May 2021 01:56:32 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]:60362) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1ldnzq-00057z-Jw; Tue, 04 May 2021 01:53:26 -0400 Received: from bilbo.ozlabs.org ([2401:3900:2:1::2]:49311 helo=ozlabs.org) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1ldnzn-0004a3-Jh; Tue, 04 May 2021 01:53:26 -0400 Received: by ozlabs.org (Postfix, from userid 1007) id 4FZ8CK0MzZz9sWB; Tue, 4 May 2021 15:53:16 +1000 (AEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=gibson.dropbear.id.au; s=201602; t=1620107597; bh=vah07RKjf90sFxm6WFtEddSHyy3538FGdU5PnH34764=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=gWvivPjDv4vcoNWkNG9bunqtf75/jkyu56D4FZ95GKQol7cKzrVjZVwfpz301Uhda GEs4QPmvEq49yfBbPB3uFlhKdAcmKINiKA+wJJenm+dvkLJICSZdiTkGCA6DgwzMos NtHEsbM6Svoy5E4OqGWbqkuJioBCc8w5LLVfvntE= From: David Gibson To: peter.maydell@linaro.org, groug@kaod.org Subject: [PULL 04/46] target/ppc: Properly sync cpu state with new msr in cpu_load_old Date: Tue, 4 May 2021 15:52:30 +1000 Message-Id: <20210504055312.306823-5-david@gibson.dropbear.id.au> X-Mailer: git-send-email 2.31.1 In-Reply-To: <20210504055312.306823-1-david@gibson.dropbear.id.au> References: <20210504055312.306823-1-david@gibson.dropbear.id.au> MIME-Version: 1.0 Received-SPF: pass client-ip=2401:3900:2:1::2; envelope-from=dgibson@ozlabs.org; helo=ozlabs.org X-Spam_score_int: -17 X-Spam_score: -1.8 X-Spam_bar: - X-Spam_report: (-1.8 / 5.0 requ) BAYES_00=-1.9, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_AU=-0.1, HEADER_FROM_DIFFERENT_DOMAINS=0.25, SPF_HELO_PASS=-0.001, SPF_PASS=-0.001 autolearn=no autolearn_force=no X-Spam_action: no action X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: Richard Henderson , David Gibson , qemu-ppc@nongnu.org, qemu-devel@nongnu.org, =?utf-8?q?C=C3=A9dric_Le_Goater?= Errors-To: qemu-devel-bounces+qemu-devel=archiver.kernel.org@nongnu.org Sender: "Qemu-devel" From: Richard Henderson Match cpu_post_load in using ppc_store_msr to set all of the cpu state implied by the value of msr. Do not restore hflags or hflags_nmsr, as we recompute them in ppc_store_msr. Signed-off-by: Richard Henderson Message-Id: <20210315184615.1985590-4-richard.henderson@linaro.org> Reviewed-by: Cédric Le Goater Signed-off-by: David Gibson --- target/ppc/machine.c | 13 +++++++++++-- 1 file changed, 11 insertions(+), 2 deletions(-) diff --git a/target/ppc/machine.c b/target/ppc/machine.c index 283db1d28a..87d7bffb86 100644 --- a/target/ppc/machine.c +++ b/target/ppc/machine.c @@ -21,6 +21,7 @@ static int cpu_load_old(QEMUFile *f, void *opaque, int version_id) int32_t slb_nr; #endif target_ulong xer; + target_ulong msr; for (i = 0; i < 32; i++) { qemu_get_betls(f, &env->gpr[i]); @@ -111,11 +112,19 @@ static int cpu_load_old(QEMUFile *f, void *opaque, int version_id) qemu_get_betls(f, &env->ivpr_mask); qemu_get_betls(f, &env->hreset_vector); qemu_get_betls(f, &env->nip); - qemu_get_betls(f, &env->hflags); - qemu_get_betls(f, &env->hflags_nmsr); + qemu_get_sbetl(f); /* Discard unused hflags */ + qemu_get_sbetl(f); /* Discard unused hflags_nmsr */ qemu_get_sbe32(f); /* Discard unused mmu_idx */ qemu_get_sbe32(f); /* Discard unused power_mode */ + /* + * Invalidate all supported msr bits except MSR_TGPR/MSR_HVB + * before restoring. Note that this recomputes hflags and mem_idx. + */ + msr = env->msr; + env->msr ^= env->msr_mask & ~((1ULL << MSR_TGPR) | MSR_HVB); + ppc_store_msr(env, msr); + /* Recompute mmu indices */ hreg_compute_mem_idx(env); From patchwork Tue May 4 05:52:31 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: David Gibson X-Patchwork-Id: 12237437 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-16.6 required=3.0 tests=BAYES_00,DKIM_INVALID, DKIM_SIGNED,HEADER_FROM_DIFFERENT_DOMAINS,INCLUDES_CR_TRAILER,INCLUDES_PATCH, MAILING_LIST_MULTI,SPF_HELO_NONE,SPF_PASS,USER_AGENT_GIT autolearn=ham autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id C11E6C433B4 for ; Tue, 4 May 2021 06:09:50 +0000 (UTC) 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 mail.kernel.org (Postfix) with ESMTPS id 3A46B611AE for ; Tue, 4 May 2021 06:09:50 +0000 (UTC) DMARC-Filter: OpenDMARC Filter v1.3.2 mail.kernel.org 3A46B611AE Authentication-Results: mail.kernel.org; dmarc=none (p=none dis=none) header.from=gibson.dropbear.id.au Authentication-Results: mail.kernel.org; spf=pass smtp.mailfrom=qemu-devel-bounces+qemu-devel=archiver.kernel.org@nongnu.org Received: from localhost ([::1]:48616 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1ldoFh-00028c-2O for qemu-devel@archiver.kernel.org; Tue, 04 May 2021 02:09:49 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]:60402) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1ldnzu-0005Az-Jq; Tue, 04 May 2021 01:53:30 -0400 Received: from ozlabs.org ([203.11.71.1]:43605) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1ldnzr-0004fR-Sg; Tue, 04 May 2021 01:53:29 -0400 Received: by ozlabs.org (Postfix, from userid 1007) id 4FZ8CK1C7zz9sWM; Tue, 4 May 2021 15:53:17 +1000 (AEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=gibson.dropbear.id.au; s=201602; t=1620107597; bh=f78B5YbYtAyXCQJDJDaRmnQ7EsORe8dS0KxqvyuLBfg=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=R3Ifb37U8NK2cclA6WdrEjotocnKgNAKpykhY8qla+Gf47AQfzZZrpjHDTDAuijtK kvx2aKZcENs49C8oUJKKNh5Va35UXEpiki2O20ywnDnBULPZEwIkrE5Wc3jpHmO/xA navL+yZGTu1zhbOQQFjkUG2nlowxXDaX2mfftOUs= From: David Gibson To: peter.maydell@linaro.org, groug@kaod.org Subject: [PULL 05/46] target/ppc: Do not call hreg_compute_mem_idx after ppc_store_msr Date: Tue, 4 May 2021 15:52:31 +1000 Message-Id: <20210504055312.306823-6-david@gibson.dropbear.id.au> X-Mailer: git-send-email 2.31.1 In-Reply-To: <20210504055312.306823-1-david@gibson.dropbear.id.au> References: <20210504055312.306823-1-david@gibson.dropbear.id.au> MIME-Version: 1.0 Received-SPF: pass client-ip=203.11.71.1; envelope-from=dgibson@ozlabs.org; helo=ozlabs.org X-Spam_score_int: -17 X-Spam_score: -1.8 X-Spam_bar: - X-Spam_report: (-1.8 / 5.0 requ) BAYES_00=-1.9, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_AU=-0.1, HEADER_FROM_DIFFERENT_DOMAINS=0.25, SPF_HELO_PASS=-0.001, SPF_PASS=-0.001 autolearn=no autolearn_force=no X-Spam_action: no action X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: Richard Henderson , David Gibson , qemu-ppc@nongnu.org, qemu-devel@nongnu.org, =?utf-8?q?C=C3=A9dric_Le_Goater?= Errors-To: qemu-devel-bounces+qemu-devel=archiver.kernel.org@nongnu.org Sender: "Qemu-devel" From: Richard Henderson In ppc_store_msr we call hreg_compute_hflags, which itself calls hreg_compute_mem_idx. Rely on ppc_store_msr to update everything required by the msr update. Signed-off-by: Richard Henderson Message-Id: <20210315184615.1985590-5-richard.henderson@linaro.org> Reviewed-by: Cédric Le Goater Signed-off-by: David Gibson --- target/ppc/machine.c | 7 +------ 1 file changed, 1 insertion(+), 6 deletions(-) diff --git a/target/ppc/machine.c b/target/ppc/machine.c index 87d7bffb86..f6eeda9642 100644 --- a/target/ppc/machine.c +++ b/target/ppc/machine.c @@ -125,9 +125,6 @@ static int cpu_load_old(QEMUFile *f, void *opaque, int version_id) env->msr ^= env->msr_mask & ~((1ULL << MSR_TGPR) | MSR_HVB); ppc_store_msr(env, msr); - /* Recompute mmu indices */ - hreg_compute_mem_idx(env); - return 0; } @@ -418,14 +415,12 @@ static int cpu_post_load(void *opaque, int version_id) /* * Invalidate all supported msr bits except MSR_TGPR/MSR_HVB - * before restoring + * before restoring. Note that this recomputes hflags and mem_idx. */ msr = env->msr; env->msr ^= env->msr_mask & ~((1ULL << MSR_TGPR) | MSR_HVB); ppc_store_msr(env, msr); - hreg_compute_mem_idx(env); - return 0; } From patchwork Tue May 4 05:52:32 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: David Gibson X-Patchwork-Id: 12237425 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-16.6 required=3.0 tests=BAYES_00,DKIM_INVALID, DKIM_SIGNED,HEADER_FROM_DIFFERENT_DOMAINS,INCLUDES_CR_TRAILER,INCLUDES_PATCH, MAILING_LIST_MULTI,SPF_HELO_NONE,SPF_PASS,USER_AGENT_GIT autolearn=ham autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id 42CE2C433B4 for ; Tue, 4 May 2021 06:00:58 +0000 (UTC) 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 mail.kernel.org (Postfix) with ESMTPS id CE40261166 for ; Tue, 4 May 2021 06:00:57 +0000 (UTC) DMARC-Filter: OpenDMARC Filter v1.3.2 mail.kernel.org CE40261166 Authentication-Results: mail.kernel.org; dmarc=none (p=none dis=none) header.from=gibson.dropbear.id.au Authentication-Results: mail.kernel.org; spf=pass smtp.mailfrom=qemu-devel-bounces+qemu-devel=archiver.kernel.org@nongnu.org Received: from localhost ([::1]:60642 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1ldo76-0003Cj-Iq for qemu-devel@archiver.kernel.org; Tue, 04 May 2021 02:00:56 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]:60404) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1ldnzu-0005B7-LC; Tue, 04 May 2021 01:53:32 -0400 Received: from ozlabs.org ([203.11.71.1]:51761) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1ldnzs-0004fS-0V; Tue, 04 May 2021 01:53:29 -0400 Received: by ozlabs.org (Postfix, from userid 1007) id 4FZ8CK0rvwz9sWC; Tue, 4 May 2021 15:53:17 +1000 (AEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=gibson.dropbear.id.au; s=201602; t=1620107597; bh=QN9OGBLE2HmT8V/0wRszHECV89IjJIxItnBzN/dvEDo=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=I7leRdoPnCOG4Zb4KWK9sKd64s3IYRQklnOsX8pvnvyReir5IXHLmrGva9kRiVduk JLV40zniKYAI5iE2NsSgHaTSvVZKj3NWdjczPcfDgD8oKzRFpxVST5VTmqgby/XRrs 3kMo+tTLJgRwwS2illfeOfiPt2Rmw3UmrpQV1+D8= From: David Gibson To: peter.maydell@linaro.org, groug@kaod.org Subject: [PULL 06/46] target/ppc: Retain hflags_nmsr only for migration Date: Tue, 4 May 2021 15:52:32 +1000 Message-Id: <20210504055312.306823-7-david@gibson.dropbear.id.au> X-Mailer: git-send-email 2.31.1 In-Reply-To: <20210504055312.306823-1-david@gibson.dropbear.id.au> References: <20210504055312.306823-1-david@gibson.dropbear.id.au> MIME-Version: 1.0 Received-SPF: pass client-ip=203.11.71.1; envelope-from=dgibson@ozlabs.org; helo=ozlabs.org X-Spam_score_int: -17 X-Spam_score: -1.8 X-Spam_bar: - X-Spam_report: (-1.8 / 5.0 requ) BAYES_00=-1.9, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_AU=-0.1, HEADER_FROM_DIFFERENT_DOMAINS=0.25, SPF_HELO_PASS=-0.001, SPF_PASS=-0.001 autolearn=no autolearn_force=no X-Spam_action: no action X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: Richard Henderson , David Gibson , qemu-ppc@nongnu.org, qemu-devel@nongnu.org, =?utf-8?q?C=C3=A9dric_Le_Goater?= Errors-To: qemu-devel-bounces+qemu-devel=archiver.kernel.org@nongnu.org Sender: "Qemu-devel" From: Richard Henderson We have eliminated all normal uses of hflags_nmsr. We need not even compute it except when we want to migrate. Rename the field to emphasize this. Remove the fixme comment for migrating access_type. This value is only ever used with the current executing instruction, and is never live when the cpu is halted for migration. Signed-off-by: Richard Henderson Message-Id: <20210315184615.1985590-6-richard.henderson@linaro.org> Reviewed-by: Cédric Le Goater Signed-off-by: David Gibson --- target/ppc/cpu.h | 4 ++-- target/ppc/helper_regs.c | 2 -- target/ppc/machine.c | 9 ++++++--- 3 files changed, 8 insertions(+), 7 deletions(-) diff --git a/target/ppc/cpu.h b/target/ppc/cpu.h index 061d2eed1b..79c4033a42 100644 --- a/target/ppc/cpu.h +++ b/target/ppc/cpu.h @@ -1105,8 +1105,8 @@ struct CPUPPCState { #endif /* These resources are used only in QEMU core */ - target_ulong hflags; /* hflags is MSR & HFLAGS_MASK */ - target_ulong hflags_nmsr; /* specific hflags, not coming from MSR */ + target_ulong hflags; + target_ulong hflags_compat_nmsr; /* for migration compatibility */ int immu_idx; /* precomputed MMU index to speed up insn accesses */ int dmmu_idx; /* precomputed MMU index to speed up data accesses */ diff --git a/target/ppc/helper_regs.c b/target/ppc/helper_regs.c index 95b9aca61f..a87e354ca2 100644 --- a/target/ppc/helper_regs.c +++ b/target/ppc/helper_regs.c @@ -104,8 +104,6 @@ void hreg_compute_hflags(CPUPPCState *env) */ uint32_t le = extract32(env->spr[SPR_HID0], 3, 1); env->hflags |= le << MSR_LE; - /* Retain for backward compatibility with migration. */ - env->hflags_nmsr = le << MSR_LE; } } diff --git a/target/ppc/machine.c b/target/ppc/machine.c index f6eeda9642..1f7a353c78 100644 --- a/target/ppc/machine.c +++ b/target/ppc/machine.c @@ -310,6 +310,10 @@ static int cpu_pre_save(void *opaque) } } + /* Retain migration compatibility for pre 6.0 for 601 machines. */ + env->hflags_compat_nmsr = (env->flags & POWERPC_FLAG_HID0_LE + ? env->hflags & MSR_LE : 0); + return 0; } @@ -829,9 +833,8 @@ const VMStateDescription vmstate_ppc_cpu = { /* Supervisor mode architected state */ VMSTATE_UINTTL(env.msr, PowerPCCPU), - /* Internal state */ - VMSTATE_UINTTL(env.hflags_nmsr, PowerPCCPU), - /* FIXME: access_type? */ + /* Backward compatible internal state */ + VMSTATE_UINTTL(env.hflags_compat_nmsr, PowerPCCPU), /* Sanity checking */ VMSTATE_UINTTL_TEST(mig_msr_mask, PowerPCCPU, cpu_pre_2_8_migration), From patchwork Tue May 4 05:52:33 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: David Gibson X-Patchwork-Id: 12237419 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-16.6 required=3.0 tests=BAYES_00,DKIM_INVALID, DKIM_SIGNED,HEADER_FROM_DIFFERENT_DOMAINS,INCLUDES_CR_TRAILER,INCLUDES_PATCH, MAILING_LIST_MULTI,SPF_HELO_NONE,SPF_PASS,USER_AGENT_GIT autolearn=ham autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id D38CFC433B4 for ; Tue, 4 May 2021 05:58:23 +0000 (UTC) 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 mail.kernel.org (Postfix) with ESMTPS id 787D161166 for ; Tue, 4 May 2021 05:58:23 +0000 (UTC) DMARC-Filter: OpenDMARC Filter v1.3.2 mail.kernel.org 787D161166 Authentication-Results: mail.kernel.org; dmarc=none (p=none dis=none) header.from=gibson.dropbear.id.au Authentication-Results: mail.kernel.org; spf=pass smtp.mailfrom=qemu-devel-bounces+qemu-devel=archiver.kernel.org@nongnu.org Received: from localhost ([::1]:55120 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1ldo4c-0000tv-Dt for qemu-devel@archiver.kernel.org; Tue, 04 May 2021 01:58:22 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]:60426) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1ldnzw-0005DO-RV; Tue, 04 May 2021 01:53:34 -0400 Received: from ozlabs.org ([203.11.71.1]:46053) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1ldnzs-0004fV-4L; Tue, 04 May 2021 01:53:30 -0400 Received: by ozlabs.org (Postfix, from userid 1007) id 4FZ8CK1xKvz9sWW; Tue, 4 May 2021 15:53:17 +1000 (AEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=gibson.dropbear.id.au; s=201602; t=1620107597; bh=O6avjl1hbr3lZtelooLHSiYSY2uVa/zlg2sxWvyezxM=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=He+sCNp9Hl2ol6wKSm+dt/YzhwrYaEQANl4sp9wt0kPVIa2zoCAVLW/K/+CUiyCs7 fsetEw5M+B0Ewk2ypVFZ1qc4jjiR1LWwYj4VKpFdvHeJ3XS0Ty6orUlB7ISFSQ3TZo KHm08wSDDe83MVnoRczgsw7+Cgea5Lgh1iECDXzs= From: David Gibson To: peter.maydell@linaro.org, groug@kaod.org Subject: [PULL 07/46] target/ppc: Fix comment for MSR_FE{0,1} Date: Tue, 4 May 2021 15:52:33 +1000 Message-Id: <20210504055312.306823-8-david@gibson.dropbear.id.au> X-Mailer: git-send-email 2.31.1 In-Reply-To: <20210504055312.306823-1-david@gibson.dropbear.id.au> References: <20210504055312.306823-1-david@gibson.dropbear.id.au> MIME-Version: 1.0 Received-SPF: pass client-ip=203.11.71.1; envelope-from=dgibson@ozlabs.org; helo=ozlabs.org X-Spam_score_int: -17 X-Spam_score: -1.8 X-Spam_bar: - X-Spam_report: (-1.8 / 5.0 requ) BAYES_00=-1.9, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_AU=-0.1, HEADER_FROM_DIFFERENT_DOMAINS=0.25, SPF_HELO_PASS=-0.001, SPF_PASS=-0.001 autolearn=no autolearn_force=no X-Spam_action: no action X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: Richard Henderson , David Gibson , qemu-ppc@nongnu.org, qemu-devel@nongnu.org, =?utf-8?q?C=C3=A9dric_Le_Goater?= Errors-To: qemu-devel-bounces+qemu-devel=archiver.kernel.org@nongnu.org Sender: "Qemu-devel" From: Richard Henderson As per hreg_compute_hflags: We 'forget' FE0 & FE1: we'll never generate imprecise exceptions remove the hflags marker from the respective comments. Signed-off-by: Richard Henderson Message-Id: <20210315184615.1985590-7-richard.henderson@linaro.org> Reviewed-by: Cédric Le Goater Signed-off-by: David Gibson --- target/ppc/cpu.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/target/ppc/cpu.h b/target/ppc/cpu.h index 79c4033a42..fd13489dce 100644 --- a/target/ppc/cpu.h +++ b/target/ppc/cpu.h @@ -322,13 +322,13 @@ typedef struct ppc_v3_pate_t { #define MSR_PR 14 /* Problem state hflags */ #define MSR_FP 13 /* Floating point available hflags */ #define MSR_ME 12 /* Machine check interrupt enable */ -#define MSR_FE0 11 /* Floating point exception mode 0 hflags */ +#define MSR_FE0 11 /* Floating point exception mode 0 */ #define MSR_SE 10 /* Single-step trace enable x hflags */ #define MSR_DWE 10 /* Debug wait enable on 405 x */ #define MSR_UBLE 10 /* User BTB lock enable on e500 x */ #define MSR_BE 9 /* Branch trace enable x hflags */ #define MSR_DE 9 /* Debug interrupts enable on embedded PowerPC x */ -#define MSR_FE1 8 /* Floating point exception mode 1 hflags */ +#define MSR_FE1 8 /* Floating point exception mode 1 */ #define MSR_AL 7 /* AL bit on POWER */ #define MSR_EP 6 /* Exception prefix on 601 */ #define MSR_IR 5 /* Instruction relocate */ From patchwork Tue May 4 05:52:34 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: David Gibson X-Patchwork-Id: 12237423 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-16.6 required=3.0 tests=BAYES_00,DKIM_INVALID, DKIM_SIGNED,HEADER_FROM_DIFFERENT_DOMAINS,INCLUDES_CR_TRAILER,INCLUDES_PATCH, MAILING_LIST_MULTI,SPF_HELO_NONE,SPF_PASS,USER_AGENT_GIT autolearn=ham autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id 5D8C4C433B4 for ; Tue, 4 May 2021 06:00:25 +0000 (UTC) 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 mail.kernel.org (Postfix) with ESMTPS id 0EB336139A for ; Tue, 4 May 2021 06:00:25 +0000 (UTC) DMARC-Filter: OpenDMARC Filter v1.3.2 mail.kernel.org 0EB336139A Authentication-Results: mail.kernel.org; dmarc=none (p=none dis=none) header.from=gibson.dropbear.id.au Authentication-Results: mail.kernel.org; spf=pass smtp.mailfrom=qemu-devel-bounces+qemu-devel=archiver.kernel.org@nongnu.org Received: from localhost ([::1]:60114 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1ldo6Y-0002z4-Vj for qemu-devel@archiver.kernel.org; Tue, 04 May 2021 02:00:23 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]:60428) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1ldnzw-0005DQ-Rj; Tue, 04 May 2021 01:53:34 -0400 Received: from ozlabs.org ([2401:3900:2:1::2]:51991) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1ldnzs-0004fX-R4; Tue, 04 May 2021 01:53:31 -0400 Received: by ozlabs.org (Postfix, from userid 1007) id 4FZ8CK1YrWz9sWH; Tue, 4 May 2021 15:53:17 +1000 (AEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=gibson.dropbear.id.au; s=201602; t=1620107597; bh=O5zitTu+nloRXDlrgGA5ooBE2GZ6ePUNtmsAOMIModU=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=jS+Y1XgtrUo/X4LKu+GcN0TgNn3KEXeWvz981JCyJDnYCXOAy7FdJP2I5J3dfkB/g nwuW/2wg/XpicofvtV8MzYDnaCnJv7AWGT+GVic34OgRrMSeV2QZcPSzvJL2Ir+KnU Hz61gcwsf/uw3yKujxeD40U1z6NYq5zRoQPk7gR4= From: David Gibson To: peter.maydell@linaro.org, groug@kaod.org Subject: [PULL 08/46] hw/ppc/pnv_core: Update hflags after setting msr Date: Tue, 4 May 2021 15:52:34 +1000 Message-Id: <20210504055312.306823-9-david@gibson.dropbear.id.au> X-Mailer: git-send-email 2.31.1 In-Reply-To: <20210504055312.306823-1-david@gibson.dropbear.id.au> References: <20210504055312.306823-1-david@gibson.dropbear.id.au> MIME-Version: 1.0 Received-SPF: pass client-ip=2401:3900:2:1::2; envelope-from=dgibson@ozlabs.org; helo=ozlabs.org X-Spam_score_int: -17 X-Spam_score: -1.8 X-Spam_bar: - X-Spam_report: (-1.8 / 5.0 requ) BAYES_00=-1.9, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_AU=-0.1, HEADER_FROM_DIFFERENT_DOMAINS=0.25, SPF_HELO_PASS=-0.001, SPF_PASS=-0.001 autolearn=no autolearn_force=no X-Spam_action: no action X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: Richard Henderson , qemu-ppc@nongnu.org, qemu-devel@nongnu.org, David Gibson Errors-To: qemu-devel-bounces+qemu-devel=archiver.kernel.org@nongnu.org Sender: "Qemu-devel" From: Richard Henderson Signed-off-by: Richard Henderson Message-Id: <20210315184615.1985590-15-richard.henderson@linaro.org> Signed-off-by: David Gibson --- hw/ppc/pnv_core.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/hw/ppc/pnv_core.c b/hw/ppc/pnv_core.c index bd2bf2e044..8c2a15a0fb 100644 --- a/hw/ppc/pnv_core.c +++ b/hw/ppc/pnv_core.c @@ -29,6 +29,7 @@ #include "hw/ppc/pnv_xscom.h" #include "hw/ppc/xics.h" #include "hw/qdev-properties.h" +#include "helper_regs.h" static const char *pnv_core_cpu_typename(PnvCore *pc) { @@ -55,8 +56,8 @@ static void pnv_core_cpu_reset(PnvCore *pc, PowerPCCPU *cpu) env->gpr[3] = PNV_FDT_ADDR; env->nip = 0x10; env->msr |= MSR_HVB; /* Hypervisor mode */ - env->spr[SPR_HRMOR] = pc->hrmor; + hreg_compute_hflags(env); pcc->intc_reset(pc->chip, cpu); } From patchwork Tue May 4 05:52:35 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: David Gibson X-Patchwork-Id: 12237445 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-16.6 required=3.0 tests=BAYES_00,DKIM_INVALID, DKIM_SIGNED,HEADER_FROM_DIFFERENT_DOMAINS,INCLUDES_CR_TRAILER,INCLUDES_PATCH, MAILING_LIST_MULTI,SPF_HELO_NONE,SPF_PASS,USER_AGENT_GIT autolearn=ham autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id 96DB6C433B4 for ; Tue, 4 May 2021 06:16:39 +0000 (UTC) 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 mail.kernel.org (Postfix) with ESMTPS id 2B96A610FC for ; Tue, 4 May 2021 06:16:39 +0000 (UTC) DMARC-Filter: OpenDMARC Filter v1.3.2 mail.kernel.org 2B96A610FC Authentication-Results: mail.kernel.org; dmarc=none (p=none dis=none) header.from=gibson.dropbear.id.au Authentication-Results: mail.kernel.org; spf=pass smtp.mailfrom=qemu-devel-bounces+qemu-devel=archiver.kernel.org@nongnu.org Received: from localhost ([::1]:57154 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1ldoMI-0005yE-3m for qemu-devel@archiver.kernel.org; Tue, 04 May 2021 02:16:38 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]:60460) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1ldnzy-0005EV-UG; Tue, 04 May 2021 01:53:36 -0400 Received: from ozlabs.org ([2401:3900:2:1::2]:48167) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1ldnzu-0004gH-Lj; Tue, 04 May 2021 01:53:33 -0400 Received: by ozlabs.org (Postfix, from userid 1007) id 4FZ8CK2mzGz9sWl; Tue, 4 May 2021 15:53:17 +1000 (AEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=gibson.dropbear.id.au; s=201602; t=1620107597; bh=EaUDafy/8AJuydSXL0bhyrdgLP0aiUNh84eXCOph83Y=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=o/ETwZDh4AmO7IMxZqN8i0QaMbHqt+DtMsK+fsYLRU3AhIeclTVNhHgSBUR23JDn+ ebpO/iCjsEQGvccAicEv2hWnXbvnNKBx5+uilUgm8F9CoO5IXd2FJFR4HT/Fg09H6t A4wuEF/9jy6ToTTIzWPKxi5UXWpREAFaMH7jFbpQ= From: David Gibson To: peter.maydell@linaro.org, groug@kaod.org Subject: [PULL 09/46] hw/ppc/spapr_rtas: Update hflags after setting msr Date: Tue, 4 May 2021 15:52:35 +1000 Message-Id: <20210504055312.306823-10-david@gibson.dropbear.id.au> X-Mailer: git-send-email 2.31.1 In-Reply-To: <20210504055312.306823-1-david@gibson.dropbear.id.au> References: <20210504055312.306823-1-david@gibson.dropbear.id.au> MIME-Version: 1.0 Received-SPF: pass client-ip=2401:3900:2:1::2; envelope-from=dgibson@ozlabs.org; helo=ozlabs.org X-Spam_score_int: -17 X-Spam_score: -1.8 X-Spam_bar: - X-Spam_report: (-1.8 / 5.0 requ) BAYES_00=-1.9, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_AU=-0.1, HEADER_FROM_DIFFERENT_DOMAINS=0.25, SPF_HELO_PASS=-0.001, SPF_PASS=-0.001 autolearn=no autolearn_force=no X-Spam_action: no action X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: Richard Henderson , qemu-ppc@nongnu.org, qemu-devel@nongnu.org, David Gibson Errors-To: qemu-devel-bounces+qemu-devel=archiver.kernel.org@nongnu.org Sender: "Qemu-devel" From: Richard Henderson Signed-off-by: Richard Henderson Message-Id: <20210315184615.1985590-16-richard.henderson@linaro.org> Signed-off-by: David Gibson --- hw/ppc/spapr_rtas.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/hw/ppc/spapr_rtas.c b/hw/ppc/spapr_rtas.c index 8a79f9c628..6ec3e71757 100644 --- a/hw/ppc/spapr_rtas.c +++ b/hw/ppc/spapr_rtas.c @@ -51,6 +51,7 @@ #include "target/ppc/mmu-hash64.h" #include "target/ppc/mmu-book3s-v3.h" #include "migration/blocker.h" +#include "helper_regs.h" static void rtas_display_character(PowerPCCPU *cpu, SpaprMachineState *spapr, uint32_t token, uint32_t nargs, @@ -163,6 +164,7 @@ static void rtas_start_cpu(PowerPCCPU *callcpu, SpaprMachineState *spapr, cpu_synchronize_state(CPU(newcpu)); env->msr = (1ULL << MSR_SF) | (1ULL << MSR_ME); + hreg_compute_hflags(env); /* Enable Power-saving mode Exit Cause exceptions for the new CPU */ lpcr = env->spr[SPR_LPCR]; From patchwork Tue May 4 05:52:36 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: David Gibson X-Patchwork-Id: 12237431 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-16.6 required=3.0 tests=BAYES_00,DKIM_INVALID, DKIM_SIGNED,HEADER_FROM_DIFFERENT_DOMAINS,INCLUDES_CR_TRAILER,INCLUDES_PATCH, MAILING_LIST_MULTI,SPF_HELO_NONE,SPF_PASS,USER_AGENT_GIT autolearn=ham autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id 04518C433ED for ; Tue, 4 May 2021 06:04:37 +0000 (UTC) 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 mail.kernel.org (Postfix) with ESMTPS id 83C9A61159 for ; Tue, 4 May 2021 06:04:36 +0000 (UTC) DMARC-Filter: OpenDMARC Filter v1.3.2 mail.kernel.org 83C9A61159 Authentication-Results: mail.kernel.org; dmarc=none (p=none dis=none) header.from=gibson.dropbear.id.au Authentication-Results: mail.kernel.org; spf=pass smtp.mailfrom=qemu-devel-bounces+qemu-devel=archiver.kernel.org@nongnu.org Received: from localhost ([::1]:41214 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1ldoAd-0007Bv-MP for qemu-devel@archiver.kernel.org; Tue, 04 May 2021 02:04:35 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]:60456) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1ldnzy-0005ER-RK; Tue, 04 May 2021 01:53:36 -0400 Received: from ozlabs.org ([203.11.71.1]:60029) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1ldnzu-0004fy-L1; Tue, 04 May 2021 01:53:33 -0400 Received: by ozlabs.org (Postfix, from userid 1007) id 4FZ8CK2HFbz9sWP; Tue, 4 May 2021 15:53:17 +1000 (AEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=gibson.dropbear.id.au; s=201602; t=1620107597; bh=oW4gZLOC55a8GtLu9aFZEjL0E+dLRASXBtOs5tL/xpw=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=QazuReShYv9d9YYcApIrSml4UbUWrVzhLV+hxfZe5Ow0OOi4S7XBexXu/ne0Qp9ES aehyZPoD+h0GLBkgd2pkXSfRLDqFs1IcspLlZAZLKUu7npRVLvHNspKzqdpTYcdbKL Tz+lDt6nglU6KxlFyT9hE6EwZ+UTzYD7e0vcyaSQ= From: David Gibson To: peter.maydell@linaro.org, groug@kaod.org Subject: [PULL 10/46] target/ppc: Extract post_load_update_msr Date: Tue, 4 May 2021 15:52:36 +1000 Message-Id: <20210504055312.306823-11-david@gibson.dropbear.id.au> X-Mailer: git-send-email 2.31.1 In-Reply-To: <20210504055312.306823-1-david@gibson.dropbear.id.au> References: <20210504055312.306823-1-david@gibson.dropbear.id.au> MIME-Version: 1.0 Received-SPF: pass client-ip=203.11.71.1; envelope-from=dgibson@ozlabs.org; helo=ozlabs.org X-Spam_score_int: -17 X-Spam_score: -1.8 X-Spam_bar: - X-Spam_report: (-1.8 / 5.0 requ) BAYES_00=-1.9, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_AU=-0.1, HEADER_FROM_DIFFERENT_DOMAINS=0.25, SPF_HELO_PASS=-0.001, SPF_PASS=-0.001 autolearn=no autolearn_force=no X-Spam_action: no action X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: Richard Henderson , David Gibson , qemu-ppc@nongnu.org, qemu-devel@nongnu.org, =?utf-8?q?C=C3=A9dric_Le_Goater?= Errors-To: qemu-devel-bounces+qemu-devel=archiver.kernel.org@nongnu.org Sender: "Qemu-devel" From: Richard Henderson Extract post_load_update_msr to share between cpu_load_old and cpu_post_load in updating the msr. Suggested-by: Cédric Le Goater Signed-off-by: Richard Henderson Message-Id: <20210323184340.619757-2-richard.henderson@linaro.org> Signed-off-by: David Gibson --- target/ppc/machine.c | 30 ++++++++++++++---------------- 1 file changed, 14 insertions(+), 16 deletions(-) diff --git a/target/ppc/machine.c b/target/ppc/machine.c index 1f7a353c78..09c5765a87 100644 --- a/target/ppc/machine.c +++ b/target/ppc/machine.c @@ -10,6 +10,18 @@ #include "kvm_ppc.h" #include "exec/helper-proto.h" +static void post_load_update_msr(CPUPPCState *env) +{ + target_ulong msr = env->msr; + + /* + * Invalidate all supported msr bits except MSR_TGPR/MSR_HVB + * before restoring. Note that this recomputes hflags and mem_idx. + */ + env->msr ^= env->msr_mask & ~((1ULL << MSR_TGPR) | MSR_HVB); + ppc_store_msr(env, msr); +} + static int cpu_load_old(QEMUFile *f, void *opaque, int version_id) { PowerPCCPU *cpu = opaque; @@ -21,7 +33,6 @@ static int cpu_load_old(QEMUFile *f, void *opaque, int version_id) int32_t slb_nr; #endif target_ulong xer; - target_ulong msr; for (i = 0; i < 32; i++) { qemu_get_betls(f, &env->gpr[i]); @@ -117,13 +128,7 @@ static int cpu_load_old(QEMUFile *f, void *opaque, int version_id) qemu_get_sbe32(f); /* Discard unused mmu_idx */ qemu_get_sbe32(f); /* Discard unused power_mode */ - /* - * Invalidate all supported msr bits except MSR_TGPR/MSR_HVB - * before restoring. Note that this recomputes hflags and mem_idx. - */ - msr = env->msr; - env->msr ^= env->msr_mask & ~((1ULL << MSR_TGPR) | MSR_HVB); - ppc_store_msr(env, msr); + post_load_update_msr(env); return 0; } @@ -343,7 +348,6 @@ static int cpu_post_load(void *opaque, int version_id) PowerPCCPU *cpu = opaque; CPUPPCState *env = &cpu->env; int i; - target_ulong msr; /* * If we're operating in compat mode, we should be ok as long as @@ -417,13 +421,7 @@ static int cpu_post_load(void *opaque, int version_id) ppc_store_sdr1(env, env->spr[SPR_SDR1]); } - /* - * Invalidate all supported msr bits except MSR_TGPR/MSR_HVB - * before restoring. Note that this recomputes hflags and mem_idx. - */ - msr = env->msr; - env->msr ^= env->msr_mask & ~((1ULL << MSR_TGPR) | MSR_HVB); - ppc_store_msr(env, msr); + post_load_update_msr(env); return 0; } From patchwork Tue May 4 05:52:37 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: David Gibson X-Patchwork-Id: 12237439 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-16.6 required=3.0 tests=BAYES_00,DKIM_INVALID, DKIM_SIGNED,HEADER_FROM_DIFFERENT_DOMAINS,INCLUDES_CR_TRAILER,INCLUDES_PATCH, MAILING_LIST_MULTI,SPF_HELO_NONE,SPF_PASS,USER_AGENT_GIT autolearn=ham autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id 8EBC4C433ED for ; Tue, 4 May 2021 06:11:10 +0000 (UTC) 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 mail.kernel.org (Postfix) with ESMTPS id 345B8611AE for ; Tue, 4 May 2021 06:11:10 +0000 (UTC) DMARC-Filter: OpenDMARC Filter v1.3.2 mail.kernel.org 345B8611AE Authentication-Results: mail.kernel.org; dmarc=none (p=none dis=none) header.from=gibson.dropbear.id.au Authentication-Results: mail.kernel.org; spf=pass smtp.mailfrom=qemu-devel-bounces+qemu-devel=archiver.kernel.org@nongnu.org Received: from localhost ([::1]:49662 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1ldoGz-0002bD-AP for qemu-devel@archiver.kernel.org; Tue, 04 May 2021 02:11:09 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]:60478) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1ldo00-0005Fj-Rx; Tue, 04 May 2021 01:53:36 -0400 Received: from ozlabs.org ([203.11.71.1]:40259) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1ldnzu-0004gR-M1; Tue, 04 May 2021 01:53:35 -0400 Received: by ozlabs.org (Postfix, from userid 1007) id 4FZ8CK37VCz9sWc; Tue, 4 May 2021 15:53:17 +1000 (AEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=gibson.dropbear.id.au; s=201602; t=1620107597; bh=krNKTKKeBY1/6yuZmLDI7IFkkJRwL6rpd5wRKD5l5NE=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=SmfC7LkVbNhZrP8aWpOKAPsL0TpFJHL+UDtT6k3mx63ZXIpG53d3wbQmlQBtYRE6K 2YnoR1ZRUv7mrmYiWYQONF0JHOfU9cFviGen7ZRGHGFIV88py4Z2nElnEICwZ3Rhqa bU1vLc9kEOcxQDW+OmaENd1OlOeXiz7vJyPMIl7s= From: David Gibson To: peter.maydell@linaro.org, groug@kaod.org Subject: [PULL 11/46] target/ppc: Disconnect hflags from MSR Date: Tue, 4 May 2021 15:52:37 +1000 Message-Id: <20210504055312.306823-12-david@gibson.dropbear.id.au> X-Mailer: git-send-email 2.31.1 In-Reply-To: <20210504055312.306823-1-david@gibson.dropbear.id.au> References: <20210504055312.306823-1-david@gibson.dropbear.id.au> MIME-Version: 1.0 Received-SPF: pass client-ip=203.11.71.1; envelope-from=dgibson@ozlabs.org; helo=ozlabs.org X-Spam_score_int: -17 X-Spam_score: -1.8 X-Spam_bar: - X-Spam_report: (-1.8 / 5.0 requ) BAYES_00=-1.9, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_AU=-0.1, HEADER_FROM_DIFFERENT_DOMAINS=0.25, SPF_HELO_PASS=-0.001, SPF_PASS=-0.001 autolearn=no autolearn_force=no X-Spam_action: no action X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: Ivan Warren , Richard Henderson , qemu-ppc@nongnu.org, qemu-devel@nongnu.org, David Gibson Errors-To: qemu-devel-bounces+qemu-devel=archiver.kernel.org@nongnu.org Sender: "Qemu-devel" From: Richard Henderson Copying flags directly from msr has drawbacks: (1) msr bits mean different things per cpu, (2) msr has 64 bits on 64 cpus while tb->flags has only 32 bits. Create a enum to define these bits. Document the origin of each bit and validate those bits that must match MSR. This fixes the truncation of env->hflags to tb->flags, because we no longer have hflags bits set above bit 31. Most of the code in ppc_tr_init_disas_context is moved over to hreg_compute_hflags. Some of it is simple extractions from msr, some requires examining other cpu flags. Anything that is moved becomes a simple extract from hflags in ppc_tr_init_disas_context. Several existing bugs are left in ppc_tr_init_disas_context, where additional changes are required -- to be addressed in future patches. Remove a broken #if 0 block. Reported-by: Ivan Warren Signed-off-by: Richard Henderson Message-Id: <20210323184340.619757-3-richard.henderson@linaro.org> Signed-off-by: David Gibson --- target/ppc/cpu.h | 25 ++++++++++++++++ target/ppc/helper_regs.c | 65 +++++++++++++++++++++++++++++++++------- target/ppc/translate.c | 55 ++++++++++------------------------ 3 files changed, 95 insertions(+), 50 deletions(-) diff --git a/target/ppc/cpu.h b/target/ppc/cpu.h index fd13489dce..fe6c3f815d 100644 --- a/target/ppc/cpu.h +++ b/target/ppc/cpu.h @@ -585,6 +585,31 @@ enum { POWERPC_FLAG_HID0_LE = 0x00400000, }; +/* + * Bits for env->hflags. + * + * Most of these bits overlap with corresponding bits in MSR, + * but some come from other sources. Those that do come from + * the MSR are validated in hreg_compute_hflags. + */ +enum { + HFLAGS_LE = 0, /* MSR_LE -- comes from elsewhere on 601 */ + HFLAGS_HV = 1, /* computed from MSR_HV and other state */ + HFLAGS_64 = 2, /* computed from MSR_CE and MSR_SF */ + HFLAGS_DR = 4, /* MSR_DR */ + HFLAGS_IR = 5, /* MSR_IR */ + HFLAGS_SPE = 6, /* from MSR_SPE if cpu has SPE; avoid overlap w/ MSR_VR */ + HFLAGS_VSX = 7, /* from MSR_VSX if cpu has VSX; avoid overlap w/ MSR_AP */ + HFLAGS_TM = 8, /* computed from MSR_TM */ + HFLAGS_BE = 9, /* MSR_BE -- from elsewhere on embedded ppc */ + HFLAGS_SE = 10, /* MSR_SE -- from elsewhere on embedded ppc */ + HFLAGS_FP = 13, /* MSR_FP */ + HFLAGS_PR = 14, /* MSR_PR */ + HFLAGS_SA = 22, /* MSR_SA */ + HFLAGS_AP = 23, /* MSR_AP */ + HFLAGS_VR = 25, /* MSR_VR if cpu has VRE */ +}; + /*****************************************************************************/ /* Floating point status and control register */ #define FPSCR_DRN2 34 /* Decimal Floating-Point rounding control */ diff --git a/target/ppc/helper_regs.c b/target/ppc/helper_regs.c index a87e354ca2..df9673b90f 100644 --- a/target/ppc/helper_regs.c +++ b/target/ppc/helper_regs.c @@ -18,6 +18,7 @@ */ #include "qemu/osdep.h" +#include "cpu.h" #include "qemu/main-loop.h" #include "exec/exec-all.h" #include "sysemu/kvm.h" @@ -87,24 +88,66 @@ void hreg_compute_mem_idx(CPUPPCState *env) void hreg_compute_hflags(CPUPPCState *env) { - target_ulong hflags_mask; + target_ulong msr = env->msr; + uint32_t ppc_flags = env->flags; + uint32_t hflags = 0; + uint32_t msr_mask; - /* We 'forget' FE0 & FE1: we'll never generate imprecise exceptions */ - hflags_mask = (1 << MSR_VR) | (1 << MSR_AP) | (1 << MSR_SA) | - (1 << MSR_PR) | (1 << MSR_FP) | (1 << MSR_SE) | (1 << MSR_BE) | - (1 << MSR_LE) | (1 << MSR_VSX) | (1 << MSR_IR) | (1 << MSR_DR); - hflags_mask |= (1ULL << MSR_CM) | (1ULL << MSR_SF) | MSR_HVB; - hreg_compute_mem_idx(env); - env->hflags = env->msr & hflags_mask; + /* Some bits come straight across from MSR. */ + QEMU_BUILD_BUG_ON(MSR_LE != HFLAGS_LE); + QEMU_BUILD_BUG_ON(MSR_PR != HFLAGS_PR); + QEMU_BUILD_BUG_ON(MSR_DR != HFLAGS_DR); + QEMU_BUILD_BUG_ON(MSR_IR != HFLAGS_IR); + QEMU_BUILD_BUG_ON(MSR_FP != HFLAGS_FP); + QEMU_BUILD_BUG_ON(MSR_SA != HFLAGS_SA); + QEMU_BUILD_BUG_ON(MSR_AP != HFLAGS_AP); + msr_mask = ((1 << MSR_LE) | (1 << MSR_PR) | + (1 << MSR_DR) | (1 << MSR_IR) | + (1 << MSR_FP) | (1 << MSR_SA) | (1 << MSR_AP)); - if (env->flags & POWERPC_FLAG_HID0_LE) { + if (ppc_flags & POWERPC_FLAG_HID0_LE) { /* * Note that MSR_LE is not set in env->msr_mask for this cpu, - * and so will never be set in msr or hflags at this point. + * and so will never be set in msr. */ uint32_t le = extract32(env->spr[SPR_HID0], 3, 1); - env->hflags |= le << MSR_LE; + hflags |= le << MSR_LE; + } + + if (ppc_flags & POWERPC_FLAG_BE) { + QEMU_BUILD_BUG_ON(MSR_BE != HFLAGS_BE); + msr_mask |= 1 << MSR_BE; + } + if (ppc_flags & POWERPC_FLAG_SE) { + QEMU_BUILD_BUG_ON(MSR_SE != HFLAGS_SE); + msr_mask |= 1 << MSR_SE; + } + + if (msr_is_64bit(env, msr)) { + hflags |= 1 << HFLAGS_64; + } + if ((ppc_flags & POWERPC_FLAG_SPE) && (msr & (1 << MSR_SPE))) { + hflags |= 1 << HFLAGS_SPE; + } + if (ppc_flags & POWERPC_FLAG_VRE) { + QEMU_BUILD_BUG_ON(MSR_VR != HFLAGS_VR); + msr_mask |= 1 << MSR_VR; } + if ((ppc_flags & POWERPC_FLAG_VSX) && (msr & (1 << MSR_VSX))) { + hflags |= 1 << HFLAGS_VSX; + } + if ((ppc_flags & POWERPC_FLAG_TM) && (msr & (1ull << MSR_TM))) { + hflags |= 1 << HFLAGS_TM; + } + +#ifndef CONFIG_USER_ONLY + if (!env->has_hv_mode || (msr & (1ull << MSR_HV))) { + hflags |= 1 << HFLAGS_HV; + } +#endif + + env->hflags = hflags | (msr & msr_mask); + hreg_compute_mem_idx(env); } void cpu_interrupt_exittb(CPUState *cs) diff --git a/target/ppc/translate.c b/target/ppc/translate.c index 0984ce637b..a9325a12e5 100644 --- a/target/ppc/translate.c +++ b/target/ppc/translate.c @@ -7879,67 +7879,48 @@ static void ppc_tr_init_disas_context(DisasContextBase *dcbase, CPUState *cs) { DisasContext *ctx = container_of(dcbase, DisasContext, base); CPUPPCState *env = cs->env_ptr; + uint32_t hflags = ctx->base.tb->flags; int bound; ctx->exception = POWERPC_EXCP_NONE; ctx->spr_cb = env->spr_cb; - ctx->pr = msr_pr; + ctx->pr = (hflags >> HFLAGS_PR) & 1; ctx->mem_idx = env->dmmu_idx; - ctx->dr = msr_dr; -#if !defined(CONFIG_USER_ONLY) - ctx->hv = msr_hv || !env->has_hv_mode; -#endif + ctx->dr = (hflags >> HFLAGS_DR) & 1; + ctx->hv = (hflags >> HFLAGS_HV) & 1; ctx->insns_flags = env->insns_flags; ctx->insns_flags2 = env->insns_flags2; ctx->access_type = -1; ctx->need_access_type = !mmu_is_64bit(env->mmu_model); - ctx->le_mode = !!(env->hflags & (1 << MSR_LE)); + ctx->le_mode = (hflags >> HFLAGS_LE) & 1; ctx->default_tcg_memop_mask = ctx->le_mode ? MO_LE : MO_BE; ctx->flags = env->flags; #if defined(TARGET_PPC64) - ctx->sf_mode = msr_is_64bit(env, env->msr); + ctx->sf_mode = (hflags >> HFLAGS_64) & 1; ctx->has_cfar = !!(env->flags & POWERPC_FLAG_CFAR); #endif ctx->lazy_tlb_flush = env->mmu_model == POWERPC_MMU_32B || env->mmu_model == POWERPC_MMU_601 || env->mmu_model & POWERPC_MMU_64; - ctx->fpu_enabled = !!msr_fp; - if ((env->flags & POWERPC_FLAG_SPE) && msr_spe) { - ctx->spe_enabled = !!msr_spe; - } else { - ctx->spe_enabled = false; - } - if ((env->flags & POWERPC_FLAG_VRE) && msr_vr) { - ctx->altivec_enabled = !!msr_vr; - } else { - ctx->altivec_enabled = false; - } - if ((env->flags & POWERPC_FLAG_VSX) && msr_vsx) { - ctx->vsx_enabled = !!msr_vsx; - } else { - ctx->vsx_enabled = false; - } + ctx->fpu_enabled = (hflags >> HFLAGS_FP) & 1; + ctx->spe_enabled = (hflags >> HFLAGS_SPE) & 1; + ctx->altivec_enabled = (hflags >> HFLAGS_VR) & 1; + ctx->vsx_enabled = (hflags >> HFLAGS_VSX) & 1; if ((env->flags & POWERPC_FLAG_SCV) && (env->spr[SPR_FSCR] & (1ull << FSCR_SCV))) { ctx->scv_enabled = true; } else { ctx->scv_enabled = false; } -#if defined(TARGET_PPC64) - if ((env->flags & POWERPC_FLAG_TM) && msr_tm) { - ctx->tm_enabled = !!msr_tm; - } else { - ctx->tm_enabled = false; - } -#endif + ctx->tm_enabled = (hflags >> HFLAGS_TM) & 1; ctx->gtse = !!(env->spr[SPR_LPCR] & LPCR_GTSE); - if ((env->flags & POWERPC_FLAG_SE) && msr_se) { - ctx->singlestep_enabled = CPU_SINGLE_STEP; - } else { - ctx->singlestep_enabled = 0; + + ctx->singlestep_enabled = 0; + if ((hflags >> HFLAGS_SE) & 1) { + ctx->singlestep_enabled |= CPU_SINGLE_STEP; } - if ((env->flags & POWERPC_FLAG_BE) && msr_be) { + if ((hflags >> HFLAGS_BE) & 1) { ctx->singlestep_enabled |= CPU_BRANCH_STEP; } if ((env->flags & POWERPC_FLAG_DE) && msr_de) { @@ -7956,10 +7937,6 @@ static void ppc_tr_init_disas_context(DisasContextBase *dcbase, CPUState *cs) if (unlikely(ctx->base.singlestep_enabled)) { ctx->singlestep_enabled |= GDBSTUB_SINGLE_STEP; } -#if defined(DO_SINGLE_STEP) && 0 - /* Single step trace mode */ - msr_se = 1; -#endif bound = -(ctx->base.pc_first | TARGET_PAGE_MASK) / 4; ctx->base.max_insns = MIN(ctx->base.max_insns, bound); From patchwork Tue May 4 05:52:38 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: David Gibson X-Patchwork-Id: 12237441 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-16.6 required=3.0 tests=BAYES_00,DKIM_INVALID, DKIM_SIGNED,HEADER_FROM_DIFFERENT_DOMAINS,INCLUDES_CR_TRAILER,INCLUDES_PATCH, MAILING_LIST_MULTI,SPF_HELO_NONE,SPF_PASS,USER_AGENT_GIT autolearn=ham autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id 5EF86C433ED for ; Tue, 4 May 2021 06:11:41 +0000 (UTC) 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 mail.kernel.org (Postfix) with ESMTPS id CAF7C611AD for ; Tue, 4 May 2021 06:11:40 +0000 (UTC) DMARC-Filter: OpenDMARC Filter v1.3.2 mail.kernel.org CAF7C611AD Authentication-Results: mail.kernel.org; dmarc=none (p=none dis=none) header.from=gibson.dropbear.id.au Authentication-Results: mail.kernel.org; spf=pass smtp.mailfrom=qemu-devel-bounces+qemu-devel=archiver.kernel.org@nongnu.org Received: from localhost ([::1]:50276 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1ldoHT-0002qr-UV for qemu-devel@archiver.kernel.org; Tue, 04 May 2021 02:11:39 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]:60482) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1ldo00-0005Fn-RV; Tue, 04 May 2021 01:53:36 -0400 Received: from bilbo.ozlabs.org ([2401:3900:2:1::2]:45969 helo=ozlabs.org) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1ldnzu-0004h3-PK; Tue, 04 May 2021 01:53:34 -0400 Received: by ozlabs.org (Postfix, from userid 1007) id 4FZ8CK3TXjz9sWp; Tue, 4 May 2021 15:53:17 +1000 (AEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=gibson.dropbear.id.au; s=201602; t=1620107597; bh=9Q0vDRcy2WGfG9TN8BUHQg8bYCUSstmE97i7Vbf7JZ4=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=EHtLWjbjww+dIgUQ9FjO/CFpUljMUlGIvKr4XZAVP0wpKd4J6Kz2P4HpO4+jmG88k dr2ZcGxJi9xSf51zEzKyBpp4hB9BSJqMbaLIRno3vAMgILqJrq1IzldCkRkhYq52Cr lLkeyGkcTaizVVXUshIld/2opdfOx+T0stLCsglI= From: David Gibson To: peter.maydell@linaro.org, groug@kaod.org Subject: [PULL 12/46] target/ppc: Reduce env->hflags to uint32_t Date: Tue, 4 May 2021 15:52:38 +1000 Message-Id: <20210504055312.306823-13-david@gibson.dropbear.id.au> X-Mailer: git-send-email 2.31.1 In-Reply-To: <20210504055312.306823-1-david@gibson.dropbear.id.au> References: <20210504055312.306823-1-david@gibson.dropbear.id.au> MIME-Version: 1.0 Received-SPF: pass client-ip=2401:3900:2:1::2; envelope-from=dgibson@ozlabs.org; helo=ozlabs.org X-Spam_score_int: -17 X-Spam_score: -1.8 X-Spam_bar: - X-Spam_report: (-1.8 / 5.0 requ) BAYES_00=-1.9, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_AU=-0.1, HEADER_FROM_DIFFERENT_DOMAINS=0.25, SPF_HELO_PASS=-0.001, SPF_PASS=-0.001 autolearn=no autolearn_force=no X-Spam_action: no action X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: Richard Henderson , David Gibson , qemu-ppc@nongnu.org, qemu-devel@nongnu.org, =?utf-8?q?C=C3=A9dric_Le_Goater?= Errors-To: qemu-devel-bounces+qemu-devel=archiver.kernel.org@nongnu.org Sender: "Qemu-devel" From: Richard Henderson It will be stored in tb->flags, which is also uint32_t, so let's use the correct size. Reviewed-by: Cédric Le Goater Reviewed-by: David Gibson Signed-off-by: Richard Henderson Message-Id: <20210323184340.619757-4-richard.henderson@linaro.org> Signed-off-by: David Gibson --- target/ppc/cpu.h | 4 ++-- target/ppc/misc_helper.c | 2 +- target/ppc/translate.c | 2 +- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/target/ppc/cpu.h b/target/ppc/cpu.h index fe6c3f815d..d5f362506a 100644 --- a/target/ppc/cpu.h +++ b/target/ppc/cpu.h @@ -1129,8 +1129,8 @@ struct CPUPPCState { bool resume_as_sreset; #endif - /* These resources are used only in QEMU core */ - target_ulong hflags; + /* These resources are used only in TCG */ + uint32_t hflags; target_ulong hflags_compat_nmsr; /* for migration compatibility */ int immu_idx; /* precomputed MMU index to speed up insn accesses */ int dmmu_idx; /* precomputed MMU index to speed up data accesses */ diff --git a/target/ppc/misc_helper.c b/target/ppc/misc_helper.c index 63e3147eb4..b04b4d7c6e 100644 --- a/target/ppc/misc_helper.c +++ b/target/ppc/misc_helper.c @@ -199,7 +199,7 @@ void helper_store_hid0_601(CPUPPCState *env, target_ulong val) if ((val ^ hid0) & 0x00000008) { /* Change current endianness */ hreg_compute_hflags(env); - qemu_log("%s: set endianness to %c => " TARGET_FMT_lx "\n", __func__, + qemu_log("%s: set endianness to %c => %08x\n", __func__, val & 0x8 ? 'l' : 'b', env->hflags); } } diff --git a/target/ppc/translate.c b/target/ppc/translate.c index a9325a12e5..a85b890bb0 100644 --- a/target/ppc/translate.c +++ b/target/ppc/translate.c @@ -7657,7 +7657,7 @@ void ppc_cpu_dump_state(CPUState *cs, FILE *f, int flags) env->nip, env->lr, env->ctr, cpu_read_xer(env), cs->cpu_index); qemu_fprintf(f, "MSR " TARGET_FMT_lx " HID0 " TARGET_FMT_lx " HF " - TARGET_FMT_lx " iidx %d didx %d\n", + "%08x iidx %d didx %d\n", env->msr, env->spr[SPR_HID0], env->hflags, env->immu_idx, env->dmmu_idx); #if !defined(NO_TIMER_DUMP) From patchwork Tue May 4 05:52:39 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: David Gibson X-Patchwork-Id: 12237435 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-16.6 required=3.0 tests=BAYES_00,DKIM_INVALID, DKIM_SIGNED,HEADER_FROM_DIFFERENT_DOMAINS,INCLUDES_CR_TRAILER,INCLUDES_PATCH, MAILING_LIST_MULTI,SPF_HELO_NONE,SPF_PASS,USER_AGENT_GIT autolearn=ham autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id 8F2C8C433ED for ; Tue, 4 May 2021 06:08:08 +0000 (UTC) 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 mail.kernel.org (Postfix) with ESMTPS id 218056139A for ; Tue, 4 May 2021 06:08:08 +0000 (UTC) DMARC-Filter: OpenDMARC Filter v1.3.2 mail.kernel.org 218056139A Authentication-Results: mail.kernel.org; dmarc=none (p=none dis=none) header.from=gibson.dropbear.id.au Authentication-Results: mail.kernel.org; spf=pass smtp.mailfrom=qemu-devel-bounces+qemu-devel=archiver.kernel.org@nongnu.org Received: from localhost ([::1]:45680 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1ldoE3-0000p7-96 for qemu-devel@archiver.kernel.org; Tue, 04 May 2021 02:08:07 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]:60530) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1ldo04-0005IN-FP; Tue, 04 May 2021 01:53:42 -0400 Received: from ozlabs.org ([2401:3900:2:1::2]:49839) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1ldnzy-0004ie-Uv; Tue, 04 May 2021 01:53:39 -0400 Received: by ozlabs.org (Postfix, from userid 1007) id 4FZ8CK4BjVz9sX5; Tue, 4 May 2021 15:53:17 +1000 (AEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=gibson.dropbear.id.au; s=201602; t=1620107597; bh=AE/4n5PGUFoays6zdARQ1IYd5KqZTCtHN4fMxuKqurw=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=CG/zmRBj11BgKHf0CMIk3b+0a/IQ3qoo7/funvWg9rGiqlypcfw4yItCqMdaSLEII dd/XWbcASUARDs4Hj/5xlSBdCmtovbYdh58aaIodPA6ZcmTO/v3bHjPqTudMVxn8Jp 6vwWsW2239DGCFiGNX/9AzO4CKfhgufVnDyWfYDo= From: David Gibson To: peter.maydell@linaro.org, groug@kaod.org Subject: [PULL 13/46] target/ppc: Put dbcr0 single-step bits into hflags Date: Tue, 4 May 2021 15:52:39 +1000 Message-Id: <20210504055312.306823-14-david@gibson.dropbear.id.au> X-Mailer: git-send-email 2.31.1 In-Reply-To: <20210504055312.306823-1-david@gibson.dropbear.id.au> References: <20210504055312.306823-1-david@gibson.dropbear.id.au> MIME-Version: 1.0 Received-SPF: pass client-ip=2401:3900:2:1::2; envelope-from=dgibson@ozlabs.org; helo=ozlabs.org X-Spam_score_int: -17 X-Spam_score: -1.8 X-Spam_bar: - X-Spam_report: (-1.8 / 5.0 requ) BAYES_00=-1.9, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_AU=-0.1, HEADER_FROM_DIFFERENT_DOMAINS=0.25, SPF_HELO_PASS=-0.001, SPF_PASS=-0.001 autolearn=no autolearn_force=no X-Spam_action: no action X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: Richard Henderson , qemu-ppc@nongnu.org, qemu-devel@nongnu.org, David Gibson Errors-To: qemu-devel-bounces+qemu-devel=archiver.kernel.org@nongnu.org Sender: "Qemu-devel" From: Richard Henderson Because these bits were not in hflags, the code generated for single-stepping on BookE was essentially random. Recompute hflags when storing to dbcr0. Reviewed-by: David Gibson Signed-off-by: Richard Henderson Message-Id: <20210323184340.619757-5-richard.henderson@linaro.org> Signed-off-by: David Gibson --- target/ppc/helper_regs.c | 24 +++++++++++++++++------- target/ppc/misc_helper.c | 3 +++ target/ppc/translate.c | 11 ----------- 3 files changed, 20 insertions(+), 18 deletions(-) diff --git a/target/ppc/helper_regs.c b/target/ppc/helper_regs.c index df9673b90f..e345966b6b 100644 --- a/target/ppc/helper_regs.c +++ b/target/ppc/helper_regs.c @@ -114,13 +114,23 @@ void hreg_compute_hflags(CPUPPCState *env) hflags |= le << MSR_LE; } - if (ppc_flags & POWERPC_FLAG_BE) { - QEMU_BUILD_BUG_ON(MSR_BE != HFLAGS_BE); - msr_mask |= 1 << MSR_BE; - } - if (ppc_flags & POWERPC_FLAG_SE) { - QEMU_BUILD_BUG_ON(MSR_SE != HFLAGS_SE); - msr_mask |= 1 << MSR_SE; + if (ppc_flags & POWERPC_FLAG_DE) { + target_ulong dbcr0 = env->spr[SPR_BOOKE_DBCR0]; + if (dbcr0 & DBCR0_ICMP) { + hflags |= 1 << HFLAGS_SE; + } + if (dbcr0 & DBCR0_BRT) { + hflags |= 1 << HFLAGS_BE; + } + } else { + if (ppc_flags & POWERPC_FLAG_BE) { + QEMU_BUILD_BUG_ON(MSR_BE != HFLAGS_BE); + msr_mask |= 1 << MSR_BE; + } + if (ppc_flags & POWERPC_FLAG_SE) { + QEMU_BUILD_BUG_ON(MSR_SE != HFLAGS_SE); + msr_mask |= 1 << MSR_SE; + } } if (msr_is_64bit(env, msr)) { diff --git a/target/ppc/misc_helper.c b/target/ppc/misc_helper.c index b04b4d7c6e..002958be26 100644 --- a/target/ppc/misc_helper.c +++ b/target/ppc/misc_helper.c @@ -215,6 +215,9 @@ void helper_store_403_pbr(CPUPPCState *env, uint32_t num, target_ulong value) void helper_store_40x_dbcr0(CPUPPCState *env, target_ulong val) { + /* Bits 26 & 27 affect single-stepping. */ + hreg_compute_hflags(env); + /* Bits 28 & 29 affect reset or shutdown. */ store_40x_dbcr0(env, val); } diff --git a/target/ppc/translate.c b/target/ppc/translate.c index a85b890bb0..7912495f28 100644 --- a/target/ppc/translate.c +++ b/target/ppc/translate.c @@ -7923,17 +7923,6 @@ static void ppc_tr_init_disas_context(DisasContextBase *dcbase, CPUState *cs) if ((hflags >> HFLAGS_BE) & 1) { ctx->singlestep_enabled |= CPU_BRANCH_STEP; } - if ((env->flags & POWERPC_FLAG_DE) && msr_de) { - ctx->singlestep_enabled = 0; - target_ulong dbcr0 = env->spr[SPR_BOOKE_DBCR0]; - if (dbcr0 & DBCR0_ICMP) { - ctx->singlestep_enabled |= CPU_SINGLE_STEP; - } - if (dbcr0 & DBCR0_BRT) { - ctx->singlestep_enabled |= CPU_BRANCH_STEP; - } - - } if (unlikely(ctx->base.singlestep_enabled)) { ctx->singlestep_enabled |= GDBSTUB_SINGLE_STEP; } From patchwork Tue May 4 05:52:40 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: David Gibson X-Patchwork-Id: 12237433 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-16.6 required=3.0 tests=BAYES_00,DKIM_INVALID, DKIM_SIGNED,HEADER_FROM_DIFFERENT_DOMAINS,INCLUDES_CR_TRAILER,INCLUDES_PATCH, MAILING_LIST_MULTI,SPF_HELO_NONE,SPF_PASS,USER_AGENT_GIT autolearn=ham autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id 1E7D3C433ED for ; Tue, 4 May 2021 06:05:19 +0000 (UTC) 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 mail.kernel.org (Postfix) with ESMTPS id 9241061159 for ; Tue, 4 May 2021 06:05:18 +0000 (UTC) DMARC-Filter: OpenDMARC Filter v1.3.2 mail.kernel.org 9241061159 Authentication-Results: mail.kernel.org; dmarc=none (p=none dis=none) header.from=gibson.dropbear.id.au Authentication-Results: mail.kernel.org; spf=pass smtp.mailfrom=qemu-devel-bounces+qemu-devel=archiver.kernel.org@nongnu.org Received: from localhost ([::1]:41828 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1ldoBJ-0007RU-Im for qemu-devel@archiver.kernel.org; Tue, 04 May 2021 02:05:17 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]:60480) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1ldo00-0005Fk-Rr; Tue, 04 May 2021 01:53:36 -0400 Received: from ozlabs.org ([203.11.71.1]:35751) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1ldnzx-0004iX-Ds; Tue, 04 May 2021 01:53:35 -0400 Received: by ozlabs.org (Postfix, from userid 1007) id 4FZ8CK3r9Gz9sWq; Tue, 4 May 2021 15:53:17 +1000 (AEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=gibson.dropbear.id.au; s=201602; t=1620107597; bh=x/kaaARkUFgaoRSSOlm3/nAAxu0ti8r5riiog6MzMng=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=SS2Zb5K/3uP1HmLgP5f7Kc0o6l6jaXc1h2Ey54o4xWjRVQ2UNf37tLM5WEe50CGgC jjKENZ2oGHnNGs3raVfzXB08AJoEh6qWZDSB6SzHTgjD+veeYAM/BS/82oWMPjCt0l VERgCXZiBWjaLaCxMTTLpXSsAI6Md8OKq+MiYnqY= From: David Gibson To: peter.maydell@linaro.org, groug@kaod.org Subject: [PULL 14/46] target/ppc: Create helper_scv Date: Tue, 4 May 2021 15:52:40 +1000 Message-Id: <20210504055312.306823-15-david@gibson.dropbear.id.au> X-Mailer: git-send-email 2.31.1 In-Reply-To: <20210504055312.306823-1-david@gibson.dropbear.id.au> References: <20210504055312.306823-1-david@gibson.dropbear.id.au> MIME-Version: 1.0 Received-SPF: pass client-ip=203.11.71.1; envelope-from=dgibson@ozlabs.org; helo=ozlabs.org X-Spam_score_int: -17 X-Spam_score: -1.8 X-Spam_bar: - X-Spam_report: (-1.8 / 5.0 requ) BAYES_00=-1.9, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_AU=-0.1, HEADER_FROM_DIFFERENT_DOMAINS=0.25, SPF_HELO_PASS=-0.001, SPF_PASS=-0.001 autolearn=no autolearn_force=no X-Spam_action: no action X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: Richard Henderson , qemu-ppc@nongnu.org, qemu-devel@nongnu.org, David Gibson Errors-To: qemu-devel-bounces+qemu-devel=archiver.kernel.org@nongnu.org Sender: "Qemu-devel" From: Richard Henderson Perform the test against FSCR_SCV at runtime, in the helper. This means we can remove the incorrect set against SCV in ppc_tr_init_disas_context and do not need to add an HFLAGS bit. Signed-off-by: Richard Henderson Message-Id: <20210323184340.619757-6-richard.henderson@linaro.org> Signed-off-by: David Gibson --- target/ppc/excp_helper.c | 9 +++++++++ target/ppc/helper.h | 1 + target/ppc/translate.c | 20 +++++++------------- 3 files changed, 17 insertions(+), 13 deletions(-) diff --git a/target/ppc/excp_helper.c b/target/ppc/excp_helper.c index 85de7e6c90..5c95e0c103 100644 --- a/target/ppc/excp_helper.c +++ b/target/ppc/excp_helper.c @@ -1130,6 +1130,15 @@ void helper_store_msr(CPUPPCState *env, target_ulong val) } #if defined(TARGET_PPC64) +void helper_scv(CPUPPCState *env, uint32_t lev) +{ + if (env->spr[SPR_FSCR] & (1ull << FSCR_SCV)) { + raise_exception_err(env, POWERPC_EXCP_SYSCALL_VECTORED, lev); + } else { + raise_exception_err(env, POWERPC_EXCP_FU, FSCR_IC_SCV); + } +} + void helper_pminsn(CPUPPCState *env, powerpc_pm_insn_t insn) { CPUState *cs; diff --git a/target/ppc/helper.h b/target/ppc/helper.h index 6a4dccf70c..513066d54d 100644 --- a/target/ppc/helper.h +++ b/target/ppc/helper.h @@ -13,6 +13,7 @@ DEF_HELPER_1(rfci, void, env) DEF_HELPER_1(rfdi, void, env) DEF_HELPER_1(rfmci, void, env) #if defined(TARGET_PPC64) +DEF_HELPER_2(scv, noreturn, env, i32) DEF_HELPER_2(pminsn, void, env, i32) DEF_HELPER_1(rfid, void, env) DEF_HELPER_1(rfscv, void, env) diff --git a/target/ppc/translate.c b/target/ppc/translate.c index 7912495f28..d48c554290 100644 --- a/target/ppc/translate.c +++ b/target/ppc/translate.c @@ -173,7 +173,6 @@ struct DisasContext { bool vsx_enabled; bool spe_enabled; bool tm_enabled; - bool scv_enabled; bool gtse; ppc_spr_t *spr_cb; /* Needed to check rights for mfspr/mtspr */ int singlestep_enabled; @@ -4081,15 +4080,16 @@ static void gen_sc(DisasContext *ctx) #if !defined(CONFIG_USER_ONLY) static void gen_scv(DisasContext *ctx) { - uint32_t lev; + uint32_t lev = (ctx->opcode >> 5) & 0x7F; - if (unlikely(!ctx->scv_enabled)) { - gen_exception_err(ctx, POWERPC_EXCP_FU, FSCR_IC_SCV); - return; + /* Set the PC back to the faulting instruction. */ + if (ctx->exception == POWERPC_EXCP_NONE) { + gen_update_nip(ctx, ctx->base.pc_next - 4); } + gen_helper_scv(cpu_env, tcg_constant_i32(lev)); - lev = (ctx->opcode >> 5) & 0x7F; - gen_exception_err(ctx, POWERPC_SYSCALL_VECTORED, lev); + /* This need not be exact, just not POWERPC_EXCP_NONE */ + ctx->exception = POWERPC_SYSCALL_VECTORED; } #endif #endif @@ -7907,12 +7907,6 @@ static void ppc_tr_init_disas_context(DisasContextBase *dcbase, CPUState *cs) ctx->spe_enabled = (hflags >> HFLAGS_SPE) & 1; ctx->altivec_enabled = (hflags >> HFLAGS_VR) & 1; ctx->vsx_enabled = (hflags >> HFLAGS_VSX) & 1; - if ((env->flags & POWERPC_FLAG_SCV) - && (env->spr[SPR_FSCR] & (1ull << FSCR_SCV))) { - ctx->scv_enabled = true; - } else { - ctx->scv_enabled = false; - } ctx->tm_enabled = (hflags >> HFLAGS_TM) & 1; ctx->gtse = !!(env->spr[SPR_LPCR] & LPCR_GTSE); From patchwork Tue May 4 05:52:41 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: David Gibson X-Patchwork-Id: 12237427 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-16.6 required=3.0 tests=BAYES_00,DKIM_INVALID, DKIM_SIGNED,HEADER_FROM_DIFFERENT_DOMAINS,INCLUDES_CR_TRAILER,INCLUDES_PATCH, MAILING_LIST_MULTI,SPF_HELO_NONE,SPF_PASS,USER_AGENT_GIT autolearn=ham autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id 2FCC7C433ED for ; Tue, 4 May 2021 06:02:49 +0000 (UTC) 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 mail.kernel.org (Postfix) with ESMTPS id E06A361159 for ; Tue, 4 May 2021 06:02:48 +0000 (UTC) DMARC-Filter: OpenDMARC Filter v1.3.2 mail.kernel.org E06A361159 Authentication-Results: mail.kernel.org; dmarc=none (p=none dis=none) header.from=gibson.dropbear.id.au Authentication-Results: mail.kernel.org; spf=pass smtp.mailfrom=qemu-devel-bounces+qemu-devel=archiver.kernel.org@nongnu.org Received: from localhost ([::1]:37274 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1ldo8t-0005Tt-Vl for qemu-devel@archiver.kernel.org; Tue, 04 May 2021 02:02:48 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]:60506) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1ldo02-0005Hc-IK; Tue, 04 May 2021 01:53:39 -0400 Received: from ozlabs.org ([203.11.71.1]:39851) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1ldnzz-0004kR-Cw; Tue, 04 May 2021 01:53:37 -0400 Received: by ozlabs.org (Postfix, from userid 1007) id 4FZ8CK4VJQz9sX3; Tue, 4 May 2021 15:53:17 +1000 (AEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=gibson.dropbear.id.au; s=201602; t=1620107597; bh=EOPu6ADeRLGhAyKKyY2SdVCCjqq706WI0Er+aWaZJ8o=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=AnXHInv5jo+304cUKO5rozSV2twH5FZNjMPDqQ4PAZRhJgM4jHLFwt1z0eNg/9RT2 fNu0Oj2NiodXUeoBknFdWAjIyrrOF7DHnKcQLiJTxC3KkWJX3jk1k/uIxZ6QVfD+V6 aPgE1SI5CLnU+ej1HgXGKMmtGt8a+TsF1/h3Uz78= From: David Gibson To: peter.maydell@linaro.org, groug@kaod.org Subject: [PULL 15/46] target/ppc: Put LPCR[GTSE] in hflags Date: Tue, 4 May 2021 15:52:41 +1000 Message-Id: <20210504055312.306823-16-david@gibson.dropbear.id.au> X-Mailer: git-send-email 2.31.1 In-Reply-To: <20210504055312.306823-1-david@gibson.dropbear.id.au> References: <20210504055312.306823-1-david@gibson.dropbear.id.au> MIME-Version: 1.0 Received-SPF: pass client-ip=203.11.71.1; envelope-from=dgibson@ozlabs.org; helo=ozlabs.org X-Spam_score_int: -17 X-Spam_score: -1.8 X-Spam_bar: - X-Spam_report: (-1.8 / 5.0 requ) BAYES_00=-1.9, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_AU=-0.1, HEADER_FROM_DIFFERENT_DOMAINS=0.25, SPF_HELO_PASS=-0.001, SPF_PASS=-0.001 autolearn=no autolearn_force=no X-Spam_action: no action X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: Richard Henderson , qemu-ppc@nongnu.org, qemu-devel@nongnu.org, David Gibson Errors-To: qemu-devel-bounces+qemu-devel=archiver.kernel.org@nongnu.org Sender: "Qemu-devel" From: Richard Henderson Because this bit was not in hflags, the privilege check for tlb instructions was essentially random. Recompute hflags when storing to LPCR. Reviewed-by: David Gibson Signed-off-by: Richard Henderson Message-Id: <20210323184340.619757-7-richard.henderson@linaro.org> Signed-off-by: David Gibson --- target/ppc/cpu.h | 1 + target/ppc/helper_regs.c | 3 +++ target/ppc/mmu-hash64.c | 3 +++ target/ppc/translate.c | 2 +- 4 files changed, 8 insertions(+), 1 deletion(-) diff --git a/target/ppc/cpu.h b/target/ppc/cpu.h index d5f362506a..3c28ddb331 100644 --- a/target/ppc/cpu.h +++ b/target/ppc/cpu.h @@ -596,6 +596,7 @@ enum { HFLAGS_LE = 0, /* MSR_LE -- comes from elsewhere on 601 */ HFLAGS_HV = 1, /* computed from MSR_HV and other state */ HFLAGS_64 = 2, /* computed from MSR_CE and MSR_SF */ + HFLAGS_GTSE = 3, /* computed from SPR_LPCR[GTSE] */ HFLAGS_DR = 4, /* MSR_DR */ HFLAGS_IR = 5, /* MSR_IR */ HFLAGS_SPE = 6, /* from MSR_SPE if cpu has SPE; avoid overlap w/ MSR_VR */ diff --git a/target/ppc/helper_regs.c b/target/ppc/helper_regs.c index e345966b6b..f85bb14d1d 100644 --- a/target/ppc/helper_regs.c +++ b/target/ppc/helper_regs.c @@ -149,6 +149,9 @@ void hreg_compute_hflags(CPUPPCState *env) if ((ppc_flags & POWERPC_FLAG_TM) && (msr & (1ull << MSR_TM))) { hflags |= 1 << HFLAGS_TM; } + if (env->spr[SPR_LPCR] & LPCR_GTSE) { + hflags |= 1 << HFLAGS_GTSE; + } #ifndef CONFIG_USER_ONLY if (!env->has_hv_mode || (msr & (1ull << MSR_HV))) { diff --git a/target/ppc/mmu-hash64.c b/target/ppc/mmu-hash64.c index 0fabc10302..d517a99832 100644 --- a/target/ppc/mmu-hash64.c +++ b/target/ppc/mmu-hash64.c @@ -30,6 +30,7 @@ #include "exec/log.h" #include "hw/hw.h" #include "mmu-book3s-v3.h" +#include "helper_regs.h" /* #define DEBUG_SLB */ @@ -1125,6 +1126,8 @@ void ppc_store_lpcr(PowerPCCPU *cpu, target_ulong val) CPUPPCState *env = &cpu->env; env->spr[SPR_LPCR] = val & pcc->lpcr_mask; + /* The gtse bit affects hflags */ + hreg_compute_hflags(env); } void helper_store_lpcr(CPUPPCState *env, target_ulong val) diff --git a/target/ppc/translate.c b/target/ppc/translate.c index d48c554290..5e629291d3 100644 --- a/target/ppc/translate.c +++ b/target/ppc/translate.c @@ -7908,7 +7908,7 @@ static void ppc_tr_init_disas_context(DisasContextBase *dcbase, CPUState *cs) ctx->altivec_enabled = (hflags >> HFLAGS_VR) & 1; ctx->vsx_enabled = (hflags >> HFLAGS_VSX) & 1; ctx->tm_enabled = (hflags >> HFLAGS_TM) & 1; - ctx->gtse = !!(env->spr[SPR_LPCR] & LPCR_GTSE); + ctx->gtse = (hflags >> HFLAGS_GTSE) & 1; ctx->singlestep_enabled = 0; if ((hflags >> HFLAGS_SE) & 1) { From patchwork Tue May 4 05:52:42 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: David Gibson X-Patchwork-Id: 12237453 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-16.6 required=3.0 tests=BAYES_00,DKIM_INVALID, DKIM_SIGNED,HEADER_FROM_DIFFERENT_DOMAINS,INCLUDES_CR_TRAILER,INCLUDES_PATCH, MAILING_LIST_MULTI,SPF_HELO_NONE,SPF_PASS,USER_AGENT_GIT autolearn=ham autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id E5AD9C433ED for ; Tue, 4 May 2021 06:21:49 +0000 (UTC) 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 mail.kernel.org (Postfix) with ESMTPS id 4927560E0C for ; Tue, 4 May 2021 06:21:49 +0000 (UTC) DMARC-Filter: OpenDMARC Filter v1.3.2 mail.kernel.org 4927560E0C Authentication-Results: mail.kernel.org; dmarc=none (p=none dis=none) header.from=gibson.dropbear.id.au Authentication-Results: mail.kernel.org; spf=pass smtp.mailfrom=qemu-devel-bounces+qemu-devel=archiver.kernel.org@nongnu.org Received: from localhost ([::1]:39066 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1ldoRI-0002HQ-7s for qemu-devel@archiver.kernel.org; Tue, 04 May 2021 02:21:48 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]:60528) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1ldo04-0005IM-FK; Tue, 04 May 2021 01:53:42 -0400 Received: from bilbo.ozlabs.org ([2401:3900:2:1::2]:51127 helo=ozlabs.org) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1ldo00-0004kV-Pa; Tue, 04 May 2021 01:53:39 -0400 Received: by ozlabs.org (Postfix, from userid 1007) id 4FZ8CK4xscz9sXH; Tue, 4 May 2021 15:53:17 +1000 (AEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=gibson.dropbear.id.au; s=201602; t=1620107597; bh=Xk1wYOuZSpZWxh2ux/tBAmxZ1jpImU1ImlZmhp9mW8o=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=azv2z9J/mErL83AOAoT9QXVFaLY4N1WtUEUecMWWwpubJbocbTTUdU+3M5FDyHf97 CzJDjWPDrPrJQlvptPRrFjXujgYi9ujgJyh1y9iM0yDmyVatnNOPqSjetDOBZ6/U2a 4CKRHOVczwG/GLggkGyJfrlOIqX6OrG2nJ4rjyKY= From: David Gibson To: peter.maydell@linaro.org, groug@kaod.org Subject: [PULL 16/46] target/ppc: Remove MSR_SA and MSR_AP from hflags Date: Tue, 4 May 2021 15:52:42 +1000 Message-Id: <20210504055312.306823-17-david@gibson.dropbear.id.au> X-Mailer: git-send-email 2.31.1 In-Reply-To: <20210504055312.306823-1-david@gibson.dropbear.id.au> References: <20210504055312.306823-1-david@gibson.dropbear.id.au> MIME-Version: 1.0 Received-SPF: pass client-ip=2401:3900:2:1::2; envelope-from=dgibson@ozlabs.org; helo=ozlabs.org X-Spam_score_int: -17 X-Spam_score: -1.8 X-Spam_bar: - X-Spam_report: (-1.8 / 5.0 requ) BAYES_00=-1.9, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_AU=-0.1, HEADER_FROM_DIFFERENT_DOMAINS=0.25, SPF_HELO_PASS=-0.001, SPF_PASS=-0.001 autolearn=no autolearn_force=no X-Spam_action: no action X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: Richard Henderson , qemu-ppc@nongnu.org, qemu-devel@nongnu.org, David Gibson Errors-To: qemu-devel-bounces+qemu-devel=archiver.kernel.org@nongnu.org Sender: "Qemu-devel" From: Richard Henderson Nothing within the translator -- or anywhere else for that matter -- checks MSR_SA or MSR_AP on the 602. This may be a mistake. However, for the moment, we need not record these bits in hflags. This allows us to simplify HFLAGS_VSX computation by moving it to overlap with MSR_VSX. Reviewed-by: David Gibson Signed-off-by: Richard Henderson Message-Id: <20210323184340.619757-8-richard.henderson@linaro.org> Signed-off-by: David Gibson --- target/ppc/cpu.h | 4 +--- target/ppc/helper_regs.c | 10 ++++------ 2 files changed, 5 insertions(+), 9 deletions(-) diff --git a/target/ppc/cpu.h b/target/ppc/cpu.h index 3c28ddb331..2f72f83ee3 100644 --- a/target/ppc/cpu.h +++ b/target/ppc/cpu.h @@ -600,14 +600,12 @@ enum { HFLAGS_DR = 4, /* MSR_DR */ HFLAGS_IR = 5, /* MSR_IR */ HFLAGS_SPE = 6, /* from MSR_SPE if cpu has SPE; avoid overlap w/ MSR_VR */ - HFLAGS_VSX = 7, /* from MSR_VSX if cpu has VSX; avoid overlap w/ MSR_AP */ HFLAGS_TM = 8, /* computed from MSR_TM */ HFLAGS_BE = 9, /* MSR_BE -- from elsewhere on embedded ppc */ HFLAGS_SE = 10, /* MSR_SE -- from elsewhere on embedded ppc */ HFLAGS_FP = 13, /* MSR_FP */ HFLAGS_PR = 14, /* MSR_PR */ - HFLAGS_SA = 22, /* MSR_SA */ - HFLAGS_AP = 23, /* MSR_AP */ + HFLAGS_VSX = 23, /* MSR_VSX if cpu has VSX */ HFLAGS_VR = 25, /* MSR_VR if cpu has VRE */ }; diff --git a/target/ppc/helper_regs.c b/target/ppc/helper_regs.c index f85bb14d1d..dd3cd770a3 100644 --- a/target/ppc/helper_regs.c +++ b/target/ppc/helper_regs.c @@ -99,11 +99,8 @@ void hreg_compute_hflags(CPUPPCState *env) QEMU_BUILD_BUG_ON(MSR_DR != HFLAGS_DR); QEMU_BUILD_BUG_ON(MSR_IR != HFLAGS_IR); QEMU_BUILD_BUG_ON(MSR_FP != HFLAGS_FP); - QEMU_BUILD_BUG_ON(MSR_SA != HFLAGS_SA); - QEMU_BUILD_BUG_ON(MSR_AP != HFLAGS_AP); msr_mask = ((1 << MSR_LE) | (1 << MSR_PR) | - (1 << MSR_DR) | (1 << MSR_IR) | - (1 << MSR_FP) | (1 << MSR_SA) | (1 << MSR_AP)); + (1 << MSR_DR) | (1 << MSR_IR) | (1 << MSR_FP)); if (ppc_flags & POWERPC_FLAG_HID0_LE) { /* @@ -143,8 +140,9 @@ void hreg_compute_hflags(CPUPPCState *env) QEMU_BUILD_BUG_ON(MSR_VR != HFLAGS_VR); msr_mask |= 1 << MSR_VR; } - if ((ppc_flags & POWERPC_FLAG_VSX) && (msr & (1 << MSR_VSX))) { - hflags |= 1 << HFLAGS_VSX; + if (ppc_flags & POWERPC_FLAG_VSX) { + QEMU_BUILD_BUG_ON(MSR_VSX != HFLAGS_VSX); + msr_mask |= 1 << MSR_VSX; } if ((ppc_flags & POWERPC_FLAG_TM) && (msr & (1ull << MSR_TM))) { hflags |= 1 << HFLAGS_TM; From patchwork Tue May 4 05:52:43 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: David Gibson X-Patchwork-Id: 12237449 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-16.6 required=3.0 tests=BAYES_00,DKIM_INVALID, DKIM_SIGNED,HEADER_FROM_DIFFERENT_DOMAINS,INCLUDES_CR_TRAILER,INCLUDES_PATCH, MAILING_LIST_MULTI,SPF_HELO_NONE,SPF_PASS,USER_AGENT_GIT autolearn=ham autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id 31BCFC433ED for ; Tue, 4 May 2021 06:18:34 +0000 (UTC) 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 mail.kernel.org (Postfix) with ESMTPS id C55FC613AA for ; Tue, 4 May 2021 06:18:33 +0000 (UTC) DMARC-Filter: OpenDMARC Filter v1.3.2 mail.kernel.org C55FC613AA Authentication-Results: mail.kernel.org; dmarc=none (p=none dis=none) header.from=gibson.dropbear.id.au Authentication-Results: mail.kernel.org; spf=pass smtp.mailfrom=qemu-devel-bounces+qemu-devel=archiver.kernel.org@nongnu.org Received: from localhost ([::1]:60736 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1ldoO8-0007ml-SQ for qemu-devel@archiver.kernel.org; Tue, 04 May 2021 02:18:32 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]:60556) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1ldo06-0005JT-DP; Tue, 04 May 2021 01:53:43 -0400 Received: from ozlabs.org ([203.11.71.1]:44901) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1ldo02-0004mZ-QF; Tue, 04 May 2021 01:53:41 -0400 Received: by ozlabs.org (Postfix, from userid 1007) id 4FZ8CK5GgVz9sXM; Tue, 4 May 2021 15:53:17 +1000 (AEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=gibson.dropbear.id.au; s=201602; t=1620107597; bh=PqIL/NNdjNzqldj5TBgHl3AG7TfjMwpEseQKUgN7u/c=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=YICwhH+PdEqi2j1lr/vqi1jyfu3DOdxQgkwywDqD4GY2n5jhTi3ue5qb6PS5a//Ww Hi6MKrlK2U4z+fzDLSc3r197bqkWwPB1cwlH6fIsb/7p7nh8Kg1ukQ8DKW3qHw9AaK wFFmyF15MW3Me3vuD8aRttgWx3hBF1mLXnbbBVhg= From: David Gibson To: peter.maydell@linaro.org, groug@kaod.org Subject: [PULL 17/46] target/ppc: Remove env->immu_idx and env->dmmu_idx Date: Tue, 4 May 2021 15:52:43 +1000 Message-Id: <20210504055312.306823-18-david@gibson.dropbear.id.au> X-Mailer: git-send-email 2.31.1 In-Reply-To: <20210504055312.306823-1-david@gibson.dropbear.id.au> References: <20210504055312.306823-1-david@gibson.dropbear.id.au> MIME-Version: 1.0 Received-SPF: pass client-ip=203.11.71.1; envelope-from=dgibson@ozlabs.org; helo=ozlabs.org X-Spam_score_int: -17 X-Spam_score: -1.8 X-Spam_bar: - X-Spam_report: (-1.8 / 5.0 requ) BAYES_00=-1.9, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_AU=-0.1, HEADER_FROM_DIFFERENT_DOMAINS=0.25, SPF_HELO_PASS=-0.001, SPF_PASS=-0.001 autolearn=no autolearn_force=no X-Spam_action: no action X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: Richard Henderson , qemu-ppc@nongnu.org, qemu-devel@nongnu.org, David Gibson Errors-To: qemu-devel-bounces+qemu-devel=archiver.kernel.org@nongnu.org Sender: "Qemu-devel" From: Richard Henderson We weren't recording MSR_GS in hflags, which means that BookE memory accesses were essentially random vs Guest State. Instead of adding this bit directly, record the completed mmu indexes instead. This makes it obvious that we are recording exactly the information that we need. This also means that we can stop directly recording MSR_IR. Reviewed-by: David Gibson Signed-off-by: Richard Henderson Message-Id: <20210323184340.619757-9-richard.henderson@linaro.org> Signed-off-by: David Gibson --- target/ppc/cpu.h | 12 ++++-- target/ppc/helper_regs.c | 89 +++++++++++++++++++--------------------- target/ppc/helper_regs.h | 1 - target/ppc/machine.c | 2 +- target/ppc/mem_helper.c | 2 +- target/ppc/translate.c | 6 +-- 6 files changed, 56 insertions(+), 56 deletions(-) diff --git a/target/ppc/cpu.h b/target/ppc/cpu.h index 2f72f83ee3..3d021f61f3 100644 --- a/target/ppc/cpu.h +++ b/target/ppc/cpu.h @@ -598,7 +598,6 @@ enum { HFLAGS_64 = 2, /* computed from MSR_CE and MSR_SF */ HFLAGS_GTSE = 3, /* computed from SPR_LPCR[GTSE] */ HFLAGS_DR = 4, /* MSR_DR */ - HFLAGS_IR = 5, /* MSR_IR */ HFLAGS_SPE = 6, /* from MSR_SPE if cpu has SPE; avoid overlap w/ MSR_VR */ HFLAGS_TM = 8, /* computed from MSR_TM */ HFLAGS_BE = 9, /* MSR_BE -- from elsewhere on embedded ppc */ @@ -607,6 +606,9 @@ enum { HFLAGS_PR = 14, /* MSR_PR */ HFLAGS_VSX = 23, /* MSR_VSX if cpu has VSX */ HFLAGS_VR = 25, /* MSR_VR if cpu has VRE */ + + HFLAGS_IMMU_IDX = 26, /* 26..28 -- the composite immu_idx */ + HFLAGS_DMMU_IDX = 29, /* 29..31 -- the composite dmmu_idx */ }; /*****************************************************************************/ @@ -1131,8 +1133,6 @@ struct CPUPPCState { /* These resources are used only in TCG */ uint32_t hflags; target_ulong hflags_compat_nmsr; /* for migration compatibility */ - int immu_idx; /* precomputed MMU index to speed up insn accesses */ - int dmmu_idx; /* precomputed MMU index to speed up data accesses */ /* Power management */ int (*check_pow)(CPUPPCState *env); @@ -1368,7 +1368,11 @@ int ppc_dcr_write(ppc_dcr_t *dcr_env, int dcrn, uint32_t val); #define MMU_USER_IDX 0 static inline int cpu_mmu_index(CPUPPCState *env, bool ifetch) { - return ifetch ? env->immu_idx : env->dmmu_idx; +#ifdef CONFIG_USER_ONLY + return MMU_USER_IDX; +#else + return (env->hflags >> (ifetch ? HFLAGS_IMMU_IDX : HFLAGS_DMMU_IDX)) & 7; +#endif } /* Compatibility modes */ diff --git a/target/ppc/helper_regs.c b/target/ppc/helper_regs.c index dd3cd770a3..5411a67e9a 100644 --- a/target/ppc/helper_regs.c +++ b/target/ppc/helper_regs.c @@ -43,49 +43,6 @@ void hreg_swap_gpr_tgpr(CPUPPCState *env) env->tgpr[3] = tmp; } -void hreg_compute_mem_idx(CPUPPCState *env) -{ - /* - * This is our encoding for server processors. The architecture - * specifies that there is no such thing as userspace with - * translation off, however it appears that MacOS does it and some - * 32-bit CPUs support it. Weird... - * - * 0 = Guest User space virtual mode - * 1 = Guest Kernel space virtual mode - * 2 = Guest User space real mode - * 3 = Guest Kernel space real mode - * 4 = HV User space virtual mode - * 5 = HV Kernel space virtual mode - * 6 = HV User space real mode - * 7 = HV Kernel space real mode - * - * For BookE, we need 8 MMU modes as follow: - * - * 0 = AS 0 HV User space - * 1 = AS 0 HV Kernel space - * 2 = AS 1 HV User space - * 3 = AS 1 HV Kernel space - * 4 = AS 0 Guest User space - * 5 = AS 0 Guest Kernel space - * 6 = AS 1 Guest User space - * 7 = AS 1 Guest Kernel space - */ - if (env->mmu_model & POWERPC_MMU_BOOKE) { - env->immu_idx = env->dmmu_idx = msr_pr ? 0 : 1; - env->immu_idx += msr_is ? 2 : 0; - env->dmmu_idx += msr_ds ? 2 : 0; - env->immu_idx += msr_gs ? 4 : 0; - env->dmmu_idx += msr_gs ? 4 : 0; - } else { - env->immu_idx = env->dmmu_idx = msr_pr ? 0 : 1; - env->immu_idx += msr_ir ? 0 : 2; - env->dmmu_idx += msr_dr ? 0 : 2; - env->immu_idx += msr_hv ? 4 : 0; - env->dmmu_idx += msr_hv ? 4 : 0; - } -} - void hreg_compute_hflags(CPUPPCState *env) { target_ulong msr = env->msr; @@ -97,10 +54,9 @@ void hreg_compute_hflags(CPUPPCState *env) QEMU_BUILD_BUG_ON(MSR_LE != HFLAGS_LE); QEMU_BUILD_BUG_ON(MSR_PR != HFLAGS_PR); QEMU_BUILD_BUG_ON(MSR_DR != HFLAGS_DR); - QEMU_BUILD_BUG_ON(MSR_IR != HFLAGS_IR); QEMU_BUILD_BUG_ON(MSR_FP != HFLAGS_FP); msr_mask = ((1 << MSR_LE) | (1 << MSR_PR) | - (1 << MSR_DR) | (1 << MSR_IR) | (1 << MSR_FP)); + (1 << MSR_DR) | (1 << MSR_FP)); if (ppc_flags & POWERPC_FLAG_HID0_LE) { /* @@ -155,10 +111,51 @@ void hreg_compute_hflags(CPUPPCState *env) if (!env->has_hv_mode || (msr & (1ull << MSR_HV))) { hflags |= 1 << HFLAGS_HV; } + + /* + * This is our encoding for server processors. The architecture + * specifies that there is no such thing as userspace with + * translation off, however it appears that MacOS does it and some + * 32-bit CPUs support it. Weird... + * + * 0 = Guest User space virtual mode + * 1 = Guest Kernel space virtual mode + * 2 = Guest User space real mode + * 3 = Guest Kernel space real mode + * 4 = HV User space virtual mode + * 5 = HV Kernel space virtual mode + * 6 = HV User space real mode + * 7 = HV Kernel space real mode + * + * For BookE, we need 8 MMU modes as follow: + * + * 0 = AS 0 HV User space + * 1 = AS 0 HV Kernel space + * 2 = AS 1 HV User space + * 3 = AS 1 HV Kernel space + * 4 = AS 0 Guest User space + * 5 = AS 0 Guest Kernel space + * 6 = AS 1 Guest User space + * 7 = AS 1 Guest Kernel space + */ + unsigned immu_idx, dmmu_idx; + dmmu_idx = msr & (1 << MSR_PR) ? 0 : 1; + if (env->mmu_model & POWERPC_MMU_BOOKE) { + dmmu_idx |= msr & (1 << MSR_GS) ? 4 : 0; + immu_idx = dmmu_idx; + immu_idx |= msr & (1 << MSR_IS) ? 2 : 0; + dmmu_idx |= msr & (1 << MSR_DS) ? 2 : 0; + } else { + dmmu_idx |= msr & (1ull << MSR_HV) ? 4 : 0; + immu_idx = dmmu_idx; + immu_idx |= msr & (1 << MSR_IR) ? 0 : 2; + dmmu_idx |= msr & (1 << MSR_DR) ? 0 : 2; + } + hflags |= immu_idx << HFLAGS_IMMU_IDX; + hflags |= dmmu_idx << HFLAGS_DMMU_IDX; #endif env->hflags = hflags | (msr & msr_mask); - hreg_compute_mem_idx(env); } void cpu_interrupt_exittb(CPUState *cs) diff --git a/target/ppc/helper_regs.h b/target/ppc/helper_regs.h index 4148a442b3..42f26870b9 100644 --- a/target/ppc/helper_regs.h +++ b/target/ppc/helper_regs.h @@ -21,7 +21,6 @@ #define HELPER_REGS_H void hreg_swap_gpr_tgpr(CPUPPCState *env); -void hreg_compute_mem_idx(CPUPPCState *env); void hreg_compute_hflags(CPUPPCState *env); void cpu_interrupt_exittb(CPUState *cs); int hreg_store_msr(CPUPPCState *env, target_ulong value, int alter_hv); diff --git a/target/ppc/machine.c b/target/ppc/machine.c index 09c5765a87..e5bffbe365 100644 --- a/target/ppc/machine.c +++ b/target/ppc/machine.c @@ -16,7 +16,7 @@ static void post_load_update_msr(CPUPPCState *env) /* * Invalidate all supported msr bits except MSR_TGPR/MSR_HVB - * before restoring. Note that this recomputes hflags and mem_idx. + * before restoring. Note that this recomputes hflags. */ env->msr ^= env->msr_mask & ~((1ULL << MSR_TGPR) | MSR_HVB); ppc_store_msr(env, msr); diff --git a/target/ppc/mem_helper.c b/target/ppc/mem_helper.c index f4f7e730de..444b2a30ef 100644 --- a/target/ppc/mem_helper.c +++ b/target/ppc/mem_helper.c @@ -278,7 +278,7 @@ static void dcbz_common(CPUPPCState *env, target_ulong addr, target_ulong mask, dcbz_size = env->dcache_line_size; uint32_t i; void *haddr; - int mmu_idx = epid ? PPC_TLB_EPID_STORE : env->dmmu_idx; + int mmu_idx = epid ? PPC_TLB_EPID_STORE : cpu_mmu_index(env, false); #if defined(TARGET_PPC64) /* Check for dcbz vs dcbzl on 970 */ diff --git a/target/ppc/translate.c b/target/ppc/translate.c index 5e629291d3..a53463b9b8 100644 --- a/target/ppc/translate.c +++ b/target/ppc/translate.c @@ -7658,8 +7658,8 @@ void ppc_cpu_dump_state(CPUState *cs, FILE *f, int flags) cs->cpu_index); qemu_fprintf(f, "MSR " TARGET_FMT_lx " HID0 " TARGET_FMT_lx " HF " "%08x iidx %d didx %d\n", - env->msr, env->spr[SPR_HID0], - env->hflags, env->immu_idx, env->dmmu_idx); + env->msr, env->spr[SPR_HID0], env->hflags, + cpu_mmu_index(env, true), cpu_mmu_index(env, false)); #if !defined(NO_TIMER_DUMP) qemu_fprintf(f, "TB %08" PRIu32 " %08" PRIu64 #if !defined(CONFIG_USER_ONLY) @@ -7885,7 +7885,7 @@ static void ppc_tr_init_disas_context(DisasContextBase *dcbase, CPUState *cs) ctx->exception = POWERPC_EXCP_NONE; ctx->spr_cb = env->spr_cb; ctx->pr = (hflags >> HFLAGS_PR) & 1; - ctx->mem_idx = env->dmmu_idx; + ctx->mem_idx = (hflags >> HFLAGS_DMMU_IDX) & 7; ctx->dr = (hflags >> HFLAGS_DR) & 1; ctx->hv = (hflags >> HFLAGS_HV) & 1; ctx->insns_flags = env->insns_flags; From patchwork Tue May 4 05:52:44 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: David Gibson X-Patchwork-Id: 12237447 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-16.6 required=3.0 tests=BAYES_00,DKIM_INVALID, DKIM_SIGNED,HEADER_FROM_DIFFERENT_DOMAINS,INCLUDES_CR_TRAILER,INCLUDES_PATCH, MAILING_LIST_MULTI,SPF_HELO_NONE,SPF_PASS,USER_AGENT_GIT autolearn=ham autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id E5615C433ED for ; Tue, 4 May 2021 06:18:29 +0000 (UTC) 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 mail.kernel.org (Postfix) with ESMTPS id 7913B610FC for ; Tue, 4 May 2021 06:18:29 +0000 (UTC) DMARC-Filter: OpenDMARC Filter v1.3.2 mail.kernel.org 7913B610FC Authentication-Results: mail.kernel.org; dmarc=none (p=none dis=none) header.from=gibson.dropbear.id.au Authentication-Results: mail.kernel.org; spf=pass smtp.mailfrom=qemu-devel-bounces+qemu-devel=archiver.kernel.org@nongnu.org Received: from localhost ([::1]:60312 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1ldoO4-0007bw-Ei for qemu-devel@archiver.kernel.org; Tue, 04 May 2021 02:18:28 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]:60554) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1ldo06-0005JS-DV; Tue, 04 May 2021 01:53:43 -0400 Received: from ozlabs.org ([2401:3900:2:1::2]:34629) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1ldo02-0004mm-M7; Tue, 04 May 2021 01:53:40 -0400 Received: by ozlabs.org (Postfix, from userid 1007) id 4FZ8CK6LJLz9sXN; Tue, 4 May 2021 15:53:17 +1000 (AEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=gibson.dropbear.id.au; s=201602; t=1620107597; bh=6Z6jyo3bzAclzYab342gMCr7M/a/GiGYHd806MpvsQw=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=kdtkbdHDsnqI4XUrnOnqBteRDvuttHL3b14s3mSU/7UfgOPrGjoCs2YI7HzkodiS9 8N7Io1PFS+i5uZQ60d8HaQ6Pu2+0aDNkm7vpRncRQN/pn4e312bhR1UhRgjZ6viYT/ fEKzeAboAzneRalwUmgzHNEYm0W1cvt7/RjUDqiY= From: David Gibson To: peter.maydell@linaro.org, groug@kaod.org Subject: [PULL 18/46] linux-user/ppc: Fix msr updates for signal handling Date: Tue, 4 May 2021 15:52:44 +1000 Message-Id: <20210504055312.306823-19-david@gibson.dropbear.id.au> X-Mailer: git-send-email 2.31.1 In-Reply-To: <20210504055312.306823-1-david@gibson.dropbear.id.au> References: <20210504055312.306823-1-david@gibson.dropbear.id.au> MIME-Version: 1.0 Received-SPF: pass client-ip=2401:3900:2:1::2; envelope-from=dgibson@ozlabs.org; helo=ozlabs.org X-Spam_score_int: -17 X-Spam_score: -1.8 X-Spam_bar: - X-Spam_report: (-1.8 / 5.0 requ) BAYES_00=-1.9, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_AU=-0.1, HEADER_FROM_DIFFERENT_DOMAINS=0.25, SPF_HELO_PASS=-0.001, SPF_PASS=-0.001 autolearn=no autolearn_force=no X-Spam_action: no action X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: Richard Henderson , qemu-ppc@nongnu.org, qemu-devel@nongnu.org, David Gibson Errors-To: qemu-devel-bounces+qemu-devel=archiver.kernel.org@nongnu.org Sender: "Qemu-devel" From: Richard Henderson In save_user_regs, there are two bugs where we OR in a bit number instead of the bit, clobbering the low bits of MSR. However: The MSR_VR and MSR_SPE bits control the availability of the insns. If the bits were not already set in MSR, then any attempt to access those registers would result in SIGILL. For linux-user, we always initialize MSR to the capabilities of the cpu. We *could* add checks vs MSR where we currently check insn_flags and insn_flags2, but we know they match. Also, there's a stray cut-and-paste comment in restore. Then, do not force little-endian binaries into big-endian mode. Finally, use ppc_store_msr for the update to affect hflags. Which is the reason none of these bugs were previously noticed. Signed-off-by: Richard Henderson Message-Id: <20210323184340.619757-10-richard.henderson@linaro.org> Signed-off-by: David Gibson --- linux-user/ppc/cpu_loop.c | 5 +++-- linux-user/ppc/signal.c | 23 +++++++++++------------ 2 files changed, 14 insertions(+), 14 deletions(-) diff --git a/linux-user/ppc/cpu_loop.c b/linux-user/ppc/cpu_loop.c index df71e15a25..4a0f6c8dc2 100644 --- a/linux-user/ppc/cpu_loop.c +++ b/linux-user/ppc/cpu_loop.c @@ -492,11 +492,12 @@ void target_cpu_copy_regs(CPUArchState *env, struct target_pt_regs *regs) #if defined(TARGET_PPC64) int flag = (env->insns_flags2 & PPC2_BOOKE206) ? MSR_CM : MSR_SF; #if defined(TARGET_ABI32) - env->msr &= ~((target_ulong)1 << flag); + ppc_store_msr(env, env->msr & ~((target_ulong)1 << flag)); #else - env->msr |= (target_ulong)1 << flag; + ppc_store_msr(env, env->msr | (target_ulong)1 << flag); #endif #endif + env->nip = regs->nip; for(i = 0; i < 32; i++) { env->gpr[i] = regs->gpr[i]; diff --git a/linux-user/ppc/signal.c b/linux-user/ppc/signal.c index b78613f7c8..bad38f8ed9 100644 --- a/linux-user/ppc/signal.c +++ b/linux-user/ppc/signal.c @@ -261,9 +261,6 @@ static void save_user_regs(CPUPPCState *env, struct target_mcontext *frame) __put_user(avr->u64[PPC_VEC_HI], &vreg->u64[0]); __put_user(avr->u64[PPC_VEC_LO], &vreg->u64[1]); } - /* Set MSR_VR in the saved MSR value to indicate that - frame->mc_vregs contains valid data. */ - msr |= MSR_VR; #if defined(TARGET_PPC64) vrsave = (uint32_t *)&frame->mc_vregs.altivec[33]; /* 64-bit needs to put a pointer to the vectors in the frame */ @@ -300,9 +297,6 @@ static void save_user_regs(CPUPPCState *env, struct target_mcontext *frame) for (i = 0; i < ARRAY_SIZE(env->gprh); i++) { __put_user(env->gprh[i], &frame->mc_vregs.spe[i]); } - /* Set MSR_SPE in the saved MSR value to indicate that - frame->mc_vregs contains valid data. */ - msr |= MSR_SPE; __put_user(env->spe_fscr, &frame->mc_vregs.spe[32]); } #endif @@ -354,8 +348,10 @@ static void restore_user_regs(CPUPPCState *env, __get_user(msr, &frame->mc_gregs[TARGET_PT_MSR]); /* If doing signal return, restore the previous little-endian mode. */ - if (sig) - env->msr = (env->msr & ~(1ull << MSR_LE)) | (msr & (1ull << MSR_LE)); + if (sig) { + ppc_store_msr(env, ((env->msr & ~(1ull << MSR_LE)) | + (msr & (1ull << MSR_LE)))); + } /* Restore Altivec registers if necessary. */ if (env->insns_flags & PPC_ALTIVEC) { @@ -376,8 +372,6 @@ static void restore_user_regs(CPUPPCState *env, __get_user(avr->u64[PPC_VEC_HI], &vreg->u64[0]); __get_user(avr->u64[PPC_VEC_LO], &vreg->u64[1]); } - /* Set MSR_VEC in the saved MSR value to indicate that - frame->mc_vregs contains valid data. */ #if defined(TARGET_PPC64) vrsave = (uint32_t *)&v_regs[33]; #else @@ -468,7 +462,7 @@ void setup_frame(int sig, struct target_sigaction *ka, env->nip = (target_ulong) ka->_sa_handler; /* Signal handlers are entered in big-endian mode. */ - env->msr &= ~(1ull << MSR_LE); + ppc_store_msr(env, env->msr & ~(1ull << MSR_LE)); unlock_user_struct(frame, frame_addr, 1); return; @@ -563,8 +557,13 @@ void setup_rt_frame(int sig, struct target_sigaction *ka, env->nip = (target_ulong) ka->_sa_handler; #endif +#ifdef TARGET_WORDS_BIGENDIAN /* Signal handlers are entered in big-endian mode. */ - env->msr &= ~(1ull << MSR_LE); + ppc_store_msr(env, env->msr & ~(1ull << MSR_LE)); +#else + /* Signal handlers are entered in little-endian mode. */ + ppc_store_msr(env, env->msr | (1ull << MSR_LE)); +#endif unlock_user_struct(rt_sf, rt_sf_addr, 1); return; From patchwork Tue May 4 05:52:45 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: David Gibson X-Patchwork-Id: 12237443 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-16.6 required=3.0 tests=BAYES_00,DKIM_INVALID, DKIM_SIGNED,HEADER_FROM_DIFFERENT_DOMAINS,INCLUDES_CR_TRAILER,INCLUDES_PATCH, MAILING_LIST_MULTI,SPF_HELO_NONE,SPF_PASS,USER_AGENT_GIT autolearn=ham autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id A3771C433ED for ; Tue, 4 May 2021 06:15:04 +0000 (UTC) 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 mail.kernel.org (Postfix) with ESMTPS id 22A4160FEB for ; Tue, 4 May 2021 06:15:04 +0000 (UTC) DMARC-Filter: OpenDMARC Filter v1.3.2 mail.kernel.org 22A4160FEB Authentication-Results: mail.kernel.org; dmarc=none (p=none dis=none) header.from=gibson.dropbear.id.au Authentication-Results: mail.kernel.org; spf=pass smtp.mailfrom=qemu-devel-bounces+qemu-devel=archiver.kernel.org@nongnu.org Received: from localhost ([::1]:56012 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1ldoKl-0005Vv-1j for qemu-devel@archiver.kernel.org; Tue, 04 May 2021 02:15:03 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]:60574) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1ldo08-0005KM-HP; Tue, 04 May 2021 01:53:44 -0400 Received: from ozlabs.org ([2401:3900:2:1::2]:39689) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1ldo04-0004o5-K3; Tue, 04 May 2021 01:53:43 -0400 Received: by ozlabs.org (Postfix, from userid 1007) id 4FZ8CK6f1gz9sXS; Tue, 4 May 2021 15:53:17 +1000 (AEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=gibson.dropbear.id.au; s=201602; t=1620107597; bh=sCuff11fEliXRuJdwQKxzTDCAkDLJs5IHy1UGt0Z4sk=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=GWWgbX9NvZERlsoa7sLo19BqB0OCR7TupQZfWJJVJZ8V662dD4eV8bCrG/v2GViXG ZUytIdDmkKbADSwhNDjfRaDzHMNivUYYBhdAcA4irFo6lUUZt5lXoLSbZ+SoQoW+op RpIkhdpqrP4vmAE7MDMvroObBAvb1eIkCNcqK1UQ= From: David Gibson To: peter.maydell@linaro.org, groug@kaod.org Subject: [PULL 19/46] target/ppc: Validate hflags with CONFIG_DEBUG_TCG Date: Tue, 4 May 2021 15:52:45 +1000 Message-Id: <20210504055312.306823-20-david@gibson.dropbear.id.au> X-Mailer: git-send-email 2.31.1 In-Reply-To: <20210504055312.306823-1-david@gibson.dropbear.id.au> References: <20210504055312.306823-1-david@gibson.dropbear.id.au> MIME-Version: 1.0 Received-SPF: pass client-ip=2401:3900:2:1::2; envelope-from=dgibson@ozlabs.org; helo=ozlabs.org X-Spam_score_int: -17 X-Spam_score: -1.8 X-Spam_bar: - X-Spam_report: (-1.8 / 5.0 requ) BAYES_00=-1.9, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_AU=-0.1, HEADER_FROM_DIFFERENT_DOMAINS=0.25, SPF_HELO_PASS=-0.001, SPF_PASS=-0.001 autolearn=no autolearn_force=no X-Spam_action: no action X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: Richard Henderson , qemu-ppc@nongnu.org, qemu-devel@nongnu.org, David Gibson Errors-To: qemu-devel-bounces+qemu-devel=archiver.kernel.org@nongnu.org Sender: "Qemu-devel" From: Richard Henderson Verify that hflags was updated correctly whenever we change cpu state that is used by hflags. Signed-off-by: Richard Henderson Message-Id: <20210323184340.619757-11-richard.henderson@linaro.org> Signed-off-by: David Gibson --- target/ppc/cpu.h | 5 +++++ target/ppc/helper_regs.c | 29 +++++++++++++++++++++++++++-- 2 files changed, 32 insertions(+), 2 deletions(-) diff --git a/target/ppc/cpu.h b/target/ppc/cpu.h index 3d021f61f3..69fc9a2831 100644 --- a/target/ppc/cpu.h +++ b/target/ppc/cpu.h @@ -2425,6 +2425,10 @@ void cpu_write_xer(CPUPPCState *env, target_ulong xer); */ #define is_book3s_arch2x(ctx) (!!((ctx)->insns_flags & PPC_SEGMENT_64B)) +#ifdef CONFIG_DEBUG_TCG +void cpu_get_tb_cpu_state(CPUPPCState *env, target_ulong *pc, + target_ulong *cs_base, uint32_t *flags); +#else static inline void cpu_get_tb_cpu_state(CPUPPCState *env, target_ulong *pc, target_ulong *cs_base, uint32_t *flags) { @@ -2432,6 +2436,7 @@ static inline void cpu_get_tb_cpu_state(CPUPPCState *env, target_ulong *pc, *cs_base = 0; *flags = env->hflags; } +#endif void QEMU_NORETURN raise_exception(CPUPPCState *env, uint32_t exception); void QEMU_NORETURN raise_exception_ra(CPUPPCState *env, uint32_t exception, diff --git a/target/ppc/helper_regs.c b/target/ppc/helper_regs.c index 5411a67e9a..3723872aa6 100644 --- a/target/ppc/helper_regs.c +++ b/target/ppc/helper_regs.c @@ -43,7 +43,7 @@ void hreg_swap_gpr_tgpr(CPUPPCState *env) env->tgpr[3] = tmp; } -void hreg_compute_hflags(CPUPPCState *env) +static uint32_t hreg_compute_hflags_value(CPUPPCState *env) { target_ulong msr = env->msr; uint32_t ppc_flags = env->flags; @@ -155,8 +155,33 @@ void hreg_compute_hflags(CPUPPCState *env) hflags |= dmmu_idx << HFLAGS_DMMU_IDX; #endif - env->hflags = hflags | (msr & msr_mask); + return hflags | (msr & msr_mask); +} + +void hreg_compute_hflags(CPUPPCState *env) +{ + env->hflags = hreg_compute_hflags_value(env); +} + +#ifdef CONFIG_DEBUG_TCG +void cpu_get_tb_cpu_state(CPUPPCState *env, target_ulong *pc, + target_ulong *cs_base, uint32_t *flags) +{ + uint32_t hflags_current = env->hflags; + uint32_t hflags_rebuilt; + + *pc = env->nip; + *cs_base = 0; + *flags = hflags_current; + + hflags_rebuilt = hreg_compute_hflags_value(env); + if (unlikely(hflags_current != hflags_rebuilt)) { + cpu_abort(env_cpu(env), + "TCG hflags mismatch (current:0x%08x rebuilt:0x%08x)\n", + hflags_current, hflags_rebuilt); + } } +#endif void cpu_interrupt_exittb(CPUState *cs) { From patchwork Tue May 4 05:52:46 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: David Gibson X-Patchwork-Id: 12237455 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-16.6 required=3.0 tests=BAYES_00,DKIM_INVALID, DKIM_SIGNED,HEADER_FROM_DIFFERENT_DOMAINS,INCLUDES_CR_TRAILER,INCLUDES_PATCH, MAILING_LIST_MULTI,SPF_HELO_NONE,SPF_PASS,USER_AGENT_GIT autolearn=ham autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id 4FC34C433B4 for ; Tue, 4 May 2021 06:22:12 +0000 (UTC) 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 mail.kernel.org (Postfix) with ESMTPS id E0CA2613AA for ; Tue, 4 May 2021 06:22:11 +0000 (UTC) DMARC-Filter: OpenDMARC Filter v1.3.2 mail.kernel.org E0CA2613AA Authentication-Results: mail.kernel.org; dmarc=none (p=none dis=none) header.from=gibson.dropbear.id.au Authentication-Results: mail.kernel.org; spf=pass smtp.mailfrom=qemu-devel-bounces+qemu-devel=archiver.kernel.org@nongnu.org Received: from localhost ([::1]:41112 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1ldoRf-0003An-09 for qemu-devel@archiver.kernel.org; Tue, 04 May 2021 02:22:11 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]:60576) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1ldo08-0005KW-Fw; Tue, 04 May 2021 01:53:44 -0400 Received: from bilbo.ozlabs.org ([2401:3900:2:1::2]:44361 helo=ozlabs.org) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1ldo04-0004o7-JW; Tue, 04 May 2021 01:53:43 -0400 Received: by ozlabs.org (Postfix, from userid 1007) id 4FZ8CK73jGz9sXV; Tue, 4 May 2021 15:53:17 +1000 (AEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=gibson.dropbear.id.au; s=201602; t=1620107597; bh=SsKlfI6yrduwGMnjRDoeM7J1/IlBU2XdXbbenbXefC8=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=PWGZHYa0ysxtJKm5AcUcl6LZKm5I5Gn/qPTc0ecisuoURXBIDlRjpBWwOjTZeu4j4 aFZALAYDQW8lxxFwv1eO0DXkHMo4f/FKkw8xOg5/z+Qdqh29kOXaELB69Mw0/kKKii Fo3FCOSVKvmf2b0r3O9j+HEhqO0TzaVxuZNY7bK0= From: David Gibson To: peter.maydell@linaro.org, groug@kaod.org Subject: [PULL 20/46] vt82c686: QOM-ify superio related functionality Date: Tue, 4 May 2021 15:52:46 +1000 Message-Id: <20210504055312.306823-21-david@gibson.dropbear.id.au> X-Mailer: git-send-email 2.31.1 In-Reply-To: <20210504055312.306823-1-david@gibson.dropbear.id.au> References: <20210504055312.306823-1-david@gibson.dropbear.id.au> MIME-Version: 1.0 Received-SPF: pass client-ip=2401:3900:2:1::2; envelope-from=dgibson@ozlabs.org; helo=ozlabs.org X-Spam_score_int: -17 X-Spam_score: -1.8 X-Spam_bar: - X-Spam_report: (-1.8 / 5.0 requ) BAYES_00=-1.9, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_AU=-0.1, HEADER_FROM_DIFFERENT_DOMAINS=0.25, SPF_HELO_PASS=-0.001, SPF_PASS=-0.001 autolearn=no autolearn_force=no X-Spam_action: no action X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: Mark Cave-Ayland , David Gibson , qemu-ppc@nongnu.org, qemu-devel@nongnu.org Errors-To: qemu-devel-bounces+qemu-devel=archiver.kernel.org@nongnu.org Sender: "Qemu-devel" From: BALATON Zoltan Collect superio functionality and its controlling config registers handling in an abstract VIA_SUPERIO class that is a subclass of ISA_SUPERIO and put vt82c686b specific parts in a subclass of this abstract class. Signed-off-by: BALATON Zoltan Reviewed-by: Mark Cave-Ayland Message-Id: Signed-off-by: David Gibson --- hw/isa/vt82c686.c | 196 +++++++++++++++++++++++++------------- include/hw/isa/vt82c686.h | 1 - 2 files changed, 132 insertions(+), 65 deletions(-) diff --git a/hw/isa/vt82c686.c b/hw/isa/vt82c686.c index 98325bb32b..ea55117724 100644 --- a/hw/isa/vt82c686.c +++ b/hw/isa/vt82c686.c @@ -265,15 +265,80 @@ static const TypeInfo vt8231_pm_info = { }; -typedef struct SuperIOConfig { +#define TYPE_VIA_SUPERIO "via-superio" +OBJECT_DECLARE_SIMPLE_TYPE(ViaSuperIOState, VIA_SUPERIO) + +struct ViaSuperIOState { + ISASuperIODevice superio; uint8_t regs[0x100]; + const MemoryRegionOps *io_ops; MemoryRegion io; -} SuperIOConfig; +}; + +static inline void via_superio_io_enable(ViaSuperIOState *s, bool enable) +{ + memory_region_set_enabled(&s->io, enable); +} + +static void via_superio_realize(DeviceState *d, Error **errp) +{ + ViaSuperIOState *s = VIA_SUPERIO(d); + ISASuperIOClass *ic = ISA_SUPERIO_GET_CLASS(s); + Error *local_err = NULL; + + assert(s->io_ops); + ic->parent_realize(d, &local_err); + if (local_err) { + error_propagate(errp, local_err); + return; + } + memory_region_init_io(&s->io, OBJECT(d), s->io_ops, s, "via-superio", 2); + memory_region_set_enabled(&s->io, false); + /* The floppy also uses 0x3f0 and 0x3f1 but this seems to work anyway */ + memory_region_add_subregion(isa_address_space_io(ISA_DEVICE(s)), 0x3f0, + &s->io); +} + +static uint64_t via_superio_cfg_read(void *opaque, hwaddr addr, unsigned size) +{ + ViaSuperIOState *sc = opaque; + uint8_t idx = sc->regs[0]; + uint8_t val = sc->regs[idx]; + + if (addr == 0) { + return idx; + } + if (addr == 1 && idx == 0) { + val = 0; /* reading reg 0 where we store index value */ + } + trace_via_superio_read(idx, val); + return val; +} + +static void via_superio_class_init(ObjectClass *klass, void *data) +{ + DeviceClass *dc = DEVICE_CLASS(klass); + ISASuperIOClass *sc = ISA_SUPERIO_CLASS(klass); + + sc->parent_realize = dc->realize; + dc->realize = via_superio_realize; +} + +static const TypeInfo via_superio_info = { + .name = TYPE_VIA_SUPERIO, + .parent = TYPE_ISA_SUPERIO, + .instance_size = sizeof(ViaSuperIOState), + .class_size = sizeof(ISASuperIOClass), + .class_init = via_superio_class_init, + .abstract = true, +}; + +#define TYPE_VT82C686B_SUPERIO "vt82c686b-superio" -static void superio_cfg_write(void *opaque, hwaddr addr, uint64_t data, - unsigned size) +static void vt82c686b_superio_cfg_write(void *opaque, hwaddr addr, + uint64_t data, unsigned size) { - SuperIOConfig *sc = opaque; + ViaSuperIOState *sc = opaque; uint8_t idx = sc->regs[0]; if (addr == 0) { /* config index register */ @@ -304,25 +369,9 @@ static void superio_cfg_write(void *opaque, hwaddr addr, uint64_t data, sc->regs[idx] = data; } -static uint64_t superio_cfg_read(void *opaque, hwaddr addr, unsigned size) -{ - SuperIOConfig *sc = opaque; - uint8_t idx = sc->regs[0]; - uint8_t val = sc->regs[idx]; - - if (addr == 0) { - return idx; - } - if (addr == 1 && idx == 0) { - val = 0; /* reading reg 0 where we store index value */ - } - trace_via_superio_read(idx, val); - return val; -} - -static const MemoryRegionOps superio_cfg_ops = { - .read = superio_cfg_read, - .write = superio_cfg_write, +static const MemoryRegionOps vt82c686b_superio_cfg_ops = { + .read = via_superio_cfg_read, + .write = vt82c686b_superio_cfg_write, .endianness = DEVICE_NATIVE_ENDIAN, .impl = { .min_access_size = 1, @@ -330,13 +379,66 @@ static const MemoryRegionOps superio_cfg_ops = { }, }; +static void vt82c686b_superio_reset(DeviceState *dev) +{ + ViaSuperIOState *s = VIA_SUPERIO(dev); + + memset(s->regs, 0, sizeof(s->regs)); + /* Device ID */ + vt82c686b_superio_cfg_write(s, 0, 0xe0, 1); + vt82c686b_superio_cfg_write(s, 1, 0x3c, 1); + /* Function select - all disabled */ + vt82c686b_superio_cfg_write(s, 0, 0xe2, 1); + vt82c686b_superio_cfg_write(s, 1, 0x03, 1); + /* Floppy ctrl base addr 0x3f0-7 */ + vt82c686b_superio_cfg_write(s, 0, 0xe3, 1); + vt82c686b_superio_cfg_write(s, 1, 0xfc, 1); + /* Parallel port base addr 0x378-f */ + vt82c686b_superio_cfg_write(s, 0, 0xe6, 1); + vt82c686b_superio_cfg_write(s, 1, 0xde, 1); + /* Serial port 1 base addr 0x3f8-f */ + vt82c686b_superio_cfg_write(s, 0, 0xe7, 1); + vt82c686b_superio_cfg_write(s, 1, 0xfe, 1); + /* Serial port 2 base addr 0x2f8-f */ + vt82c686b_superio_cfg_write(s, 0, 0xe8, 1); + vt82c686b_superio_cfg_write(s, 1, 0xbe, 1); + + vt82c686b_superio_cfg_write(s, 0, 0, 1); +} + +static void vt82c686b_superio_init(Object *obj) +{ + VIA_SUPERIO(obj)->io_ops = &vt82c686b_superio_cfg_ops; +} + +static void vt82c686b_superio_class_init(ObjectClass *klass, void *data) +{ + DeviceClass *dc = DEVICE_CLASS(klass); + ISASuperIOClass *sc = ISA_SUPERIO_CLASS(klass); + + dc->reset = vt82c686b_superio_reset; + sc->serial.count = 2; + sc->parallel.count = 1; + sc->ide.count = 0; /* emulated by via-ide */ + sc->floppy.count = 1; +} + +static const TypeInfo vt82c686b_superio_info = { + .name = TYPE_VT82C686B_SUPERIO, + .parent = TYPE_VIA_SUPERIO, + .instance_size = sizeof(ViaSuperIOState), + .instance_init = vt82c686b_superio_init, + .class_size = sizeof(ISASuperIOClass), + .class_init = vt82c686b_superio_class_init, +}; + OBJECT_DECLARE_SIMPLE_TYPE(VT82C686BISAState, VT82C686B_ISA) struct VT82C686BISAState { PCIDevice dev; qemu_irq cpu_intr; - SuperIOConfig superio_cfg; + ViaSuperIOState *via_sio; }; static void via_isa_request_i8259_irq(void *opaque, int irq, int level) @@ -354,7 +456,7 @@ static void vt82c686b_write_config(PCIDevice *d, uint32_t addr, pci_default_write_config(d, addr, val, len); if (addr == 0x85) { /* BIT(1): enable or disable superio config io ports */ - memory_region_set_enabled(&s->superio_cfg.io, val & BIT(1)); + via_superio_io_enable(s->via_sio, val & BIT(1)); } } @@ -386,13 +488,6 @@ static void vt82c686b_isa_reset(DeviceState *dev) pci_conf[0x5a] = 0x04; /* KBC/RTC Control*/ pci_conf[0x5f] = 0x04; pci_conf[0x77] = 0x10; /* GPIO Control 1/2/3/4 */ - - s->superio_cfg.regs[0xe0] = 0x3c; /* Device ID */ - s->superio_cfg.regs[0xe2] = 0x03; /* Function select */ - s->superio_cfg.regs[0xe3] = 0xfc; /* Floppy ctrl base addr */ - s->superio_cfg.regs[0xe6] = 0xde; /* Parallel port base addr */ - s->superio_cfg.regs[0xe7] = 0xfe; /* Serial port 1 base addr */ - s->superio_cfg.regs[0xe8] = 0xbe; /* Serial port 2 base addr */ } static void vt82c686b_realize(PCIDevice *d, Error **errp) @@ -410,7 +505,8 @@ static void vt82c686b_realize(PCIDevice *d, Error **errp) isa_bus_irqs(isa_bus, i8259_init(isa_bus, *isa_irq)); i8254_pit_init(isa_bus, 0x40, 0, NULL); i8257_dma_init(isa_bus, 0); - isa_create_simple(isa_bus, TYPE_VT82C686B_SUPERIO); + s->via_sio = VIA_SUPERIO(isa_create_simple(isa_bus, + TYPE_VT82C686B_SUPERIO)); mc146818_rtc_init(isa_bus, 2000, NULL); for (i = 0; i < PCI_CONFIG_HEADER_SIZE; i++) { @@ -418,16 +514,6 @@ static void vt82c686b_realize(PCIDevice *d, Error **errp) d->wmask[i] = 0; } } - - memory_region_init_io(&s->superio_cfg.io, OBJECT(d), &superio_cfg_ops, - &s->superio_cfg, "superio_cfg", 2); - memory_region_set_enabled(&s->superio_cfg.io, false); - /* - * The floppy also uses 0x3f0 and 0x3f1. - * But we do not emulate a floppy, so just set it here. - */ - memory_region_add_subregion(isa_bus->address_space_io, 0x3f0, - &s->superio_cfg.io); } static void via_class_init(ObjectClass *klass, void *data) @@ -463,32 +549,14 @@ static const TypeInfo via_info = { }; -static void vt82c686b_superio_class_init(ObjectClass *klass, void *data) -{ - ISASuperIOClass *sc = ISA_SUPERIO_CLASS(klass); - - sc->serial.count = 2; - sc->parallel.count = 1; - sc->ide.count = 0; - sc->floppy.count = 1; -} - -static const TypeInfo via_superio_info = { - .name = TYPE_VT82C686B_SUPERIO, - .parent = TYPE_ISA_SUPERIO, - .instance_size = sizeof(ISASuperIODevice), - .class_size = sizeof(ISASuperIOClass), - .class_init = vt82c686b_superio_class_init, -}; - - static void vt82c686b_register_types(void) { type_register_static(&via_pm_info); type_register_static(&vt82c686b_pm_info); type_register_static(&vt8231_pm_info); - type_register_static(&via_info); type_register_static(&via_superio_info); + type_register_static(&vt82c686b_superio_info); + type_register_static(&via_info); } type_init(vt82c686b_register_types) diff --git a/include/hw/isa/vt82c686.h b/include/hw/isa/vt82c686.h index 9b6d610e83..0692b9a527 100644 --- a/include/hw/isa/vt82c686.h +++ b/include/hw/isa/vt82c686.h @@ -2,7 +2,6 @@ #define HW_VT82C686_H #define TYPE_VT82C686B_ISA "vt82c686b-isa" -#define TYPE_VT82C686B_SUPERIO "vt82c686b-superio" #define TYPE_VT82C686B_PM "vt82c686b-pm" #define TYPE_VT8231_PM "vt8231-pm" #define TYPE_VIA_AC97 "via-ac97" From patchwork Tue May 4 05:52:47 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: David Gibson X-Patchwork-Id: 12237473 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-16.6 required=3.0 tests=BAYES_00,DKIM_INVALID, DKIM_SIGNED,HEADER_FROM_DIFFERENT_DOMAINS,INCLUDES_CR_TRAILER,INCLUDES_PATCH, MAILING_LIST_MULTI,SPF_HELO_NONE,SPF_PASS,USER_AGENT_GIT autolearn=ham autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id BC283C433ED for ; Tue, 4 May 2021 06:29:20 +0000 (UTC) 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 mail.kernel.org (Postfix) with ESMTPS id 67DBD61183 for ; Tue, 4 May 2021 06:29:20 +0000 (UTC) DMARC-Filter: OpenDMARC Filter v1.3.2 mail.kernel.org 67DBD61183 Authentication-Results: mail.kernel.org; dmarc=none (p=none dis=none) header.from=gibson.dropbear.id.au Authentication-Results: mail.kernel.org; spf=pass smtp.mailfrom=qemu-devel-bounces+qemu-devel=archiver.kernel.org@nongnu.org Received: from localhost ([::1]:53276 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1ldoYS-00005b-1y for qemu-devel@archiver.kernel.org; Tue, 04 May 2021 02:29:12 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]:60638) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1ldo0R-0005vC-1C; Tue, 04 May 2021 01:54:03 -0400 Received: from bilbo.ozlabs.org ([2401:3900:2:1::2]:50861 helo=ozlabs.org) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1ldo0O-0004o8-KR; Tue, 04 May 2021 01:54:02 -0400 Received: by ozlabs.org (Postfix, from userid 1007) id 4FZ8CL0JWMz9sXb; Tue, 4 May 2021 15:53:17 +1000 (AEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=gibson.dropbear.id.au; s=201602; t=1620107598; bh=AlcnnbXsSRiB8mP7j8xA/Pa1V2sXA654j3UmiJEirOc=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=mi5/qmZcQ5TaMbphgtnJG9xYNcZFy7au6bdIEBDdQ/7jORDZH4C7zvmCSvuk8CB7s SnTRsCTmlM1MO5vz3sw8ceYXNIXXrodbOokNSGt+crZmm/lYKX8LclIxq1u0XXHibT OahQ7EEpaY/BWnlAZTqGV9p8SWpurBZFs3/+PRyI= From: David Gibson To: peter.maydell@linaro.org, groug@kaod.org Subject: [PULL 21/46] vt82c686: Add VT8231_SUPERIO based on VIA_SUPERIO Date: Tue, 4 May 2021 15:52:47 +1000 Message-Id: <20210504055312.306823-22-david@gibson.dropbear.id.au> X-Mailer: git-send-email 2.31.1 In-Reply-To: <20210504055312.306823-1-david@gibson.dropbear.id.au> References: <20210504055312.306823-1-david@gibson.dropbear.id.au> MIME-Version: 1.0 Received-SPF: pass client-ip=2401:3900:2:1::2; envelope-from=dgibson@ozlabs.org; helo=ozlabs.org X-Spam_score_int: -17 X-Spam_score: -1.8 X-Spam_bar: - X-Spam_report: (-1.8 / 5.0 requ) BAYES_00=-1.9, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_AU=-0.1, HEADER_FROM_DIFFERENT_DOMAINS=0.25, SPF_HELO_PASS=-0.001, SPF_PASS=-0.001 autolearn=no autolearn_force=no X-Spam_action: no action X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: =?utf-8?q?Philippe_Mathieu-Daud=C3=A9?= , qemu-ppc@nongnu.org, qemu-devel@nongnu.org, David Gibson Errors-To: qemu-devel-bounces+qemu-devel=archiver.kernel.org@nongnu.org Sender: "Qemu-devel" From: BALATON Zoltan The VT8231 south bridge is very similar to VT82C686B but there are some differences in register addresses and functionality, e.g. the VT8231 only has one serial port. This commit adds VT8231_SUPERIO subclass based on the abstract VIA_SUPERIO class to emulate the superio part of VT8231. Signed-off-by: BALATON Zoltan Reviewed-by: Philippe Mathieu-Daudé Message-Id: <8108809321f9ecf3fb1aea22ddaeccc7c3a57c8e.1616680239.git.balaton@eik.bme.hu> Signed-off-by: David Gibson --- hw/isa/vt82c686.c | 102 ++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 102 insertions(+) diff --git a/hw/isa/vt82c686.c b/hw/isa/vt82c686.c index ea55117724..952c6fc867 100644 --- a/hw/isa/vt82c686.c +++ b/hw/isa/vt82c686.c @@ -433,6 +433,107 @@ static const TypeInfo vt82c686b_superio_info = { }; +#define TYPE_VT8231_SUPERIO "vt8231-superio" + +static void vt8231_superio_cfg_write(void *opaque, hwaddr addr, + uint64_t data, unsigned size) +{ + ViaSuperIOState *sc = opaque; + uint8_t idx = sc->regs[0]; + + if (addr == 0) { /* config index register */ + sc->regs[0] = data; + return; + } + + /* config data register */ + trace_via_superio_write(idx, data); + switch (idx) { + case 0x00 ... 0xdf: + case 0xe7 ... 0xef: + case 0xf0 ... 0xf1: + case 0xf5: + case 0xf8: + case 0xfd: + /* ignore write to read only registers */ + return; + default: + qemu_log_mask(LOG_UNIMP, + "via_superio_cfg: unimplemented register 0x%x\n", idx); + break; + } + sc->regs[idx] = data; +} + +static const MemoryRegionOps vt8231_superio_cfg_ops = { + .read = via_superio_cfg_read, + .write = vt8231_superio_cfg_write, + .endianness = DEVICE_NATIVE_ENDIAN, + .impl = { + .min_access_size = 1, + .max_access_size = 1, + }, +}; + +static void vt8231_superio_reset(DeviceState *dev) +{ + ViaSuperIOState *s = VIA_SUPERIO(dev); + + memset(s->regs, 0, sizeof(s->regs)); + /* Device ID */ + s->regs[0xf0] = 0x3c; + /* Device revision */ + s->regs[0xf1] = 0x01; + /* Function select - all disabled */ + vt8231_superio_cfg_write(s, 0, 0xf2, 1); + vt8231_superio_cfg_write(s, 1, 0x03, 1); + /* Serial port base addr */ + vt8231_superio_cfg_write(s, 0, 0xf4, 1); + vt8231_superio_cfg_write(s, 1, 0xfe, 1); + /* Parallel port base addr */ + vt8231_superio_cfg_write(s, 0, 0xf6, 1); + vt8231_superio_cfg_write(s, 1, 0xde, 1); + /* Floppy ctrl base addr */ + vt8231_superio_cfg_write(s, 0, 0xf7, 1); + vt8231_superio_cfg_write(s, 1, 0xfc, 1); + + vt8231_superio_cfg_write(s, 0, 0, 1); +} + +static void vt8231_superio_init(Object *obj) +{ + VIA_SUPERIO(obj)->io_ops = &vt8231_superio_cfg_ops; +} + +static uint16_t vt8231_superio_serial_iobase(ISASuperIODevice *sio, + uint8_t index) +{ + return 0x2f8; /* FIXME: This should be settable via registers f2-f4 */ +} + +static void vt8231_superio_class_init(ObjectClass *klass, void *data) +{ + DeviceClass *dc = DEVICE_CLASS(klass); + ISASuperIOClass *sc = ISA_SUPERIO_CLASS(klass); + + dc->reset = vt8231_superio_reset; + sc->serial.count = 1; + sc->serial.get_iobase = vt8231_superio_serial_iobase; + sc->parallel.count = 1; + sc->ide.count = 0; /* emulated by via-ide */ + sc->floppy.count = 1; +} + +static const TypeInfo vt8231_superio_info = { + .name = TYPE_VT8231_SUPERIO, + .parent = TYPE_VIA_SUPERIO, + .instance_size = sizeof(ViaSuperIOState), + .instance_init = vt8231_superio_init, + .class_size = sizeof(ISASuperIOClass), + .class_init = vt8231_superio_class_init, +}; + + OBJECT_DECLARE_SIMPLE_TYPE(VT82C686BISAState, VT82C686B_ISA) struct VT82C686BISAState { @@ -556,6 +657,7 @@ static void vt82c686b_register_types(void) type_register_static(&vt8231_pm_info); type_register_static(&via_superio_info); type_register_static(&vt82c686b_superio_info); + type_register_static(&vt8231_superio_info); type_register_static(&via_info); } From patchwork Tue May 4 05:52:48 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: David Gibson X-Patchwork-Id: 12237477 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-16.6 required=3.0 tests=BAYES_00,DKIM_INVALID, DKIM_SIGNED,HEADER_FROM_DIFFERENT_DOMAINS,INCLUDES_CR_TRAILER,INCLUDES_PATCH, MAILING_LIST_MULTI,SPF_HELO_NONE,SPF_PASS,USER_AGENT_GIT autolearn=ham autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id ECBA1C433B4 for ; Tue, 4 May 2021 06:32:35 +0000 (UTC) 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 mail.kernel.org (Postfix) with ESMTPS id 5136C610A0 for ; Tue, 4 May 2021 06:32:35 +0000 (UTC) DMARC-Filter: OpenDMARC Filter v1.3.2 mail.kernel.org 5136C610A0 Authentication-Results: mail.kernel.org; dmarc=none (p=none dis=none) header.from=gibson.dropbear.id.au Authentication-Results: mail.kernel.org; spf=pass smtp.mailfrom=qemu-devel-bounces+qemu-devel=archiver.kernel.org@nongnu.org Received: from localhost ([::1]:57998 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1ldobi-0002KU-7w for qemu-devel@archiver.kernel.org; Tue, 04 May 2021 02:32:34 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]:60648) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1ldo0S-0005yi-IB; Tue, 04 May 2021 01:54:04 -0400 Received: from ozlabs.org ([2401:3900:2:1::2]:34985) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1ldo0Q-0004pc-Gw; Tue, 04 May 2021 01:54:04 -0400 Received: by ozlabs.org (Postfix, from userid 1007) id 4FZ8CL0kzgz9sXh; Tue, 4 May 2021 15:53:18 +1000 (AEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=gibson.dropbear.id.au; s=201602; t=1620107598; bh=ZXngux+vg82chzEMmTJ7/137V6OF57z5Jfn89SAnKLs=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=fRTEn249Uo8eVm1TrNQPgpyRMa3xEWslkfZSIHfNZDEKSnJc26lCb9lb4Bo/5UzzZ aAcMGf8At6HfDg6Q98iBxrIX92tKUeLRWIfQJ4RIkca0VGx9EZbnfioU2bfCXyPjQ8 KxHSEPpWEydovpHGdKtX/xA7rzuBU/8J+Y0spZaY= From: David Gibson To: peter.maydell@linaro.org, groug@kaod.org Subject: [PULL 22/46] vt82c686: Introduce abstract TYPE_VIA_ISA and base vt82c686b_isa on it Date: Tue, 4 May 2021 15:52:48 +1000 Message-Id: <20210504055312.306823-23-david@gibson.dropbear.id.au> X-Mailer: git-send-email 2.31.1 In-Reply-To: <20210504055312.306823-1-david@gibson.dropbear.id.au> References: <20210504055312.306823-1-david@gibson.dropbear.id.au> MIME-Version: 1.0 Received-SPF: pass client-ip=2401:3900:2:1::2; envelope-from=dgibson@ozlabs.org; helo=ozlabs.org X-Spam_score_int: -17 X-Spam_score: -1.8 X-Spam_bar: - X-Spam_report: (-1.8 / 5.0 requ) BAYES_00=-1.9, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_AU=-0.1, HEADER_FROM_DIFFERENT_DOMAINS=0.25, SPF_HELO_PASS=-0.001, SPF_PASS=-0.001 autolearn=no autolearn_force=no X-Spam_action: no action X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: =?utf-8?q?Philippe_Mathieu-Daud=C3=A9?= , qemu-ppc@nongnu.org, qemu-devel@nongnu.org, David Gibson Errors-To: qemu-devel-bounces+qemu-devel=archiver.kernel.org@nongnu.org Sender: "Qemu-devel" From: BALATON Zoltan To allow reusing ISA bridge emulation for vt8231_isa move the device state of vt82c686b_isa emulation in an abstract via_isa class. This change breaks migration back compatibility but this is not an issue for Fuloong2E machine which is not versioned or migration supported. Signed-off-by: BALATON Zoltan Reviewed-by: Philippe Mathieu-Daudé Message-Id: <0cb8fc69c7aaa555589181931b881335fecd2ef3.1616680239.git.balaton@eik.bme.hu> Signed-off-by: David Gibson --- hw/isa/vt82c686.c | 70 ++++++++++++++++++++++------------------ include/hw/pci/pci_ids.h | 2 +- 2 files changed, 40 insertions(+), 32 deletions(-) diff --git a/hw/isa/vt82c686.c b/hw/isa/vt82c686.c index 952c6fc867..b09bfe3fa2 100644 --- a/hw/isa/vt82c686.c +++ b/hw/isa/vt82c686.c @@ -534,24 +534,48 @@ static const TypeInfo vt8231_superio_info = { }; -OBJECT_DECLARE_SIMPLE_TYPE(VT82C686BISAState, VT82C686B_ISA) +#define TYPE_VIA_ISA "via-isa" +OBJECT_DECLARE_SIMPLE_TYPE(ViaISAState, VIA_ISA) -struct VT82C686BISAState { +struct ViaISAState { PCIDevice dev; qemu_irq cpu_intr; ViaSuperIOState *via_sio; }; +static const VMStateDescription vmstate_via = { + .name = "via-isa", + .version_id = 1, + .minimum_version_id = 1, + .fields = (VMStateField[]) { + VMSTATE_PCI_DEVICE(dev, ViaISAState), + VMSTATE_END_OF_LIST() + } +}; + +static const TypeInfo via_isa_info = { + .name = TYPE_VIA_ISA, + .parent = TYPE_PCI_DEVICE, + .instance_size = sizeof(ViaISAState), + .abstract = true, + .interfaces = (InterfaceInfo[]) { + { INTERFACE_CONVENTIONAL_PCI_DEVICE }, + { }, + }, +}; + static void via_isa_request_i8259_irq(void *opaque, int irq, int level) { - VT82C686BISAState *s = opaque; + ViaISAState *s = opaque; qemu_set_irq(s->cpu_intr, level); } +/* TYPE_VT82C686B_ISA */ + static void vt82c686b_write_config(PCIDevice *d, uint32_t addr, uint32_t val, int len) { - VT82C686BISAState *s = VT82C686B_ISA(d); + ViaISAState *s = VIA_ISA(d); trace_via_isa_write(addr, val, len); pci_default_write_config(d, addr, val, len); @@ -561,19 +585,9 @@ static void vt82c686b_write_config(PCIDevice *d, uint32_t addr, } } -static const VMStateDescription vmstate_via = { - .name = "vt82c686b", - .version_id = 1, - .minimum_version_id = 1, - .fields = (VMStateField[]) { - VMSTATE_PCI_DEVICE(dev, VT82C686BISAState), - VMSTATE_END_OF_LIST() - } -}; - static void vt82c686b_isa_reset(DeviceState *dev) { - VT82C686BISAState *s = VT82C686B_ISA(dev); + ViaISAState *s = VIA_ISA(dev); uint8_t *pci_conf = s->dev.config; pci_set_long(pci_conf + PCI_CAPABILITY_LIST, 0x000000c0); @@ -593,7 +607,7 @@ static void vt82c686b_isa_reset(DeviceState *dev) static void vt82c686b_realize(PCIDevice *d, Error **errp) { - VT82C686BISAState *s = VT82C686B_ISA(d); + ViaISAState *s = VIA_ISA(d); DeviceState *dev = DEVICE(d); ISABus *isa_bus; qemu_irq *isa_irq; @@ -617,7 +631,7 @@ static void vt82c686b_realize(PCIDevice *d, Error **errp) } } -static void via_class_init(ObjectClass *klass, void *data) +static void vt82c686b_class_init(ObjectClass *klass, void *data) { DeviceClass *dc = DEVICE_CLASS(klass); PCIDeviceClass *k = PCI_DEVICE_CLASS(klass); @@ -625,28 +639,21 @@ static void via_class_init(ObjectClass *klass, void *data) k->realize = vt82c686b_realize; k->config_write = vt82c686b_write_config; k->vendor_id = PCI_VENDOR_ID_VIA; - k->device_id = PCI_DEVICE_ID_VIA_ISA_BRIDGE; + k->device_id = PCI_DEVICE_ID_VIA_82C686B_ISA; k->class_id = PCI_CLASS_BRIDGE_ISA; k->revision = 0x40; dc->reset = vt82c686b_isa_reset; dc->desc = "ISA bridge"; dc->vmsd = &vmstate_via; - /* - * Reason: part of VIA VT82C686 southbridge, needs to be wired up, - * e.g. by mips_fuloong2e_init() - */ + /* Reason: part of VIA VT82C686 southbridge, needs to be wired up */ dc->user_creatable = false; } -static const TypeInfo via_info = { +static const TypeInfo vt82c686b_isa_info = { .name = TYPE_VT82C686B_ISA, - .parent = TYPE_PCI_DEVICE, - .instance_size = sizeof(VT82C686BISAState), - .class_init = via_class_init, - .interfaces = (InterfaceInfo[]) { - { INTERFACE_CONVENTIONAL_PCI_DEVICE }, - { }, - }, + .parent = TYPE_VIA_ISA, + .instance_size = sizeof(ViaISAState), + .class_init = vt82c686b_class_init, }; @@ -658,7 +665,8 @@ static void vt82c686b_register_types(void) type_register_static(&via_superio_info); type_register_static(&vt82c686b_superio_info); type_register_static(&vt8231_superio_info); - type_register_static(&via_info); + type_register_static(&via_isa_info); + type_register_static(&vt82c686b_isa_info); } type_init(vt82c686b_register_types) diff --git a/include/hw/pci/pci_ids.h b/include/hw/pci/pci_ids.h index ea28dcc850..aa3f67eaa4 100644 --- a/include/hw/pci/pci_ids.h +++ b/include/hw/pci/pci_ids.h @@ -204,7 +204,7 @@ #define PCI_VENDOR_ID_XILINX 0x10ee #define PCI_VENDOR_ID_VIA 0x1106 -#define PCI_DEVICE_ID_VIA_ISA_BRIDGE 0x0686 +#define PCI_DEVICE_ID_VIA_82C686B_ISA 0x0686 #define PCI_DEVICE_ID_VIA_IDE 0x0571 #define PCI_DEVICE_ID_VIA_UHCI 0x3038 #define PCI_DEVICE_ID_VIA_82C686B_PM 0x3057 From patchwork Tue May 4 05:52:49 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: David Gibson X-Patchwork-Id: 12237457 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-16.6 required=3.0 tests=BAYES_00,DKIM_INVALID, DKIM_SIGNED,HEADER_FROM_DIFFERENT_DOMAINS,INCLUDES_CR_TRAILER,INCLUDES_PATCH, MAILING_LIST_MULTI,SPF_HELO_NONE,SPF_PASS,USER_AGENT_GIT autolearn=ham autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id B228BC433ED for ; Tue, 4 May 2021 06:22:16 +0000 (UTC) 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 mail.kernel.org (Postfix) with ESMTPS id 3C19F613AA for ; Tue, 4 May 2021 06:22:16 +0000 (UTC) DMARC-Filter: OpenDMARC Filter v1.3.2 mail.kernel.org 3C19F613AA Authentication-Results: mail.kernel.org; dmarc=none (p=none dis=none) header.from=gibson.dropbear.id.au Authentication-Results: mail.kernel.org; spf=pass smtp.mailfrom=qemu-devel-bounces+qemu-devel=archiver.kernel.org@nongnu.org Received: from localhost ([::1]:41464 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1ldoRj-0003Jc-AB for qemu-devel@archiver.kernel.org; Tue, 04 May 2021 02:22:15 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]:60672) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1ldo0U-000644-Gl; Tue, 04 May 2021 01:54:06 -0400 Received: from bilbo.ozlabs.org ([2401:3900:2:1::2]:50977 helo=ozlabs.org) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1ldo0S-0004qm-FY; Tue, 04 May 2021 01:54:06 -0400 Received: by ozlabs.org (Postfix, from userid 1007) id 4FZ8CL1MTwz9shn; Tue, 4 May 2021 15:53:18 +1000 (AEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=gibson.dropbear.id.au; s=201602; t=1620107598; bh=uFVn2kz8KBK8M3OG9zv+1RPO2YvwjFTQNPbOIkUl470=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=Nhsy31H6i3u5nK8MsrwAbFJg0JIaqwgJpP3R3Dm3DcwIpEn8x87KhJ9UZfRhh0VmY 1OcMXtjdk1J4O5+zHNU4CSZyh4PbmC+uhDkxv5ieGARjKMM1TP7iwCiwx15yer7e01 OiwVCulhgETTzT1wHlqdeceHC2bPU/zCbOfoZACw= From: David Gibson To: peter.maydell@linaro.org, groug@kaod.org Subject: [PULL 23/46] vt82c686: Add emulation of VT8231 south bridge Date: Tue, 4 May 2021 15:52:49 +1000 Message-Id: <20210504055312.306823-24-david@gibson.dropbear.id.au> X-Mailer: git-send-email 2.31.1 In-Reply-To: <20210504055312.306823-1-david@gibson.dropbear.id.au> References: <20210504055312.306823-1-david@gibson.dropbear.id.au> MIME-Version: 1.0 Received-SPF: pass client-ip=2401:3900:2:1::2; envelope-from=dgibson@ozlabs.org; helo=ozlabs.org X-Spam_score_int: -17 X-Spam_score: -1.8 X-Spam_bar: - X-Spam_report: (-1.8 / 5.0 requ) BAYES_00=-1.9, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_AU=-0.1, HEADER_FROM_DIFFERENT_DOMAINS=0.25, SPF_HELO_PASS=-0.001, SPF_PASS=-0.001 autolearn=no autolearn_force=no X-Spam_action: no action X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: =?utf-8?q?Philippe_Mathieu-Daud=C3=A9?= , qemu-ppc@nongnu.org, qemu-devel@nongnu.org, David Gibson Errors-To: qemu-devel-bounces+qemu-devel=archiver.kernel.org@nongnu.org Sender: "Qemu-devel" From: BALATON Zoltan Add emulation of VT8231 south bridge ISA part based on the similar VT82C686B but implemented in a separate subclass that holds the differences while reusing parts that can be shared. Signed-off-by: BALATON Zoltan Reviewed-by: Philippe Mathieu-Daudé Message-Id: <10abc9f89854e7c980b9731c33d25a2e307e9c4f.1616680239.git.balaton@eik.bme.hu> Signed-off-by: David Gibson --- hw/isa/vt82c686.c | 84 +++++++++++++++++++++++++++++++++++++++ include/hw/isa/vt82c686.h | 1 + include/hw/pci/pci_ids.h | 1 + 3 files changed, 86 insertions(+) diff --git a/hw/isa/vt82c686.c b/hw/isa/vt82c686.c index b09bfe3fa2..7b2e90c7e1 100644 --- a/hw/isa/vt82c686.c +++ b/hw/isa/vt82c686.c @@ -8,6 +8,9 @@ * * Contributions after 2012-01-13 are licensed under the terms of the * GNU GPL, version 2 or (at your option) any later version. + * + * VT8231 south bridge support and general clean up to allow it + * Copyright (c) 2018-2020 BALATON Zoltan */ #include "qemu/osdep.h" @@ -656,6 +659,86 @@ static const TypeInfo vt82c686b_isa_info = { .class_init = vt82c686b_class_init, }; +/* TYPE_VT8231_ISA */ + +static void vt8231_write_config(PCIDevice *d, uint32_t addr, + uint32_t val, int len) +{ + ViaISAState *s = VIA_ISA(d); + + trace_via_isa_write(addr, val, len); + pci_default_write_config(d, addr, val, len); + if (addr == 0x50) { + /* BIT(2): enable or disable superio config io ports */ + via_superio_io_enable(s->via_sio, val & BIT(2)); + } +} + +static void vt8231_isa_reset(DeviceState *dev) +{ + ViaISAState *s = VIA_ISA(dev); + uint8_t *pci_conf = s->dev.config; + + pci_set_long(pci_conf + PCI_CAPABILITY_LIST, 0x000000c0); + pci_set_word(pci_conf + PCI_COMMAND, PCI_COMMAND_IO | PCI_COMMAND_MEMORY | + PCI_COMMAND_MASTER | PCI_COMMAND_SPECIAL); + pci_set_word(pci_conf + PCI_STATUS, PCI_STATUS_DEVSEL_MEDIUM); + + pci_conf[0x58] = 0x40; /* Miscellaneous Control 0 */ + pci_conf[0x67] = 0x08; /* Fast IR Config */ + pci_conf[0x6b] = 0x01; /* Fast IR I/O Base */ +} + +static void vt8231_realize(PCIDevice *d, Error **errp) +{ + ViaISAState *s = VIA_ISA(d); + DeviceState *dev = DEVICE(d); + ISABus *isa_bus; + qemu_irq *isa_irq; + int i; + + qdev_init_gpio_out(dev, &s->cpu_intr, 1); + isa_irq = qemu_allocate_irqs(via_isa_request_i8259_irq, s, 1); + isa_bus = isa_bus_new(dev, get_system_memory(), pci_address_space_io(d), + &error_fatal); + isa_bus_irqs(isa_bus, i8259_init(isa_bus, *isa_irq)); + i8254_pit_init(isa_bus, 0x40, 0, NULL); + i8257_dma_init(isa_bus, 0); + s->via_sio = VIA_SUPERIO(isa_create_simple(isa_bus, TYPE_VT8231_SUPERIO)); + mc146818_rtc_init(isa_bus, 2000, NULL); + + for (i = 0; i < PCI_CONFIG_HEADER_SIZE; i++) { + if (i < PCI_COMMAND || i >= PCI_REVISION_ID) { + d->wmask[i] = 0; + } + } +} + +static void vt8231_class_init(ObjectClass *klass, void *data) +{ + DeviceClass *dc = DEVICE_CLASS(klass); + PCIDeviceClass *k = PCI_DEVICE_CLASS(klass); + + k->realize = vt8231_realize; + k->config_write = vt8231_write_config; + k->vendor_id = PCI_VENDOR_ID_VIA; + k->device_id = PCI_DEVICE_ID_VIA_8231_ISA; + k->class_id = PCI_CLASS_BRIDGE_ISA; + k->revision = 0x10; + dc->reset = vt8231_isa_reset; + dc->desc = "ISA bridge"; + dc->vmsd = &vmstate_via; + /* Reason: part of VIA VT8231 southbridge, needs to be wired up */ + dc->user_creatable = false; +} + +static const TypeInfo vt8231_isa_info = { + .name = TYPE_VT8231_ISA, + .parent = TYPE_VIA_ISA, + .instance_size = sizeof(ViaISAState), + .class_init = vt8231_class_init, +}; + static void vt82c686b_register_types(void) { @@ -667,6 +750,7 @@ static void vt82c686b_register_types(void) type_register_static(&vt8231_superio_info); type_register_static(&via_isa_info); type_register_static(&vt82c686b_isa_info); + type_register_static(&vt8231_isa_info); } type_init(vt82c686b_register_types) diff --git a/include/hw/isa/vt82c686.h b/include/hw/isa/vt82c686.h index 0692b9a527..0f01aaa471 100644 --- a/include/hw/isa/vt82c686.h +++ b/include/hw/isa/vt82c686.h @@ -3,6 +3,7 @@ #define TYPE_VT82C686B_ISA "vt82c686b-isa" #define TYPE_VT82C686B_PM "vt82c686b-pm" +#define TYPE_VT8231_ISA "vt8231-isa" #define TYPE_VT8231_PM "vt8231-pm" #define TYPE_VIA_AC97 "via-ac97" #define TYPE_VIA_MC97 "via-mc97" diff --git a/include/hw/pci/pci_ids.h b/include/hw/pci/pci_ids.h index aa3f67eaa4..ac0c23ebc7 100644 --- a/include/hw/pci/pci_ids.h +++ b/include/hw/pci/pci_ids.h @@ -210,6 +210,7 @@ #define PCI_DEVICE_ID_VIA_82C686B_PM 0x3057 #define PCI_DEVICE_ID_VIA_AC97 0x3058 #define PCI_DEVICE_ID_VIA_MC97 0x3068 +#define PCI_DEVICE_ID_VIA_8231_ISA 0x8231 #define PCI_DEVICE_ID_VIA_8231_PM 0x8235 #define PCI_VENDOR_ID_MARVELL 0x11ab From patchwork Tue May 4 05:52:50 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: David Gibson X-Patchwork-Id: 12237459 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-16.6 required=3.0 tests=BAYES_00,DKIM_INVALID, DKIM_SIGNED,HEADER_FROM_DIFFERENT_DOMAINS,INCLUDES_CR_TRAILER,INCLUDES_PATCH, MAILING_LIST_MULTI,SPF_HELO_NONE,SPF_PASS,USER_AGENT_GIT autolearn=ham autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id 38602C433B4 for ; Tue, 4 May 2021 06:26:16 +0000 (UTC) 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 mail.kernel.org (Postfix) with ESMTPS id 81D53610FC for ; Tue, 4 May 2021 06:26:15 +0000 (UTC) DMARC-Filter: OpenDMARC Filter v1.3.2 mail.kernel.org 81D53610FC Authentication-Results: mail.kernel.org; dmarc=none (p=none dis=none) header.from=gibson.dropbear.id.au Authentication-Results: mail.kernel.org; spf=pass smtp.mailfrom=qemu-devel-bounces+qemu-devel=archiver.kernel.org@nongnu.org Received: from localhost ([::1]:48700 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1ldoVa-0006Os-BZ for qemu-devel@archiver.kernel.org; Tue, 04 May 2021 02:26:14 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]:60600) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1ldo0C-0005Ud-SV; Tue, 04 May 2021 01:53:48 -0400 Received: from ozlabs.org ([203.11.71.1]:52995) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1ldo08-0004qg-05; Tue, 04 May 2021 01:53:48 -0400 Received: by ozlabs.org (Postfix, from userid 1007) id 4FZ8CL32Pzz9sj1; Tue, 4 May 2021 15:53:18 +1000 (AEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=gibson.dropbear.id.au; s=201602; t=1620107598; bh=aMszBASnOMgUqBoSWZbUMX+9F0SKRNtr0ST6cUwbElM=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=S3F+KbN3rizaQT7G/hL53QMng0zntR3q9XhrfOqu1hJtZ9kYKxyJwzgJxQDp6dONl 6g6FU9o72xicYrGh/t6RESYopa2CTbI7Lu2uGRCVtxcz26oZeAVdKzWcVWLRU40Es+ UytGJU8VwRDzStylPTyLD87w3Rw8OD3dPOHtB4Ds= From: David Gibson To: peter.maydell@linaro.org, groug@kaod.org Subject: [PULL 24/46] hw/pci-host: Add emulation of Marvell MV64361 PPC system controller Date: Tue, 4 May 2021 15:52:50 +1000 Message-Id: <20210504055312.306823-25-david@gibson.dropbear.id.au> X-Mailer: git-send-email 2.31.1 In-Reply-To: <20210504055312.306823-1-david@gibson.dropbear.id.au> References: <20210504055312.306823-1-david@gibson.dropbear.id.au> MIME-Version: 1.0 Received-SPF: pass client-ip=203.11.71.1; envelope-from=dgibson@ozlabs.org; helo=ozlabs.org X-Spam_score_int: -17 X-Spam_score: -1.8 X-Spam_bar: - X-Spam_report: (-1.8 / 5.0 requ) BAYES_00=-1.9, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_AU=-0.1, HEADER_FROM_DIFFERENT_DOMAINS=0.25, SPF_HELO_PASS=-0.001, SPF_PASS=-0.001 autolearn=no autolearn_force=no X-Spam_action: no action X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: David Gibson , qemu-ppc@nongnu.org, qemu-devel@nongnu.org Errors-To: qemu-devel-bounces+qemu-devel=archiver.kernel.org@nongnu.org Sender: "Qemu-devel" From: BALATON Zoltan The Marvell Discovery II aka. MV64361 is a PowerPC system controller chip that is used on the pegasos2 PPC board. This adds emulation of it that models the device enough to boot guests on this board. The mv643xx.h header with register definitions is taken from Linux 4.15.10 only fixing white space errors, removing not needed parts and changing formatting for QEMU coding style. Signed-off-by: BALATON Zoltan Message-Id: <79545ebd03bfe0665b73d2d7cbc74fdf3d62629e.1616680239.git.balaton@eik.bme.hu> Signed-off-by: David Gibson --- hw/pci-host/Kconfig | 4 + hw/pci-host/meson.build | 2 + hw/pci-host/mv64361.c | 951 ++++++++++++++++++++++++++++++++++ hw/pci-host/mv643xx.h | 918 ++++++++++++++++++++++++++++++++ hw/pci-host/trace-events | 6 + include/hw/pci-host/mv64361.h | 8 + include/hw/pci/pci_ids.h | 1 + 7 files changed, 1890 insertions(+) create mode 100644 hw/pci-host/mv64361.c create mode 100644 hw/pci-host/mv643xx.h create mode 100644 include/hw/pci-host/mv64361.h diff --git a/hw/pci-host/Kconfig b/hw/pci-host/Kconfig index 2ccc96f02c..79c20bf28b 100644 --- a/hw/pci-host/Kconfig +++ b/hw/pci-host/Kconfig @@ -72,3 +72,7 @@ config REMOTE_PCIHOST config SH_PCI bool select PCI + +config MV64361 + bool + select PCI diff --git a/hw/pci-host/meson.build b/hw/pci-host/meson.build index 87a896973e..34b3538beb 100644 --- a/hw/pci-host/meson.build +++ b/hw/pci-host/meson.build @@ -19,6 +19,8 @@ pci_ss.add(when: 'CONFIG_GRACKLE_PCI', if_true: files('grackle.c')) pci_ss.add(when: 'CONFIG_UNIN_PCI', if_true: files('uninorth.c')) # PowerPC E500 boards pci_ss.add(when: 'CONFIG_PPCE500_PCI', if_true: files('ppce500.c')) +# Pegasos2 +pci_ss.add(when: 'CONFIG_MV64361', if_true: files('mv64361.c')) # ARM devices pci_ss.add(when: 'CONFIG_VERSATILE_PCI', if_true: files('versatile.c')) diff --git a/hw/pci-host/mv64361.c b/hw/pci-host/mv64361.c new file mode 100644 index 0000000000..20510d8680 --- /dev/null +++ b/hw/pci-host/mv64361.c @@ -0,0 +1,951 @@ +/* + * Marvell Discovery II MV64361 System Controller for + * QEMU PowerPC CHRP (Genesi/bPlan Pegasos II) hardware System Emulator + * + * Copyright (c) 2018-2020 BALATON Zoltan + * + * This work is licensed under the GNU GPL license version 2 or later. + * + */ + +#include "qemu/osdep.h" +#include "qemu-common.h" +#include "qemu/units.h" +#include "qapi/error.h" +#include "hw/hw.h" +#include "hw/sysbus.h" +#include "hw/pci/pci.h" +#include "hw/pci/pci_host.h" +#include "hw/irq.h" +#include "hw/intc/i8259.h" +#include "hw/qdev-properties.h" +#include "exec/address-spaces.h" +#include "qemu/log.h" +#include "qemu/error-report.h" +#include "trace.h" +#include "hw/pci-host/mv64361.h" +#include "mv643xx.h" + +#define TYPE_MV64361_PCI_BRIDGE "mv64361-pcibridge" + +static void mv64361_pcibridge_class_init(ObjectClass *klass, void *data) +{ + DeviceClass *dc = DEVICE_CLASS(klass); + PCIDeviceClass *k = PCI_DEVICE_CLASS(klass); + + k->vendor_id = PCI_VENDOR_ID_MARVELL; + k->device_id = PCI_DEVICE_ID_MARVELL_MV6436X; + k->class_id = PCI_CLASS_BRIDGE_HOST; + /* + * PCI-facing part of the host bridge, + * not usable without the host-facing part + */ + dc->user_creatable = false; +} + +static const TypeInfo mv64361_pcibridge_info = { + .name = TYPE_MV64361_PCI_BRIDGE, + .parent = TYPE_PCI_DEVICE, + .instance_size = sizeof(PCIDevice), + .class_init = mv64361_pcibridge_class_init, + .interfaces = (InterfaceInfo[]) { + { INTERFACE_CONVENTIONAL_PCI_DEVICE }, + { }, + }, +}; + + +#define TYPE_MV64361_PCI "mv64361-pcihost" +OBJECT_DECLARE_SIMPLE_TYPE(MV64361PCIState, MV64361_PCI) + +struct MV64361PCIState { + PCIHostState parent_obj; + + uint8_t index; + MemoryRegion io; + MemoryRegion mem; + qemu_irq irq[PCI_NUM_PINS]; + + uint32_t io_base; + uint32_t io_size; + uint32_t mem_base[4]; + uint32_t mem_size[4]; + uint64_t remap[5]; +}; + +static int mv64361_pcihost_map_irq(PCIDevice *pci_dev, int n) +{ + return (n + PCI_SLOT(pci_dev->devfn)) % PCI_NUM_PINS; +} + +static void mv64361_pcihost_set_irq(void *opaque, int n, int level) +{ + MV64361PCIState *s = opaque; + qemu_set_irq(s->irq[n], level); +} + +static void mv64361_pcihost_realize(DeviceState *dev, Error **errp) +{ + MV64361PCIState *s = MV64361_PCI(dev); + PCIHostState *h = PCI_HOST_BRIDGE(dev); + char *name; + + name = g_strdup_printf("pci%d-io", s->index); + memory_region_init(&s->io, OBJECT(dev), name, 0x10000); + g_free(name); + name = g_strdup_printf("pci%d-mem", s->index); + memory_region_init(&s->mem, OBJECT(dev), name, 1ULL << 32); + g_free(name); + name = g_strdup_printf("pci.%d", s->index); + h->bus = pci_register_root_bus(dev, name, mv64361_pcihost_set_irq, + mv64361_pcihost_map_irq, dev, + &s->mem, &s->io, 0, 4, TYPE_PCI_BUS); + g_free(name); + pci_create_simple(h->bus, 0, TYPE_MV64361_PCI_BRIDGE); +} + +static Property mv64361_pcihost_props[] = { + DEFINE_PROP_UINT8("index", MV64361PCIState, index, 0), + DEFINE_PROP_END_OF_LIST() +}; + +static void mv64361_pcihost_class_init(ObjectClass *klass, void *data) +{ + DeviceClass *dc = DEVICE_CLASS(klass); + + dc->realize = mv64361_pcihost_realize; + device_class_set_props(dc, mv64361_pcihost_props); + set_bit(DEVICE_CATEGORY_BRIDGE, dc->categories); +} + +static const TypeInfo mv64361_pcihost_info = { + .name = TYPE_MV64361_PCI, + .parent = TYPE_PCI_HOST_BRIDGE, + .instance_size = sizeof(MV64361PCIState), + .class_init = mv64361_pcihost_class_init, +}; + +static void mv64361_pci_register_types(void) +{ + type_register_static(&mv64361_pcihost_info); + type_register_static(&mv64361_pcibridge_info); +} + +type_init(mv64361_pci_register_types) + + +OBJECT_DECLARE_SIMPLE_TYPE(MV64361State, MV64361) + +struct MV64361State { + SysBusDevice parent_obj; + + MemoryRegion regs; + MV64361PCIState pci[2]; + MemoryRegion cpu_win[19]; + qemu_irq cpu_irq; + + /* registers state */ + uint32_t cpu_conf; + uint32_t regs_base; + uint32_t base_addr_enable; + uint64_t main_int_cr; + uint64_t cpu0_int_mask; + uint32_t gpp_io; + uint32_t gpp_level; + uint32_t gpp_value; + uint32_t gpp_int_cr; + uint32_t gpp_int_mask; + bool gpp_int_level; +}; + +enum mv64361_irq_cause { + MV64361_IRQ_DEVERR = 1, + MV64361_IRQ_DMAERR = 2, + MV64361_IRQ_CPUERR = 3, + MV64361_IRQ_IDMA0 = 4, + MV64361_IRQ_IDMA1 = 5, + MV64361_IRQ_IDMA2 = 6, + MV64361_IRQ_IDMA3 = 7, + MV64361_IRQ_TIMER0 = 8, + MV64361_IRQ_TIMER1 = 9, + MV64361_IRQ_TIMER2 = 10, + MV64361_IRQ_TIMER3 = 11, + MV64361_IRQ_PCI0 = 12, + MV64361_IRQ_SRAMERR = 13, + MV64361_IRQ_GBEERR = 14, + MV64361_IRQ_CERR = 15, + MV64361_IRQ_PCI1 = 16, + MV64361_IRQ_DRAMERR = 17, + MV64361_IRQ_WDNMI = 18, + MV64361_IRQ_WDE = 19, + MV64361_IRQ_PCI0IN = 20, + MV64361_IRQ_PCI0OUT = 21, + MV64361_IRQ_PCI1IN = 22, + MV64361_IRQ_PCI1OUT = 23, + MV64361_IRQ_P1_GPP0_7 = 24, + MV64361_IRQ_P1_GPP8_15 = 25, + MV64361_IRQ_P1_GPP16_23 = 26, + MV64361_IRQ_P1_GPP24_31 = 27, + MV64361_IRQ_P1_CPU_DB = 28, + /* 29-31: reserved */ + MV64361_IRQ_GBE0 = 32, + MV64361_IRQ_GBE1 = 33, + MV64361_IRQ_GBE2 = 34, + /* 35: reserved */ + MV64361_IRQ_SDMA0 = 36, + MV64361_IRQ_TWSI = 37, + MV64361_IRQ_SDMA1 = 38, + MV64361_IRQ_BRG = 39, + MV64361_IRQ_MPSC0 = 40, + MV64361_IRQ_MPSC1 = 41, + MV64361_IRQ_G0RX = 42, + MV64361_IRQ_G0TX = 43, + MV64361_IRQ_G0MISC = 44, + MV64361_IRQ_G1RX = 45, + MV64361_IRQ_G1TX = 46, + MV64361_IRQ_G1MISC = 47, + MV64361_IRQ_G2RX = 48, + MV64361_IRQ_G2TX = 49, + MV64361_IRQ_G2MISC = 50, + /* 51-55: reserved */ + MV64361_IRQ_P0_GPP0_7 = 56, + MV64361_IRQ_P0_GPP8_15 = 57, + MV64361_IRQ_P0_GPP16_23 = 58, + MV64361_IRQ_P0_GPP24_31 = 59, + MV64361_IRQ_P0_CPU_DB = 60, + /* 61-63: reserved */ +}; + +PCIBus *mv64361_get_pci_bus(DeviceState *dev, int n) +{ + MV64361State *mv = MV64361(dev); + return PCI_HOST_BRIDGE(&mv->pci[n])->bus; +} + +static void unmap_region(MemoryRegion *mr) +{ + if (memory_region_is_mapped(mr)) { + memory_region_del_subregion(get_system_memory(), mr); + object_unparent(OBJECT(mr)); + } +} + +static void map_pci_region(MemoryRegion *mr, MemoryRegion *parent, + struct Object *owner, const char *name, + hwaddr poffs, uint64_t size, hwaddr moffs) +{ + memory_region_init_alias(mr, owner, name, parent, poffs, size); + memory_region_add_subregion(get_system_memory(), moffs, mr); + trace_mv64361_region_map(name, poffs, size, moffs); +} + +static void set_mem_windows(MV64361State *s, uint32_t val) +{ + MV64361PCIState *p; + MemoryRegion *mr; + uint32_t mask; + int i; + + val &= 0x1fffff; + for (mask = 1, i = 0; i < 21; i++, mask <<= 1) { + if ((val & mask) != (s->base_addr_enable & mask)) { + trace_mv64361_region_enable(!(val & mask) ? "enable" : "disable", i); + /* + * 0-3 are SDRAM chip selects but we map all RAM directly + * 4-7 are device chip selects (not sure what those are) + * 8 is Boot device (ROM) chip select but we map that directly too + */ + if (i == 9) { + p = &s->pci[0]; + mr = &s->cpu_win[i]; + unmap_region(mr); + if (!(val & mask)) { + map_pci_region(mr, &p->io, OBJECT(s), "pci0-io-win", + p->remap[4], (p->io_size + 1) << 16, + (p->io_base & 0xfffff) << 16); + } + } else if (i == 10) { + p = &s->pci[0]; + mr = &s->cpu_win[i]; + unmap_region(mr); + if (!(val & mask)) { + map_pci_region(mr, &p->mem, OBJECT(s), "pci0-mem0-win", + p->remap[0], (p->mem_size[0] + 1) << 16, + (p->mem_base[0] & 0xfffff) << 16); + } + } else if (i == 11) { + p = &s->pci[0]; + mr = &s->cpu_win[i]; + unmap_region(mr); + if (!(val & mask)) { + map_pci_region(mr, &p->mem, OBJECT(s), "pci0-mem1-win", + p->remap[1], (p->mem_size[1] + 1) << 16, + (p->mem_base[1] & 0xfffff) << 16); + } + } else if (i == 12) { + p = &s->pci[0]; + mr = &s->cpu_win[i]; + unmap_region(mr); + if (!(val & mask)) { + map_pci_region(mr, &p->mem, OBJECT(s), "pci0-mem2-win", + p->remap[2], (p->mem_size[2] + 1) << 16, + (p->mem_base[2] & 0xfffff) << 16); + } + } else if (i == 13) { + p = &s->pci[0]; + mr = &s->cpu_win[i]; + unmap_region(mr); + if (!(val & mask)) { + map_pci_region(mr, &p->mem, OBJECT(s), "pci0-mem3-win", + p->remap[3], (p->mem_size[3] + 1) << 16, + (p->mem_base[3] & 0xfffff) << 16); + } + } else if (i == 14) { + p = &s->pci[1]; + mr = &s->cpu_win[i]; + unmap_region(mr); + if (!(val & mask)) { + map_pci_region(mr, &p->io, OBJECT(s), "pci1-io-win", + p->remap[4], (p->io_size + 1) << 16, + (p->io_base & 0xfffff) << 16); + } + } else if (i == 15) { + p = &s->pci[1]; + mr = &s->cpu_win[i]; + unmap_region(mr); + if (!(val & mask)) { + map_pci_region(mr, &p->mem, OBJECT(s), "pci1-mem0-win", + p->remap[0], (p->mem_size[0] + 1) << 16, + (p->mem_base[0] & 0xfffff) << 16); + } + } else if (i == 16) { + p = &s->pci[1]; + mr = &s->cpu_win[i]; + unmap_region(mr); + if (!(val & mask)) { + map_pci_region(mr, &p->mem, OBJECT(s), "pci1-mem1-win", + p->remap[1], (p->mem_size[1] + 1) << 16, + (p->mem_base[1] & 0xfffff) << 16); + } + } else if (i == 17) { + p = &s->pci[1]; + mr = &s->cpu_win[i]; + unmap_region(mr); + if (!(val & mask)) { + map_pci_region(mr, &p->mem, OBJECT(s), "pci1-mem2-win", + p->remap[2], (p->mem_size[2] + 1) << 16, + (p->mem_base[2] & 0xfffff) << 16); + } + } else if (i == 18) { + p = &s->pci[1]; + mr = &s->cpu_win[i]; + unmap_region(mr); + if (!(val & mask)) { + map_pci_region(mr, &p->mem, OBJECT(s), "pci1-mem3-win", + p->remap[3], (p->mem_size[3] + 1) << 16, + (p->mem_base[3] & 0xfffff) << 16); + } + /* 19 is integrated SRAM */ + } else if (i == 20) { + mr = &s->regs; + unmap_region(mr); + if (!(val & mask)) { + memory_region_add_subregion(get_system_memory(), + (s->regs_base & 0xfffff) << 16, mr); + } + } + } + } + s->base_addr_enable = val; +} + +static void mv64361_update_irq(void *opaque, int n, int level) +{ + MV64361State *s = opaque; + uint64_t val = s->main_int_cr; + + if (level) { + val |= BIT_ULL(n); + } else { + val &= ~BIT_ULL(n); + } + if ((s->main_int_cr & s->cpu0_int_mask) != (val & s->cpu0_int_mask)) { + qemu_set_irq(s->cpu_irq, level); + } + s->main_int_cr = val; +} + +static uint64_t mv64361_read(void *opaque, hwaddr addr, unsigned int size) +{ + MV64361State *s = MV64361(opaque); + uint32_t ret = 0; + + switch (addr) { + case MV64340_CPU_CONFIG: + ret = s->cpu_conf; + break; + case MV64340_PCI_0_IO_BASE_ADDR: + ret = s->pci[0].io_base; + break; + case MV64340_PCI_0_IO_SIZE: + ret = s->pci[0].io_size; + break; + case MV64340_PCI_0_IO_ADDR_REMAP: + ret = s->pci[0].remap[4] >> 16; + break; + case MV64340_PCI_0_MEMORY0_BASE_ADDR: + ret = s->pci[0].mem_base[0]; + break; + case MV64340_PCI_0_MEMORY0_SIZE: + ret = s->pci[0].mem_size[0]; + break; + case MV64340_PCI_0_MEMORY0_LOW_ADDR_REMAP: + ret = (s->pci[0].remap[0] & 0xffff0000) >> 16; + break; + case MV64340_PCI_0_MEMORY0_HIGH_ADDR_REMAP: + ret = s->pci[0].remap[0] >> 32; + break; + case MV64340_PCI_0_MEMORY1_BASE_ADDR: + ret = s->pci[0].mem_base[1]; + break; + case MV64340_PCI_0_MEMORY1_SIZE: + ret = s->pci[0].mem_size[1]; + break; + case MV64340_PCI_0_MEMORY1_LOW_ADDR_REMAP: + ret = (s->pci[0].remap[1] & 0xffff0000) >> 16; + break; + case MV64340_PCI_0_MEMORY1_HIGH_ADDR_REMAP: + ret = s->pci[0].remap[1] >> 32; + break; + case MV64340_PCI_0_MEMORY2_BASE_ADDR: + ret = s->pci[0].mem_base[2]; + break; + case MV64340_PCI_0_MEMORY2_SIZE: + ret = s->pci[0].mem_size[2]; + break; + case MV64340_PCI_0_MEMORY2_LOW_ADDR_REMAP: + ret = (s->pci[0].remap[2] & 0xffff0000) >> 16; + break; + case MV64340_PCI_0_MEMORY2_HIGH_ADDR_REMAP: + ret = s->pci[0].remap[2] >> 32; + break; + case MV64340_PCI_0_MEMORY3_BASE_ADDR: + ret = s->pci[0].mem_base[3]; + break; + case MV64340_PCI_0_MEMORY3_SIZE: + ret = s->pci[0].mem_size[3]; + break; + case MV64340_PCI_0_MEMORY3_LOW_ADDR_REMAP: + ret = (s->pci[0].remap[3] & 0xffff0000) >> 16; + break; + case MV64340_PCI_0_MEMORY3_HIGH_ADDR_REMAP: + ret = s->pci[0].remap[3] >> 32; + break; + case MV64340_PCI_1_IO_BASE_ADDR: + ret = s->pci[1].io_base; + break; + case MV64340_PCI_1_IO_SIZE: + ret = s->pci[1].io_size; + break; + case MV64340_PCI_1_IO_ADDR_REMAP: + ret = s->pci[1].remap[4] >> 16; + break; + case MV64340_PCI_1_MEMORY0_BASE_ADDR: + ret = s->pci[1].mem_base[0]; + break; + case MV64340_PCI_1_MEMORY0_SIZE: + ret = s->pci[1].mem_size[0]; + break; + case MV64340_PCI_1_MEMORY0_LOW_ADDR_REMAP: + ret = (s->pci[1].remap[0] & 0xffff0000) >> 16; + break; + case MV64340_PCI_1_MEMORY0_HIGH_ADDR_REMAP: + ret = s->pci[1].remap[0] >> 32; + break; + case MV64340_PCI_1_MEMORY1_BASE_ADDR: + ret = s->pci[1].mem_base[1]; + break; + case MV64340_PCI_1_MEMORY1_SIZE: + ret = s->pci[1].mem_size[1]; + break; + case MV64340_PCI_1_MEMORY1_LOW_ADDR_REMAP: + ret = (s->pci[1].remap[1] & 0xffff0000) >> 16; + break; + case MV64340_PCI_1_MEMORY1_HIGH_ADDR_REMAP: + ret = s->pci[1].remap[1] >> 32; + break; + case MV64340_PCI_1_MEMORY2_BASE_ADDR: + ret = s->pci[1].mem_base[2]; + break; + case MV64340_PCI_1_MEMORY2_SIZE: + ret = s->pci[1].mem_size[2]; + break; + case MV64340_PCI_1_MEMORY2_LOW_ADDR_REMAP: + ret = (s->pci[1].remap[2] & 0xffff0000) >> 16; + break; + case MV64340_PCI_1_MEMORY2_HIGH_ADDR_REMAP: + ret = s->pci[1].remap[2] >> 32; + break; + case MV64340_PCI_1_MEMORY3_BASE_ADDR: + ret = s->pci[1].mem_base[3]; + break; + case MV64340_PCI_1_MEMORY3_SIZE: + ret = s->pci[1].mem_size[3]; + break; + case MV64340_PCI_1_MEMORY3_LOW_ADDR_REMAP: + ret = (s->pci[1].remap[3] & 0xffff0000) >> 16; + break; + case MV64340_PCI_1_MEMORY3_HIGH_ADDR_REMAP: + ret = s->pci[1].remap[3] >> 32; + break; + case MV64340_INTERNAL_SPACE_BASE_ADDR: + ret = s->regs_base; + break; + case MV64340_BASE_ADDR_ENABLE: + ret = s->base_addr_enable; + break; + case MV64340_PCI_0_CONFIG_ADDR: + ret = pci_host_conf_le_ops.read(PCI_HOST_BRIDGE(&s->pci[0]), 0, size); + break; + case MV64340_PCI_0_CONFIG_DATA_VIRTUAL_REG ... + MV64340_PCI_0_CONFIG_DATA_VIRTUAL_REG + 3: + ret = pci_host_data_le_ops.read(PCI_HOST_BRIDGE(&s->pci[0]), + addr - MV64340_PCI_0_CONFIG_DATA_VIRTUAL_REG, size); + break; + case MV64340_PCI_1_CONFIG_ADDR: + ret = pci_host_conf_le_ops.read(PCI_HOST_BRIDGE(&s->pci[1]), 0, size); + break; + case MV64340_PCI_1_CONFIG_DATA_VIRTUAL_REG ... + MV64340_PCI_1_CONFIG_DATA_VIRTUAL_REG + 3: + ret = pci_host_data_le_ops.read(PCI_HOST_BRIDGE(&s->pci[1]), + addr - MV64340_PCI_1_CONFIG_DATA_VIRTUAL_REG, size); + break; + case MV64340_PCI_1_INTERRUPT_ACKNOWLEDGE_VIRTUAL_REG: + /* FIXME: Should this be sent via the PCI bus somehow? */ + if (s->gpp_int_level && (s->gpp_value & BIT(31))) { + ret = pic_read_irq(isa_pic); + } + break; + case MV64340_MAIN_INTERRUPT_CAUSE_LOW: + ret = s->main_int_cr; + break; + case MV64340_MAIN_INTERRUPT_CAUSE_HIGH: + ret = s->main_int_cr >> 32; + break; + case MV64340_CPU_INTERRUPT0_MASK_LOW: + ret = s->cpu0_int_mask; + break; + case MV64340_CPU_INTERRUPT0_MASK_HIGH: + ret = s->cpu0_int_mask >> 32; + break; + case MV64340_CPU_INTERRUPT0_SELECT_CAUSE: + ret = s->main_int_cr; + if (s->main_int_cr & s->cpu0_int_mask) { + if (!(s->main_int_cr & s->cpu0_int_mask & 0xffffffff)) { + ret = s->main_int_cr >> 32 | BIT(30); + } else if ((s->main_int_cr & s->cpu0_int_mask) >> 32) { + ret |= BIT(31); + } + } + break; + case MV64340_CUNIT_ARBITER_CONTROL_REG: + ret = 0x11ff0000 | (s->gpp_int_level << 10); + break; + case MV64340_GPP_IO_CONTROL: + ret = s->gpp_io; + break; + case MV64340_GPP_LEVEL_CONTROL: + ret = s->gpp_level; + break; + case MV64340_GPP_VALUE: + ret = s->gpp_value; + break; + case MV64340_GPP_VALUE_SET: + case MV64340_GPP_VALUE_CLEAR: + ret = 0; + break; + case MV64340_GPP_INTERRUPT_CAUSE: + ret = s->gpp_int_cr; + break; + case MV64340_GPP_INTERRUPT_MASK0: + case MV64340_GPP_INTERRUPT_MASK1: + ret = s->gpp_int_mask; + break; + default: + qemu_log_mask(LOG_UNIMP, "%s: Unimplemented register read 0x%" + HWADDR_PRIx "\n", __func__, addr); + break; + } + if (addr != MV64340_PCI_1_INTERRUPT_ACKNOWLEDGE_VIRTUAL_REG) { + trace_mv64361_reg_read(addr, ret); + } + return ret; +} + +static void warn_swap_bit(uint64_t val) +{ + if ((val & 0x3000000ULL) >> 24 != 1) { + qemu_log_mask(LOG_UNIMP, "%s: Data swap not implemented", __func__); + } +} + +static void mv64361_set_pci_mem_remap(MV64361State *s, int bus, int idx, + uint64_t val, bool high) +{ + if (high) { + s->pci[bus].remap[idx] = val; + } else { + s->pci[bus].remap[idx] &= 0xffffffff00000000ULL; + s->pci[bus].remap[idx] |= (val & 0xffffULL) << 16; + } +} + +static void mv64361_write(void *opaque, hwaddr addr, uint64_t val, + unsigned int size) +{ + MV64361State *s = MV64361(opaque); + + trace_mv64361_reg_write(addr, val); + switch (addr) { + case MV64340_CPU_CONFIG: + s->cpu_conf = val & 0xe4e3bffULL; + s->cpu_conf |= BIT(23); + break; + case MV64340_PCI_0_IO_BASE_ADDR: + s->pci[0].io_base = val & 0x30fffffULL; + warn_swap_bit(val); + if (!(s->cpu_conf & BIT(27))) { + s->pci[0].remap[4] = (val & 0xffffULL) << 16; + } + break; + case MV64340_PCI_0_IO_SIZE: + s->pci[0].io_size = val & 0xffffULL; + break; + case MV64340_PCI_0_IO_ADDR_REMAP: + s->pci[0].remap[4] = (val & 0xffffULL) << 16; + break; + case MV64340_PCI_0_MEMORY0_BASE_ADDR: + s->pci[0].mem_base[0] = val & 0x70fffffULL; + warn_swap_bit(val); + if (!(s->cpu_conf & BIT(27))) { + mv64361_set_pci_mem_remap(s, 0, 0, val, false); + } + break; + case MV64340_PCI_0_MEMORY0_SIZE: + s->pci[0].mem_size[0] = val & 0xffffULL; + break; + case MV64340_PCI_0_MEMORY0_LOW_ADDR_REMAP: + case MV64340_PCI_0_MEMORY0_HIGH_ADDR_REMAP: + mv64361_set_pci_mem_remap(s, 0, 0, val, + (addr == MV64340_PCI_0_MEMORY0_HIGH_ADDR_REMAP)); + break; + case MV64340_PCI_0_MEMORY1_BASE_ADDR: + s->pci[0].mem_base[1] = val & 0x70fffffULL; + warn_swap_bit(val); + if (!(s->cpu_conf & BIT(27))) { + mv64361_set_pci_mem_remap(s, 0, 1, val, false); + } + break; + case MV64340_PCI_0_MEMORY1_SIZE: + s->pci[0].mem_size[1] = val & 0xffffULL; + break; + case MV64340_PCI_0_MEMORY1_LOW_ADDR_REMAP: + case MV64340_PCI_0_MEMORY1_HIGH_ADDR_REMAP: + mv64361_set_pci_mem_remap(s, 0, 1, val, + (addr == MV64340_PCI_0_MEMORY1_HIGH_ADDR_REMAP)); + break; + case MV64340_PCI_0_MEMORY2_BASE_ADDR: + s->pci[0].mem_base[2] = val & 0x70fffffULL; + warn_swap_bit(val); + if (!(s->cpu_conf & BIT(27))) { + mv64361_set_pci_mem_remap(s, 0, 2, val, false); + } + break; + case MV64340_PCI_0_MEMORY2_SIZE: + s->pci[0].mem_size[2] = val & 0xffffULL; + break; + case MV64340_PCI_0_MEMORY2_LOW_ADDR_REMAP: + case MV64340_PCI_0_MEMORY2_HIGH_ADDR_REMAP: + mv64361_set_pci_mem_remap(s, 0, 2, val, + (addr == MV64340_PCI_0_MEMORY2_HIGH_ADDR_REMAP)); + break; + case MV64340_PCI_0_MEMORY3_BASE_ADDR: + s->pci[0].mem_base[3] = val & 0x70fffffULL; + warn_swap_bit(val); + if (!(s->cpu_conf & BIT(27))) { + mv64361_set_pci_mem_remap(s, 0, 3, val, false); + } + break; + case MV64340_PCI_0_MEMORY3_SIZE: + s->pci[0].mem_size[3] = val & 0xffffULL; + break; + case MV64340_PCI_0_MEMORY3_LOW_ADDR_REMAP: + case MV64340_PCI_0_MEMORY3_HIGH_ADDR_REMAP: + mv64361_set_pci_mem_remap(s, 0, 3, val, + (addr == MV64340_PCI_0_MEMORY3_HIGH_ADDR_REMAP)); + break; + case MV64340_PCI_1_IO_BASE_ADDR: + s->pci[1].io_base = val & 0x30fffffULL; + warn_swap_bit(val); + break; + if (!(s->cpu_conf & BIT(27))) { + s->pci[1].remap[4] = (val & 0xffffULL) << 16; + } + break; + case MV64340_PCI_1_IO_SIZE: + s->pci[1].io_size = val & 0xffffULL; + break; + case MV64340_PCI_1_MEMORY0_BASE_ADDR: + s->pci[1].mem_base[0] = val & 0x70fffffULL; + warn_swap_bit(val); + if (!(s->cpu_conf & BIT(27))) { + mv64361_set_pci_mem_remap(s, 1, 0, val, false); + } + break; + case MV64340_PCI_1_MEMORY0_SIZE: + s->pci[1].mem_size[0] = val & 0xffffULL; + break; + case MV64340_PCI_1_MEMORY0_LOW_ADDR_REMAP: + case MV64340_PCI_1_MEMORY0_HIGH_ADDR_REMAP: + mv64361_set_pci_mem_remap(s, 1, 0, val, + (addr == MV64340_PCI_1_MEMORY0_HIGH_ADDR_REMAP)); + break; + case MV64340_PCI_1_MEMORY1_BASE_ADDR: + s->pci[1].mem_base[1] = val & 0x70fffffULL; + warn_swap_bit(val); + if (!(s->cpu_conf & BIT(27))) { + mv64361_set_pci_mem_remap(s, 1, 1, val, false); + } + break; + case MV64340_PCI_1_MEMORY1_SIZE: + s->pci[1].mem_size[1] = val & 0xffffULL; + break; + case MV64340_PCI_1_MEMORY1_LOW_ADDR_REMAP: + case MV64340_PCI_1_MEMORY1_HIGH_ADDR_REMAP: + mv64361_set_pci_mem_remap(s, 1, 1, val, + (addr == MV64340_PCI_1_MEMORY1_HIGH_ADDR_REMAP)); + break; + case MV64340_PCI_1_MEMORY2_BASE_ADDR: + s->pci[1].mem_base[2] = val & 0x70fffffULL; + warn_swap_bit(val); + if (!(s->cpu_conf & BIT(27))) { + mv64361_set_pci_mem_remap(s, 1, 2, val, false); + } + break; + case MV64340_PCI_1_MEMORY2_SIZE: + s->pci[1].mem_size[2] = val & 0xffffULL; + break; + case MV64340_PCI_1_MEMORY2_LOW_ADDR_REMAP: + case MV64340_PCI_1_MEMORY2_HIGH_ADDR_REMAP: + mv64361_set_pci_mem_remap(s, 1, 2, val, + (addr == MV64340_PCI_1_MEMORY2_HIGH_ADDR_REMAP)); + break; + case MV64340_PCI_1_MEMORY3_BASE_ADDR: + s->pci[1].mem_base[3] = val & 0x70fffffULL; + warn_swap_bit(val); + if (!(s->cpu_conf & BIT(27))) { + mv64361_set_pci_mem_remap(s, 1, 3, val, false); + } + break; + case MV64340_PCI_1_MEMORY3_SIZE: + s->pci[1].mem_size[3] = val & 0xffffULL; + break; + case MV64340_PCI_1_MEMORY3_LOW_ADDR_REMAP: + case MV64340_PCI_1_MEMORY3_HIGH_ADDR_REMAP: + mv64361_set_pci_mem_remap(s, 1, 3, val, + (addr == MV64340_PCI_1_MEMORY3_HIGH_ADDR_REMAP)); + break; + case MV64340_INTERNAL_SPACE_BASE_ADDR: + s->regs_base = val & 0xfffffULL; + break; + case MV64340_BASE_ADDR_ENABLE: + set_mem_windows(s, val); + break; + case MV64340_PCI_0_CONFIG_ADDR: + pci_host_conf_le_ops.write(PCI_HOST_BRIDGE(&s->pci[0]), 0, val, size); + break; + case MV64340_PCI_0_CONFIG_DATA_VIRTUAL_REG ... + MV64340_PCI_0_CONFIG_DATA_VIRTUAL_REG + 3: + pci_host_data_le_ops.write(PCI_HOST_BRIDGE(&s->pci[0]), + addr - MV64340_PCI_0_CONFIG_DATA_VIRTUAL_REG, val, size); + break; + case MV64340_PCI_1_CONFIG_ADDR: + pci_host_conf_le_ops.write(PCI_HOST_BRIDGE(&s->pci[1]), 0, val, size); + break; + case MV64340_PCI_1_CONFIG_DATA_VIRTUAL_REG ... + MV64340_PCI_1_CONFIG_DATA_VIRTUAL_REG + 3: + pci_host_data_le_ops.write(PCI_HOST_BRIDGE(&s->pci[1]), + addr - MV64340_PCI_1_CONFIG_DATA_VIRTUAL_REG, val, size); + break; + case MV64340_CPU_INTERRUPT0_MASK_LOW: + s->cpu0_int_mask &= 0xffffffff00000000ULL; + s->cpu0_int_mask |= val & 0xffffffffULL; + break; + case MV64340_CPU_INTERRUPT0_MASK_HIGH: + s->cpu0_int_mask &= 0xffffffffULL; + s->cpu0_int_mask |= val << 32; + break; + case MV64340_CUNIT_ARBITER_CONTROL_REG: + s->gpp_int_level = !!(val & BIT(10)); + break; + case MV64340_GPP_IO_CONTROL: + s->gpp_io = val; + break; + case MV64340_GPP_LEVEL_CONTROL: + s->gpp_level = val; + break; + case MV64340_GPP_VALUE: + s->gpp_value &= ~s->gpp_io; + s->gpp_value |= val & s->gpp_io; + break; + case MV64340_GPP_VALUE_SET: + s->gpp_value |= val & s->gpp_io; + break; + case MV64340_GPP_VALUE_CLEAR: + s->gpp_value &= ~(val & s->gpp_io); + break; + case MV64340_GPP_INTERRUPT_CAUSE: + if (!s->gpp_int_level && val != s->gpp_int_cr) { + int i; + uint32_t ch = s->gpp_int_cr ^ val; + s->gpp_int_cr = val; + for (i = 0; i < 4; i++) { + if ((ch & 0xff << i) && !(val & 0xff << i)) { + mv64361_update_irq(opaque, MV64361_IRQ_P0_GPP0_7 + i, 0); + } + } + } else { + s->gpp_int_cr = val; + } + break; + case MV64340_GPP_INTERRUPT_MASK0: + case MV64340_GPP_INTERRUPT_MASK1: + s->gpp_int_mask = val; + break; + default: + qemu_log_mask(LOG_UNIMP, "%s: Unimplemented register write 0x%" + HWADDR_PRIx " = %"PRIx64"\n", __func__, addr, val); + break; + } +} + +static const MemoryRegionOps mv64361_ops = { + .read = mv64361_read, + .write = mv64361_write, + .valid.min_access_size = 1, + .valid.max_access_size = 4, + .endianness = DEVICE_LITTLE_ENDIAN, +}; + +static void mv64361_gpp_irq(void *opaque, int n, int level) +{ + MV64361State *s = opaque; + uint32_t mask = BIT(n); + uint32_t val = s->gpp_value & ~mask; + + if (s->gpp_level & mask) { + level = !level; + } + val |= level << n; + if (val > s->gpp_value) { + s->gpp_value = val; + s->gpp_int_cr |= mask; + if (s->gpp_int_mask & mask) { + mv64361_update_irq(opaque, MV64361_IRQ_P0_GPP0_7 + n / 8, 1); + } + } else if (val < s->gpp_value) { + int b = n / 8; + s->gpp_value = val; + if (s->gpp_int_level && !(val & 0xff << b)) { + mv64361_update_irq(opaque, MV64361_IRQ_P0_GPP0_7 + b, 0); + } + } +} + +static void mv64361_realize(DeviceState *dev, Error **errp) +{ + MV64361State *s = MV64361(dev); + int i; + + s->base_addr_enable = 0x1fffff; + memory_region_init_io(&s->regs, OBJECT(s), &mv64361_ops, s, + TYPE_MV64361, 0x10000); + for (i = 0; i < 2; i++) { + g_autofree char *name = g_strdup_printf("pcihost%d", i); + object_initialize_child(OBJECT(dev), name, &s->pci[i], + TYPE_MV64361_PCI); + DeviceState *pci = DEVICE(&s->pci[i]); + qdev_prop_set_uint8(pci, "index", i); + sysbus_realize_and_unref(SYS_BUS_DEVICE(pci), &error_fatal); + } + sysbus_init_irq(SYS_BUS_DEVICE(dev), &s->cpu_irq); + qdev_init_gpio_in_named(dev, mv64361_gpp_irq, "gpp", 32); + /* FIXME: PCI IRQ connections may be board specific */ + for (i = 0; i < PCI_NUM_PINS; i++) { + s->pci[1].irq[i] = qdev_get_gpio_in_named(dev, "gpp", 12 + i); + } +} + +static void mv64361_reset(DeviceState *dev) +{ + MV64361State *s = MV64361(dev); + int i, j; + + /* + * These values may be board specific + * Real chip supports init from an eprom but that's not modelled + */ + set_mem_windows(s, 0x1fffff); + s->cpu_conf = 0x28000ff; + s->regs_base = 0x100f100; + s->pci[0].io_base = 0x100f800; + s->pci[0].io_size = 0xff; + s->pci[0].mem_base[0] = 0x100c000; + s->pci[0].mem_size[0] = 0x1fff; + s->pci[0].mem_base[1] = 0x100f900; + s->pci[0].mem_size[1] = 0xff; + s->pci[0].mem_base[2] = 0x100f400; + s->pci[0].mem_size[2] = 0x1ff; + s->pci[0].mem_base[3] = 0x100f600; + s->pci[0].mem_size[3] = 0x1ff; + s->pci[1].io_base = 0x100fe00; + s->pci[1].io_size = 0xff; + s->pci[1].mem_base[0] = 0x1008000; + s->pci[1].mem_size[0] = 0x3fff; + s->pci[1].mem_base[1] = 0x100fd00; + s->pci[1].mem_size[1] = 0xff; + s->pci[1].mem_base[2] = 0x1002600; + s->pci[1].mem_size[2] = 0x1ff; + s->pci[1].mem_base[3] = 0x100ff80; + s->pci[1].mem_size[3] = 0x7f; + for (i = 0; i < 2; i++) { + for (j = 0; j < 4; j++) { + s->pci[i].remap[j] = s->pci[i].mem_base[j] << 16; + } + } + s->pci[0].remap[1] = 0; + s->pci[1].remap[1] = 0; + set_mem_windows(s, 0xfbfff); +} + +static void mv64361_class_init(ObjectClass *klass, void *data) +{ + DeviceClass *dc = DEVICE_CLASS(klass); + + dc->realize = mv64361_realize; + dc->reset = mv64361_reset; +} + +static const TypeInfo mv64361_type_info = { + .name = TYPE_MV64361, + .parent = TYPE_SYS_BUS_DEVICE, + .instance_size = sizeof(MV64361State), + .class_init = mv64361_class_init, +}; + +static void mv64361_register_types(void) +{ + type_register_static(&mv64361_type_info); +} + +type_init(mv64361_register_types) diff --git a/hw/pci-host/mv643xx.h b/hw/pci-host/mv643xx.h new file mode 100644 index 0000000000..cd26a43f18 --- /dev/null +++ b/hw/pci-host/mv643xx.h @@ -0,0 +1,918 @@ +/* + * mv643xx.h - MV-643XX Internal registers definition file. + * + * Copyright 2002 Momentum Computer, Inc. + * Author: Matthew Dharm + * Copyright 2002 GALILEO TECHNOLOGY, LTD. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. + */ +#ifndef ASM_MV643XX_H +#define ASM_MV643XX_H + +/****************************************/ +/* Processor Address Space */ +/****************************************/ + +/* DDR SDRAM BAR and size registers */ + +#define MV64340_CS_0_BASE_ADDR 0x008 +#define MV64340_CS_0_SIZE 0x010 +#define MV64340_CS_1_BASE_ADDR 0x208 +#define MV64340_CS_1_SIZE 0x210 +#define MV64340_CS_2_BASE_ADDR 0x018 +#define MV64340_CS_2_SIZE 0x020 +#define MV64340_CS_3_BASE_ADDR 0x218 +#define MV64340_CS_3_SIZE 0x220 + +/* Devices BAR and size registers */ + +#define MV64340_DEV_CS0_BASE_ADDR 0x028 +#define MV64340_DEV_CS0_SIZE 0x030 +#define MV64340_DEV_CS1_BASE_ADDR 0x228 +#define MV64340_DEV_CS1_SIZE 0x230 +#define MV64340_DEV_CS2_BASE_ADDR 0x248 +#define MV64340_DEV_CS2_SIZE 0x250 +#define MV64340_DEV_CS3_BASE_ADDR 0x038 +#define MV64340_DEV_CS3_SIZE 0x040 +#define MV64340_BOOTCS_BASE_ADDR 0x238 +#define MV64340_BOOTCS_SIZE 0x240 + +/* PCI 0 BAR and size registers */ + +#define MV64340_PCI_0_IO_BASE_ADDR 0x048 +#define MV64340_PCI_0_IO_SIZE 0x050 +#define MV64340_PCI_0_MEMORY0_BASE_ADDR 0x058 +#define MV64340_PCI_0_MEMORY0_SIZE 0x060 +#define MV64340_PCI_0_MEMORY1_BASE_ADDR 0x080 +#define MV64340_PCI_0_MEMORY1_SIZE 0x088 +#define MV64340_PCI_0_MEMORY2_BASE_ADDR 0x258 +#define MV64340_PCI_0_MEMORY2_SIZE 0x260 +#define MV64340_PCI_0_MEMORY3_BASE_ADDR 0x280 +#define MV64340_PCI_0_MEMORY3_SIZE 0x288 + +/* PCI 1 BAR and size registers */ +#define MV64340_PCI_1_IO_BASE_ADDR 0x090 +#define MV64340_PCI_1_IO_SIZE 0x098 +#define MV64340_PCI_1_MEMORY0_BASE_ADDR 0x0a0 +#define MV64340_PCI_1_MEMORY0_SIZE 0x0a8 +#define MV64340_PCI_1_MEMORY1_BASE_ADDR 0x0b0 +#define MV64340_PCI_1_MEMORY1_SIZE 0x0b8 +#define MV64340_PCI_1_MEMORY2_BASE_ADDR 0x2a0 +#define MV64340_PCI_1_MEMORY2_SIZE 0x2a8 +#define MV64340_PCI_1_MEMORY3_BASE_ADDR 0x2b0 +#define MV64340_PCI_1_MEMORY3_SIZE 0x2b8 + +/* SRAM base address */ +#define MV64340_INTEGRATED_SRAM_BASE_ADDR 0x268 + +/* internal registers space base address */ +#define MV64340_INTERNAL_SPACE_BASE_ADDR 0x068 + +/* Enables the CS , DEV_CS , PCI 0 and PCI 1 windows above */ +#define MV64340_BASE_ADDR_ENABLE 0x278 + +/****************************************/ +/* PCI remap registers */ +/****************************************/ + + /* PCI 0 */ +#define MV64340_PCI_0_IO_ADDR_REMAP 0x0f0 +#define MV64340_PCI_0_MEMORY0_LOW_ADDR_REMAP 0x0f8 +#define MV64340_PCI_0_MEMORY0_HIGH_ADDR_REMAP 0x320 +#define MV64340_PCI_0_MEMORY1_LOW_ADDR_REMAP 0x100 +#define MV64340_PCI_0_MEMORY1_HIGH_ADDR_REMAP 0x328 +#define MV64340_PCI_0_MEMORY2_LOW_ADDR_REMAP 0x2f8 +#define MV64340_PCI_0_MEMORY2_HIGH_ADDR_REMAP 0x330 +#define MV64340_PCI_0_MEMORY3_LOW_ADDR_REMAP 0x300 +#define MV64340_PCI_0_MEMORY3_HIGH_ADDR_REMAP 0x338 + /* PCI 1 */ +#define MV64340_PCI_1_IO_ADDR_REMAP 0x108 +#define MV64340_PCI_1_MEMORY0_LOW_ADDR_REMAP 0x110 +#define MV64340_PCI_1_MEMORY0_HIGH_ADDR_REMAP 0x340 +#define MV64340_PCI_1_MEMORY1_LOW_ADDR_REMAP 0x118 +#define MV64340_PCI_1_MEMORY1_HIGH_ADDR_REMAP 0x348 +#define MV64340_PCI_1_MEMORY2_LOW_ADDR_REMAP 0x310 +#define MV64340_PCI_1_MEMORY2_HIGH_ADDR_REMAP 0x350 +#define MV64340_PCI_1_MEMORY3_LOW_ADDR_REMAP 0x318 +#define MV64340_PCI_1_MEMORY3_HIGH_ADDR_REMAP 0x358 + +#define MV64340_CPU_PCI_0_HEADERS_RETARGET_CONTROL 0x3b0 +#define MV64340_CPU_PCI_0_HEADERS_RETARGET_BASE 0x3b8 +#define MV64340_CPU_PCI_1_HEADERS_RETARGET_CONTROL 0x3c0 +#define MV64340_CPU_PCI_1_HEADERS_RETARGET_BASE 0x3c8 +#define MV64340_CPU_GE_HEADERS_RETARGET_CONTROL 0x3d0 +#define MV64340_CPU_GE_HEADERS_RETARGET_BASE 0x3d8 +#define MV64340_CPU_IDMA_HEADERS_RETARGET_CONTROL 0x3e0 +#define MV64340_CPU_IDMA_HEADERS_RETARGET_BASE 0x3e8 + +/****************************************/ +/* CPU Control Registers */ +/****************************************/ + +#define MV64340_CPU_CONFIG 0x000 +#define MV64340_CPU_MODE 0x120 +#define MV64340_CPU_MASTER_CONTROL 0x160 +#define MV64340_CPU_CROSS_BAR_CONTROL_LOW 0x150 +#define MV64340_CPU_CROSS_BAR_CONTROL_HIGH 0x158 +#define MV64340_CPU_CROSS_BAR_TIMEOUT 0x168 + +/****************************************/ +/* SMP RegisterS */ +/****************************************/ + +#define MV64340_SMP_WHO_AM_I 0x200 +#define MV64340_SMP_CPU0_DOORBELL 0x214 +#define MV64340_SMP_CPU0_DOORBELL_CLEAR 0x21C +#define MV64340_SMP_CPU1_DOORBELL 0x224 +#define MV64340_SMP_CPU1_DOORBELL_CLEAR 0x22C +#define MV64340_SMP_CPU0_DOORBELL_MASK 0x234 +#define MV64340_SMP_CPU1_DOORBELL_MASK 0x23C +#define MV64340_SMP_SEMAPHOR0 0x244 +#define MV64340_SMP_SEMAPHOR1 0x24c +#define MV64340_SMP_SEMAPHOR2 0x254 +#define MV64340_SMP_SEMAPHOR3 0x25c +#define MV64340_SMP_SEMAPHOR4 0x264 +#define MV64340_SMP_SEMAPHOR5 0x26c +#define MV64340_SMP_SEMAPHOR6 0x274 +#define MV64340_SMP_SEMAPHOR7 0x27c + +/****************************************/ +/* CPU Sync Barrier Register */ +/****************************************/ + +#define MV64340_CPU_0_SYNC_BARRIER_TRIGGER 0x0c0 +#define MV64340_CPU_0_SYNC_BARRIER_VIRTUAL 0x0c8 +#define MV64340_CPU_1_SYNC_BARRIER_TRIGGER 0x0d0 +#define MV64340_CPU_1_SYNC_BARRIER_VIRTUAL 0x0d8 + +/****************************************/ +/* CPU Access Protect */ +/****************************************/ + +#define MV64340_CPU_PROTECT_WINDOW_0_BASE_ADDR 0x180 +#define MV64340_CPU_PROTECT_WINDOW_0_SIZE 0x188 +#define MV64340_CPU_PROTECT_WINDOW_1_BASE_ADDR 0x190 +#define MV64340_CPU_PROTECT_WINDOW_1_SIZE 0x198 +#define MV64340_CPU_PROTECT_WINDOW_2_BASE_ADDR 0x1a0 +#define MV64340_CPU_PROTECT_WINDOW_2_SIZE 0x1a8 +#define MV64340_CPU_PROTECT_WINDOW_3_BASE_ADDR 0x1b0 +#define MV64340_CPU_PROTECT_WINDOW_3_SIZE 0x1b8 + + +/****************************************/ +/* CPU Error Report */ +/****************************************/ + +#define MV64340_CPU_ERROR_ADDR_LOW 0x070 +#define MV64340_CPU_ERROR_ADDR_HIGH 0x078 +#define MV64340_CPU_ERROR_DATA_LOW 0x128 +#define MV64340_CPU_ERROR_DATA_HIGH 0x130 +#define MV64340_CPU_ERROR_PARITY 0x138 +#define MV64340_CPU_ERROR_CAUSE 0x140 +#define MV64340_CPU_ERROR_MASK 0x148 + +/****************************************/ +/* CPU Interface Debug Registers */ +/****************************************/ + +#define MV64340_PUNIT_SLAVE_DEBUG_LOW 0x360 +#define MV64340_PUNIT_SLAVE_DEBUG_HIGH 0x368 +#define MV64340_PUNIT_MASTER_DEBUG_LOW 0x370 +#define MV64340_PUNIT_MASTER_DEBUG_HIGH 0x378 +#define MV64340_PUNIT_MMASK 0x3e4 + +/****************************************/ +/* Integrated SRAM Registers */ +/****************************************/ + +#define MV64340_SRAM_CONFIG 0x380 +#define MV64340_SRAM_TEST_MODE 0X3F4 +#define MV64340_SRAM_ERROR_CAUSE 0x388 +#define MV64340_SRAM_ERROR_ADDR 0x390 +#define MV64340_SRAM_ERROR_ADDR_HIGH 0X3F8 +#define MV64340_SRAM_ERROR_DATA_LOW 0x398 +#define MV64340_SRAM_ERROR_DATA_HIGH 0x3a0 +#define MV64340_SRAM_ERROR_DATA_PARITY 0x3a8 + +/****************************************/ +/* SDRAM Configuration */ +/****************************************/ + +#define MV64340_SDRAM_CONFIG 0x1400 +#define MV64340_D_UNIT_CONTROL_LOW 0x1404 +#define MV64340_D_UNIT_CONTROL_HIGH 0x1424 +#define MV64340_SDRAM_TIMING_CONTROL_LOW 0x1408 +#define MV64340_SDRAM_TIMING_CONTROL_HIGH 0x140c +#define MV64340_SDRAM_ADDR_CONTROL 0x1410 +#define MV64340_SDRAM_OPEN_PAGES_CONTROL 0x1414 +#define MV64340_SDRAM_OPERATION 0x1418 +#define MV64340_SDRAM_MODE 0x141c +#define MV64340_EXTENDED_DRAM_MODE 0x1420 +#define MV64340_SDRAM_CROSS_BAR_CONTROL_LOW 0x1430 +#define MV64340_SDRAM_CROSS_BAR_CONTROL_HIGH 0x1434 +#define MV64340_SDRAM_CROSS_BAR_TIMEOUT 0x1438 +#define MV64340_SDRAM_ADDR_CTRL_PADS_CALIBRATION 0x14c0 +#define MV64340_SDRAM_DATA_PADS_CALIBRATION 0x14c4 + +/****************************************/ +/* SDRAM Error Report */ +/****************************************/ + +#define MV64340_SDRAM_ERROR_DATA_LOW 0x1444 +#define MV64340_SDRAM_ERROR_DATA_HIGH 0x1440 +#define MV64340_SDRAM_ERROR_ADDR 0x1450 +#define MV64340_SDRAM_RECEIVED_ECC 0x1448 +#define MV64340_SDRAM_CALCULATED_ECC 0x144c +#define MV64340_SDRAM_ECC_CONTROL 0x1454 +#define MV64340_SDRAM_ECC_ERROR_COUNTER 0x1458 + +/******************************************/ +/* Controlled Delay Line (CDL) Registers */ +/******************************************/ + +#define MV64340_DFCDL_CONFIG0 0x1480 +#define MV64340_DFCDL_CONFIG1 0x1484 +#define MV64340_DLL_WRITE 0x1488 +#define MV64340_DLL_READ 0x148c +#define MV64340_SRAM_ADDR 0x1490 +#define MV64340_SRAM_DATA0 0x1494 +#define MV64340_SRAM_DATA1 0x1498 +#define MV64340_SRAM_DATA2 0x149c +#define MV64340_DFCL_PROBE 0x14a0 + +/******************************************/ +/* Debug Registers */ +/******************************************/ + +#define MV64340_DUNIT_DEBUG_LOW 0x1460 +#define MV64340_DUNIT_DEBUG_HIGH 0x1464 +#define MV64340_DUNIT_MMASK 0X1b40 + +/****************************************/ +/* Device Parameters */ +/****************************************/ + +#define MV64340_DEVICE_BANK0_PARAMETERS 0x45c +#define MV64340_DEVICE_BANK1_PARAMETERS 0x460 +#define MV64340_DEVICE_BANK2_PARAMETERS 0x464 +#define MV64340_DEVICE_BANK3_PARAMETERS 0x468 +#define MV64340_DEVICE_BOOT_BANK_PARAMETERS 0x46c +#define MV64340_DEVICE_INTERFACE_CONTROL 0x4c0 +#define MV64340_DEVICE_INTERFACE_CROSS_BAR_CONTROL_LOW 0x4c8 +#define MV64340_DEVICE_INTERFACE_CROSS_BAR_CONTROL_HIGH 0x4cc +#define MV64340_DEVICE_INTERFACE_CROSS_BAR_TIMEOUT 0x4c4 + +/****************************************/ +/* Device interrupt registers */ +/****************************************/ + +#define MV64340_DEVICE_INTERRUPT_CAUSE 0x4d0 +#define MV64340_DEVICE_INTERRUPT_MASK 0x4d4 +#define MV64340_DEVICE_ERROR_ADDR 0x4d8 +#define MV64340_DEVICE_ERROR_DATA 0x4dc +#define MV64340_DEVICE_ERROR_PARITY 0x4e0 + +/****************************************/ +/* Device debug registers */ +/****************************************/ + +#define MV64340_DEVICE_DEBUG_LOW 0x4e4 +#define MV64340_DEVICE_DEBUG_HIGH 0x4e8 +#define MV64340_RUNIT_MMASK 0x4f0 + +/****************************************/ +/* PCI Slave Address Decoding registers */ +/****************************************/ + +#define MV64340_PCI_0_CS_0_BANK_SIZE 0xc08 +#define MV64340_PCI_1_CS_0_BANK_SIZE 0xc88 +#define MV64340_PCI_0_CS_1_BANK_SIZE 0xd08 +#define MV64340_PCI_1_CS_1_BANK_SIZE 0xd88 +#define MV64340_PCI_0_CS_2_BANK_SIZE 0xc0c +#define MV64340_PCI_1_CS_2_BANK_SIZE 0xc8c +#define MV64340_PCI_0_CS_3_BANK_SIZE 0xd0c +#define MV64340_PCI_1_CS_3_BANK_SIZE 0xd8c +#define MV64340_PCI_0_DEVCS_0_BANK_SIZE 0xc10 +#define MV64340_PCI_1_DEVCS_0_BANK_SIZE 0xc90 +#define MV64340_PCI_0_DEVCS_1_BANK_SIZE 0xd10 +#define MV64340_PCI_1_DEVCS_1_BANK_SIZE 0xd90 +#define MV64340_PCI_0_DEVCS_2_BANK_SIZE 0xd18 +#define MV64340_PCI_1_DEVCS_2_BANK_SIZE 0xd98 +#define MV64340_PCI_0_DEVCS_3_BANK_SIZE 0xc14 +#define MV64340_PCI_1_DEVCS_3_BANK_SIZE 0xc94 +#define MV64340_PCI_0_DEVCS_BOOT_BANK_SIZE 0xd14 +#define MV64340_PCI_1_DEVCS_BOOT_BANK_SIZE 0xd94 +#define MV64340_PCI_0_P2P_MEM0_BAR_SIZE 0xd1c +#define MV64340_PCI_1_P2P_MEM0_BAR_SIZE 0xd9c +#define MV64340_PCI_0_P2P_MEM1_BAR_SIZE 0xd20 +#define MV64340_PCI_1_P2P_MEM1_BAR_SIZE 0xda0 +#define MV64340_PCI_0_P2P_I_O_BAR_SIZE 0xd24 +#define MV64340_PCI_1_P2P_I_O_BAR_SIZE 0xda4 +#define MV64340_PCI_0_CPU_BAR_SIZE 0xd28 +#define MV64340_PCI_1_CPU_BAR_SIZE 0xda8 +#define MV64340_PCI_0_INTERNAL_SRAM_BAR_SIZE 0xe00 +#define MV64340_PCI_1_INTERNAL_SRAM_BAR_SIZE 0xe80 +#define MV64340_PCI_0_EXPANSION_ROM_BAR_SIZE 0xd2c +#define MV64340_PCI_1_EXPANSION_ROM_BAR_SIZE 0xd9c +#define MV64340_PCI_0_BASE_ADDR_REG_ENABLE 0xc3c +#define MV64340_PCI_1_BASE_ADDR_REG_ENABLE 0xcbc +#define MV64340_PCI_0_CS_0_BASE_ADDR_REMAP 0xc48 +#define MV64340_PCI_1_CS_0_BASE_ADDR_REMAP 0xcc8 +#define MV64340_PCI_0_CS_1_BASE_ADDR_REMAP 0xd48 +#define MV64340_PCI_1_CS_1_BASE_ADDR_REMAP 0xdc8 +#define MV64340_PCI_0_CS_2_BASE_ADDR_REMAP 0xc4c +#define MV64340_PCI_1_CS_2_BASE_ADDR_REMAP 0xccc +#define MV64340_PCI_0_CS_3_BASE_ADDR_REMAP 0xd4c +#define MV64340_PCI_1_CS_3_BASE_ADDR_REMAP 0xdcc +#define MV64340_PCI_0_CS_0_BASE_HIGH_ADDR_REMAP 0xF04 +#define MV64340_PCI_1_CS_0_BASE_HIGH_ADDR_REMAP 0xF84 +#define MV64340_PCI_0_CS_1_BASE_HIGH_ADDR_REMAP 0xF08 +#define MV64340_PCI_1_CS_1_BASE_HIGH_ADDR_REMAP 0xF88 +#define MV64340_PCI_0_CS_2_BASE_HIGH_ADDR_REMAP 0xF0C +#define MV64340_PCI_1_CS_2_BASE_HIGH_ADDR_REMAP 0xF8C +#define MV64340_PCI_0_CS_3_BASE_HIGH_ADDR_REMAP 0xF10 +#define MV64340_PCI_1_CS_3_BASE_HIGH_ADDR_REMAP 0xF90 +#define MV64340_PCI_0_DEVCS_0_BASE_ADDR_REMAP 0xc50 +#define MV64340_PCI_1_DEVCS_0_BASE_ADDR_REMAP 0xcd0 +#define MV64340_PCI_0_DEVCS_1_BASE_ADDR_REMAP 0xd50 +#define MV64340_PCI_1_DEVCS_1_BASE_ADDR_REMAP 0xdd0 +#define MV64340_PCI_0_DEVCS_2_BASE_ADDR_REMAP 0xd58 +#define MV64340_PCI_1_DEVCS_2_BASE_ADDR_REMAP 0xdd8 +#define MV64340_PCI_0_DEVCS_3_BASE_ADDR_REMAP 0xc54 +#define MV64340_PCI_1_DEVCS_3_BASE_ADDR_REMAP 0xcd4 +#define MV64340_PCI_0_DEVCS_BOOTCS_BASE_ADDR_REMAP 0xd54 +#define MV64340_PCI_1_DEVCS_BOOTCS_BASE_ADDR_REMAP 0xdd4 +#define MV64340_PCI_0_P2P_MEM0_BASE_ADDR_REMAP_LOW 0xd5c +#define MV64340_PCI_1_P2P_MEM0_BASE_ADDR_REMAP_LOW 0xddc +#define MV64340_PCI_0_P2P_MEM0_BASE_ADDR_REMAP_HIGH 0xd60 +#define MV64340_PCI_1_P2P_MEM0_BASE_ADDR_REMAP_HIGH 0xde0 +#define MV64340_PCI_0_P2P_MEM1_BASE_ADDR_REMAP_LOW 0xd64 +#define MV64340_PCI_1_P2P_MEM1_BASE_ADDR_REMAP_LOW 0xde4 +#define MV64340_PCI_0_P2P_MEM1_BASE_ADDR_REMAP_HIGH 0xd68 +#define MV64340_PCI_1_P2P_MEM1_BASE_ADDR_REMAP_HIGH 0xde8 +#define MV64340_PCI_0_P2P_I_O_BASE_ADDR_REMAP 0xd6c +#define MV64340_PCI_1_P2P_I_O_BASE_ADDR_REMAP 0xdec +#define MV64340_PCI_0_CPU_BASE_ADDR_REMAP_LOW 0xd70 +#define MV64340_PCI_1_CPU_BASE_ADDR_REMAP_LOW 0xdf0 +#define MV64340_PCI_0_CPU_BASE_ADDR_REMAP_HIGH 0xd74 +#define MV64340_PCI_1_CPU_BASE_ADDR_REMAP_HIGH 0xdf4 +#define MV64340_PCI_0_INTEGRATED_SRAM_BASE_ADDR_REMAP 0xf00 +#define MV64340_PCI_1_INTEGRATED_SRAM_BASE_ADDR_REMAP 0xf80 +#define MV64340_PCI_0_EXPANSION_ROM_BASE_ADDR_REMAP 0xf38 +#define MV64340_PCI_1_EXPANSION_ROM_BASE_ADDR_REMAP 0xfb8 +#define MV64340_PCI_0_ADDR_DECODE_CONTROL 0xd3c +#define MV64340_PCI_1_ADDR_DECODE_CONTROL 0xdbc +#define MV64340_PCI_0_HEADERS_RETARGET_CONTROL 0xF40 +#define MV64340_PCI_1_HEADERS_RETARGET_CONTROL 0xFc0 +#define MV64340_PCI_0_HEADERS_RETARGET_BASE 0xF44 +#define MV64340_PCI_1_HEADERS_RETARGET_BASE 0xFc4 +#define MV64340_PCI_0_HEADERS_RETARGET_HIGH 0xF48 +#define MV64340_PCI_1_HEADERS_RETARGET_HIGH 0xFc8 + +/***********************************/ +/* PCI Control Register Map */ +/***********************************/ + +#define MV64340_PCI_0_DLL_STATUS_AND_COMMAND 0x1d20 +#define MV64340_PCI_1_DLL_STATUS_AND_COMMAND 0x1da0 +#define MV64340_PCI_0_MPP_PADS_DRIVE_CONTROL 0x1d1C +#define MV64340_PCI_1_MPP_PADS_DRIVE_CONTROL 0x1d9C +#define MV64340_PCI_0_COMMAND 0xc00 +#define MV64340_PCI_1_COMMAND 0xc80 +#define MV64340_PCI_0_MODE 0xd00 +#define MV64340_PCI_1_MODE 0xd80 +#define MV64340_PCI_0_RETRY 0xc04 +#define MV64340_PCI_1_RETRY 0xc84 +#define MV64340_PCI_0_READ_BUFFER_DISCARD_TIMER 0xd04 +#define MV64340_PCI_1_READ_BUFFER_DISCARD_TIMER 0xd84 +#define MV64340_PCI_0_MSI_TRIGGER_TIMER 0xc38 +#define MV64340_PCI_1_MSI_TRIGGER_TIMER 0xcb8 +#define MV64340_PCI_0_ARBITER_CONTROL 0x1d00 +#define MV64340_PCI_1_ARBITER_CONTROL 0x1d80 +#define MV64340_PCI_0_CROSS_BAR_CONTROL_LOW 0x1d08 +#define MV64340_PCI_1_CROSS_BAR_CONTROL_LOW 0x1d88 +#define MV64340_PCI_0_CROSS_BAR_CONTROL_HIGH 0x1d0c +#define MV64340_PCI_1_CROSS_BAR_CONTROL_HIGH 0x1d8c +#define MV64340_PCI_0_CROSS_BAR_TIMEOUT 0x1d04 +#define MV64340_PCI_1_CROSS_BAR_TIMEOUT 0x1d84 +#define MV64340_PCI_0_SYNC_BARRIER_TRIGGER_REG 0x1D18 +#define MV64340_PCI_1_SYNC_BARRIER_TRIGGER_REG 0x1D98 +#define MV64340_PCI_0_SYNC_BARRIER_VIRTUAL_REG 0x1d10 +#define MV64340_PCI_1_SYNC_BARRIER_VIRTUAL_REG 0x1d90 +#define MV64340_PCI_0_P2P_CONFIG 0x1d14 +#define MV64340_PCI_1_P2P_CONFIG 0x1d94 + +#define MV64340_PCI_0_ACCESS_CONTROL_BASE_0_LOW 0x1e00 +#define MV64340_PCI_0_ACCESS_CONTROL_BASE_0_HIGH 0x1e04 +#define MV64340_PCI_0_ACCESS_CONTROL_SIZE_0 0x1e08 +#define MV64340_PCI_0_ACCESS_CONTROL_BASE_1_LOW 0x1e10 +#define MV64340_PCI_0_ACCESS_CONTROL_BASE_1_HIGH 0x1e14 +#define MV64340_PCI_0_ACCESS_CONTROL_SIZE_1 0x1e18 +#define MV64340_PCI_0_ACCESS_CONTROL_BASE_2_LOW 0x1e20 +#define MV64340_PCI_0_ACCESS_CONTROL_BASE_2_HIGH 0x1e24 +#define MV64340_PCI_0_ACCESS_CONTROL_SIZE_2 0x1e28 +#define MV64340_PCI_0_ACCESS_CONTROL_BASE_3_LOW 0x1e30 +#define MV64340_PCI_0_ACCESS_CONTROL_BASE_3_HIGH 0x1e34 +#define MV64340_PCI_0_ACCESS_CONTROL_SIZE_3 0x1e38 +#define MV64340_PCI_0_ACCESS_CONTROL_BASE_4_LOW 0x1e40 +#define MV64340_PCI_0_ACCESS_CONTROL_BASE_4_HIGH 0x1e44 +#define MV64340_PCI_0_ACCESS_CONTROL_SIZE_4 0x1e48 +#define MV64340_PCI_0_ACCESS_CONTROL_BASE_5_LOW 0x1e50 +#define MV64340_PCI_0_ACCESS_CONTROL_BASE_5_HIGH 0x1e54 +#define MV64340_PCI_0_ACCESS_CONTROL_SIZE_5 0x1e58 + +#define MV64340_PCI_1_ACCESS_CONTROL_BASE_0_LOW 0x1e80 +#define MV64340_PCI_1_ACCESS_CONTROL_BASE_0_HIGH 0x1e84 +#define MV64340_PCI_1_ACCESS_CONTROL_SIZE_0 0x1e88 +#define MV64340_PCI_1_ACCESS_CONTROL_BASE_1_LOW 0x1e90 +#define MV64340_PCI_1_ACCESS_CONTROL_BASE_1_HIGH 0x1e94 +#define MV64340_PCI_1_ACCESS_CONTROL_SIZE_1 0x1e98 +#define MV64340_PCI_1_ACCESS_CONTROL_BASE_2_LOW 0x1ea0 +#define MV64340_PCI_1_ACCESS_CONTROL_BASE_2_HIGH 0x1ea4 +#define MV64340_PCI_1_ACCESS_CONTROL_SIZE_2 0x1ea8 +#define MV64340_PCI_1_ACCESS_CONTROL_BASE_3_LOW 0x1eb0 +#define MV64340_PCI_1_ACCESS_CONTROL_BASE_3_HIGH 0x1eb4 +#define MV64340_PCI_1_ACCESS_CONTROL_SIZE_3 0x1eb8 +#define MV64340_PCI_1_ACCESS_CONTROL_BASE_4_LOW 0x1ec0 +#define MV64340_PCI_1_ACCESS_CONTROL_BASE_4_HIGH 0x1ec4 +#define MV64340_PCI_1_ACCESS_CONTROL_SIZE_4 0x1ec8 +#define MV64340_PCI_1_ACCESS_CONTROL_BASE_5_LOW 0x1ed0 +#define MV64340_PCI_1_ACCESS_CONTROL_BASE_5_HIGH 0x1ed4 +#define MV64340_PCI_1_ACCESS_CONTROL_SIZE_5 0x1ed8 + +/****************************************/ +/* PCI Configuration Access Registers */ +/****************************************/ + +#define MV64340_PCI_0_CONFIG_ADDR 0xcf8 +#define MV64340_PCI_0_CONFIG_DATA_VIRTUAL_REG 0xcfc +#define MV64340_PCI_1_CONFIG_ADDR 0xc78 +#define MV64340_PCI_1_CONFIG_DATA_VIRTUAL_REG 0xc7c +#define MV64340_PCI_0_INTERRUPT_ACKNOWLEDGE_VIRTUAL_REG 0xc34 +#define MV64340_PCI_1_INTERRUPT_ACKNOWLEDGE_VIRTUAL_REG 0xcb4 + +/****************************************/ +/* PCI Error Report Registers */ +/****************************************/ + +#define MV64340_PCI_0_SERR_MASK 0xc28 +#define MV64340_PCI_1_SERR_MASK 0xca8 +#define MV64340_PCI_0_ERROR_ADDR_LOW 0x1d40 +#define MV64340_PCI_1_ERROR_ADDR_LOW 0x1dc0 +#define MV64340_PCI_0_ERROR_ADDR_HIGH 0x1d44 +#define MV64340_PCI_1_ERROR_ADDR_HIGH 0x1dc4 +#define MV64340_PCI_0_ERROR_ATTRIBUTE 0x1d48 +#define MV64340_PCI_1_ERROR_ATTRIBUTE 0x1dc8 +#define MV64340_PCI_0_ERROR_COMMAND 0x1d50 +#define MV64340_PCI_1_ERROR_COMMAND 0x1dd0 +#define MV64340_PCI_0_ERROR_CAUSE 0x1d58 +#define MV64340_PCI_1_ERROR_CAUSE 0x1dd8 +#define MV64340_PCI_0_ERROR_MASK 0x1d5c +#define MV64340_PCI_1_ERROR_MASK 0x1ddc + +/****************************************/ +/* PCI Debug Registers */ +/****************************************/ + +#define MV64340_PCI_0_MMASK 0X1D24 +#define MV64340_PCI_1_MMASK 0X1DA4 + +/*********************************************/ +/* PCI Configuration, Function 0, Registers */ +/*********************************************/ + +#define MV64340_PCI_DEVICE_AND_VENDOR_ID 0x000 +#define MV64340_PCI_STATUS_AND_COMMAND 0x004 +#define MV64340_PCI_CLASS_CODE_AND_REVISION_ID 0x008 +#define MV64340_PCI_BIST_HEADER_TYPE_LATENCY_TIMER_CACHE_LINE 0x00C + +#define MV64340_PCI_SCS_0_BASE_ADDR_LOW 0x010 +#define MV64340_PCI_SCS_0_BASE_ADDR_HIGH 0x014 +#define MV64340_PCI_SCS_1_BASE_ADDR_LOW 0x018 +#define MV64340_PCI_SCS_1_BASE_ADDR_HIGH 0x01C +#define MV64340_PCI_INTERNAL_REG_MEM_MAPPED_BASE_ADDR_LOW 0x020 +#define MV64340_PCI_INTERNAL_REG_MEM_MAPPED_BASE_ADDR_HIGH 0x024 +#define MV64340_PCI_SUBSYSTEM_ID_AND_SUBSYSTEM_VENDOR_ID 0x02c +#define MV64340_PCI_EXPANSION_ROM_BASE_ADDR_REG 0x030 +#define MV64340_PCI_CAPABILTY_LIST_POINTER 0x034 +#define MV64340_PCI_INTERRUPT_PIN_AND_LINE 0x03C + /* capability list */ +#define MV64340_PCI_POWER_MANAGEMENT_CAPABILITY 0x040 +#define MV64340_PCI_POWER_MANAGEMENT_STATUS_AND_CONTROL 0x044 +#define MV64340_PCI_VPD_ADDR 0x048 +#define MV64340_PCI_VPD_DATA 0x04c +#define MV64340_PCI_MSI_MESSAGE_CONTROL 0x050 +#define MV64340_PCI_MSI_MESSAGE_ADDR 0x054 +#define MV64340_PCI_MSI_MESSAGE_UPPER_ADDR 0x058 +#define MV64340_PCI_MSI_MESSAGE_DATA 0x05c +#define MV64340_PCI_X_COMMAND 0x060 +#define MV64340_PCI_X_STATUS 0x064 +#define MV64340_PCI_COMPACT_PCI_HOT_SWAP 0x068 + +/***********************************************/ +/* PCI Configuration, Function 1, Registers */ +/***********************************************/ + +#define MV64340_PCI_SCS_2_BASE_ADDR_LOW 0x110 +#define MV64340_PCI_SCS_2_BASE_ADDR_HIGH 0x114 +#define MV64340_PCI_SCS_3_BASE_ADDR_LOW 0x118 +#define MV64340_PCI_SCS_3_BASE_ADDR_HIGH 0x11c +#define MV64340_PCI_INTERNAL_SRAM_BASE_ADDR_LOW 0x120 +#define MV64340_PCI_INTERNAL_SRAM_BASE_ADDR_HIGH 0x124 + +/***********************************************/ +/* PCI Configuration, Function 2, Registers */ +/***********************************************/ + +#define MV64340_PCI_DEVCS_0_BASE_ADDR_LOW 0x210 +#define MV64340_PCI_DEVCS_0_BASE_ADDR_HIGH 0x214 +#define MV64340_PCI_DEVCS_1_BASE_ADDR_LOW 0x218 +#define MV64340_PCI_DEVCS_1_BASE_ADDR_HIGH 0x21c +#define MV64340_PCI_DEVCS_2_BASE_ADDR_LOW 0x220 +#define MV64340_PCI_DEVCS_2_BASE_ADDR_HIGH 0x224 + +/***********************************************/ +/* PCI Configuration, Function 3, Registers */ +/***********************************************/ + +#define MV64340_PCI_DEVCS_3_BASE_ADDR_LOW 0x310 +#define MV64340_PCI_DEVCS_3_BASE_ADDR_HIGH 0x314 +#define MV64340_PCI_BOOT_CS_BASE_ADDR_LOW 0x318 +#define MV64340_PCI_BOOT_CS_BASE_ADDR_HIGH 0x31c +#define MV64340_PCI_CPU_BASE_ADDR_LOW 0x220 +#define MV64340_PCI_CPU_BASE_ADDR_HIGH 0x224 + +/***********************************************/ +/* PCI Configuration, Function 4, Registers */ +/***********************************************/ + +#define MV64340_PCI_P2P_MEM0_BASE_ADDR_LOW 0x410 +#define MV64340_PCI_P2P_MEM0_BASE_ADDR_HIGH 0x414 +#define MV64340_PCI_P2P_MEM1_BASE_ADDR_LOW 0x418 +#define MV64340_PCI_P2P_MEM1_BASE_ADDR_HIGH 0x41c +#define MV64340_PCI_P2P_I_O_BASE_ADDR 0x420 +#define MV64340_PCI_INTERNAL_REGS_I_O_MAPPED_BASE_ADDR 0x424 + +/****************************************/ +/* Messaging Unit Registers (I20) */ +/****************************************/ + +#define MV64340_I2O_INBOUND_MESSAGE_REG0_PCI_0_SIDE 0x010 +#define MV64340_I2O_INBOUND_MESSAGE_REG1_PCI_0_SIDE 0x014 +#define MV64340_I2O_OUTBOUND_MESSAGE_REG0_PCI_0_SIDE 0x018 +#define MV64340_I2O_OUTBOUND_MESSAGE_REG1_PCI_0_SIDE 0x01C +#define MV64340_I2O_INBOUND_DOORBELL_REG_PCI_0_SIDE 0x020 +#define MV64340_I2O_INBOUND_INTERRUPT_CAUSE_REG_PCI_0_SIDE 0x024 +#define MV64340_I2O_INBOUND_INTERRUPT_MASK_REG_PCI_0_SIDE 0x028 +#define MV64340_I2O_OUTBOUND_DOORBELL_REG_PCI_0_SIDE 0x02C +#define MV64340_I2O_OUTBOUND_INTERRUPT_CAUSE_REG_PCI_0_SIDE 0x030 +#define MV64340_I2O_OUTBOUND_INTERRUPT_MASK_REG_PCI_0_SIDE 0x034 +#define MV64340_I2O_INBOUND_QUEUE_PORT_VIRTUAL_REG_PCI_0_SIDE 0x040 +#define MV64340_I2O_OUTBOUND_QUEUE_PORT_VIRTUAL_REG_PCI_0_SIDE 0x044 +#define MV64340_I2O_QUEUE_CONTROL_REG_PCI_0_SIDE 0x050 +#define MV64340_I2O_QUEUE_BASE_ADDR_REG_PCI_0_SIDE 0x054 +#define MV64340_I2O_INBOUND_FREE_HEAD_POINTER_REG_PCI_0_SIDE 0x060 +#define MV64340_I2O_INBOUND_FREE_TAIL_POINTER_REG_PCI_0_SIDE 0x064 +#define MV64340_I2O_INBOUND_POST_HEAD_POINTER_REG_PCI_0_SIDE 0x068 +#define MV64340_I2O_INBOUND_POST_TAIL_POINTER_REG_PCI_0_SIDE 0x06C +#define MV64340_I2O_OUTBOUND_FREE_HEAD_POINTER_REG_PCI_0_SIDE 0x070 +#define MV64340_I2O_OUTBOUND_FREE_TAIL_POINTER_REG_PCI_0_SIDE 0x074 +#define MV64340_I2O_OUTBOUND_POST_HEAD_POINTER_REG_PCI_0_SIDE 0x0F8 +#define MV64340_I2O_OUTBOUND_POST_TAIL_POINTER_REG_PCI_0_SIDE 0x0FC + +#define MV64340_I2O_INBOUND_MESSAGE_REG0_PCI_1_SIDE 0x090 +#define MV64340_I2O_INBOUND_MESSAGE_REG1_PCI_1_SIDE 0x094 +#define MV64340_I2O_OUTBOUND_MESSAGE_REG0_PCI_1_SIDE 0x098 +#define MV64340_I2O_OUTBOUND_MESSAGE_REG1_PCI_1_SIDE 0x09C +#define MV64340_I2O_INBOUND_DOORBELL_REG_PCI_1_SIDE 0x0A0 +#define MV64340_I2O_INBOUND_INTERRUPT_CAUSE_REG_PCI_1_SIDE 0x0A4 +#define MV64340_I2O_INBOUND_INTERRUPT_MASK_REG_PCI_1_SIDE 0x0A8 +#define MV64340_I2O_OUTBOUND_DOORBELL_REG_PCI_1_SIDE 0x0AC +#define MV64340_I2O_OUTBOUND_INTERRUPT_CAUSE_REG_PCI_1_SIDE 0x0B0 +#define MV64340_I2O_OUTBOUND_INTERRUPT_MASK_REG_PCI_1_SIDE 0x0B4 +#define MV64340_I2O_INBOUND_QUEUE_PORT_VIRTUAL_REG_PCI_1_SIDE 0x0C0 +#define MV64340_I2O_OUTBOUND_QUEUE_PORT_VIRTUAL_REG_PCI_1_SIDE 0x0C4 +#define MV64340_I2O_QUEUE_CONTROL_REG_PCI_1_SIDE 0x0D0 +#define MV64340_I2O_QUEUE_BASE_ADDR_REG_PCI_1_SIDE 0x0D4 +#define MV64340_I2O_INBOUND_FREE_HEAD_POINTER_REG_PCI_1_SIDE 0x0E0 +#define MV64340_I2O_INBOUND_FREE_TAIL_POINTER_REG_PCI_1_SIDE 0x0E4 +#define MV64340_I2O_INBOUND_POST_HEAD_POINTER_REG_PCI_1_SIDE 0x0E8 +#define MV64340_I2O_INBOUND_POST_TAIL_POINTER_REG_PCI_1_SIDE 0x0EC +#define MV64340_I2O_OUTBOUND_FREE_HEAD_POINTER_REG_PCI_1_SIDE 0x0F0 +#define MV64340_I2O_OUTBOUND_FREE_TAIL_POINTER_REG_PCI_1_SIDE 0x0F4 +#define MV64340_I2O_OUTBOUND_POST_HEAD_POINTER_REG_PCI_1_SIDE 0x078 +#define MV64340_I2O_OUTBOUND_POST_TAIL_POINTER_REG_PCI_1_SIDE 0x07C + +#define MV64340_I2O_INBOUND_MESSAGE_REG0_CPU0_SIDE 0x1C10 +#define MV64340_I2O_INBOUND_MESSAGE_REG1_CPU0_SIDE 0x1C14 +#define MV64340_I2O_OUTBOUND_MESSAGE_REG0_CPU0_SIDE 0x1C18 +#define MV64340_I2O_OUTBOUND_MESSAGE_REG1_CPU0_SIDE 0x1C1C +#define MV64340_I2O_INBOUND_DOORBELL_REG_CPU0_SIDE 0x1C20 +#define MV64340_I2O_INBOUND_INTERRUPT_CAUSE_REG_CPU0_SIDE 0x1C24 +#define MV64340_I2O_INBOUND_INTERRUPT_MASK_REG_CPU0_SIDE 0x1C28 +#define MV64340_I2O_OUTBOUND_DOORBELL_REG_CPU0_SIDE 0x1C2C +#define MV64340_I2O_OUTBOUND_INTERRUPT_CAUSE_REG_CPU0_SIDE 0x1C30 +#define MV64340_I2O_OUTBOUND_INTERRUPT_MASK_REG_CPU0_SIDE 0x1C34 +#define MV64340_I2O_INBOUND_QUEUE_PORT_VIRTUAL_REG_CPU0_SIDE 0x1C40 +#define MV64340_I2O_OUTBOUND_QUEUE_PORT_VIRTUAL_REG_CPU0_SIDE 0x1C44 +#define MV64340_I2O_QUEUE_CONTROL_REG_CPU0_SIDE 0x1C50 +#define MV64340_I2O_QUEUE_BASE_ADDR_REG_CPU0_SIDE 0x1C54 +#define MV64340_I2O_INBOUND_FREE_HEAD_POINTER_REG_CPU0_SIDE 0x1C60 +#define MV64340_I2O_INBOUND_FREE_TAIL_POINTER_REG_CPU0_SIDE 0x1C64 +#define MV64340_I2O_INBOUND_POST_HEAD_POINTER_REG_CPU0_SIDE 0x1C68 +#define MV64340_I2O_INBOUND_POST_TAIL_POINTER_REG_CPU0_SIDE 0x1C6C +#define MV64340_I2O_OUTBOUND_FREE_HEAD_POINTER_REG_CPU0_SIDE 0x1C70 +#define MV64340_I2O_OUTBOUND_FREE_TAIL_POINTER_REG_CPU0_SIDE 0x1C74 +#define MV64340_I2O_OUTBOUND_POST_HEAD_POINTER_REG_CPU0_SIDE 0x1CF8 +#define MV64340_I2O_OUTBOUND_POST_TAIL_POINTER_REG_CPU0_SIDE 0x1CFC +#define MV64340_I2O_INBOUND_MESSAGE_REG0_CPU1_SIDE 0x1C90 +#define MV64340_I2O_INBOUND_MESSAGE_REG1_CPU1_SIDE 0x1C94 +#define MV64340_I2O_OUTBOUND_MESSAGE_REG0_CPU1_SIDE 0x1C98 +#define MV64340_I2O_OUTBOUND_MESSAGE_REG1_CPU1_SIDE 0x1C9C +#define MV64340_I2O_INBOUND_DOORBELL_REG_CPU1_SIDE 0x1CA0 +#define MV64340_I2O_INBOUND_INTERRUPT_CAUSE_REG_CPU1_SIDE 0x1CA4 +#define MV64340_I2O_INBOUND_INTERRUPT_MASK_REG_CPU1_SIDE 0x1CA8 +#define MV64340_I2O_OUTBOUND_DOORBELL_REG_CPU1_SIDE 0x1CAC +#define MV64340_I2O_OUTBOUND_INTERRUPT_CAUSE_REG_CPU1_SIDE 0x1CB0 +#define MV64340_I2O_OUTBOUND_INTERRUPT_MASK_REG_CPU1_SIDE 0x1CB4 +#define MV64340_I2O_INBOUND_QUEUE_PORT_VIRTUAL_REG_CPU1_SIDE 0x1CC0 +#define MV64340_I2O_OUTBOUND_QUEUE_PORT_VIRTUAL_REG_CPU1_SIDE 0x1CC4 +#define MV64340_I2O_QUEUE_CONTROL_REG_CPU1_SIDE 0x1CD0 +#define MV64340_I2O_QUEUE_BASE_ADDR_REG_CPU1_SIDE 0x1CD4 +#define MV64340_I2O_INBOUND_FREE_HEAD_POINTER_REG_CPU1_SIDE 0x1CE0 +#define MV64340_I2O_INBOUND_FREE_TAIL_POINTER_REG_CPU1_SIDE 0x1CE4 +#define MV64340_I2O_INBOUND_POST_HEAD_POINTER_REG_CPU1_SIDE 0x1CE8 +#define MV64340_I2O_INBOUND_POST_TAIL_POINTER_REG_CPU1_SIDE 0x1CEC +#define MV64340_I2O_OUTBOUND_FREE_HEAD_POINTER_REG_CPU1_SIDE 0x1CF0 +#define MV64340_I2O_OUTBOUND_FREE_TAIL_POINTER_REG_CPU1_SIDE 0x1CF4 +#define MV64340_I2O_OUTBOUND_POST_HEAD_POINTER_REG_CPU1_SIDE 0x1C78 +#define MV64340_I2O_OUTBOUND_POST_TAIL_POINTER_REG_CPU1_SIDE 0x1C7C + +/****************************************/ +/* Ethernet Unit Registers */ +/****************************************/ + +/*******************************************/ +/* CUNIT Registers */ +/*******************************************/ + + /* Address Decoding Register Map */ + +#define MV64340_CUNIT_BASE_ADDR_REG0 0xf200 +#define MV64340_CUNIT_BASE_ADDR_REG1 0xf208 +#define MV64340_CUNIT_BASE_ADDR_REG2 0xf210 +#define MV64340_CUNIT_BASE_ADDR_REG3 0xf218 +#define MV64340_CUNIT_SIZE0 0xf204 +#define MV64340_CUNIT_SIZE1 0xf20c +#define MV64340_CUNIT_SIZE2 0xf214 +#define MV64340_CUNIT_SIZE3 0xf21c +#define MV64340_CUNIT_HIGH_ADDR_REMAP_REG0 0xf240 +#define MV64340_CUNIT_HIGH_ADDR_REMAP_REG1 0xf244 +#define MV64340_CUNIT_BASE_ADDR_ENABLE_REG 0xf250 +#define MV64340_MPSC0_ACCESS_PROTECTION_REG 0xf254 +#define MV64340_MPSC1_ACCESS_PROTECTION_REG 0xf258 +#define MV64340_CUNIT_INTERNAL_SPACE_BASE_ADDR_REG 0xf25C + + /* Error Report Registers */ + +#define MV64340_CUNIT_INTERRUPT_CAUSE_REG 0xf310 +#define MV64340_CUNIT_INTERRUPT_MASK_REG 0xf314 +#define MV64340_CUNIT_ERROR_ADDR 0xf318 + + /* Cunit Control Registers */ + +#define MV64340_CUNIT_ARBITER_CONTROL_REG 0xf300 +#define MV64340_CUNIT_CONFIG_REG 0xb40c +#define MV64340_CUNIT_CRROSBAR_TIMEOUT_REG 0xf304 + + /* Cunit Debug Registers */ + +#define MV64340_CUNIT_DEBUG_LOW 0xf340 +#define MV64340_CUNIT_DEBUG_HIGH 0xf344 +#define MV64340_CUNIT_MMASK 0xf380 + + /* MPSCs Clocks Routing Registers */ + +#define MV64340_MPSC_ROUTING_REG 0xb400 +#define MV64340_MPSC_RX_CLOCK_ROUTING_REG 0xb404 +#define MV64340_MPSC_TX_CLOCK_ROUTING_REG 0xb408 + + /* MPSCs Interrupts Registers */ + +#define MV64340_MPSC_CAUSE_REG(port) (0xb804 + (port << 3)) +#define MV64340_MPSC_MASK_REG(port) (0xb884 + (port << 3)) + +#define MV64340_MPSC_MAIN_CONFIG_LOW(port) (0x8000 + (port << 12)) +#define MV64340_MPSC_MAIN_CONFIG_HIGH(port) (0x8004 + (port << 12)) +#define MV64340_MPSC_PROTOCOL_CONFIG(port) (0x8008 + (port << 12)) +#define MV64340_MPSC_CHANNEL_REG1(port) (0x800c + (port << 12)) +#define MV64340_MPSC_CHANNEL_REG2(port) (0x8010 + (port << 12)) +#define MV64340_MPSC_CHANNEL_REG3(port) (0x8014 + (port << 12)) +#define MV64340_MPSC_CHANNEL_REG4(port) (0x8018 + (port << 12)) +#define MV64340_MPSC_CHANNEL_REG5(port) (0x801c + (port << 12)) +#define MV64340_MPSC_CHANNEL_REG6(port) (0x8020 + (port << 12)) +#define MV64340_MPSC_CHANNEL_REG7(port) (0x8024 + (port << 12)) +#define MV64340_MPSC_CHANNEL_REG8(port) (0x8028 + (port << 12)) +#define MV64340_MPSC_CHANNEL_REG9(port) (0x802c + (port << 12)) +#define MV64340_MPSC_CHANNEL_REG10(port) (0x8030 + (port << 12)) + + /* MPSC0 Registers */ + + +/***************************************/ +/* SDMA Registers */ +/***************************************/ + +#define MV64340_SDMA_CONFIG_REG(channel) (0x4000 + (channel << 13)) +#define MV64340_SDMA_COMMAND_REG(channel) (0x4008 + (channel << 13)) +#define MV64340_SDMA_CURRENT_RX_DESCRIPTOR_POINTER(channel) (0x4810 + (channel << 13)) +#define MV64340_SDMA_CURRENT_TX_DESCRIPTOR_POINTER(channel) (0x4c10 + (channel << 13)) +#define MV64340_SDMA_FIRST_TX_DESCRIPTOR_POINTER(channel) (0x4c14 + (channel << 13)) + +#define MV64340_SDMA_CAUSE_REG 0xb800 +#define MV64340_SDMA_MASK_REG 0xb880 + +/* BRG Interrupts */ + +#define MV64340_BRG_CONFIG_REG(brg) (0xb200 + (brg << 3)) +#define MV64340_BRG_BAUDE_TUNING_REG(brg) (0xb208 + (brg << 3)) +#define MV64340_BRG_CAUSE_REG 0xb834 +#define MV64340_BRG_MASK_REG 0xb8b4 + +/****************************************/ +/* DMA Channel Control */ +/****************************************/ + +#define MV64340_DMA_CHANNEL0_CONTROL 0x840 +#define MV64340_DMA_CHANNEL0_CONTROL_HIGH 0x880 +#define MV64340_DMA_CHANNEL1_CONTROL 0x844 +#define MV64340_DMA_CHANNEL1_CONTROL_HIGH 0x884 +#define MV64340_DMA_CHANNEL2_CONTROL 0x848 +#define MV64340_DMA_CHANNEL2_CONTROL_HIGH 0x888 +#define MV64340_DMA_CHANNEL3_CONTROL 0x84C +#define MV64340_DMA_CHANNEL3_CONTROL_HIGH 0x88C + + +/****************************************/ +/* IDMA Registers */ +/****************************************/ + +#define MV64340_DMA_CHANNEL0_BYTE_COUNT 0x800 +#define MV64340_DMA_CHANNEL1_BYTE_COUNT 0x804 +#define MV64340_DMA_CHANNEL2_BYTE_COUNT 0x808 +#define MV64340_DMA_CHANNEL3_BYTE_COUNT 0x80C +#define MV64340_DMA_CHANNEL0_SOURCE_ADDR 0x810 +#define MV64340_DMA_CHANNEL1_SOURCE_ADDR 0x814 +#define MV64340_DMA_CHANNEL2_SOURCE_ADDR 0x818 +#define MV64340_DMA_CHANNEL3_SOURCE_ADDR 0x81c +#define MV64340_DMA_CHANNEL0_DESTINATION_ADDR 0x820 +#define MV64340_DMA_CHANNEL1_DESTINATION_ADDR 0x824 +#define MV64340_DMA_CHANNEL2_DESTINATION_ADDR 0x828 +#define MV64340_DMA_CHANNEL3_DESTINATION_ADDR 0x82C +#define MV64340_DMA_CHANNEL0_NEXT_DESCRIPTOR_POINTER 0x830 +#define MV64340_DMA_CHANNEL1_NEXT_DESCRIPTOR_POINTER 0x834 +#define MV64340_DMA_CHANNEL2_NEXT_DESCRIPTOR_POINTER 0x838 +#define MV64340_DMA_CHANNEL3_NEXT_DESCRIPTOR_POINTER 0x83C +#define MV64340_DMA_CHANNEL0_CURRENT_DESCRIPTOR_POINTER 0x870 +#define MV64340_DMA_CHANNEL1_CURRENT_DESCRIPTOR_POINTER 0x874 +#define MV64340_DMA_CHANNEL2_CURRENT_DESCRIPTOR_POINTER 0x878 +#define MV64340_DMA_CHANNEL3_CURRENT_DESCRIPTOR_POINTER 0x87C + + /* IDMA Address Decoding Base Address Registers */ + +#define MV64340_DMA_BASE_ADDR_REG0 0xa00 +#define MV64340_DMA_BASE_ADDR_REG1 0xa08 +#define MV64340_DMA_BASE_ADDR_REG2 0xa10 +#define MV64340_DMA_BASE_ADDR_REG3 0xa18 +#define MV64340_DMA_BASE_ADDR_REG4 0xa20 +#define MV64340_DMA_BASE_ADDR_REG5 0xa28 +#define MV64340_DMA_BASE_ADDR_REG6 0xa30 +#define MV64340_DMA_BASE_ADDR_REG7 0xa38 + + /* IDMA Address Decoding Size Address Register */ + +#define MV64340_DMA_SIZE_REG0 0xa04 +#define MV64340_DMA_SIZE_REG1 0xa0c +#define MV64340_DMA_SIZE_REG2 0xa14 +#define MV64340_DMA_SIZE_REG3 0xa1c +#define MV64340_DMA_SIZE_REG4 0xa24 +#define MV64340_DMA_SIZE_REG5 0xa2c +#define MV64340_DMA_SIZE_REG6 0xa34 +#define MV64340_DMA_SIZE_REG7 0xa3C + + /* IDMA Address Decoding High Address Remap and Access Protection Registers */ + +#define MV64340_DMA_HIGH_ADDR_REMAP_REG0 0xa60 +#define MV64340_DMA_HIGH_ADDR_REMAP_REG1 0xa64 +#define MV64340_DMA_HIGH_ADDR_REMAP_REG2 0xa68 +#define MV64340_DMA_HIGH_ADDR_REMAP_REG3 0xa6C +#define MV64340_DMA_BASE_ADDR_ENABLE_REG 0xa80 +#define MV64340_DMA_CHANNEL0_ACCESS_PROTECTION_REG 0xa70 +#define MV64340_DMA_CHANNEL1_ACCESS_PROTECTION_REG 0xa74 +#define MV64340_DMA_CHANNEL2_ACCESS_PROTECTION_REG 0xa78 +#define MV64340_DMA_CHANNEL3_ACCESS_PROTECTION_REG 0xa7c +#define MV64340_DMA_ARBITER_CONTROL 0x860 +#define MV64340_DMA_CROSS_BAR_TIMEOUT 0x8d0 + + /* IDMA Headers Retarget Registers */ + +#define MV64340_DMA_HEADERS_RETARGET_CONTROL 0xa84 +#define MV64340_DMA_HEADERS_RETARGET_BASE 0xa88 + + /* IDMA Interrupt Register */ + +#define MV64340_DMA_INTERRUPT_CAUSE_REG 0x8c0 +#define MV64340_DMA_INTERRUPT_CAUSE_MASK 0x8c4 +#define MV64340_DMA_ERROR_ADDR 0x8c8 +#define MV64340_DMA_ERROR_SELECT 0x8cc + + /* IDMA Debug Register ( for internal use ) */ + +#define MV64340_DMA_DEBUG_LOW 0x8e0 +#define MV64340_DMA_DEBUG_HIGH 0x8e4 +#define MV64340_DMA_SPARE 0xA8C + +/****************************************/ +/* Timer_Counter */ +/****************************************/ + +#define MV64340_TIMER_COUNTER0 0x850 +#define MV64340_TIMER_COUNTER1 0x854 +#define MV64340_TIMER_COUNTER2 0x858 +#define MV64340_TIMER_COUNTER3 0x85C +#define MV64340_TIMER_COUNTER_0_3_CONTROL 0x864 +#define MV64340_TIMER_COUNTER_0_3_INTERRUPT_CAUSE 0x868 +#define MV64340_TIMER_COUNTER_0_3_INTERRUPT_MASK 0x86c + +/****************************************/ +/* Watchdog registers */ +/****************************************/ + +#define MV64340_WATCHDOG_CONFIG_REG 0xb410 +#define MV64340_WATCHDOG_VALUE_REG 0xb414 + +/****************************************/ +/* I2C Registers */ +/****************************************/ + +#define MV64XXX_I2C_OFFSET 0xc000 +#define MV64XXX_I2C_REG_BLOCK_SIZE 0x0020 + +/****************************************/ +/* GPP Interface Registers */ +/****************************************/ + +#define MV64340_GPP_IO_CONTROL 0xf100 +#define MV64340_GPP_LEVEL_CONTROL 0xf110 +#define MV64340_GPP_VALUE 0xf104 +#define MV64340_GPP_INTERRUPT_CAUSE 0xf108 +#define MV64340_GPP_INTERRUPT_MASK0 0xf10c +#define MV64340_GPP_INTERRUPT_MASK1 0xf114 +#define MV64340_GPP_VALUE_SET 0xf118 +#define MV64340_GPP_VALUE_CLEAR 0xf11c + +/****************************************/ +/* Interrupt Controller Registers */ +/****************************************/ + +/****************************************/ +/* Interrupts */ +/****************************************/ + +#define MV64340_MAIN_INTERRUPT_CAUSE_LOW 0x004 +#define MV64340_MAIN_INTERRUPT_CAUSE_HIGH 0x00c +#define MV64340_CPU_INTERRUPT0_MASK_LOW 0x014 +#define MV64340_CPU_INTERRUPT0_MASK_HIGH 0x01c +#define MV64340_CPU_INTERRUPT0_SELECT_CAUSE 0x024 +#define MV64340_CPU_INTERRUPT1_MASK_LOW 0x034 +#define MV64340_CPU_INTERRUPT1_MASK_HIGH 0x03c +#define MV64340_CPU_INTERRUPT1_SELECT_CAUSE 0x044 +#define MV64340_INTERRUPT0_MASK_0_LOW 0x054 +#define MV64340_INTERRUPT0_MASK_0_HIGH 0x05c +#define MV64340_INTERRUPT0_SELECT_CAUSE 0x064 +#define MV64340_INTERRUPT1_MASK_0_LOW 0x074 +#define MV64340_INTERRUPT1_MASK_0_HIGH 0x07c +#define MV64340_INTERRUPT1_SELECT_CAUSE 0x084 + +/****************************************/ +/* MPP Interface Registers */ +/****************************************/ + +#define MV64340_MPP_CONTROL0 0xf000 +#define MV64340_MPP_CONTROL1 0xf004 +#define MV64340_MPP_CONTROL2 0xf008 +#define MV64340_MPP_CONTROL3 0xf00c + +/****************************************/ +/* Serial Initialization registers */ +/****************************************/ + +#define MV64340_SERIAL_INIT_LAST_DATA 0xf324 +#define MV64340_SERIAL_INIT_CONTROL 0xf328 +#define MV64340_SERIAL_INIT_STATUS 0xf32c + +#endif /* ASM_MV643XX_H */ diff --git a/hw/pci-host/trace-events b/hw/pci-host/trace-events index 7d8063ac42..dac86ad3f0 100644 --- a/hw/pci-host/trace-events +++ b/hw/pci-host/trace-events @@ -3,6 +3,12 @@ # grackle.c grackle_set_irq(int irq_num, int level) "set_irq num %d level %d" +# mv64361.c +mv64361_region_map(const char *name, uint64_t poffs, uint64_t size, uint64_t moffs) "Mapping %s 0x%"PRIx64"+0x%"PRIx64" @ 0x%"PRIx64 +mv64361_region_enable(const char *op, int num) "Should %s region %d" +mv64361_reg_read(uint64_t addr, uint32_t val) "0x%"PRIx64" -> 0x%x" +mv64361_reg_write(uint64_t addr, uint64_t val) "0x%"PRIx64" <- 0x%"PRIx64 + # sabre.c sabre_set_request(int irq_num) "request irq %d" sabre_clear_request(int irq_num) "clear request irq %d" diff --git a/include/hw/pci-host/mv64361.h b/include/hw/pci-host/mv64361.h new file mode 100644 index 0000000000..9cdb35cb3c --- /dev/null +++ b/include/hw/pci-host/mv64361.h @@ -0,0 +1,8 @@ +#ifndef MV64361_H +#define MV64361_H + +#define TYPE_MV64361 "mv64361" + +PCIBus *mv64361_get_pci_bus(DeviceState *dev, int n); + +#endif diff --git a/include/hw/pci/pci_ids.h b/include/hw/pci/pci_ids.h index ac0c23ebc7..5c14681b82 100644 --- a/include/hw/pci/pci_ids.h +++ b/include/hw/pci/pci_ids.h @@ -214,6 +214,7 @@ #define PCI_DEVICE_ID_VIA_8231_PM 0x8235 #define PCI_VENDOR_ID_MARVELL 0x11ab +#define PCI_DEVICE_ID_MARVELL_MV6436X 0x6460 #define PCI_VENDOR_ID_SILICON_MOTION 0x126f #define PCI_DEVICE_ID_SM501 0x0501 From patchwork Tue May 4 05:52:51 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: David Gibson X-Patchwork-Id: 12237451 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-16.6 required=3.0 tests=BAYES_00,DKIM_INVALID, DKIM_SIGNED,HEADER_FROM_DIFFERENT_DOMAINS,INCLUDES_CR_TRAILER,INCLUDES_PATCH, MAILING_LIST_MULTI,SPF_HELO_NONE,SPF_PASS,USER_AGENT_GIT autolearn=ham autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id F0994C433B4 for ; Tue, 4 May 2021 06:20:54 +0000 (UTC) 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 mail.kernel.org (Postfix) with ESMTPS id 6149C610FC for ; Tue, 4 May 2021 06:20:54 +0000 (UTC) DMARC-Filter: OpenDMARC Filter v1.3.2 mail.kernel.org 6149C610FC Authentication-Results: mail.kernel.org; dmarc=none (p=none dis=none) header.from=gibson.dropbear.id.au Authentication-Results: mail.kernel.org; spf=pass smtp.mailfrom=qemu-devel-bounces+qemu-devel=archiver.kernel.org@nongnu.org Received: from localhost ([::1]:37214 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1ldoQP-0001O1-8c for qemu-devel@archiver.kernel.org; Tue, 04 May 2021 02:20:53 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]:60590) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1ldo0B-0005Pn-14; Tue, 04 May 2021 01:53:47 -0400 Received: from ozlabs.org ([203.11.71.1]:41511) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1ldo08-0004s4-QG; Tue, 04 May 2021 01:53:46 -0400 Received: by ozlabs.org (Postfix, from userid 1007) id 4FZ8CL6R2Nz9sjD; Tue, 4 May 2021 15:53:18 +1000 (AEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=gibson.dropbear.id.au; s=201602; t=1620107598; bh=A4jdODat3Z6GefaXXFSiKe0Cos01b2C3YnZHIpUCy0Q=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=PDmSS8iugnbmWIygHh7xgkacmEKTYbGo1kUOpAWqitU6oNRNfnDd/gdQkcdSjGZhj +z/dDGDXjILzPChv+Ez8rBQl9D7pEp7JmmXCa5YO9kI0qQydDYFeP6EgIkj6aJfeGI s06fktHhm5Fyvp1JZ+p20LckPvF2iPiYBqfUeO1E= From: David Gibson To: peter.maydell@linaro.org, groug@kaod.org Subject: [PULL 25/46] hw/ppc: Add emulation of Genesi/bPlan Pegasos II Date: Tue, 4 May 2021 15:52:51 +1000 Message-Id: <20210504055312.306823-26-david@gibson.dropbear.id.au> X-Mailer: git-send-email 2.31.1 In-Reply-To: <20210504055312.306823-1-david@gibson.dropbear.id.au> References: <20210504055312.306823-1-david@gibson.dropbear.id.au> MIME-Version: 1.0 Received-SPF: pass client-ip=203.11.71.1; envelope-from=dgibson@ozlabs.org; helo=ozlabs.org X-Spam_score_int: -17 X-Spam_score: -1.8 X-Spam_bar: - X-Spam_report: (-1.8 / 5.0 requ) BAYES_00=-1.9, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_AU=-0.1, HEADER_FROM_DIFFERENT_DOMAINS=0.25, SPF_HELO_PASS=-0.001, SPF_PASS=-0.001 autolearn=no autolearn_force=no X-Spam_action: no action X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: =?utf-8?q?Philippe_Mathieu-Daud=C3=A9?= , qemu-ppc@nongnu.org, qemu-devel@nongnu.org, David Gibson Errors-To: qemu-devel-bounces+qemu-devel=archiver.kernel.org@nongnu.org Sender: "Qemu-devel" From: BALATON Zoltan Add new machine called pegasos2 emulating the Genesi/bPlan Pegasos II, a PowerPC board based on the Marvell MV64361 system controller and the VIA VT8231 integrated south bridge/superio chips. It can run Linux, AmigaOS and a wide range of MorphOS versions. Currently a firmware ROM image is needed to boot and only MorphOS has a video driver to produce graphics output. Linux could work too but distros that supported this machine don't include usual video drivers so those only run with serial console for now. Signed-off-by: BALATON Zoltan Reviewed-by: Philippe Mathieu-Daudé Message-Id: <30cbfb9cbe6f46a1e15a69a75fac45ac39340122.1616680239.git.balaton@eik.bme.hu> Signed-off-by: David Gibson --- MAINTAINERS | 10 ++ default-configs/devices/ppc-softmmu.mak | 2 + hw/ppc/Kconfig | 9 ++ hw/ppc/meson.build | 2 + hw/ppc/pegasos2.c | 144 ++++++++++++++++++++++++ 5 files changed, 167 insertions(+) create mode 100644 hw/ppc/pegasos2.c diff --git a/MAINTAINERS b/MAINTAINERS index 4c05ff8bba..6bc008d825 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -1364,6 +1364,16 @@ F: pc-bios/canyonlands.dt[sb] F: pc-bios/u-boot-sam460ex-20100605.bin F: roms/u-boot-sam460ex +pegasos2 +M: BALATON Zoltan +R: David Gibson +L: qemu-ppc@nongnu.org +S: Maintained +F: hw/ppc/pegasos2.c +F: hw/pci-host/mv64361.c +F: hw/pci-host/mv643xx.h +F: include/hw/pci-host/mv64361.h + RISC-V Machines --------------- OpenTitan diff --git a/default-configs/devices/ppc-softmmu.mak b/default-configs/devices/ppc-softmmu.mak index 61b78b844d..c2d41198cd 100644 --- a/default-configs/devices/ppc-softmmu.mak +++ b/default-configs/devices/ppc-softmmu.mak @@ -14,5 +14,7 @@ CONFIG_SAM460EX=y CONFIG_MAC_OLDWORLD=y CONFIG_MAC_NEWWORLD=y +CONFIG_PEGASOS2=n + # For PReP CONFIG_PREP=y diff --git a/hw/ppc/Kconfig b/hw/ppc/Kconfig index d11dc30509..e51e0e5e5a 100644 --- a/hw/ppc/Kconfig +++ b/hw/ppc/Kconfig @@ -68,6 +68,15 @@ config SAM460EX select USB_OHCI select FDT_PPC +config PEGASOS2 + bool + select MV64361 + select VT82C686 + select IDE_VIA + select SMBUS_EEPROM +# This should come with VT82C686 + select ACPI_X86 + config PREP bool imply PCI_DEVICES diff --git a/hw/ppc/meson.build b/hw/ppc/meson.build index 218631c883..86d6f379d1 100644 --- a/hw/ppc/meson.build +++ b/hw/ppc/meson.build @@ -78,5 +78,7 @@ ppc_ss.add(when: 'CONFIG_E500', if_true: files( )) # PowerPC 440 Xilinx ML507 reference board. ppc_ss.add(when: 'CONFIG_VIRTEX', if_true: files('virtex_ml507.c')) +# Pegasos2 +ppc_ss.add(when: 'CONFIG_PEGASOS2', if_true: files('pegasos2.c')) hw_arch += {'ppc': ppc_ss} diff --git a/hw/ppc/pegasos2.c b/hw/ppc/pegasos2.c new file mode 100644 index 0000000000..0bfd0928aa --- /dev/null +++ b/hw/ppc/pegasos2.c @@ -0,0 +1,144 @@ +/* + * QEMU PowerPC CHRP (Genesi/bPlan Pegasos II) hardware System Emulator + * + * Copyright (c) 2018-2020 BALATON Zoltan + * + * This work is licensed under the GNU GPL license version 2 or later. + * + */ + +#include "qemu/osdep.h" +#include "qemu-common.h" +#include "qemu/units.h" +#include "qapi/error.h" +#include "hw/hw.h" +#include "hw/ppc/ppc.h" +#include "hw/sysbus.h" +#include "hw/pci/pci_host.h" +#include "hw/irq.h" +#include "hw/pci-host/mv64361.h" +#include "hw/isa/vt82c686.h" +#include "hw/ide/pci.h" +#include "hw/i2c/smbus_eeprom.h" +#include "hw/qdev-properties.h" +#include "sysemu/reset.h" +#include "hw/boards.h" +#include "hw/loader.h" +#include "hw/fw-path-provider.h" +#include "elf.h" +#include "qemu/log.h" +#include "qemu/error-report.h" +#include "sysemu/kvm.h" +#include "kvm_ppc.h" +#include "exec/address-spaces.h" +#include "trace.h" +#include "qemu/datadir.h" +#include "sysemu/device_tree.h" + +#define PROM_FILENAME "pegasos2.rom" +#define PROM_ADDR 0xfff00000 +#define PROM_SIZE 0x80000 + +#define BUS_FREQ_HZ 133333333 + +static void pegasos2_cpu_reset(void *opaque) +{ + PowerPCCPU *cpu = opaque; + + cpu_reset(CPU(cpu)); + cpu->env.spr[SPR_HID1] = 7ULL << 28; +} + +static void pegasos2_init(MachineState *machine) +{ + PowerPCCPU *cpu = NULL; + MemoryRegion *rom = g_new(MemoryRegion, 1); + DeviceState *mv; + PCIBus *pci_bus; + PCIDevice *dev; + I2CBus *i2c_bus; + const char *fwname = machine->firmware ?: PROM_FILENAME; + char *filename; + int sz; + uint8_t *spd_data; + + /* init CPU */ + cpu = POWERPC_CPU(cpu_create(machine->cpu_type)); + if (PPC_INPUT(&cpu->env) != PPC_FLAGS_INPUT_6xx) { + error_report("Incompatible CPU, only 6xx bus supported"); + exit(1); + } + + /* Set time-base frequency */ + cpu_ppc_tb_init(&cpu->env, BUS_FREQ_HZ / 4); + qemu_register_reset(pegasos2_cpu_reset, cpu); + + /* RAM */ + memory_region_add_subregion(get_system_memory(), 0, machine->ram); + + /* allocate and load firmware */ + filename = qemu_find_file(QEMU_FILE_TYPE_BIOS, fwname); + if (!filename) { + error_report("Could not find firmware '%s'", fwname); + exit(1); + } + memory_region_init_rom(rom, NULL, "pegasos2.rom", PROM_SIZE, &error_fatal); + memory_region_add_subregion(get_system_memory(), PROM_ADDR, rom); + sz = load_elf(filename, NULL, NULL, NULL, NULL, NULL, NULL, NULL, 1, + PPC_ELF_MACHINE, 0, 0); + if (sz <= 0) { + sz = load_image_targphys(filename, PROM_ADDR, PROM_SIZE); + } + if (sz <= 0 || sz > PROM_SIZE) { + error_report("Could not load firmware '%s'", filename); + exit(1); + } + g_free(filename); + + /* Marvell Discovery II system controller */ + mv = DEVICE(sysbus_create_simple(TYPE_MV64361, -1, + ((qemu_irq *)cpu->env.irq_inputs)[PPC6xx_INPUT_INT])); + pci_bus = mv64361_get_pci_bus(mv, 1); + + /* VIA VT8231 South Bridge (multifunction PCI device) */ + /* VT8231 function 0: PCI-to-ISA Bridge */ + dev = pci_create_simple_multifunction(pci_bus, PCI_DEVFN(12, 0), true, + TYPE_VT8231_ISA); + qdev_connect_gpio_out(DEVICE(dev), 0, + qdev_get_gpio_in_named(mv, "gpp", 31)); + + /* VT8231 function 1: IDE Controller */ + dev = pci_create_simple(pci_bus, PCI_DEVFN(12, 1), "via-ide"); + pci_ide_create_devs(dev); + + /* VT8231 function 2-3: USB Ports */ + pci_create_simple(pci_bus, PCI_DEVFN(12, 2), "vt82c686b-usb-uhci"); + pci_create_simple(pci_bus, PCI_DEVFN(12, 3), "vt82c686b-usb-uhci"); + + /* VT8231 function 4: Power Management Controller */ + dev = pci_create_simple(pci_bus, PCI_DEVFN(12, 4), TYPE_VT8231_PM); + i2c_bus = I2C_BUS(qdev_get_child_bus(DEVICE(dev), "i2c")); + spd_data = spd_data_generate(DDR, machine->ram_size); + smbus_eeprom_init_one(i2c_bus, 0x57, spd_data); + + /* VT8231 function 5-6: AC97 Audio & Modem */ + pci_create_simple(pci_bus, PCI_DEVFN(12, 5), TYPE_VIA_AC97); + pci_create_simple(pci_bus, PCI_DEVFN(12, 6), TYPE_VIA_MC97); + + /* other PC hardware */ + pci_vga_init(pci_bus); +} + +static void pegasos2_machine(MachineClass *mc) +{ + mc->desc = "Genesi/bPlan Pegasos II"; + mc->init = pegasos2_init; + mc->block_default_type = IF_IDE; + mc->default_boot_order = "cd"; + mc->default_display = "std"; + mc->default_cpu_type = POWERPC_CPU_TYPE_NAME("7400_v2.9"); + mc->default_ram_id = "pegasos2.ram"; + mc->default_ram_size = 512 * MiB; +} + +DEFINE_MACHINE("pegasos2", pegasos2_machine) From patchwork Tue May 4 05:52:52 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: David Gibson X-Patchwork-Id: 12237481 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-14.9 required=3.0 tests=BAYES_00,DKIM_INVALID, DKIM_SIGNED,HEADER_FROM_DIFFERENT_DOMAINS,INCLUDES_CR_TRAILER,INCLUDES_PATCH, MAILING_LIST_MULTI,SPF_HELO_NONE,SPF_PASS,URIBL_BLACK,USER_AGENT_GIT autolearn=ham autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id 09BF6C433ED for ; Tue, 4 May 2021 06:37:05 +0000 (UTC) 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 mail.kernel.org (Postfix) with ESMTPS id 81BAD61164 for ; Tue, 4 May 2021 06:37:04 +0000 (UTC) DMARC-Filter: OpenDMARC Filter v1.3.2 mail.kernel.org 81BAD61164 Authentication-Results: mail.kernel.org; dmarc=none (p=none dis=none) header.from=gibson.dropbear.id.au Authentication-Results: mail.kernel.org; spf=pass smtp.mailfrom=qemu-devel-bounces+qemu-devel=archiver.kernel.org@nongnu.org Received: from localhost ([::1]:38896 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1ldog3-0006S2-DB for qemu-devel@archiver.kernel.org; Tue, 04 May 2021 02:37:03 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]:60674) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1ldo0V-00065Y-0E; Tue, 04 May 2021 01:54:07 -0400 Received: from bilbo.ozlabs.org ([2401:3900:2:1::2]:51089 helo=ozlabs.org) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1ldo0T-0004s7-6J; Tue, 04 May 2021 01:54:06 -0400 Received: by ozlabs.org (Postfix, from userid 1007) id 4FZ8CL5TWKz9sj5; Tue, 4 May 2021 15:53:18 +1000 (AEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=gibson.dropbear.id.au; s=201602; t=1620107598; bh=7ujQDPPP/0A+ekFnLR3g7Ouqjx8k9nF6bDg8z4HD3eU=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=N3BbwXYpTZbFTPYSHeOH0kYLwFD3q1sKc33grGyP/M4rgy6NTNZzhpInDfBiHgCmY 0dhy+BbxU40Le8aRrq2lyj50sQjtDZ2F6e1UOZQ7CHpjRoH1v/7kqcR7IobTctEnH0 cUFqm98k5umZkgBhWcMSfeVdh9PRqFzNgudJ4PGA= From: David Gibson To: peter.maydell@linaro.org, groug@kaod.org Subject: [PULL 26/46] spapr: Rename RTAS_MAX_ADDR to FDT_MAX_ADDR Date: Tue, 4 May 2021 15:52:52 +1000 Message-Id: <20210504055312.306823-27-david@gibson.dropbear.id.au> X-Mailer: git-send-email 2.31.1 In-Reply-To: <20210504055312.306823-1-david@gibson.dropbear.id.au> References: <20210504055312.306823-1-david@gibson.dropbear.id.au> MIME-Version: 1.0 Received-SPF: pass client-ip=2401:3900:2:1::2; envelope-from=dgibson@ozlabs.org; helo=ozlabs.org X-Spam_score_int: -17 X-Spam_score: -1.8 X-Spam_bar: - X-Spam_report: (-1.8 / 5.0 requ) BAYES_00=-1.9, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_AU=-0.1, HEADER_FROM_DIFFERENT_DOMAINS=0.25, SPF_HELO_PASS=-0.001, SPF_PASS=-0.001 autolearn=no autolearn_force=no X-Spam_action: no action X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: Alexey Kardashevskiy , qemu-ppc@nongnu.org, qemu-devel@nongnu.org, David Gibson Errors-To: qemu-devel-bounces+qemu-devel=archiver.kernel.org@nongnu.org Sender: "Qemu-devel" From: Alexey Kardashevskiy SLOF instantiates RTAS since 744a928ccee9 ("spapr: Stop providing RTAS blob") so the max address applies to the FDT only. This renames the macro and fixes up the comment. This should not cause any behavioral change. Signed-off-by: Alexey Kardashevskiy Message-Id: <20210331025123.29310-1-aik@ozlabs.ru> Reviewed-by: Greg Kurz Signed-off-by: David Gibson --- hw/ppc/spapr.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/hw/ppc/spapr.c b/hw/ppc/spapr.c index 529ff056dd..fd53615df0 100644 --- a/hw/ppc/spapr.c +++ b/hw/ppc/spapr.c @@ -100,7 +100,7 @@ * * We load our kernel at 4M, leaving space for SLOF initial image */ -#define RTAS_MAX_ADDR 0x80000000 /* RTAS must stay below that */ +#define FDT_MAX_ADDR 0x80000000 /* FDT must stay below that */ #define FW_MAX_SIZE 0x400000 #define FW_FILE_NAME "slof.bin" #define FW_OVERHEAD 0x2800000 @@ -1617,11 +1617,11 @@ static void spapr_machine_reset(MachineState *machine) spapr_clear_pending_events(spapr); /* - * We place the device tree and RTAS just below either the top of the RMA, + * We place the device tree just below either the top of the RMA, * or just below 2GB, whichever is lower, so that it can be * processed with 32-bit real mode code if necessary */ - fdt_addr = MIN(spapr->rma_size, RTAS_MAX_ADDR) - FDT_MAX_SIZE; + fdt_addr = MIN(spapr->rma_size, FDT_MAX_ADDR) - FDT_MAX_SIZE; fdt = spapr_build_fdt(spapr, true, FDT_MAX_SIZE); @@ -2694,7 +2694,7 @@ static void spapr_machine_init(MachineState *machine) spapr->rma_size = spapr_rma_size(spapr, &error_fatal); /* Setup a load limit for the ramdisk leaving room for SLOF and FDT */ - load_limit = MIN(spapr->rma_size, RTAS_MAX_ADDR) - FW_OVERHEAD; + load_limit = MIN(spapr->rma_size, FDT_MAX_ADDR) - FW_OVERHEAD; /* * VSMT must be set in order to be able to compute VCPU ids, ie to From patchwork Tue May 4 05:52:53 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: David Gibson X-Patchwork-Id: 12237485 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-21.6 required=3.0 tests=BAYES_00,DKIM_INVALID, DKIM_SIGNED,HEADER_FROM_DIFFERENT_DOMAINS,INCLUDES_CR_TRAILER,INCLUDES_PATCH, MAILING_LIST_MULTI,MENTIONS_GIT_HOSTING,SPF_HELO_NONE,SPF_PASS,USER_AGENT_GIT autolearn=ham autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id CCE51C433B4 for ; Tue, 4 May 2021 06:37:42 +0000 (UTC) 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 mail.kernel.org (Postfix) with ESMTPS id 8061361164 for ; Tue, 4 May 2021 06:37:42 +0000 (UTC) DMARC-Filter: OpenDMARC Filter v1.3.2 mail.kernel.org 8061361164 Authentication-Results: mail.kernel.org; dmarc=none (p=none dis=none) header.from=gibson.dropbear.id.au Authentication-Results: mail.kernel.org; spf=pass smtp.mailfrom=qemu-devel-bounces+qemu-devel=archiver.kernel.org@nongnu.org Received: from localhost ([::1]:41256 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1ldogf-0007Sb-Jj for qemu-devel@archiver.kernel.org; Tue, 04 May 2021 02:37:41 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]:60708) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1ldo0X-0006Ai-Ad; Tue, 04 May 2021 01:54:09 -0400 Received: from ozlabs.org ([2401:3900:2:1::2]:46745) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1ldo0V-0004sq-6f; Tue, 04 May 2021 01:54:09 -0400 Received: by ozlabs.org (Postfix, from userid 1007) id 4FZ8CM1Nmwz9srX; Tue, 4 May 2021 15:53:18 +1000 (AEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=gibson.dropbear.id.au; s=201602; t=1620107599; bh=1d7nN6jGRx7ijwvK8kfjaNHQNkM9cCoWtEW4yFnwJIc=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=Qhw399nPrBz8j/LjhPVOwfb7jF6zziIHkCu6ZF/w9keaoYTa6R0yeD4X1wReBppBH y10x4x0VbBqT7HBFBbhuGoiFtOaGygeJNxvlx5Exkb/CZiVeWZnuFIA+fvDm+tTifM cvoVBnvWA9GtWVxLpJoZN2Yi/OW1wlASGnm6Ikbk= From: David Gibson To: peter.maydell@linaro.org, groug@kaod.org Subject: [PULL 27/46] ppc/spapr: Add support for implement support for H_SCM_HEALTH Date: Tue, 4 May 2021 15:52:53 +1000 Message-Id: <20210504055312.306823-28-david@gibson.dropbear.id.au> X-Mailer: git-send-email 2.31.1 In-Reply-To: <20210504055312.306823-1-david@gibson.dropbear.id.au> References: <20210504055312.306823-1-david@gibson.dropbear.id.au> MIME-Version: 1.0 Received-SPF: pass client-ip=2401:3900:2:1::2; envelope-from=dgibson@ozlabs.org; helo=ozlabs.org X-Spam_score_int: -17 X-Spam_score: -1.8 X-Spam_bar: - X-Spam_report: (-1.8 / 5.0 requ) BAYES_00=-1.9, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_AU=-0.1, HEADER_FROM_DIFFERENT_DOMAINS=0.25, SPF_HELO_PASS=-0.001, SPF_PASS=-0.001 autolearn=no autolearn_force=no X-Spam_action: no action X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: Vaibhav Jain , qemu-ppc@nongnu.org, qemu-devel@nongnu.org, David Gibson Errors-To: qemu-devel-bounces+qemu-devel=archiver.kernel.org@nongnu.org Sender: "Qemu-devel" From: Vaibhav Jain Add support for H_SCM_HEALTH hcall described at [1] for spapr nvdimms. This enables guest to detect the 'unarmed' status of a specific spapr nvdimm identified by its DRC and if its unarmed, mark the region backed by the nvdimm as read-only. The patch adds h_scm_health() to handle the H_SCM_HEALTH hcall which returns two 64-bit bitmaps (health bitmap, health bitmap mask) derived from 'struct nvdimm->unarmed' member. Linux kernel side changes to enable handling of 'unarmed' nvdimms for ppc64 are proposed at [2]. References: [1] "Hypercall Op-codes (hcalls)" https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/tree/Documentation/powerpc/papr_hcalls.rst#n220 [2] "powerpc/papr_scm: Mark nvdimm as unarmed if needed during probe" https://lore.kernel.org/linux-nvdimm/20210329113103.476760-1-vaibhav@linux.ibm.com/ Signed-off-by: Vaibhav Jain Message-Id: <20210402102128.213943-1-vaibhav@linux.ibm.com> Reviewed-by: Greg Kurz Signed-off-by: David Gibson --- hw/ppc/spapr_nvdimm.c | 36 ++++++++++++++++++++++++++++++++++++ include/hw/ppc/spapr.h | 3 ++- 2 files changed, 38 insertions(+), 1 deletion(-) diff --git a/hw/ppc/spapr_nvdimm.c b/hw/ppc/spapr_nvdimm.c index b46c36917c..252204e25f 100644 --- a/hw/ppc/spapr_nvdimm.c +++ b/hw/ppc/spapr_nvdimm.c @@ -31,6 +31,10 @@ #include "qemu/range.h" #include "hw/ppc/spapr_numa.h" +/* DIMM health bitmap bitmap indicators. Taken from kernel's papr_scm.c */ +/* SCM device is unable to persist memory contents */ +#define PAPR_PMEM_UNARMED PPC_BIT(0) + bool spapr_nvdimm_validate(HotplugHandler *hotplug_dev, NVDIMMDevice *nvdimm, uint64_t size, Error **errp) { @@ -467,6 +471,37 @@ static target_ulong h_scm_unbind_all(PowerPCCPU *cpu, SpaprMachineState *spapr, return H_SUCCESS; } +static target_ulong h_scm_health(PowerPCCPU *cpu, SpaprMachineState *spapr, + target_ulong opcode, target_ulong *args) +{ + + NVDIMMDevice *nvdimm; + uint64_t hbitmap = 0; + uint32_t drc_index = args[0]; + SpaprDrc *drc = spapr_drc_by_index(drc_index); + const uint64_t hbitmap_mask = PAPR_PMEM_UNARMED; + + + /* Ensure that the drc is valid & is valid PMEM dimm and is plugged in */ + if (!drc || !drc->dev || + spapr_drc_type(drc) != SPAPR_DR_CONNECTOR_TYPE_PMEM) { + return H_PARAMETER; + } + + nvdimm = NVDIMM(drc->dev); + + /* Update if the nvdimm is unarmed and send its status via health bitmaps */ + if (object_property_get_bool(OBJECT(nvdimm), NVDIMM_UNARMED_PROP, NULL)) { + hbitmap |= PAPR_PMEM_UNARMED; + } + + /* Update the out args with health bitmap/mask */ + args[0] = hbitmap; + args[1] = hbitmap_mask; + + return H_SUCCESS; +} + static void spapr_scm_register_types(void) { /* qemu/scm specific hcalls */ @@ -475,6 +510,7 @@ static void spapr_scm_register_types(void) spapr_register_hypercall(H_SCM_BIND_MEM, h_scm_bind_mem); spapr_register_hypercall(H_SCM_UNBIND_MEM, h_scm_unbind_mem); spapr_register_hypercall(H_SCM_UNBIND_ALL, h_scm_unbind_all); + spapr_register_hypercall(H_SCM_HEALTH, h_scm_health); } type_init(spapr_scm_register_types) diff --git a/include/hw/ppc/spapr.h b/include/hw/ppc/spapr.h index bf7cab7a2c..d2b5a9bdf9 100644 --- a/include/hw/ppc/spapr.h +++ b/include/hw/ppc/spapr.h @@ -538,8 +538,9 @@ struct SpaprMachineState { #define H_SCM_BIND_MEM 0x3EC #define H_SCM_UNBIND_MEM 0x3F0 #define H_SCM_UNBIND_ALL 0x3FC +#define H_SCM_HEALTH 0x400 -#define MAX_HCALL_OPCODE H_SCM_UNBIND_ALL +#define MAX_HCALL_OPCODE H_SCM_HEALTH /* The hcalls above are standardized in PAPR and implemented by pHyp * as well. From patchwork Tue May 4 05:52:54 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: David Gibson X-Patchwork-Id: 12237479 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-16.6 required=3.0 tests=BAYES_00,DKIM_INVALID, DKIM_SIGNED,HEADER_FROM_DIFFERENT_DOMAINS,INCLUDES_CR_TRAILER,INCLUDES_PATCH, MAILING_LIST_MULTI,SPF_HELO_NONE,SPF_PASS,USER_AGENT_GIT autolearn=ham autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id 7D192C433B4 for ; Tue, 4 May 2021 06:34:03 +0000 (UTC) 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 mail.kernel.org (Postfix) with ESMTPS id 3E328613B4 for ; Tue, 4 May 2021 06:34:03 +0000 (UTC) DMARC-Filter: OpenDMARC Filter v1.3.2 mail.kernel.org 3E328613B4 Authentication-Results: mail.kernel.org; dmarc=none (p=none dis=none) header.from=gibson.dropbear.id.au Authentication-Results: mail.kernel.org; spf=pass smtp.mailfrom=qemu-devel-bounces+qemu-devel=archiver.kernel.org@nongnu.org Received: from localhost ([::1]:60874 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1ldod8-0003ar-9W for qemu-devel@archiver.kernel.org; Tue, 04 May 2021 02:34:02 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]:60698) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1ldo0W-000690-MI; Tue, 04 May 2021 01:54:08 -0400 Received: from ozlabs.org ([203.11.71.1]:55857) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1ldo0U-0004so-Vv; Tue, 04 May 2021 01:54:08 -0400 Received: by ozlabs.org (Postfix, from userid 1007) id 4FZ8CM0GnFz9sjB; Tue, 4 May 2021 15:53:18 +1000 (AEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=gibson.dropbear.id.au; s=201602; t=1620107599; bh=CdNzPgX1E1MQGbEspxa9vwUoiQIUOXrms6BJeQ7RFHw=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=kQmLMl5TUsCbOnnNkH21p3LVB4bHOiJKQzdH5aS2n0OIEZPj6upr9dR7Fa1RIuaE9 qeMqz1ZlwaXz36RdopiBVR1GmkRZOZ45G9ZNHDlbKMXsOohtDJThk5Ib58vV0x/jHH 36HUNFjVY72K0atqFNVBGurfDUFYEVkhYH77ps9w= From: David Gibson To: peter.maydell@linaro.org, groug@kaod.org Subject: [PULL 28/46] roms/Makefile: Update ppce500 u-boot build directory name Date: Tue, 4 May 2021 15:52:54 +1000 Message-Id: <20210504055312.306823-29-david@gibson.dropbear.id.au> X-Mailer: git-send-email 2.31.1 In-Reply-To: <20210504055312.306823-1-david@gibson.dropbear.id.au> References: <20210504055312.306823-1-david@gibson.dropbear.id.au> MIME-Version: 1.0 Received-SPF: pass client-ip=203.11.71.1; envelope-from=dgibson@ozlabs.org; helo=ozlabs.org X-Spam_score_int: -17 X-Spam_score: -1.8 X-Spam_bar: - X-Spam_report: (-1.8 / 5.0 requ) BAYES_00=-1.9, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_AU=-0.1, HEADER_FROM_DIFFERENT_DOMAINS=0.25, SPF_HELO_PASS=-0.001, SPF_PASS=-0.001 autolearn=no autolearn_force=no X-Spam_action: no action X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: Bin Meng , qemu-ppc@nongnu.org, qemu-devel@nongnu.org, David Gibson Errors-To: qemu-devel-bounces+qemu-devel=archiver.kernel.org@nongnu.org Sender: "Qemu-devel" From: Bin Meng Currently building ppce500 u-boot image results in modified: roms/u-boot (untracked content) As roms/u-boot/.gitignore indicates, update the build directory name to build-e500 to eliminate this message. Signed-off-by: Bin Meng Signed-off-by: David Gibson --- roms/Makefile | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/roms/Makefile b/roms/Makefile index 5ffe3317ac..eeb5970348 100644 --- a/roms/Makefile +++ b/roms/Makefile @@ -154,10 +154,10 @@ slof: cp SLOF/boot_rom.bin ../pc-bios/slof.bin u-boot.e500: - $(MAKE) -C u-boot O=build.e500 qemu-ppce500_config + $(MAKE) -C u-boot O=build-e500 qemu-ppce500_config $(MAKE) -C u-boot CROSS_COMPILE=$(powerpc_cross_prefix) \ - O=build.e500 - $(powerpc_cross_prefix)strip u-boot/build.e500/u-boot -o \ + O=build-e500 + $(powerpc_cross_prefix)strip u-boot/build-e500/u-boot -o \ ../pc-bios/u-boot.e500 u-boot.sam460: @@ -205,7 +205,7 @@ clean: $(MAKE) -C ipxe/src veryclean $(MAKE) -C edk2/BaseTools clean $(MAKE) -C SLOF clean - rm -rf u-boot/build.e500 + rm -rf u-boot/build-e500 $(MAKE) -C u-boot-sam460ex distclean $(MAKE) -C skiboot clean $(MAKE) -f Makefile.edk2 clean From patchwork Tue May 4 05:52:55 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: David Gibson X-Patchwork-Id: 12237475 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-13.5 required=3.0 tests=BAYES_00,DKIM_INVALID, DKIM_SIGNED,HEADER_FROM_DIFFERENT_DOMAINS,INCLUDES_CR_TRAILER,INCLUDES_PATCH, LOTS_OF_MONEY,MAILING_LIST_MULTI,NORMAL_HTTP_TO_IP,NUMERIC_HTTP_ADDR, PERCENT_RANDOM,SPF_HELO_NONE,SPF_PASS,USER_AGENT_GIT autolearn=ham autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id 33C82C433B4 for ; Tue, 4 May 2021 06:31:39 +0000 (UTC) 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 mail.kernel.org (Postfix) with ESMTPS id 17DE4610A0 for ; Tue, 4 May 2021 06:31:38 +0000 (UTC) DMARC-Filter: OpenDMARC Filter v1.3.2 mail.kernel.org 17DE4610A0 Authentication-Results: mail.kernel.org; dmarc=none (p=none dis=none) header.from=gibson.dropbear.id.au Authentication-Results: mail.kernel.org; spf=pass smtp.mailfrom=qemu-devel-bounces+qemu-devel=archiver.kernel.org@nongnu.org Received: from localhost ([::1]:55556 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1ldoam-00016h-Qm for qemu-devel@archiver.kernel.org; Tue, 04 May 2021 02:31:36 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]:60774) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1ldo0g-0006Ot-RD; Tue, 04 May 2021 01:54:19 -0400 Received: from bilbo.ozlabs.org ([2401:3900:2:1::2]:38617 helo=ozlabs.org) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1ldo0Z-0004wG-NQ; Tue, 04 May 2021 01:54:18 -0400 Received: by ozlabs.org (Postfix, from userid 1007) id 4FZ8CM51vcz9svs; Tue, 4 May 2021 15:53:19 +1000 (AEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=gibson.dropbear.id.au; s=201602; t=1620107599; bh=WgqvPBqbsKNIEU1Ak2PGkhRInv9InFycS2JsTcB/ukA=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=SqRi4EE0ShDFZg9nMQrVA72MkdQZkYe9FhF9gjfSdapGUSpT0EepuZmelMKi6YOA3 5Fu7/zV7nmZCaEYX6AowY6dj86FDjtLPmsbDdG5YVdCz0vevDHPUIal2buLeRUyVTV l4f2C/X0dgGpCCt7BZRcDwpd6gWcmsPWmqUnMjIc= From: David Gibson To: peter.maydell@linaro.org, groug@kaod.org Subject: [PULL 29/46] roms/u-boot: Bump ppce500 u-boot to v2021.04 to fix broken pci support Date: Tue, 4 May 2021 15:52:55 +1000 Message-Id: <20210504055312.306823-30-david@gibson.dropbear.id.au> X-Mailer: git-send-email 2.31.1 In-Reply-To: <20210504055312.306823-1-david@gibson.dropbear.id.au> References: <20210504055312.306823-1-david@gibson.dropbear.id.au> MIME-Version: 1.0 Received-SPF: pass client-ip=2401:3900:2:1::2; envelope-from=dgibson@ozlabs.org; helo=ozlabs.org X-Spam_score_int: 15 X-Spam_score: 1.5 X-Spam_bar: + X-Spam_report: (1.5 / 5.0 requ) BAYES_05=-0.5, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_AU=-0.1, HEADER_FROM_DIFFERENT_DOMAINS=0.25, LOTS_OF_MONEY=0.001, PERCENT_RANDOM=1.838, SPF_HELO_PASS=-0.001, SPF_PASS=-0.001 autolearn=no autolearn_force=no X-Spam_action: no action X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: Bin Meng , qemu-ppc@nongnu.org, qemu-devel@nongnu.org, David Gibson Errors-To: qemu-devel-bounces+qemu-devel=archiver.kernel.org@nongnu.org Sender: "Qemu-devel" From: Bin Meng When QEMU originally supported the ppce500 machine back in Jan 2014, it was created with a 1:1 mapping of PCI bus address. Things seemed to change rapidly that in Nov 2014 with the following QEMU commits: commit e6b4e5f4795b ("PPC: e500: Move CCSR and MMIO space to upper end of address space") and commit cb3778a0455a ("PPC: e500 pci host: Add support for ATMUs") the PCI memory and IO physical address were moved to beyond 4 GiB, but PCI bus address remained below 4 GiB, hence a non-identity mapping was created. Unfortunately corresponding U-Boot updates were missed along with the QEMU changes and the U-Boot QEMU ppce500 PCI support has been broken since then, until this issue was fixed recently in U-Boot mainline v2021.04 release, specifically by the following U-Boot series: http://patchwork.ozlabs.org/project/uboot/list/?series=230985&state=* The cross-compilation toolchain used to build the U-Boot image is: https://mirrors.edge.kernel.org/pub/tools/crosstool/files/bin/x86_64/10.1.0/x86_64-gcc-10.1.0-nolibc-powerpc-linux.tar.xz Signed-off-by: Bin Meng Signed-off-by: David Gibson --- pc-bios/u-boot.e500 | Bin 349148 -> 406920 bytes roms/u-boot | 2 +- 2 files changed, 1 insertion(+), 1 deletion(-) diff --git a/pc-bios/u-boot.e500 b/pc-bios/u-boot.e500 index 732660f348f6123d24144ee29ef38611428dc2d9..d2e29f81d648e4fa7e010ab7c44f2d22154094aa 100644 GIT binary patch literal 406920 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 BEhzv1 literal 349148 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�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

cULUbAe`rToX#%6E% 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%0A@F;Ey9=?i>|i3=me4EVi7lzi-l`SzeU=& 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 m%`1){|GRG|>Fy)`liuw X-Patchwork-Id: 12237501 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-16.6 required=3.0 tests=BAYES_00,DKIM_INVALID, DKIM_SIGNED,HEADER_FROM_DIFFERENT_DOMAINS,INCLUDES_CR_TRAILER,INCLUDES_PATCH, MAILING_LIST_MULTI,SPF_HELO_NONE,SPF_PASS,USER_AGENT_GIT autolearn=ham autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id B877AC433ED for ; Tue, 4 May 2021 06:45:40 +0000 (UTC) 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 mail.kernel.org (Postfix) with ESMTPS id 3A504613B3 for ; Tue, 4 May 2021 06:45:40 +0000 (UTC) DMARC-Filter: OpenDMARC Filter v1.3.2 mail.kernel.org 3A504613B3 Authentication-Results: mail.kernel.org; dmarc=none (p=none dis=none) header.from=gibson.dropbear.id.au Authentication-Results: mail.kernel.org; spf=pass smtp.mailfrom=qemu-devel-bounces+qemu-devel=archiver.kernel.org@nongnu.org Received: from localhost ([::1]:38022 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1ldooN-0001Eg-BD for qemu-devel@archiver.kernel.org; Tue, 04 May 2021 02:45:39 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]:60746) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1ldo0a-0006I2-IW; Tue, 04 May 2021 01:54:12 -0400 Received: from bilbo.ozlabs.org ([2401:3900:2:1::2]:51695 helo=ozlabs.org) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1ldo0Y-0004uk-2e; Tue, 04 May 2021 01:54:12 -0400 Received: by ozlabs.org (Postfix, from userid 1007) id 4FZ8CM2kjhz9sjJ; Tue, 4 May 2021 15:53:19 +1000 (AEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=gibson.dropbear.id.au; s=201602; t=1620107599; bh=HWTtl1ahThSbHqQXvslhnACNMugZ3bq/E6L7ucQzf/M=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=BnwTGvk7JlLQkwK8VVMS9DN/1mBn1hNOg6ASCgUf6qPfeRgp6js8bbMz4HgF7CjfY b16kN4rP2ECI0EYJUoTgqya6wpL/51MyeTHVqGedfiAnTVkHSpzz062QYUsALLPMWK Wfx1ilJryQr2Qt2p7eXj38GDG9H8xepjexR9epXE= From: David Gibson To: peter.maydell@linaro.org, groug@kaod.org Subject: [PULL 30/46] docs/system: ppc: Add documentation for ppce500 machine Date: Tue, 4 May 2021 15:52:56 +1000 Message-Id: <20210504055312.306823-31-david@gibson.dropbear.id.au> X-Mailer: git-send-email 2.31.1 In-Reply-To: <20210504055312.306823-1-david@gibson.dropbear.id.au> References: <20210504055312.306823-1-david@gibson.dropbear.id.au> MIME-Version: 1.0 Received-SPF: pass client-ip=2401:3900:2:1::2; envelope-from=dgibson@ozlabs.org; helo=ozlabs.org X-Spam_score_int: -17 X-Spam_score: -1.8 X-Spam_bar: - X-Spam_report: (-1.8 / 5.0 requ) BAYES_00=-1.9, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_AU=-0.1, HEADER_FROM_DIFFERENT_DOMAINS=0.25, SPF_HELO_PASS=-0.001, SPF_PASS=-0.001 autolearn=no autolearn_force=no X-Spam_action: no action X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: Bin Meng , qemu-ppc@nongnu.org, qemu-devel@nongnu.org, David Gibson Errors-To: qemu-devel-bounces+qemu-devel=archiver.kernel.org@nongnu.org Sender: "Qemu-devel" From: Bin Meng This adds detailed documentation for PowerPC `ppce500` machine, including the following information: - Supported devices - Hardware configuration information - Boot options - Running Linux kernel - Running U-Boot Signed-off-by: Bin Meng Signed-off-by: David Gibson --- docs/system/ppc/ppce500.rst | 156 ++++++++++++++++++++++++++++++++++++ docs/system/target-ppc.rst | 1 + 2 files changed, 157 insertions(+) create mode 100644 docs/system/ppc/ppce500.rst diff --git a/docs/system/ppc/ppce500.rst b/docs/system/ppc/ppce500.rst new file mode 100644 index 0000000000..7a815c1881 --- /dev/null +++ b/docs/system/ppc/ppce500.rst @@ -0,0 +1,156 @@ +ppce500 generic platform (``ppce500``) +====================================== + +QEMU for PPC supports a special ``ppce500`` machine designed for emulation and +virtualization purposes. + +Supported devices +----------------- + +The ``ppce500`` machine supports the following devices: + +* PowerPC e500 series core (e500v2/e500mc/e5500/e6500) +* Configuration, Control, and Status Register (CCSR) +* Multicore Programmable Interrupt Controller (MPIC) with MSI support +* 1 16550A UART device +* 1 Freescale MPC8xxx I2C controller +* 1 Pericom pt7c4338 RTC via I2C +* 1 Freescale MPC8xxx GPIO controller +* Power-off functionality via one GPIO pin +* 1 Freescale MPC8xxx PCI host controller +* VirtIO devices via PCI bus + +Hardware configuration information +---------------------------------- + +The ``ppce500`` machine automatically generates a device tree blob ("dtb") +which it passes to the guest, if there is no ``-dtb`` option. This provides +information about the addresses, interrupt lines and other configuration of +the various devices in the system. + +If users want to provide their own DTB, they can use the ``-dtb`` option. +These DTBs should have the following requirements: + +* The number of subnodes under /cpus node should match QEMU's ``-smp`` option +* The /memory reg size should match QEMU’s selected ram_size via ``-m`` + +Both ``qemu-system-ppc`` and ``qemu-system-ppc64`` provide emulation for the +following 32-bit PowerPC CPUs: + +* e500v2 +* e500mc + +Additionally ``qemu-system-ppc64`` provides support for the following 64-bit +PowerPC CPUs: + +* e5500 +* e6500 + +The CPU type can be specified via the ``-cpu`` command line. If not specified, +it creates a machine with e500v2 core. The following example shows an e6500 +based machine creation: + +.. code-block:: bash + + $ qemu-system-ppc64 -nographic -M ppce500 -cpu e6500 + +Boot options +------------ + +The ``ppce500`` machine can start using the standard -kernel functionality +for loading a payload like an OS kernel (e.g.: Linux), or U-Boot firmware. + +When -bios is omitted, the default pc-bios/u-boot.e500 firmware image is used +as the BIOS. QEMU follows below truth table to select which payload to execute: + +===== ========== ======= +-bios -kernel payload +===== ========== ======= + N N u-boot + N Y kernel + Y don't care u-boot +===== ========== ======= + +When both -bios and -kernel are present, QEMU loads U-Boot and U-Boot in turns +automatically loads the kernel image specified by the -kernel parameter via +U-Boot's built-in "bootm" command, hence a legacy uImage format is required in +such senario. + +Running Linux kernel +-------------------- + +Linux mainline v5.11 release is tested at the time of writing. To build a +Linux mainline kernel that can be booted by the ``ppce500`` machine in +64-bit mode, simply configure the kernel using the defconfig configuration: + +.. code-block:: bash + + $ export ARCH=powerpc + $ export CROSS_COMPILE=powerpc-linux- + $ make corenet64_smp_defconfig + $ make menuconfig + +then manually select the following configuration: + + Platform support > Freescale Book-E Machine Type > QEMU generic e500 platform + +To boot the newly built Linux kernel in QEMU with the ``ppce500`` machine: + +.. code-block:: bash + + $ qemu-system-ppc64 -M ppce500 -cpu e5500 -smp 4 -m 2G \ + -display none -serial stdio \ + -kernel vmlinux \ + -initrd /path/to/rootfs.cpio \ + -append "root=/dev/ram" + +To build a Linux mainline kernel that can be booted by the ``ppce500`` machine +in 32-bit mode, use the same 64-bit configuration steps except the defconfig +file should use corenet32_smp_defconfig. + +To boot the 32-bit Linux kernel: + +.. code-block:: bash + + $ qemu-system-ppc{64|32} -M ppce500 -cpu e500mc -smp 4 -m 2G \ + -display none -serial stdio \ + -kernel vmlinux \ + -initrd /path/to/rootfs.cpio \ + -append "root=/dev/ram" + +Running U-Boot +-------------- + +U-Boot mainline v2021.04 release is tested at the time of writing. To build a +U-Boot mainline bootloader that can be booted by the ``ppce500`` machine, use +the qemu-ppce500_defconfig with similar commands as described above for Linux: + +.. code-block:: bash + + $ export CROSS_COMPILE=powerpc-linux- + $ make qemu-ppce500_defconfig + +You will get u-boot file in the build tree. + +When U-Boot boots, you will notice the following if using with ``-cpu e6500``: + +.. code-block:: none + + CPU: Unknown, Version: 0.0, (0x00000000) + Core: e6500, Version: 2.0, (0x80400020) + +This is because we only specified a core name to QEMU and it does not have a +meaningful SVR value which represents an actual SoC that integrates such core. +You can specify a real world SoC device that QEMU has built-in support but all +these SoCs are e500v2 based MPC85xx series, hence you cannot test anything +built for P4080 (e500mc), P5020 (e5500) and T2080 (e6500). + +By default a VirtIO standard PCI networking device is connected as an ethernet +interface at PCI address 0.1.0, but we can switch that to an e1000 NIC by: + +.. code-block:: bash + + $ qemu-system-ppc -M ppce500 -smp 4 -m 2G \ + -display none -serial stdio \ + -bios u-boot \ + -nic tap,ifname=tap0,script=no,downscript=no,model=e1000 diff --git a/docs/system/target-ppc.rst b/docs/system/target-ppc.rst index 67905b8f2a..4f6eb93b17 100644 --- a/docs/system/target-ppc.rst +++ b/docs/system/target-ppc.rst @@ -20,5 +20,6 @@ help``. ppc/embedded ppc/powermac ppc/powernv + ppc/ppce500 ppc/prep ppc/pseries From patchwork Tue May 4 05:52:57 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: David Gibson X-Patchwork-Id: 12237489 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-16.6 required=3.0 tests=BAYES_00,DKIM_INVALID, DKIM_SIGNED,HEADER_FROM_DIFFERENT_DOMAINS,INCLUDES_CR_TRAILER,INCLUDES_PATCH, MAILING_LIST_MULTI,SPF_HELO_NONE,SPF_PASS,USER_AGENT_GIT autolearn=ham autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id 62ED7C433ED for ; Tue, 4 May 2021 06:40:50 +0000 (UTC) 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 mail.kernel.org (Postfix) with ESMTPS id 057D361175 for ; Tue, 4 May 2021 06:40:49 +0000 (UTC) DMARC-Filter: OpenDMARC Filter v1.3.2 mail.kernel.org 057D361175 Authentication-Results: mail.kernel.org; dmarc=none (p=none dis=none) header.from=gibson.dropbear.id.au Authentication-Results: mail.kernel.org; spf=pass smtp.mailfrom=qemu-devel-bounces+qemu-devel=archiver.kernel.org@nongnu.org Received: from localhost ([::1]:49684 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1ldojg-0002bb-Tj for qemu-devel@archiver.kernel.org; Tue, 04 May 2021 02:40:48 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]:60712) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1ldo0X-0006C9-Qi; Tue, 04 May 2021 01:54:09 -0400 Received: from ozlabs.org ([203.11.71.1]:46407) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1ldo0V-00055Z-MI; Tue, 04 May 2021 01:54:09 -0400 Received: by ozlabs.org (Postfix, from userid 1007) id 4FZ8CN1mXKz9t0G; Tue, 4 May 2021 15:53:19 +1000 (AEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=gibson.dropbear.id.au; s=201602; t=1620107600; bh=kHU+IpRVWH4mT4/KamL8kAx2HykZRBjU4mtZkvOiTis=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=GDCCToeXnnmKNOemjdgNoP6OFGUj0fWJBPbqtE5P4Qj2Gn866aJV1n7lkdSQHfKOB Br/vHD1kiF9W7scyv8/W16FhN3gpGZxqVV29vl8tBHzR0OKriw5uxqvQS0hIQXvb7k Y9MdOSp5gjS8JjbwXdrM9OLLOMj9r76iiU608IZs= From: David Gibson To: peter.maydell@linaro.org, groug@kaod.org Subject: [PULL 31/46] target/ppc: Fix POWER9 radix guest HV interrupt AIL behaviour Date: Tue, 4 May 2021 15:52:57 +1000 Message-Id: <20210504055312.306823-32-david@gibson.dropbear.id.au> X-Mailer: git-send-email 2.31.1 In-Reply-To: <20210504055312.306823-1-david@gibson.dropbear.id.au> References: <20210504055312.306823-1-david@gibson.dropbear.id.au> MIME-Version: 1.0 Received-SPF: pass client-ip=203.11.71.1; envelope-from=dgibson@ozlabs.org; helo=ozlabs.org X-Spam_score_int: -17 X-Spam_score: -1.8 X-Spam_bar: - X-Spam_report: (-1.8 / 5.0 requ) BAYES_00=-1.9, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_AU=-0.1, HEADER_FROM_DIFFERENT_DOMAINS=0.25, SPF_HELO_PASS=-0.001, SPF_PASS=-0.001 autolearn=no autolearn_force=no X-Spam_action: no action X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: David Gibson , qemu-ppc@nongnu.org, qemu-devel@nongnu.org, Nicholas Piggin , Fabiano Rosas Errors-To: qemu-devel-bounces+qemu-devel=archiver.kernel.org@nongnu.org Sender: "Qemu-devel" From: Nicholas Piggin ISA v3.0 radix guest execution has a quirk in AIL behaviour such that the LPCR[AIL] value can apply to hypervisor interrupts. This affects machines that emulate HV=1 mode (i.e., powernv9). Signed-off-by: Nicholas Piggin Message-Id: <20210415054227.1793812-2-npiggin@gmail.com> Reviewed-by: Fabiano Rosas Signed-off-by: David Gibson --- target/ppc/excp_helper.c | 17 +++++++++++++---- 1 file changed, 13 insertions(+), 4 deletions(-) diff --git a/target/ppc/excp_helper.c b/target/ppc/excp_helper.c index 5c95e0c103..344af66f66 100644 --- a/target/ppc/excp_helper.c +++ b/target/ppc/excp_helper.c @@ -791,14 +791,23 @@ static inline void powerpc_excp(PowerPCCPU *cpu, int excp_model, int excp) #endif /* - * AIL only works if there is no HV transition and we are running - * with translations enabled + * AIL only works if MSR[IR] and MSR[DR] are both enabled. */ - if (!((msr >> MSR_IR) & 1) || !((msr >> MSR_DR) & 1) || - ((new_msr & MSR_HVB) && !(msr & MSR_HVB))) { + if (!((msr >> MSR_IR) & 1) || !((msr >> MSR_DR) & 1)) { ail = 0; } + /* + * 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. + */ + if ((new_msr & MSR_HVB) && !(msr & MSR_HVB)) { + if (!(env->spr[SPR_LPCR] & LPCR_HR)) { + ail = 0; + } + } + vector = env->excp_vectors[excp]; if (vector == (target_ulong)-1ULL) { cpu_abort(cs, "Raised an exception without defined vector %d\n", From patchwork Tue May 4 05:52:58 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: David Gibson X-Patchwork-Id: 12237491 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-16.6 required=3.0 tests=BAYES_00,DKIM_INVALID, DKIM_SIGNED,HEADER_FROM_DIFFERENT_DOMAINS,INCLUDES_CR_TRAILER,INCLUDES_PATCH, MAILING_LIST_MULTI,SPF_HELO_NONE,SPF_PASS,USER_AGENT_GIT autolearn=ham autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id A7ABCC433B4 for ; Tue, 4 May 2021 06:40:56 +0000 (UTC) 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 mail.kernel.org (Postfix) with ESMTPS id 39AE161164 for ; Tue, 4 May 2021 06:40:56 +0000 (UTC) DMARC-Filter: OpenDMARC Filter v1.3.2 mail.kernel.org 39AE161164 Authentication-Results: mail.kernel.org; dmarc=none (p=none dis=none) header.from=gibson.dropbear.id.au Authentication-Results: mail.kernel.org; spf=pass smtp.mailfrom=qemu-devel-bounces+qemu-devel=archiver.kernel.org@nongnu.org Received: from localhost ([::1]:50312 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1ldojn-0002rz-59 for qemu-devel@archiver.kernel.org; Tue, 04 May 2021 02:40:55 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]:60800) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1ldo0q-0006Wh-PG; Tue, 04 May 2021 01:54:28 -0400 Received: from ozlabs.org ([2401:3900:2:1::2]:59521) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1ldo0p-00054j-1R; Tue, 04 May 2021 01:54:28 -0400 Received: by ozlabs.org (Postfix, from userid 1007) id 4FZ8CN013dz9sSs; Tue, 4 May 2021 15:53:19 +1000 (AEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=gibson.dropbear.id.au; s=201602; t=1620107600; bh=JddXZ4HFUbuGSa+QOkqe9ljYM4oIszU9SoEuSDNnxs8=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=iAL6vsldBMMqmdWUd0WQ5uipxhk1U19mXuAatSSnrIc3Tsjsb11gte6z3DqLIOtA2 Cd3i6+cIITbnRfo4i990quuQKYYuYttybhadxaxKfmsg6oNwqrZvnclP200i/SDZ/e eNF0LXIH4VIBXlI8yZ/2CXPAmh+EZQOKE3pDJaMY= From: David Gibson To: peter.maydell@linaro.org, groug@kaod.org Subject: [PULL 32/46] target/ppc: POWER10 supports scv Date: Tue, 4 May 2021 15:52:58 +1000 Message-Id: <20210504055312.306823-33-david@gibson.dropbear.id.au> X-Mailer: git-send-email 2.31.1 In-Reply-To: <20210504055312.306823-1-david@gibson.dropbear.id.au> References: <20210504055312.306823-1-david@gibson.dropbear.id.au> MIME-Version: 1.0 Received-SPF: pass client-ip=2401:3900:2:1::2; envelope-from=dgibson@ozlabs.org; helo=ozlabs.org X-Spam_score_int: -17 X-Spam_score: -1.8 X-Spam_bar: - X-Spam_report: (-1.8 / 5.0 requ) BAYES_00=-1.9, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_AU=-0.1, HEADER_FROM_DIFFERENT_DOMAINS=0.25, SPF_HELO_PASS=-0.001, SPF_PASS=-0.001 autolearn=no autolearn_force=no X-Spam_action: no action X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: David Gibson , qemu-ppc@nongnu.org, qemu-devel@nongnu.org, Nicholas Piggin , =?utf-8?q?C?= =?utf-8?q?=C3=A9dric_Le_Goater?= Errors-To: qemu-devel-bounces+qemu-devel=archiver.kernel.org@nongnu.org Sender: "Qemu-devel" From: Nicholas Piggin This must have slipped through the cracks between adding POWER10 support and scv support. Signed-off-by: Nicholas Piggin Message-Id: <20210415054227.1793812-3-npiggin@gmail.com> Reviewed-by: Cédric Le Goater Signed-off-by: David Gibson --- target/ppc/translate_init.c.inc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/target/ppc/translate_init.c.inc b/target/ppc/translate_init.c.inc index 049d76cfd1..06686489a0 100644 --- a/target/ppc/translate_init.c.inc +++ b/target/ppc/translate_init.c.inc @@ -9323,7 +9323,7 @@ POWERPC_FAMILY(POWER10)(ObjectClass *oc, void *data) 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_VSX | POWERPC_FLAG_TM | POWERPC_FLAG_SCV; pcc->l1_dcache_size = 0x8000; pcc->l1_icache_size = 0x8000; pcc->interrupts_big_endian = ppc_cpu_interrupts_big_endian_lpcr; From patchwork Tue May 4 05:52:59 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: David Gibson X-Patchwork-Id: 12237461 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-16.6 required=3.0 tests=BAYES_00,DKIM_INVALID, DKIM_SIGNED,HEADER_FROM_DIFFERENT_DOMAINS,INCLUDES_CR_TRAILER,INCLUDES_PATCH, MAILING_LIST_MULTI,SPF_HELO_NONE,SPF_PASS,USER_AGENT_GIT autolearn=ham autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id D6A1EC433ED for ; Tue, 4 May 2021 06:27:01 +0000 (UTC) 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 mail.kernel.org (Postfix) with ESMTPS id 2C3D561183 for ; Tue, 4 May 2021 06:27:01 +0000 (UTC) DMARC-Filter: OpenDMARC Filter v1.3.2 mail.kernel.org 2C3D561183 Authentication-Results: mail.kernel.org; dmarc=none (p=none dis=none) header.from=gibson.dropbear.id.au Authentication-Results: mail.kernel.org; spf=pass smtp.mailfrom=qemu-devel-bounces+qemu-devel=archiver.kernel.org@nongnu.org Received: from localhost ([::1]:50368 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1ldoWK-0007D6-1f for qemu-devel@archiver.kernel.org; Tue, 04 May 2021 02:27:00 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]:60738) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1ldo0Z-0006Fo-D7; Tue, 04 May 2021 01:54:11 -0400 Received: from ozlabs.org ([203.11.71.1]:39521) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1ldo0X-000570-HI; Tue, 04 May 2021 01:54:11 -0400 Received: by ozlabs.org (Postfix, from userid 1007) id 4FZ8CN3mHxz9t0J; Tue, 4 May 2021 15:53:20 +1000 (AEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=gibson.dropbear.id.au; s=201602; t=1620107600; bh=CRHqLETkCbZCv40pzPfeO0sTEltt6FO4e3KcDka05M0=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=lEUXJohwodaYOvra/3YRUIkdGlAhhSGkmh7orhWKKNhD8RQ2FWD0hLXRGHASn7uGc bb3oHs3THzHxQmZYmU4bUgC9fctw8tbDFT1GOHNnaABiT2WTsBdP/kLBnaHMjmlDLy Q4VjZkV3/DaKYQgHgCmfBMZG5pYC81pt8ULpcNlU= From: David Gibson To: peter.maydell@linaro.org, groug@kaod.org Subject: [PULL 33/46] ppc: Rename current DAWR macros and variables Date: Tue, 4 May 2021 15:52:59 +1000 Message-Id: <20210504055312.306823-34-david@gibson.dropbear.id.au> X-Mailer: git-send-email 2.31.1 In-Reply-To: <20210504055312.306823-1-david@gibson.dropbear.id.au> References: <20210504055312.306823-1-david@gibson.dropbear.id.au> MIME-Version: 1.0 Received-SPF: pass client-ip=203.11.71.1; envelope-from=dgibson@ozlabs.org; helo=ozlabs.org X-Spam_score_int: -17 X-Spam_score: -1.8 X-Spam_bar: - X-Spam_report: (-1.8 / 5.0 requ) BAYES_00=-1.9, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_AU=-0.1, HEADER_FROM_DIFFERENT_DOMAINS=0.25, SPF_HELO_PASS=-0.001, SPF_PASS=-0.001 autolearn=no autolearn_force=no X-Spam_action: no action X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: Ravi Bangoria , qemu-ppc@nongnu.org, qemu-devel@nongnu.org, David Gibson Errors-To: qemu-devel-bounces+qemu-devel=archiver.kernel.org@nongnu.org Sender: "Qemu-devel" From: Ravi Bangoria Power10 is introducing second DAWR. Use real register names (with suffix 0) from ISA for current macros and variables used by Qemu. One exception to this is KVM_REG_PPC_DAWR[X]. This is from kernel uapi header and thus not changed in kernel as well as Qemu. Signed-off-by: Ravi Bangoria Reviewed-by: Greg Kurz Reviewed-by: David Gibson Message-Id: <20210412114433.129702-3-ravi.bangoria@linux.ibm.com> Signed-off-by: David Gibson --- include/hw/ppc/spapr.h | 2 +- target/ppc/cpu.h | 4 ++-- target/ppc/translate_init.c.inc | 4 ++-- 3 files changed, 5 insertions(+), 5 deletions(-) diff --git a/include/hw/ppc/spapr.h b/include/hw/ppc/spapr.h index d2b5a9bdf9..49a79fbf96 100644 --- a/include/hw/ppc/spapr.h +++ b/include/hw/ppc/spapr.h @@ -363,7 +363,7 @@ struct SpaprMachineState { /* Values for 2nd argument to H_SET_MODE */ #define H_SET_MODE_RESOURCE_SET_CIABR 1 -#define H_SET_MODE_RESOURCE_SET_DAWR 2 +#define H_SET_MODE_RESOURCE_SET_DAWR0 2 #define H_SET_MODE_RESOURCE_ADDR_TRANS_MODE 3 #define H_SET_MODE_RESOURCE_LE 4 diff --git a/target/ppc/cpu.h b/target/ppc/cpu.h index 69fc9a2831..8c18bb0762 100644 --- a/target/ppc/cpu.h +++ b/target/ppc/cpu.h @@ -1489,10 +1489,10 @@ typedef PowerPCCPU ArchCPU; #define SPR_MPC_BAR (0x09F) #define SPR_PSPB (0x09F) #define SPR_DPDES (0x0B0) -#define SPR_DAWR (0x0B4) +#define SPR_DAWR0 (0x0B4) #define SPR_RPR (0x0BA) #define SPR_CIABR (0x0BB) -#define SPR_DAWRX (0x0BC) +#define SPR_DAWRX0 (0x0BC) #define SPR_HFSCR (0x0BE) #define SPR_VRSAVE (0x100) #define SPR_USPRG0 (0x100) diff --git a/target/ppc/translate_init.c.inc b/target/ppc/translate_init.c.inc index 06686489a0..58473c4c09 100644 --- a/target/ppc/translate_init.c.inc +++ b/target/ppc/translate_init.c.inc @@ -7748,12 +7748,12 @@ static void gen_spr_book3s_dbg(CPUPPCState *env) static void gen_spr_book3s_207_dbg(CPUPPCState *env) { - spr_register_kvm_hv(env, SPR_DAWR, "DAWR", + 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_DAWRX, "DAWRX", + spr_register_kvm_hv(env, SPR_DAWRX0, "DAWRX0", SPR_NOACCESS, SPR_NOACCESS, SPR_NOACCESS, SPR_NOACCESS, &spr_read_generic, &spr_write_generic, From patchwork Tue May 4 05:53:00 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: David Gibson X-Patchwork-Id: 12237495 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-16.6 required=3.0 tests=BAYES_00,DKIM_INVALID, DKIM_SIGNED,HEADER_FROM_DIFFERENT_DOMAINS,INCLUDES_CR_TRAILER,INCLUDES_PATCH, MAILING_LIST_MULTI,SPF_HELO_NONE,SPF_PASS,USER_AGENT_GIT autolearn=ham autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id 09149C433B4 for ; Tue, 4 May 2021 06:42:58 +0000 (UTC) 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 mail.kernel.org (Postfix) with ESMTPS id 89DB9610A6 for ; Tue, 4 May 2021 06:42:57 +0000 (UTC) DMARC-Filter: OpenDMARC Filter v1.3.2 mail.kernel.org 89DB9610A6 Authentication-Results: mail.kernel.org; dmarc=none (p=none dis=none) header.from=gibson.dropbear.id.au Authentication-Results: mail.kernel.org; spf=pass smtp.mailfrom=qemu-devel-bounces+qemu-devel=archiver.kernel.org@nongnu.org Received: from localhost ([::1]:58188 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1ldolk-0006HK-Ae for qemu-devel@archiver.kernel.org; Tue, 04 May 2021 02:42:56 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]:60734) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1ldo0Z-0006F8-2L; Tue, 04 May 2021 01:54:11 -0400 Received: from ozlabs.org ([203.11.71.1]:60255) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1ldo0X-00056r-3o; Tue, 04 May 2021 01:54:10 -0400 Received: by ozlabs.org (Postfix, from userid 1007) id 4FZ8CN2hX2z9sxS; Tue, 4 May 2021 15:53:20 +1000 (AEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=gibson.dropbear.id.au; s=201602; t=1620107600; bh=wGnIirSsUVp7mZHT1NOlF7GNp+krjgYkY2MXH1rKUJM=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=iJ9aQdMAFzVUd7M+mAl40Vmy8DdqO/Fenos8dEAggx8RjjgHvZXEJRn+Wn1InhE9z rFo21CussToJTrQvBSZcVYv88F3umvg4zNFCXstlMvjWDwnLmXuwBeCeQAgC8LXyZc VUllYm2a/5AfsUmpPvO8tvcb2RqV9UMP2ecOJoJg= From: David Gibson To: peter.maydell@linaro.org, groug@kaod.org Subject: [PULL 34/46] spapr.c: do not use MachineClass::max_cpus to limit CPUs Date: Tue, 4 May 2021 15:53:00 +1000 Message-Id: <20210504055312.306823-35-david@gibson.dropbear.id.au> X-Mailer: git-send-email 2.31.1 In-Reply-To: <20210504055312.306823-1-david@gibson.dropbear.id.au> References: <20210504055312.306823-1-david@gibson.dropbear.id.au> MIME-Version: 1.0 Received-SPF: pass client-ip=203.11.71.1; envelope-from=dgibson@ozlabs.org; helo=ozlabs.org X-Spam_score_int: -17 X-Spam_score: -1.8 X-Spam_bar: - X-Spam_report: (-1.8 / 5.0 requ) BAYES_00=-1.9, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_AU=-0.1, HEADER_FROM_DIFFERENT_DOMAINS=0.25, SPF_HELO_PASS=-0.001, SPF_PASS=-0.001 autolearn=no autolearn_force=no X-Spam_action: no action X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: Daniel Henrique Barboza , qemu-ppc@nongnu.org, qemu-devel@nongnu.org, David Gibson Errors-To: qemu-devel-bounces+qemu-devel=archiver.kernel.org@nongnu.org Sender: "Qemu-devel" From: Daniel Henrique Barboza Up to this patch, 'max_cpus' value is hardcoded to 1024 (commit 6244bb7e5811). In theory this patch would simply bump it to 2048, since it's the default NR_CPUS kernel setting for ppc64 servers nowadays, but the whole mechanic of MachineClass:max_cpus is flawed for the pSeries machine. The two supported accelerators, KVM and TCG, can live without it. TCG guests don't have a theoretical limit. The user must be free to emulate as many CPUs as the hardware is capable of. And even if there were a limit, max_cpus is not the proper way to report it since it's a common value checked by SMP code in machine_smp_parse() for KVM as well. For KVM guests, the proper way to limit KVM CPUs is by host configuration via NR_CPUS, not a QEMU hardcoded value. There is no technical reason for a pSeries QEMU guest to forcefully stay below NR_CPUS. This hardcoded value also disregard hosts that might have a lower NR_CPUS limit, say 512. In this case, machine.c:machine_smp_parse() will allow a 1024 value to pass, but then kvm_init() will complain about it because it will exceed NR_CPUS: Number of SMP cpus requested (1024) exceeds the maximum cpus supported by KVM (512) A better 'max_cpus' value would consider host settings, but MachineClass::max_cpus is defined well before machine_init() and kvm_init(). We can't check for KVM limits because it's too soon, so we end up making a guess. This patch makes MachineClass:max_cpus settings innocuous by setting it to INT32_MAX. machine.c:machine_smp_parse() will not fail the verification based on max_cpus, letting kvm_init() do the checking with actual host settings. And TCG guests get to do whatever the hardware is capable of emulating. Signed-off-by: Daniel Henrique Barboza Message-Id: <20210408204049.221802-2-danielhb413@gmail.com> Signed-off-by: David Gibson --- hw/ppc/spapr.c | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/hw/ppc/spapr.c b/hw/ppc/spapr.c index fd53615df0..b37ceb8ee8 100644 --- a/hw/ppc/spapr.c +++ b/hw/ppc/spapr.c @@ -4487,7 +4487,16 @@ static void spapr_machine_class_init(ObjectClass *oc, void *data) mc->init = spapr_machine_init; mc->reset = spapr_machine_reset; mc->block_default_type = IF_SCSI; - mc->max_cpus = 1024; + + /* + * Setting max_cpus to INT32_MAX. Both KVM and TCG max_cpus values + * should be limited by the host capability instead of hardcoded. + * max_cpus for KVM guests will be checked in kvm_init(), and TCG + * guests are welcome to have as many CPUs as the host are capable + * of emulate. + */ + mc->max_cpus = INT32_MAX; + mc->no_parallel = 1; mc->default_boot_order = ""; mc->default_ram_size = 512 * MiB; From patchwork Tue May 4 05:53:01 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: David Gibson X-Patchwork-Id: 12237487 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-16.6 required=3.0 tests=BAYES_00,DKIM_INVALID, DKIM_SIGNED,HEADER_FROM_DIFFERENT_DOMAINS,INCLUDES_CR_TRAILER,INCLUDES_PATCH, MAILING_LIST_MULTI,SPF_HELO_NONE,SPF_PASS,USER_AGENT_GIT autolearn=ham autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id 6357FC433B4 for ; Tue, 4 May 2021 06:38:10 +0000 (UTC) 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 mail.kernel.org (Postfix) with ESMTPS id EA3E061175 for ; Tue, 4 May 2021 06:38:09 +0000 (UTC) DMARC-Filter: OpenDMARC Filter v1.3.2 mail.kernel.org EA3E061175 Authentication-Results: mail.kernel.org; dmarc=none (p=none dis=none) header.from=gibson.dropbear.id.au Authentication-Results: mail.kernel.org; spf=pass smtp.mailfrom=qemu-devel-bounces+qemu-devel=archiver.kernel.org@nongnu.org Received: from localhost ([::1]:42926 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1ldoh7-000885-0S for qemu-devel@archiver.kernel.org; Tue, 04 May 2021 02:38:09 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]:60848) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1ldo0v-0006eG-Jd; Tue, 04 May 2021 01:54:34 -0400 Received: from ozlabs.org ([203.11.71.1]:46663) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1ldo0t-00058w-VE; Tue, 04 May 2021 01:54:33 -0400 Received: by ozlabs.org (Postfix, from userid 1007) id 4FZ8CN5lCfz9t0Y; Tue, 4 May 2021 15:53:20 +1000 (AEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=gibson.dropbear.id.au; s=201602; t=1620107600; bh=OHhNrur6TQw1fecKrtW3azDhMVUz44PDqaV7D4I5q98=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=QTwiOQB8PW3d9XT+F0H1YidlMYNC0PMriLmVRaekE9uVmJMn6g4inr6IfIFyZyg1e wmLzMOtLZbqxTqqANfhox7aqdbhJ8asEgqyH+KqA8VShlwkt1IWu824IFtG40OU45W PzHkd8YWNf7yo/SP/baYIMQLseW4j4hBKH/z8rlk= From: David Gibson To: peter.maydell@linaro.org, groug@kaod.org Subject: [PULL 35/46] spapr.h: increase FDT_MAX_SIZE Date: Tue, 4 May 2021 15:53:01 +1000 Message-Id: <20210504055312.306823-36-david@gibson.dropbear.id.au> X-Mailer: git-send-email 2.31.1 In-Reply-To: <20210504055312.306823-1-david@gibson.dropbear.id.au> References: <20210504055312.306823-1-david@gibson.dropbear.id.au> MIME-Version: 1.0 Received-SPF: pass client-ip=203.11.71.1; envelope-from=dgibson@ozlabs.org; helo=ozlabs.org X-Spam_score_int: -17 X-Spam_score: -1.8 X-Spam_bar: - X-Spam_report: (-1.8 / 5.0 requ) BAYES_00=-1.9, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_AU=-0.1, HEADER_FROM_DIFFERENT_DOMAINS=0.25, SPF_HELO_PASS=-0.001, SPF_PASS=-0.001 autolearn=no autolearn_force=no X-Spam_action: no action X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: Daniel Henrique Barboza , qemu-ppc@nongnu.org, qemu-devel@nongnu.org, David Gibson Errors-To: qemu-devel-bounces+qemu-devel=archiver.kernel.org@nongnu.org Sender: "Qemu-devel" From: Daniel Henrique Barboza Certain SMP topologies stress, e.g. 1 thread/core, 2048 cores and 1 socket, stress the current maximum size of the pSeries FDT: Calling ibm,client-architecture-support...qemu-system-ppc64: error creating device tree: (fdt_setprop(fdt, offset, "ibm,processor-segment-sizes", segs, sizeof(segs))): FDT_ERR_NOSPACE 2048 is the default NR_CPUS value for the pSeries kernel. It's expected that users will want QEMU to be able to handle this kind of configuration. Bumping FDT_MAX_SIZE to 2MB is enough for these setups to be created. Signed-off-by: Daniel Henrique Barboza Message-Id: <20210408204049.221802-3-danielhb413@gmail.com> Signed-off-by: David Gibson --- include/hw/ppc/spapr.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/include/hw/ppc/spapr.h b/include/hw/ppc/spapr.h index 49a79fbf96..7f40a158f4 100644 --- a/include/hw/ppc/spapr.h +++ b/include/hw/ppc/spapr.h @@ -95,7 +95,7 @@ typedef enum { #define SPAPR_CAP_FIXED_CCD 0x03 #define SPAPR_CAP_FIXED_NA 0x10 /* Lets leave a bit of a gap... */ -#define FDT_MAX_SIZE 0x100000 +#define FDT_MAX_SIZE 0x200000 /* * NUMA related macros. MAX_DISTANCE_REF_POINTS was taken From patchwork Tue May 4 05:53:02 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: David Gibson X-Patchwork-Id: 12237497 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-16.6 required=3.0 tests=BAYES_00,DKIM_INVALID, DKIM_SIGNED,HEADER_FROM_DIFFERENT_DOMAINS,INCLUDES_CR_TRAILER,INCLUDES_PATCH, MAILING_LIST_MULTI,SPF_HELO_NONE,SPF_PASS,USER_AGENT_GIT autolearn=ham autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id 66A24C433ED for ; Tue, 4 May 2021 06:43:04 +0000 (UTC) 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 mail.kernel.org (Postfix) with ESMTPS id 14BAD613B3 for ; Tue, 4 May 2021 06:43:04 +0000 (UTC) DMARC-Filter: OpenDMARC Filter v1.3.2 mail.kernel.org 14BAD613B3 Authentication-Results: mail.kernel.org; dmarc=none (p=none dis=none) header.from=gibson.dropbear.id.au Authentication-Results: mail.kernel.org; spf=pass smtp.mailfrom=qemu-devel-bounces+qemu-devel=archiver.kernel.org@nongnu.org Received: from localhost ([::1]:58736 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1ldolq-0006V8-Vz for qemu-devel@archiver.kernel.org; Tue, 04 May 2021 02:43:03 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]:60846) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1ldo0v-0006eF-Eh; Tue, 04 May 2021 01:54:34 -0400 Received: from ozlabs.org ([2401:3900:2:1::2]:35451) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1ldo0t-00058O-EZ; Tue, 04 May 2021 01:54:33 -0400 Received: by ozlabs.org (Postfix, from userid 1007) id 4FZ8CN4RbTz9ssP; Tue, 4 May 2021 15:53:20 +1000 (AEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=gibson.dropbear.id.au; s=201602; t=1620107600; bh=vL7ZdIT5+fnPoAOJ3OovBILu3ZlCN96VCnTNs+tkAok=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=XmuDtzoZ9PAXbusjdiUA9RoTgU0nu6dLGaw/QhfIy+hmbMW3w0zYw/dqzTILO1yNL WUCwBIir/giKaaYwCIO4b6s6ZACVmbHVyw0ORVoyYF2GLzf7Esp5rGfsoZL/jfPaXF lEa2hS+L698l8b4p/lUdhy/BreWXl9kPlmc9ZA2w= From: David Gibson To: peter.maydell@linaro.org, groug@kaod.org Subject: [PULL 36/46] spapr_drc.c: handle hotunplug errors in drc_unisolate_logical() Date: Tue, 4 May 2021 15:53:02 +1000 Message-Id: <20210504055312.306823-37-david@gibson.dropbear.id.au> X-Mailer: git-send-email 2.31.1 In-Reply-To: <20210504055312.306823-1-david@gibson.dropbear.id.au> References: <20210504055312.306823-1-david@gibson.dropbear.id.au> MIME-Version: 1.0 Received-SPF: pass client-ip=2401:3900:2:1::2; envelope-from=dgibson@ozlabs.org; helo=ozlabs.org X-Spam_score_int: -17 X-Spam_score: -1.8 X-Spam_bar: - X-Spam_report: (-1.8 / 5.0 requ) BAYES_00=-1.9, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_AU=-0.1, HEADER_FROM_DIFFERENT_DOMAINS=0.25, SPF_HELO_PASS=-0.001, SPF_PASS=-0.001 autolearn=no autolearn_force=no X-Spam_action: no action X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: Daniel Henrique Barboza , qemu-ppc@nongnu.org, qemu-devel@nongnu.org, David Gibson Errors-To: qemu-devel-bounces+qemu-devel=archiver.kernel.org@nongnu.org Sender: "Qemu-devel" From: Daniel Henrique Barboza At this moment, PAPR does not provide a way to report errors during a device removal operation. This led the pSeries machine to implement extra mechanisms to try to fallback and recover from an error that might have happened during the hotunplug in the guest side. This started to change a bit with commit fe1831eff8a4 ("spapr_drc.c: use DRC reconfiguration to cleanup DIMM unplug state"), where one way to fallback from a memory removal error was introduced. Around the same time, in [1], the idea of using RTAS set-indicator for this role was first introduced. The RTAS set-indicator call, when attempting to UNISOLATE a DRC that is already UNISOLATED or CONFIGURED, returns RTAS_OK and does nothing else for both QEMU and phyp. This gives us an opportunity to use this behavior to signal the hypervisor layer when a device removal errir happens, allowing QEMU/phyp to do a proper error handling. Using set-indicator to report HP errors isn't strange to PAPR, as per R1-13.5.3.4-4. of table 13.7 of current PAPR [2]: "For all DR options: If this is a DR operation that involves the user insert- ing a DR entity, then if the firmware can determine that the inserted entity would cause a system disturbance, then the set-indicator RTAS call must not unisolate the entity and must return an error status which is unique to the particular error." A change was proposed to the pSeries Linux kernel to call set-indicator to move a DRC to 'unisolate' in the case of a hotunplug error in the guest side [3]. Setting a DRC that is already unisolated or configured to 'unisolate' is a no-op (returns RTAS_OK) for QEMU and also for phyp. Being a benign change for hypervisors that doesn't care about handling such errors, we expect the kernel to accept this change at some point. This patch prepares the pSeries machine for this new kernel feature by changing drc_unisolate_logical() to handle guest side hotunplug errors. For CPUs it's a simple matter of setting drc->unplug_requested to 'false', while for LMBs the process is similar to the rollback that is done in rtas_ibm_configure_connector(). [1] https://lists.gnu.org/archive/html/qemu-devel/2021-02/msg06395.html [2] https://openpowerfoundation.org/wp-content/uploads/2020/07/LoPAR-20200611.pdf [3] https://patchwork.ozlabs.org/project/linuxppc-dev/patch/20210416210216.380291-3-danielhb413@gmail.com/ Reviewed-by: David Gibson Signed-off-by: Daniel Henrique Barboza Message-Id: <20210420165100.108368-2-danielhb413@gmail.com> Signed-off-by: David Gibson --- hw/ppc/spapr_drc.c | 23 +++++++++++++++++++++++ 1 file changed, 23 insertions(+) diff --git a/hw/ppc/spapr_drc.c b/hw/ppc/spapr_drc.c index 9e16505fa1..6918e0c9d1 100644 --- a/hw/ppc/spapr_drc.c +++ b/hw/ppc/spapr_drc.c @@ -151,9 +151,32 @@ static uint32_t drc_isolate_logical(SpaprDrc *drc) static uint32_t drc_unisolate_logical(SpaprDrc *drc) { + SpaprMachineState *spapr = NULL; + switch (drc->state) { case SPAPR_DRC_STATE_LOGICAL_UNISOLATE: case SPAPR_DRC_STATE_LOGICAL_CONFIGURED: + /* + * Unisolating a logical DRC that was marked for unplug + * means that the kernel is refusing the removal. + */ + if (drc->unplug_requested && drc->dev) { + if (spapr_drc_type(drc) == SPAPR_DR_CONNECTOR_TYPE_LMB) { + spapr = SPAPR_MACHINE(qdev_get_machine()); + + spapr_memory_unplug_rollback(spapr, drc->dev); + } + + drc->unplug_requested = false; + error_report("Device hotunplug rejected by the guest " + "for device %s", drc->dev->id); + + /* + * TODO: send a QAPI DEVICE_UNPLUG_ERROR event when + * it is implemented. + */ + } + return RTAS_OUT_SUCCESS; /* Nothing to do */ case SPAPR_DRC_STATE_LOGICAL_AVAILABLE: break; /* see below */ From patchwork Tue May 4 05:53:03 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: David Gibson X-Patchwork-Id: 12237493 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-16.6 required=3.0 tests=BAYES_00,DKIM_INVALID, DKIM_SIGNED,HEADER_FROM_DIFFERENT_DOMAINS,INCLUDES_CR_TRAILER,INCLUDES_PATCH, MAILING_LIST_MULTI,SPF_HELO_NONE,SPF_PASS,USER_AGENT_GIT autolearn=ham autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id E5ADAC433B4 for ; Tue, 4 May 2021 06:41:09 +0000 (UTC) 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 mail.kernel.org (Postfix) with ESMTPS id 69A1B613B3 for ; Tue, 4 May 2021 06:41:09 +0000 (UTC) DMARC-Filter: OpenDMARC Filter v1.3.2 mail.kernel.org 69A1B613B3 Authentication-Results: mail.kernel.org; dmarc=none (p=none dis=none) header.from=gibson.dropbear.id.au Authentication-Results: mail.kernel.org; spf=pass smtp.mailfrom=qemu-devel-bounces+qemu-devel=archiver.kernel.org@nongnu.org Received: from localhost ([::1]:51528 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1ldok0-0003OW-FG for qemu-devel@archiver.kernel.org; Tue, 04 May 2021 02:41:08 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]:60882) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1ldo0z-0006go-4s; Tue, 04 May 2021 01:54:37 -0400 Received: from ozlabs.org ([203.11.71.1]:36827) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1ldo0u-00059E-AB; Tue, 04 May 2021 01:54:35 -0400 Received: by ozlabs.org (Postfix, from userid 1007) id 4FZ8CP0mB7z9t0T; Tue, 4 May 2021 15:53:20 +1000 (AEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=gibson.dropbear.id.au; s=201602; t=1620107601; bh=U9GyzUbSH4St3uV5hHuWwRQqe01HWFvGg8Y2fjxAvJo=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=DxTFQB6UuPErgkaxdNKNKXhzix15+C828C4kbavMLcvyN9hQdufwt1RoKrhcfu3or OVUgNIc7Gn4WUdsV8fMH9LfF+n5lYPySo2QaZDOFYYV35dp8RaypYEVBfAsK9Iij3P FYdL9Us01BLUZSlN6PvtV4ynKQC+61hKfsWBd1o4= From: David Gibson To: peter.maydell@linaro.org, groug@kaod.org Subject: [PULL 37/46] target/ppc: code motion from translate_init.c.inc to gdbstub.c Date: Tue, 4 May 2021 15:53:03 +1000 Message-Id: <20210504055312.306823-38-david@gibson.dropbear.id.au> X-Mailer: git-send-email 2.31.1 In-Reply-To: <20210504055312.306823-1-david@gibson.dropbear.id.au> References: <20210504055312.306823-1-david@gibson.dropbear.id.au> MIME-Version: 1.0 Received-SPF: pass client-ip=203.11.71.1; envelope-from=dgibson@ozlabs.org; helo=ozlabs.org X-Spam_score_int: -17 X-Spam_score: -1.8 X-Spam_bar: - X-Spam_report: (-1.8 / 5.0 requ) BAYES_00=-1.9, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_AU=-0.1, HEADER_FROM_DIFFERENT_DOMAINS=0.25, SPF_HELO_PASS=-0.001, SPF_PASS=-0.001 autolearn=no autolearn_force=no X-Spam_action: no action X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: "Bruno Larsen \(billionai\)" , David Gibson , qemu-ppc@nongnu.org, qemu-devel@nongnu.org, Fabiano Rosas Errors-To: qemu-devel-bounces+qemu-devel=archiver.kernel.org@nongnu.org Sender: "Qemu-devel" From: "Bruno Larsen (billionai)" All the code related to gdb has been moved from translate_init.c.inc file to the gdbstub.c file, where it makes more sense. Version 4 fixes the omission of internal.h in gdbstub, mentioned in <87sg3d2gf5.fsf@linux.ibm.com>, and the extra blank line. Signed-off-by: Bruno Larsen (billionai) Suggested-by: Fabiano Rosas Message-Id: <20210426184706.48040-1-bruno.larsen@eldorado.org.br> Signed-off-by: David Gibson --- target/ppc/gdbstub.c | 258 ++++++++++++++++++++++++++++++++ target/ppc/internal.h | 5 + target/ppc/translate_init.c.inc | 254 +------------------------------ 3 files changed, 264 insertions(+), 253 deletions(-) diff --git a/target/ppc/gdbstub.c b/target/ppc/gdbstub.c index c28319fb97..94a7273ee0 100644 --- a/target/ppc/gdbstub.c +++ b/target/ppc/gdbstub.c @@ -20,6 +20,8 @@ #include "qemu/osdep.h" #include "cpu.h" #include "exec/gdbstub.h" +#include "exec/helper-proto.h" +#include "internal.h" static int ppc_gdb_register_len_apple(int n) { @@ -387,3 +389,259 @@ const char *ppc_gdb_get_dynamic_xml(CPUState *cs, const char *xml_name) return NULL; } #endif + +static bool avr_need_swap(CPUPPCState *env) +{ +#ifdef HOST_WORDS_BIGENDIAN + return msr_le; +#else + return !msr_le; +#endif +} + +#if !defined(CONFIG_USER_ONLY) +static int gdb_find_spr_idx(CPUPPCState *env, int n) +{ + int i; + + for (i = 0; i < ARRAY_SIZE(env->spr_cb); i++) { + ppc_spr_t *spr = &env->spr_cb[i]; + + if (spr->name && spr->gdb_id == n) { + return i; + } + } + return -1; +} + +static int gdb_get_spr_reg(CPUPPCState *env, GByteArray *buf, int n) +{ + int reg; + int len; + + reg = gdb_find_spr_idx(env, n); + if (reg < 0) { + return 0; + } + + len = TARGET_LONG_SIZE; + gdb_get_regl(buf, env->spr[reg]); + ppc_maybe_bswap_register(env, gdb_get_reg_ptr(buf, len), len); + return len; +} + +static int gdb_set_spr_reg(CPUPPCState *env, uint8_t *mem_buf, int n) +{ + int reg; + int len; + + reg = gdb_find_spr_idx(env, n); + if (reg < 0) { + return 0; + } + + len = TARGET_LONG_SIZE; + ppc_maybe_bswap_register(env, mem_buf, len); + env->spr[reg] = ldn_p(mem_buf, len); + + return len; +} +#endif + +static int gdb_get_float_reg(CPUPPCState *env, GByteArray *buf, int n) +{ + uint8_t *mem_buf; + if (n < 32) { + gdb_get_reg64(buf, *cpu_fpr_ptr(env, n)); + mem_buf = gdb_get_reg_ptr(buf, 8); + ppc_maybe_bswap_register(env, mem_buf, 8); + return 8; + } + if (n == 32) { + gdb_get_reg32(buf, env->fpscr); + mem_buf = gdb_get_reg_ptr(buf, 4); + ppc_maybe_bswap_register(env, mem_buf, 4); + return 4; + } + return 0; +} + +static int gdb_set_float_reg(CPUPPCState *env, uint8_t *mem_buf, int n) +{ + if (n < 32) { + ppc_maybe_bswap_register(env, mem_buf, 8); + *cpu_fpr_ptr(env, n) = ldq_p(mem_buf); + return 8; + } + if (n == 32) { + ppc_maybe_bswap_register(env, mem_buf, 4); + store_fpscr(env, ldl_p(mem_buf), 0xffffffff); + return 4; + } + return 0; +} + +static int gdb_get_avr_reg(CPUPPCState *env, GByteArray *buf, int n) +{ + uint8_t *mem_buf; + + if (n < 32) { + ppc_avr_t *avr = cpu_avr_ptr(env, n); + if (!avr_need_swap(env)) { + gdb_get_reg128(buf, avr->u64[0] , avr->u64[1]); + } else { + gdb_get_reg128(buf, avr->u64[1] , avr->u64[0]); + } + mem_buf = gdb_get_reg_ptr(buf, 16); + ppc_maybe_bswap_register(env, mem_buf, 8); + ppc_maybe_bswap_register(env, mem_buf + 8, 8); + return 16; + } + if (n == 32) { + gdb_get_reg32(buf, helper_mfvscr(env)); + mem_buf = gdb_get_reg_ptr(buf, 4); + ppc_maybe_bswap_register(env, mem_buf, 4); + return 4; + } + if (n == 33) { + gdb_get_reg32(buf, (uint32_t)env->spr[SPR_VRSAVE]); + mem_buf = gdb_get_reg_ptr(buf, 4); + ppc_maybe_bswap_register(env, mem_buf, 4); + return 4; + } + return 0; +} + +static int gdb_set_avr_reg(CPUPPCState *env, uint8_t *mem_buf, int n) +{ + if (n < 32) { + ppc_avr_t *avr = cpu_avr_ptr(env, n); + ppc_maybe_bswap_register(env, mem_buf, 8); + ppc_maybe_bswap_register(env, mem_buf + 8, 8); + if (!avr_need_swap(env)) { + avr->u64[0] = ldq_p(mem_buf); + avr->u64[1] = ldq_p(mem_buf + 8); + } else { + avr->u64[1] = ldq_p(mem_buf); + avr->u64[0] = ldq_p(mem_buf + 8); + } + return 16; + } + if (n == 32) { + ppc_maybe_bswap_register(env, mem_buf, 4); + helper_mtvscr(env, ldl_p(mem_buf)); + return 4; + } + if (n == 33) { + ppc_maybe_bswap_register(env, mem_buf, 4); + env->spr[SPR_VRSAVE] = (target_ulong)ldl_p(mem_buf); + return 4; + } + return 0; +} + +static int gdb_get_spe_reg(CPUPPCState *env, GByteArray *buf, int n) +{ + if (n < 32) { +#if defined(TARGET_PPC64) + gdb_get_reg32(buf, env->gpr[n] >> 32); + ppc_maybe_bswap_register(env, gdb_get_reg_ptr(buf, 4), 4); +#else + gdb_get_reg32(buf, env->gprh[n]); +#endif + return 4; + } + if (n == 32) { + gdb_get_reg64(buf, env->spe_acc); + ppc_maybe_bswap_register(env, gdb_get_reg_ptr(buf, 8), 8); + return 8; + } + if (n == 33) { + gdb_get_reg32(buf, env->spe_fscr); + ppc_maybe_bswap_register(env, gdb_get_reg_ptr(buf, 4), 4); + return 4; + } + return 0; +} + +static int gdb_set_spe_reg(CPUPPCState *env, uint8_t *mem_buf, int n) +{ + if (n < 32) { +#if defined(TARGET_PPC64) + target_ulong lo = (uint32_t)env->gpr[n]; + target_ulong hi; + + ppc_maybe_bswap_register(env, mem_buf, 4); + + hi = (target_ulong)ldl_p(mem_buf) << 32; + env->gpr[n] = lo | hi; +#else + env->gprh[n] = ldl_p(mem_buf); +#endif + return 4; + } + if (n == 32) { + ppc_maybe_bswap_register(env, mem_buf, 8); + env->spe_acc = ldq_p(mem_buf); + return 8; + } + if (n == 33) { + ppc_maybe_bswap_register(env, mem_buf, 4); + env->spe_fscr = ldl_p(mem_buf); + return 4; + } + return 0; +} + +static int gdb_get_vsx_reg(CPUPPCState *env, GByteArray *buf, int n) +{ + if (n < 32) { + gdb_get_reg64(buf, *cpu_vsrl_ptr(env, n)); + ppc_maybe_bswap_register(env, gdb_get_reg_ptr(buf, 8), 8); + return 8; + } + return 0; +} + +static int gdb_set_vsx_reg(CPUPPCState *env, uint8_t *mem_buf, int n) +{ + if (n < 32) { + ppc_maybe_bswap_register(env, mem_buf, 8); + *cpu_vsrl_ptr(env, n) = ldq_p(mem_buf); + return 8; + } + return 0; +} + +gchar *ppc_gdb_arch_name(CPUState *cs) +{ +#if defined(TARGET_PPC64) + return g_strdup("powerpc:common64"); +#else + return g_strdup("powerpc:common"); +#endif +} + +void ppc_gdb_init(CPUState *cs, PowerPCCPUClass *pcc) +{ + if (pcc->insns_flags & PPC_FLOAT) { + gdb_register_coprocessor(cs, gdb_get_float_reg, gdb_set_float_reg, + 33, "power-fpu.xml", 0); + } + if (pcc->insns_flags & PPC_ALTIVEC) { + gdb_register_coprocessor(cs, gdb_get_avr_reg, gdb_set_avr_reg, + 34, "power-altivec.xml", 0); + } + if (pcc->insns_flags & PPC_SPE) { + gdb_register_coprocessor(cs, gdb_get_spe_reg, gdb_set_spe_reg, + 34, "power-spe.xml", 0); + } + if (pcc->insns_flags2 & PPC2_VSX) { + gdb_register_coprocessor(cs, gdb_get_vsx_reg, gdb_set_vsx_reg, + 32, "power-vsx.xml", 0); + } +#ifndef CONFIG_USER_ONLY + gdb_register_coprocessor(cs, gdb_get_spr_reg, gdb_set_spr_reg, + pcc->gdb_num_sprs, "power-spr.xml", 0); +#endif +} diff --git a/target/ppc/internal.h b/target/ppc/internal.h index d547448065..c401658e8d 100644 --- a/target/ppc/internal.h +++ b/target/ppc/internal.h @@ -215,4 +215,9 @@ void helper_compute_fprf_float128(CPUPPCState *env, float128 arg); void ppc_cpu_do_unaligned_access(CPUState *cs, vaddr addr, MMUAccessType access_type, int mmu_idx, uintptr_t retaddr); + +/* gdbstub.c */ +void ppc_gdb_init(CPUState *cs, PowerPCCPUClass *ppc); +gchar *ppc_gdb_arch_name(CPUState *cs); + #endif /* PPC_INTERNAL_H */ diff --git a/target/ppc/translate_init.c.inc b/target/ppc/translate_init.c.inc index 58473c4c09..9ab2c32cc4 100644 --- a/target/ppc/translate_init.c.inc +++ b/target/ppc/translate_init.c.inc @@ -9895,230 +9895,6 @@ static void dump_ppc_insns(CPUPPCState *env) } } #endif - -static bool avr_need_swap(CPUPPCState *env) -{ -#ifdef HOST_WORDS_BIGENDIAN - return msr_le; -#else - return !msr_le; -#endif -} - -#if !defined(CONFIG_USER_ONLY) -static int gdb_find_spr_idx(CPUPPCState *env, int n) -{ - int i; - - for (i = 0; i < ARRAY_SIZE(env->spr_cb); i++) { - ppc_spr_t *spr = &env->spr_cb[i]; - - if (spr->name && spr->gdb_id == n) { - return i; - } - } - return -1; -} - -static int gdb_get_spr_reg(CPUPPCState *env, GByteArray *buf, int n) -{ - int reg; - int len; - - reg = gdb_find_spr_idx(env, n); - if (reg < 0) { - return 0; - } - - len = TARGET_LONG_SIZE; - gdb_get_regl(buf, env->spr[reg]); - ppc_maybe_bswap_register(env, gdb_get_reg_ptr(buf, len), len); - return len; -} - -static int gdb_set_spr_reg(CPUPPCState *env, uint8_t *mem_buf, int n) -{ - int reg; - int len; - - reg = gdb_find_spr_idx(env, n); - if (reg < 0) { - return 0; - } - - len = TARGET_LONG_SIZE; - ppc_maybe_bswap_register(env, mem_buf, len); - env->spr[reg] = ldn_p(mem_buf, len); - - return len; -} -#endif - -static int gdb_get_float_reg(CPUPPCState *env, GByteArray *buf, int n) -{ - uint8_t *mem_buf; - if (n < 32) { - gdb_get_reg64(buf, *cpu_fpr_ptr(env, n)); - mem_buf = gdb_get_reg_ptr(buf, 8); - ppc_maybe_bswap_register(env, mem_buf, 8); - return 8; - } - if (n == 32) { - gdb_get_reg32(buf, env->fpscr); - mem_buf = gdb_get_reg_ptr(buf, 4); - ppc_maybe_bswap_register(env, mem_buf, 4); - return 4; - } - return 0; -} - -static int gdb_set_float_reg(CPUPPCState *env, uint8_t *mem_buf, int n) -{ - if (n < 32) { - ppc_maybe_bswap_register(env, mem_buf, 8); - *cpu_fpr_ptr(env, n) = ldq_p(mem_buf); - return 8; - } - if (n == 32) { - ppc_maybe_bswap_register(env, mem_buf, 4); - helper_store_fpscr(env, ldl_p(mem_buf), 0xffffffff); - return 4; - } - return 0; -} - -static int gdb_get_avr_reg(CPUPPCState *env, GByteArray *buf, int n) -{ - uint8_t *mem_buf; - - if (n < 32) { - ppc_avr_t *avr = cpu_avr_ptr(env, n); - if (!avr_need_swap(env)) { - gdb_get_reg128(buf, avr->u64[0] , avr->u64[1]); - } else { - gdb_get_reg128(buf, avr->u64[1] , avr->u64[0]); - } - mem_buf = gdb_get_reg_ptr(buf, 16); - ppc_maybe_bswap_register(env, mem_buf, 8); - ppc_maybe_bswap_register(env, mem_buf + 8, 8); - return 16; - } - if (n == 32) { - gdb_get_reg32(buf, helper_mfvscr(env)); - mem_buf = gdb_get_reg_ptr(buf, 4); - ppc_maybe_bswap_register(env, mem_buf, 4); - return 4; - } - if (n == 33) { - gdb_get_reg32(buf, (uint32_t)env->spr[SPR_VRSAVE]); - mem_buf = gdb_get_reg_ptr(buf, 4); - ppc_maybe_bswap_register(env, mem_buf, 4); - return 4; - } - return 0; -} - -static int gdb_set_avr_reg(CPUPPCState *env, uint8_t *mem_buf, int n) -{ - if (n < 32) { - ppc_avr_t *avr = cpu_avr_ptr(env, n); - ppc_maybe_bswap_register(env, mem_buf, 8); - ppc_maybe_bswap_register(env, mem_buf + 8, 8); - if (!avr_need_swap(env)) { - avr->u64[0] = ldq_p(mem_buf); - avr->u64[1] = ldq_p(mem_buf + 8); - } else { - avr->u64[1] = ldq_p(mem_buf); - avr->u64[0] = ldq_p(mem_buf + 8); - } - return 16; - } - if (n == 32) { - ppc_maybe_bswap_register(env, mem_buf, 4); - helper_mtvscr(env, ldl_p(mem_buf)); - return 4; - } - if (n == 33) { - ppc_maybe_bswap_register(env, mem_buf, 4); - env->spr[SPR_VRSAVE] = (target_ulong)ldl_p(mem_buf); - return 4; - } - return 0; -} - -static int gdb_get_spe_reg(CPUPPCState *env, GByteArray *buf, int n) -{ - if (n < 32) { -#if defined(TARGET_PPC64) - gdb_get_reg32(buf, env->gpr[n] >> 32); - ppc_maybe_bswap_register(env, gdb_get_reg_ptr(buf, 4), 4); -#else - gdb_get_reg32(buf, env->gprh[n]); -#endif - return 4; - } - if (n == 32) { - gdb_get_reg64(buf, env->spe_acc); - ppc_maybe_bswap_register(env, gdb_get_reg_ptr(buf, 8), 8); - return 8; - } - if (n == 33) { - gdb_get_reg32(buf, env->spe_fscr); - ppc_maybe_bswap_register(env, gdb_get_reg_ptr(buf, 4), 4); - return 4; - } - return 0; -} - -static int gdb_set_spe_reg(CPUPPCState *env, uint8_t *mem_buf, int n) -{ - if (n < 32) { -#if defined(TARGET_PPC64) - target_ulong lo = (uint32_t)env->gpr[n]; - target_ulong hi; - - ppc_maybe_bswap_register(env, mem_buf, 4); - - hi = (target_ulong)ldl_p(mem_buf) << 32; - env->gpr[n] = lo | hi; -#else - env->gprh[n] = ldl_p(mem_buf); -#endif - return 4; - } - if (n == 32) { - ppc_maybe_bswap_register(env, mem_buf, 8); - env->spe_acc = ldq_p(mem_buf); - return 8; - } - if (n == 33) { - ppc_maybe_bswap_register(env, mem_buf, 4); - env->spe_fscr = ldl_p(mem_buf); - return 4; - } - return 0; -} - -static int gdb_get_vsx_reg(CPUPPCState *env, GByteArray *buf, int n) -{ - if (n < 32) { - gdb_get_reg64(buf, *cpu_vsrl_ptr(env, n)); - ppc_maybe_bswap_register(env, gdb_get_reg_ptr(buf, 8), 8); - return 8; - } - return 0; -} - -static int gdb_set_vsx_reg(CPUPPCState *env, uint8_t *mem_buf, int n) -{ - if (n < 32) { - ppc_maybe_bswap_register(env, mem_buf, 8); - *cpu_vsrl_ptr(env, n) = ldq_p(mem_buf); - return 8; - } - return 0; -} - static int ppc_fixup_cpu(PowerPCCPU *cpu) { CPUPPCState *env = &cpu->env; @@ -10174,26 +9950,7 @@ static void ppc_cpu_realize(DeviceState *dev, Error **errp) } init_ppc_proc(cpu); - if (pcc->insns_flags & PPC_FLOAT) { - gdb_register_coprocessor(cs, gdb_get_float_reg, gdb_set_float_reg, - 33, "power-fpu.xml", 0); - } - if (pcc->insns_flags & PPC_ALTIVEC) { - gdb_register_coprocessor(cs, gdb_get_avr_reg, gdb_set_avr_reg, - 34, "power-altivec.xml", 0); - } - if (pcc->insns_flags & PPC_SPE) { - gdb_register_coprocessor(cs, gdb_get_spe_reg, gdb_set_spe_reg, - 34, "power-spe.xml", 0); - } - if (pcc->insns_flags2 & PPC2_VSX) { - gdb_register_coprocessor(cs, gdb_get_vsx_reg, gdb_set_vsx_reg, - 32, "power-vsx.xml", 0); - } -#ifndef CONFIG_USER_ONLY - gdb_register_coprocessor(cs, gdb_get_spr_reg, gdb_set_spr_reg, - pcc->gdb_num_sprs, "power-spr.xml", 0); -#endif + ppc_gdb_init(cs, pcc); qemu_init_vcpu(cs); pcc->parent_realize(dev, errp); @@ -10835,15 +10592,6 @@ static bool ppc_pvr_match_default(PowerPCCPUClass *pcc, uint32_t pvr) return pcc->pvr == pvr; } -static gchar *ppc_gdb_arch_name(CPUState *cs) -{ -#if defined(TARGET_PPC64) - return g_strdup("powerpc:common64"); -#else - return g_strdup("powerpc:common"); -#endif -} - static void ppc_disas_set_info(CPUState *cs, disassemble_info *info) { PowerPCCPU *cpu = POWERPC_CPU(cs); From patchwork Tue May 4 05:53:04 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: David Gibson X-Patchwork-Id: 12237499 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-16.6 required=3.0 tests=BAYES_00,DKIM_INVALID, DKIM_SIGNED,HEADER_FROM_DIFFERENT_DOMAINS,INCLUDES_CR_TRAILER,INCLUDES_PATCH, MAILING_LIST_MULTI,SPF_HELO_NONE,SPF_PASS,USER_AGENT_GIT autolearn=ham autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id A0A38C433B4 for ; Tue, 4 May 2021 06:43:31 +0000 (UTC) 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 mail.kernel.org (Postfix) with ESMTPS id 39A3E613B3 for ; Tue, 4 May 2021 06:43:31 +0000 (UTC) DMARC-Filter: OpenDMARC Filter v1.3.2 mail.kernel.org 39A3E613B3 Authentication-Results: mail.kernel.org; dmarc=none (p=none dis=none) header.from=gibson.dropbear.id.au Authentication-Results: mail.kernel.org; spf=pass smtp.mailfrom=qemu-devel-bounces+qemu-devel=archiver.kernel.org@nongnu.org Received: from localhost ([::1]:60278 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1ldomI-00079p-A9 for qemu-devel@archiver.kernel.org; Tue, 04 May 2021 02:43:30 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]:60884) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1ldo0z-0006gy-71; Tue, 04 May 2021 01:54:37 -0400 Received: from ozlabs.org ([203.11.71.1]:37727) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1ldo0v-0005A1-Ec; Tue, 04 May 2021 01:54:36 -0400 Received: by ozlabs.org (Postfix, from userid 1007) id 4FZ8CP2QPCz9t0k; Tue, 4 May 2021 15:53:20 +1000 (AEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=gibson.dropbear.id.au; s=201602; t=1620107601; bh=uHYxqL7MwJR1AGjlaCDo2saew1p+mMOoXYp2KNeVJYQ=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=ZWs9lpOg5bxOPl3bxRRT3e+QMH8YpLr0FYQ80LEieVzveu4bJeGCz98xmdTWgZ9zz LX/FDpzTtY/gnkzOjxscYczYaQXjG/oLpGNJygCzQOm8jcBPBiSl+v0CuUI5wk0Uqx 5vKnECNpCwXDYxKp5XViSvqxc++Lse9IVRh4pP6w= From: David Gibson To: peter.maydell@linaro.org, groug@kaod.org Subject: [PULL 38/46] target/ppc: move opcode table logic to translate.c Date: Tue, 4 May 2021 15:53:04 +1000 Message-Id: <20210504055312.306823-39-david@gibson.dropbear.id.au> X-Mailer: git-send-email 2.31.1 In-Reply-To: <20210504055312.306823-1-david@gibson.dropbear.id.au> References: <20210504055312.306823-1-david@gibson.dropbear.id.au> MIME-Version: 1.0 Received-SPF: pass client-ip=203.11.71.1; envelope-from=dgibson@ozlabs.org; helo=ozlabs.org X-Spam_score_int: -17 X-Spam_score: -1.8 X-Spam_bar: - X-Spam_report: (-1.8 / 5.0 requ) BAYES_00=-1.9, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_AU=-0.1, HEADER_FROM_DIFFERENT_DOMAINS=0.25, SPF_HELO_PASS=-0.001, SPF_PASS=-0.001 autolearn=no autolearn_force=no X-Spam_action: no action X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: "Bruno Larsen \(billionai\)" , Richard Henderson , qemu-ppc@nongnu.org, qemu-devel@nongnu.org, David Gibson Errors-To: qemu-devel-bounces+qemu-devel=archiver.kernel.org@nongnu.org Sender: "Qemu-devel" From: "Bruno Larsen (billionai)" code motion to remove opcode callback table from translate_init.c.inc to translate.c in preparation to remove the #include from translate.c. Also created destroy_ppc_opcodes and removed that logic from ppc_cpu_unrealize Signed-off-by: Bruno Larsen (billionai) Message-Id: <20210429162130.2412-2-bruno.larsen@eldorado.org.br> Reviewed-by: Richard Henderson Signed-off-by: David Gibson --- target/ppc/internal.h | 8 + target/ppc/translate.c | 394 ++++++++++++++++++++++++++++++++ target/ppc/translate_init.c.inc | 391 +------------------------------ 3 files changed, 403 insertions(+), 390 deletions(-) diff --git a/target/ppc/internal.h b/target/ppc/internal.h index c401658e8d..184ba6d6b3 100644 --- a/target/ppc/internal.h +++ b/target/ppc/internal.h @@ -216,6 +216,14 @@ void ppc_cpu_do_unaligned_access(CPUState *cs, vaddr addr, MMUAccessType access_type, int mmu_idx, uintptr_t retaddr); +/* translate.c */ + +/* #define PPC_DUMP_CPU */ + +int ppc_fixup_cpu(PowerPCCPU *cpu); +void create_ppc_opcodes(PowerPCCPU *cpu, Error **errp); +void destroy_ppc_opcodes(PowerPCCPU *cpu); + /* gdbstub.c */ void ppc_gdb_init(CPUState *cs, PowerPCCPUClass *ppc); gchar *ppc_gdb_arch_name(CPUState *cs); diff --git a/target/ppc/translate.c b/target/ppc/translate.c index a53463b9b8..a7c568ca9c 100644 --- a/target/ppc/translate.c +++ b/target/ppc/translate.c @@ -7825,6 +7825,400 @@ void ppc_cpu_dump_state(CPUState *cs, FILE *f, int flags) #undef RFPL } +/*****************************************************************************/ +/* Opcode types */ +enum { + PPC_DIRECT = 0, /* Opcode routine */ + PPC_INDIRECT = 1, /* Indirect opcode table */ +}; + +#define PPC_OPCODE_MASK 0x3 + +static inline int is_indirect_opcode(void *handler) +{ + return ((uintptr_t)handler & PPC_OPCODE_MASK) == PPC_INDIRECT; +} + +static inline opc_handler_t **ind_table(void *handler) +{ + return (opc_handler_t **)((uintptr_t)handler & ~PPC_OPCODE_MASK); +} + +/* Instruction table creation */ +/* Opcodes tables creation */ +static void fill_new_table(opc_handler_t **table, int len) +{ + int i; + + for (i = 0; i < len; i++) { + table[i] = &invalid_handler; + } +} + +static int create_new_table(opc_handler_t **table, unsigned char idx) +{ + opc_handler_t **tmp; + + tmp = g_new(opc_handler_t *, PPC_CPU_INDIRECT_OPCODES_LEN); + fill_new_table(tmp, PPC_CPU_INDIRECT_OPCODES_LEN); + table[idx] = (opc_handler_t *)((uintptr_t)tmp | PPC_INDIRECT); + + return 0; +} + +static int insert_in_table(opc_handler_t **table, unsigned char idx, + opc_handler_t *handler) +{ + if (table[idx] != &invalid_handler) { + return -1; + } + table[idx] = handler; + + return 0; +} + +static int register_direct_insn(opc_handler_t **ppc_opcodes, + unsigned char idx, opc_handler_t *handler) +{ + if (insert_in_table(ppc_opcodes, idx, handler) < 0) { + printf("*** ERROR: opcode %02x already assigned in main " + "opcode table\n", idx); +#if defined(DO_PPC_STATISTICS) || defined(PPC_DUMP_CPU) + printf(" Registered handler '%s' - new handler '%s'\n", + ppc_opcodes[idx]->oname, handler->oname); +#endif + return -1; + } + + return 0; +} + +static int register_ind_in_table(opc_handler_t **table, + unsigned char idx1, unsigned char idx2, + opc_handler_t *handler) +{ + if (table[idx1] == &invalid_handler) { + if (create_new_table(table, idx1) < 0) { + printf("*** ERROR: unable to create indirect table " + "idx=%02x\n", idx1); + return -1; + } + } else { + if (!is_indirect_opcode(table[idx1])) { + printf("*** ERROR: idx %02x already assigned to a direct " + "opcode\n", idx1); +#if defined(DO_PPC_STATISTICS) || defined(PPC_DUMP_CPU) + printf(" Registered handler '%s' - new handler '%s'\n", + ind_table(table[idx1])[idx2]->oname, handler->oname); +#endif + return -1; + } + } + if (handler != NULL && + insert_in_table(ind_table(table[idx1]), idx2, handler) < 0) { + printf("*** ERROR: opcode %02x already assigned in " + "opcode table %02x\n", idx2, idx1); +#if defined(DO_PPC_STATISTICS) || defined(PPC_DUMP_CPU) + printf(" Registered handler '%s' - new handler '%s'\n", + ind_table(table[idx1])[idx2]->oname, handler->oname); +#endif + return -1; + } + + return 0; +} + +static int register_ind_insn(opc_handler_t **ppc_opcodes, + unsigned char idx1, unsigned char idx2, + opc_handler_t *handler) +{ + return register_ind_in_table(ppc_opcodes, idx1, idx2, handler); +} + +static int register_dblind_insn(opc_handler_t **ppc_opcodes, + unsigned char idx1, unsigned char idx2, + unsigned char idx3, opc_handler_t *handler) +{ + if (register_ind_in_table(ppc_opcodes, idx1, idx2, NULL) < 0) { + printf("*** ERROR: unable to join indirect table idx " + "[%02x-%02x]\n", idx1, idx2); + return -1; + } + if (register_ind_in_table(ind_table(ppc_opcodes[idx1]), idx2, idx3, + handler) < 0) { + printf("*** ERROR: unable to insert opcode " + "[%02x-%02x-%02x]\n", idx1, idx2, idx3); + return -1; + } + + return 0; +} + +static int register_trplind_insn(opc_handler_t **ppc_opcodes, + unsigned char idx1, unsigned char idx2, + unsigned char idx3, unsigned char idx4, + opc_handler_t *handler) +{ + opc_handler_t **table; + + if (register_ind_in_table(ppc_opcodes, idx1, idx2, NULL) < 0) { + printf("*** ERROR: unable to join indirect table idx " + "[%02x-%02x]\n", idx1, idx2); + return -1; + } + table = ind_table(ppc_opcodes[idx1]); + if (register_ind_in_table(table, idx2, idx3, NULL) < 0) { + printf("*** ERROR: unable to join 2nd-level indirect table idx " + "[%02x-%02x-%02x]\n", idx1, idx2, idx3); + return -1; + } + table = ind_table(table[idx2]); + if (register_ind_in_table(table, idx3, idx4, handler) < 0) { + printf("*** ERROR: unable to insert opcode " + "[%02x-%02x-%02x-%02x]\n", idx1, idx2, idx3, idx4); + return -1; + } + return 0; +} +static int register_insn(opc_handler_t **ppc_opcodes, opcode_t *insn) +{ + if (insn->opc2 != 0xFF) { + if (insn->opc3 != 0xFF) { + if (insn->opc4 != 0xFF) { + if (register_trplind_insn(ppc_opcodes, insn->opc1, insn->opc2, + insn->opc3, insn->opc4, + &insn->handler) < 0) { + return -1; + } + } else { + if (register_dblind_insn(ppc_opcodes, insn->opc1, insn->opc2, + insn->opc3, &insn->handler) < 0) { + return -1; + } + } + } else { + if (register_ind_insn(ppc_opcodes, insn->opc1, + insn->opc2, &insn->handler) < 0) { + return -1; + } + } + } else { + if (register_direct_insn(ppc_opcodes, insn->opc1, &insn->handler) < 0) { + return -1; + } + } + + return 0; +} + +static int test_opcode_table(opc_handler_t **table, int len) +{ + int i, count, tmp; + + for (i = 0, count = 0; i < len; i++) { + /* Consistency fixup */ + if (table[i] == NULL) { + table[i] = &invalid_handler; + } + if (table[i] != &invalid_handler) { + if (is_indirect_opcode(table[i])) { + tmp = test_opcode_table(ind_table(table[i]), + PPC_CPU_INDIRECT_OPCODES_LEN); + if (tmp == 0) { + free(table[i]); + table[i] = &invalid_handler; + } else { + count++; + } + } else { + count++; + } + } + } + + return count; +} + +static void fix_opcode_tables(opc_handler_t **ppc_opcodes) +{ + if (test_opcode_table(ppc_opcodes, PPC_CPU_OPCODES_LEN) == 0) { + printf("*** WARNING: no opcode defined !\n"); + } +} + +/*****************************************************************************/ +void create_ppc_opcodes(PowerPCCPU *cpu, Error **errp) +{ + PowerPCCPUClass *pcc = POWERPC_CPU_GET_CLASS(cpu); + opcode_t *opc; + + fill_new_table(cpu->opcodes, PPC_CPU_OPCODES_LEN); + for (opc = opcodes; opc < &opcodes[ARRAY_SIZE(opcodes)]; opc++) { + if (((opc->handler.type & pcc->insns_flags) != 0) || + ((opc->handler.type2 & pcc->insns_flags2) != 0)) { + if (register_insn(cpu->opcodes, opc) < 0) { + error_setg(errp, "ERROR initializing PowerPC instruction " + "0x%02x 0x%02x 0x%02x", opc->opc1, opc->opc2, + opc->opc3); + return; + } + } + } + fix_opcode_tables(cpu->opcodes); + fflush(stdout); + fflush(stderr); +} + +void destroy_ppc_opcodes(PowerPCCPU *cpu) +{ + opc_handler_t **table, **table_2; + int i, j, k; + + for (i = 0; i < PPC_CPU_OPCODES_LEN; i++) { + if (cpu->opcodes[i] == &invalid_handler) { + continue; + } + if (is_indirect_opcode(cpu->opcodes[i])) { + table = ind_table(cpu->opcodes[i]); + for (j = 0; j < PPC_CPU_INDIRECT_OPCODES_LEN; j++) { + if (table[j] == &invalid_handler) { + continue; + } + if (is_indirect_opcode(table[j])) { + table_2 = ind_table(table[j]); + for (k = 0; k < PPC_CPU_INDIRECT_OPCODES_LEN; k++) { + if (table_2[k] != &invalid_handler && + is_indirect_opcode(table_2[k])) { + g_free((opc_handler_t *)((uintptr_t)table_2[k] & + ~PPC_INDIRECT)); + } + } + g_free((opc_handler_t *)((uintptr_t)table[j] & + ~PPC_INDIRECT)); + } + } + g_free((opc_handler_t *)((uintptr_t)cpu->opcodes[i] & + ~PPC_INDIRECT)); + } + } +} + +#if defined(PPC_DUMP_CPU) +static void dump_ppc_insns(CPUPPCState *env) +{ + opc_handler_t **table, *handler; + const char *p, *q; + uint8_t opc1, opc2, opc3, opc4; + + printf("Instructions set:\n"); + /* opc1 is 6 bits long */ + for (opc1 = 0x00; opc1 < PPC_CPU_OPCODES_LEN; opc1++) { + table = env->opcodes; + handler = table[opc1]; + if (is_indirect_opcode(handler)) { + /* opc2 is 5 bits long */ + for (opc2 = 0; opc2 < PPC_CPU_INDIRECT_OPCODES_LEN; opc2++) { + table = env->opcodes; + handler = env->opcodes[opc1]; + table = ind_table(handler); + handler = table[opc2]; + if (is_indirect_opcode(handler)) { + table = ind_table(handler); + /* opc3 is 5 bits long */ + for (opc3 = 0; opc3 < PPC_CPU_INDIRECT_OPCODES_LEN; + opc3++) { + handler = table[opc3]; + if (is_indirect_opcode(handler)) { + table = ind_table(handler); + /* opc4 is 5 bits long */ + for (opc4 = 0; opc4 < PPC_CPU_INDIRECT_OPCODES_LEN; + opc4++) { + handler = table[opc4]; + if (handler->handler != &gen_invalid) { + printf("INSN: %02x %02x %02x %02x -- " + "(%02d %04d %02d) : %s\n", + opc1, opc2, opc3, opc4, + opc1, (opc3 << 5) | opc2, opc4, + handler->oname); + } + } + } else { + if (handler->handler != &gen_invalid) { + /* Special hack to properly dump SPE insns */ + p = strchr(handler->oname, '_'); + if (p == NULL) { + printf("INSN: %02x %02x %02x (%02d %04d) : " + "%s\n", + opc1, opc2, opc3, opc1, + (opc3 << 5) | opc2, + handler->oname); + } else { + q = "speundef"; + if ((p - handler->oname) != strlen(q) + || (memcmp(handler->oname, q, strlen(q)) + != 0)) { + /* First instruction */ + printf("INSN: %02x %02x %02x" + "(%02d %04d) : %.*s\n", + opc1, opc2 << 1, opc3, opc1, + (opc3 << 6) | (opc2 << 1), + (int)(p - handler->oname), + handler->oname); + } + if (strcmp(p + 1, q) != 0) { + /* Second instruction */ + printf("INSN: %02x %02x %02x " + "(%02d %04d) : %s\n", opc1, + (opc2 << 1) | 1, opc3, opc1, + (opc3 << 6) | (opc2 << 1) | 1, + p + 1); + } + } + } + } + } + } else { + if (handler->handler != &gen_invalid) { + printf("INSN: %02x %02x -- (%02d %04d) : %s\n", + opc1, opc2, opc1, opc2, handler->oname); + } + } + } + } else { + if (handler->handler != &gen_invalid) { + printf("INSN: %02x -- -- (%02d ----) : %s\n", + opc1, opc1, handler->oname); + } + } + } +} +#endif +int ppc_fixup_cpu(PowerPCCPU *cpu) +{ + CPUPPCState *env = &cpu->env; + + /* + * TCG doesn't (yet) emulate some groups of instructions that are + * implemented on some otherwise supported CPUs (e.g. VSX and + * decimal floating point instructions on POWER7). We remove + * unsupported instruction groups from the cpu state's instruction + * masks and hope the guest can cope. For at least the pseries + * machine, the unavailability of these instructions can be + * advertised to the guest via the device tree. + */ + if ((env->insns_flags & ~PPC_TCG_INSNS) + || (env->insns_flags2 & ~PPC_TCG_INSNS2)) { + warn_report("Disabling some instructions which are not " + "emulated by TCG (0x%" PRIx64 ", 0x%" PRIx64 ")", + env->insns_flags & ~PPC_TCG_INSNS, + env->insns_flags2 & ~PPC_TCG_INSNS2); + } + env->insns_flags &= PPC_TCG_INSNS; + env->insns_flags2 &= PPC_TCG_INSNS2; + return 0; +} + + void ppc_cpu_dump_statistics(CPUState *cs, int flags) { #if defined(DO_PPC_STATISTICS) diff --git a/target/ppc/translate_init.c.inc b/target/ppc/translate_init.c.inc index 9ab2c32cc4..42b3a4fd57 100644 --- a/target/ppc/translate_init.c.inc +++ b/target/ppc/translate_init.c.inc @@ -42,7 +42,6 @@ #include "fpu/softfloat.h" #include "qapi/qapi-commands-machine-target.h" -/* #define PPC_DUMP_CPU */ /* #define PPC_DEBUG_SPR */ /* #define PPC_DUMP_SPR_ACCESSES */ /* #define USE_APPLE_GDB */ @@ -9560,366 +9559,6 @@ static void dump_ppc_sprs(CPUPPCState *env) } #endif -/*****************************************************************************/ - -/* Opcode types */ -enum { - PPC_DIRECT = 0, /* Opcode routine */ - PPC_INDIRECT = 1, /* Indirect opcode table */ -}; - -#define PPC_OPCODE_MASK 0x3 - -static inline int is_indirect_opcode(void *handler) -{ - return ((uintptr_t)handler & PPC_OPCODE_MASK) == PPC_INDIRECT; -} - -static inline opc_handler_t **ind_table(void *handler) -{ - return (opc_handler_t **)((uintptr_t)handler & ~PPC_OPCODE_MASK); -} - -/* Instruction table creation */ -/* Opcodes tables creation */ -static void fill_new_table(opc_handler_t **table, int len) -{ - int i; - - for (i = 0; i < len; i++) { - table[i] = &invalid_handler; - } -} - -static int create_new_table(opc_handler_t **table, unsigned char idx) -{ - opc_handler_t **tmp; - - tmp = g_new(opc_handler_t *, PPC_CPU_INDIRECT_OPCODES_LEN); - fill_new_table(tmp, PPC_CPU_INDIRECT_OPCODES_LEN); - table[idx] = (opc_handler_t *)((uintptr_t)tmp | PPC_INDIRECT); - - return 0; -} - -static int insert_in_table(opc_handler_t **table, unsigned char idx, - opc_handler_t *handler) -{ - if (table[idx] != &invalid_handler) { - return -1; - } - table[idx] = handler; - - return 0; -} - -static int register_direct_insn(opc_handler_t **ppc_opcodes, - unsigned char idx, opc_handler_t *handler) -{ - if (insert_in_table(ppc_opcodes, idx, handler) < 0) { - printf("*** ERROR: opcode %02x already assigned in main " - "opcode table\n", idx); -#if defined(DO_PPC_STATISTICS) || defined(PPC_DUMP_CPU) - printf(" Registered handler '%s' - new handler '%s'\n", - ppc_opcodes[idx]->oname, handler->oname); -#endif - return -1; - } - - return 0; -} - -static int register_ind_in_table(opc_handler_t **table, - unsigned char idx1, unsigned char idx2, - opc_handler_t *handler) -{ - if (table[idx1] == &invalid_handler) { - if (create_new_table(table, idx1) < 0) { - printf("*** ERROR: unable to create indirect table " - "idx=%02x\n", idx1); - return -1; - } - } else { - if (!is_indirect_opcode(table[idx1])) { - printf("*** ERROR: idx %02x already assigned to a direct " - "opcode\n", idx1); -#if defined(DO_PPC_STATISTICS) || defined(PPC_DUMP_CPU) - printf(" Registered handler '%s' - new handler '%s'\n", - ind_table(table[idx1])[idx2]->oname, handler->oname); -#endif - return -1; - } - } - if (handler != NULL && - insert_in_table(ind_table(table[idx1]), idx2, handler) < 0) { - printf("*** ERROR: opcode %02x already assigned in " - "opcode table %02x\n", idx2, idx1); -#if defined(DO_PPC_STATISTICS) || defined(PPC_DUMP_CPU) - printf(" Registered handler '%s' - new handler '%s'\n", - ind_table(table[idx1])[idx2]->oname, handler->oname); -#endif - return -1; - } - - return 0; -} - -static int register_ind_insn(opc_handler_t **ppc_opcodes, - unsigned char idx1, unsigned char idx2, - opc_handler_t *handler) -{ - return register_ind_in_table(ppc_opcodes, idx1, idx2, handler); -} - -static int register_dblind_insn(opc_handler_t **ppc_opcodes, - unsigned char idx1, unsigned char idx2, - unsigned char idx3, opc_handler_t *handler) -{ - if (register_ind_in_table(ppc_opcodes, idx1, idx2, NULL) < 0) { - printf("*** ERROR: unable to join indirect table idx " - "[%02x-%02x]\n", idx1, idx2); - return -1; - } - if (register_ind_in_table(ind_table(ppc_opcodes[idx1]), idx2, idx3, - handler) < 0) { - printf("*** ERROR: unable to insert opcode " - "[%02x-%02x-%02x]\n", idx1, idx2, idx3); - return -1; - } - - return 0; -} - -static int register_trplind_insn(opc_handler_t **ppc_opcodes, - unsigned char idx1, unsigned char idx2, - unsigned char idx3, unsigned char idx4, - opc_handler_t *handler) -{ - opc_handler_t **table; - - if (register_ind_in_table(ppc_opcodes, idx1, idx2, NULL) < 0) { - printf("*** ERROR: unable to join indirect table idx " - "[%02x-%02x]\n", idx1, idx2); - return -1; - } - table = ind_table(ppc_opcodes[idx1]); - if (register_ind_in_table(table, idx2, idx3, NULL) < 0) { - printf("*** ERROR: unable to join 2nd-level indirect table idx " - "[%02x-%02x-%02x]\n", idx1, idx2, idx3); - return -1; - } - table = ind_table(table[idx2]); - if (register_ind_in_table(table, idx3, idx4, handler) < 0) { - printf("*** ERROR: unable to insert opcode " - "[%02x-%02x-%02x-%02x]\n", idx1, idx2, idx3, idx4); - return -1; - } - return 0; -} -static int register_insn(opc_handler_t **ppc_opcodes, opcode_t *insn) -{ - if (insn->opc2 != 0xFF) { - if (insn->opc3 != 0xFF) { - if (insn->opc4 != 0xFF) { - if (register_trplind_insn(ppc_opcodes, insn->opc1, insn->opc2, - insn->opc3, insn->opc4, - &insn->handler) < 0) { - return -1; - } - } else { - if (register_dblind_insn(ppc_opcodes, insn->opc1, insn->opc2, - insn->opc3, &insn->handler) < 0) { - return -1; - } - } - } else { - if (register_ind_insn(ppc_opcodes, insn->opc1, - insn->opc2, &insn->handler) < 0) { - return -1; - } - } - } else { - if (register_direct_insn(ppc_opcodes, insn->opc1, &insn->handler) < 0) { - return -1; - } - } - - return 0; -} - -static int test_opcode_table(opc_handler_t **table, int len) -{ - int i, count, tmp; - - for (i = 0, count = 0; i < len; i++) { - /* Consistency fixup */ - if (table[i] == NULL) { - table[i] = &invalid_handler; - } - if (table[i] != &invalid_handler) { - if (is_indirect_opcode(table[i])) { - tmp = test_opcode_table(ind_table(table[i]), - PPC_CPU_INDIRECT_OPCODES_LEN); - if (tmp == 0) { - free(table[i]); - table[i] = &invalid_handler; - } else { - count++; - } - } else { - count++; - } - } - } - - return count; -} - -static void fix_opcode_tables(opc_handler_t **ppc_opcodes) -{ - if (test_opcode_table(ppc_opcodes, PPC_CPU_OPCODES_LEN) == 0) { - printf("*** WARNING: no opcode defined !\n"); - } -} - -/*****************************************************************************/ -static void create_ppc_opcodes(PowerPCCPU *cpu, Error **errp) -{ - PowerPCCPUClass *pcc = POWERPC_CPU_GET_CLASS(cpu); - opcode_t *opc; - - fill_new_table(cpu->opcodes, PPC_CPU_OPCODES_LEN); - for (opc = opcodes; opc < &opcodes[ARRAY_SIZE(opcodes)]; opc++) { - if (((opc->handler.type & pcc->insns_flags) != 0) || - ((opc->handler.type2 & pcc->insns_flags2) != 0)) { - if (register_insn(cpu->opcodes, opc) < 0) { - error_setg(errp, "ERROR initializing PowerPC instruction " - "0x%02x 0x%02x 0x%02x", opc->opc1, opc->opc2, - opc->opc3); - return; - } - } - } - fix_opcode_tables(cpu->opcodes); - fflush(stdout); - fflush(stderr); -} - -#if defined(PPC_DUMP_CPU) -static void dump_ppc_insns(CPUPPCState *env) -{ - opc_handler_t **table, *handler; - const char *p, *q; - uint8_t opc1, opc2, opc3, opc4; - - printf("Instructions set:\n"); - /* opc1 is 6 bits long */ - for (opc1 = 0x00; opc1 < PPC_CPU_OPCODES_LEN; opc1++) { - table = env->opcodes; - handler = table[opc1]; - if (is_indirect_opcode(handler)) { - /* opc2 is 5 bits long */ - for (opc2 = 0; opc2 < PPC_CPU_INDIRECT_OPCODES_LEN; opc2++) { - table = env->opcodes; - handler = env->opcodes[opc1]; - table = ind_table(handler); - handler = table[opc2]; - if (is_indirect_opcode(handler)) { - table = ind_table(handler); - /* opc3 is 5 bits long */ - for (opc3 = 0; opc3 < PPC_CPU_INDIRECT_OPCODES_LEN; - opc3++) { - handler = table[opc3]; - if (is_indirect_opcode(handler)) { - table = ind_table(handler); - /* opc4 is 5 bits long */ - for (opc4 = 0; opc4 < PPC_CPU_INDIRECT_OPCODES_LEN; - opc4++) { - handler = table[opc4]; - if (handler->handler != &gen_invalid) { - printf("INSN: %02x %02x %02x %02x -- " - "(%02d %04d %02d) : %s\n", - opc1, opc2, opc3, opc4, - opc1, (opc3 << 5) | opc2, opc4, - handler->oname); - } - } - } else { - if (handler->handler != &gen_invalid) { - /* Special hack to properly dump SPE insns */ - p = strchr(handler->oname, '_'); - if (p == NULL) { - printf("INSN: %02x %02x %02x (%02d %04d) : " - "%s\n", - opc1, opc2, opc3, opc1, - (opc3 << 5) | opc2, - handler->oname); - } else { - q = "speundef"; - if ((p - handler->oname) != strlen(q) - || (memcmp(handler->oname, q, strlen(q)) - != 0)) { - /* First instruction */ - printf("INSN: %02x %02x %02x" - "(%02d %04d) : %.*s\n", - opc1, opc2 << 1, opc3, opc1, - (opc3 << 6) | (opc2 << 1), - (int)(p - handler->oname), - handler->oname); - } - if (strcmp(p + 1, q) != 0) { - /* Second instruction */ - printf("INSN: %02x %02x %02x " - "(%02d %04d) : %s\n", opc1, - (opc2 << 1) | 1, opc3, opc1, - (opc3 << 6) | (opc2 << 1) | 1, - p + 1); - } - } - } - } - } - } else { - if (handler->handler != &gen_invalid) { - printf("INSN: %02x %02x -- (%02d %04d) : %s\n", - opc1, opc2, opc1, opc2, handler->oname); - } - } - } - } else { - if (handler->handler != &gen_invalid) { - printf("INSN: %02x -- -- (%02d ----) : %s\n", - opc1, opc1, handler->oname); - } - } - } -} -#endif -static int ppc_fixup_cpu(PowerPCCPU *cpu) -{ - CPUPPCState *env = &cpu->env; - - /* - * TCG doesn't (yet) emulate some groups of instructions that are - * implemented on some otherwise supported CPUs (e.g. VSX and - * decimal floating point instructions on POWER7). We remove - * unsupported instruction groups from the cpu state's instruction - * masks and hope the guest can cope. For at least the pseries - * machine, the unavailability of these instructions can be - * advertised to the guest via the device tree. - */ - if ((env->insns_flags & ~PPC_TCG_INSNS) - || (env->insns_flags2 & ~PPC_TCG_INSNS2)) { - warn_report("Disabling some instructions which are not " - "emulated by TCG (0x%" PRIx64 ", 0x%" PRIx64 ")", - env->insns_flags & ~PPC_TCG_INSNS, - env->insns_flags2 & ~PPC_TCG_INSNS2); - } - env->insns_flags &= PPC_TCG_INSNS; - env->insns_flags2 &= PPC_TCG_INSNS2; - return 0; -} - static void ppc_cpu_realize(DeviceState *dev, Error **errp) { CPUState *cs = CPU(dev); @@ -10131,40 +9770,12 @@ static void ppc_cpu_unrealize(DeviceState *dev) { PowerPCCPU *cpu = POWERPC_CPU(dev); PowerPCCPUClass *pcc = POWERPC_CPU_GET_CLASS(cpu); - opc_handler_t **table, **table_2; - int i, j, k; pcc->parent_unrealize(dev); cpu_remove_sync(CPU(cpu)); - for (i = 0; i < PPC_CPU_OPCODES_LEN; i++) { - if (cpu->opcodes[i] == &invalid_handler) { - continue; - } - if (is_indirect_opcode(cpu->opcodes[i])) { - table = ind_table(cpu->opcodes[i]); - for (j = 0; j < PPC_CPU_INDIRECT_OPCODES_LEN; j++) { - if (table[j] == &invalid_handler) { - continue; - } - if (is_indirect_opcode(table[j])) { - table_2 = ind_table(table[j]); - for (k = 0; k < PPC_CPU_INDIRECT_OPCODES_LEN; k++) { - if (table_2[k] != &invalid_handler && - is_indirect_opcode(table_2[k])) { - g_free((opc_handler_t *)((uintptr_t)table_2[k] & - ~PPC_INDIRECT)); - } - } - g_free((opc_handler_t *)((uintptr_t)table[j] & - ~PPC_INDIRECT)); - } - } - g_free((opc_handler_t *)((uintptr_t)cpu->opcodes[i] & - ~PPC_INDIRECT)); - } - } + destroy_ppc_opcodes(cpu); } static gint ppc_cpu_compare_class_pvr(gconstpointer a, gconstpointer b) From patchwork Tue May 4 05:53:05 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: David Gibson X-Patchwork-Id: 12237503 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-16.6 required=3.0 tests=BAYES_00,DKIM_INVALID, DKIM_SIGNED,HEADER_FROM_DIFFERENT_DOMAINS,INCLUDES_CR_TRAILER,INCLUDES_PATCH, MAILING_LIST_MULTI,SPF_HELO_NONE,SPF_PASS,USER_AGENT_GIT autolearn=ham autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id 4FE3AC433ED for ; Tue, 4 May 2021 06:45:49 +0000 (UTC) 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 mail.kernel.org (Postfix) with ESMTPS id AD231610A6 for ; Tue, 4 May 2021 06:45:48 +0000 (UTC) DMARC-Filter: OpenDMARC Filter v1.3.2 mail.kernel.org AD231610A6 Authentication-Results: mail.kernel.org; dmarc=none (p=none dis=none) header.from=gibson.dropbear.id.au Authentication-Results: mail.kernel.org; spf=pass smtp.mailfrom=qemu-devel-bounces+qemu-devel=archiver.kernel.org@nongnu.org Received: from localhost ([::1]:38536 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1ldooV-0001TT-Jf for qemu-devel@archiver.kernel.org; Tue, 04 May 2021 02:45:47 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]:60880) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1ldo0z-0006gm-5z; Tue, 04 May 2021 01:54:37 -0400 Received: from ozlabs.org ([2401:3900:2:1::2]:49855) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1ldo0w-0005A9-3i; Tue, 04 May 2021 01:54:36 -0400 Received: by ozlabs.org (Postfix, from userid 1007) id 4FZ8CP319Gz9t0p; Tue, 4 May 2021 15:53:21 +1000 (AEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=gibson.dropbear.id.au; s=201602; t=1620107601; bh=QR2zcAf6goM5WAwuXHkSFi0GzTiS9Ue5wHyMsGgu9Vk=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=jmInMLY8K9bH1wnMoJ51iDm7nU0nwM6xc/gPHPnKAo4ObNqr/cDD6jWBYxs+dsazV 1e2USJx1a9cOi0GCv8FDH3eK7S2viFO76nZpPCezdBuXz7Ra/QMkeZ65APs0MDZ0VL KEp/PDfo2yrRYLQhhXDllgyHPiw7U+FR2f7OVMLw= From: David Gibson To: peter.maydell@linaro.org, groug@kaod.org Subject: [PULL 39/46] target/ppc: rework AIL logic in interrupt delivery Date: Tue, 4 May 2021 15:53:05 +1000 Message-Id: <20210504055312.306823-40-david@gibson.dropbear.id.au> X-Mailer: git-send-email 2.31.1 In-Reply-To: <20210504055312.306823-1-david@gibson.dropbear.id.au> References: <20210504055312.306823-1-david@gibson.dropbear.id.au> MIME-Version: 1.0 Received-SPF: pass client-ip=2401:3900:2:1::2; envelope-from=dgibson@ozlabs.org; helo=ozlabs.org X-Spam_score_int: -17 X-Spam_score: -1.8 X-Spam_bar: - X-Spam_report: (-1.8 / 5.0 requ) BAYES_00=-1.9, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_AU=-0.1, HEADER_FROM_DIFFERENT_DOMAINS=0.25, SPF_HELO_PASS=-0.001, SPF_PASS=-0.001 autolearn=no autolearn_force=no X-Spam_action: no action X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: David Gibson , qemu-ppc@nongnu.org, qemu-devel@nongnu.org, Nicholas Piggin , =?utf-8?q?C?= =?utf-8?q?=C3=A9dric_Le_Goater?= Errors-To: qemu-devel-bounces+qemu-devel=archiver.kernel.org@nongnu.org Sender: "Qemu-devel" From: Nicholas Piggin The AIL logic is becoming unmanageable spread all over powerpc_excp(), and it is slated to get even worse with POWER10 support. Move it all to a new helper function. Reviewed-by: Cédric Le Goater Tested-by: Cédric Le Goater Signed-off-by: Nicholas Piggin Message-Id: <20210501072436.145444-2-npiggin@gmail.com> [dwg: Corrected tab indenting] Signed-off-by: David Gibson --- hw/ppc/spapr_hcall.c | 3 +- target/ppc/cpu.h | 8 -- target/ppc/excp_helper.c | 165 ++++++++++++++++++++------------ target/ppc/translate_init.c.inc | 2 +- 4 files changed, 108 insertions(+), 70 deletions(-) diff --git a/hw/ppc/spapr_hcall.c b/hw/ppc/spapr_hcall.c index 7b5cd3553c..2fbe04a689 100644 --- a/hw/ppc/spapr_hcall.c +++ b/hw/ppc/spapr_hcall.c @@ -1395,7 +1395,8 @@ static target_ulong h_set_mode_resource_addr_trans_mode(PowerPCCPU *cpu, return H_P4; } - if (mflags == AIL_RESERVED) { + if (mflags == 1) { + /* AIL=1 is reserved */ return H_UNSUPPORTED_FLAG; } diff --git a/target/ppc/cpu.h b/target/ppc/cpu.h index 8c18bb0762..be24a501fc 100644 --- a/target/ppc/cpu.h +++ b/target/ppc/cpu.h @@ -2405,14 +2405,6 @@ enum { HMER_XSCOM_STATUS_MASK = PPC_BITMASK(21, 23), }; -/* Alternate Interrupt Location (AIL) */ -enum { - AIL_NONE = 0, - AIL_RESERVED = 1, - AIL_0001_8000 = 2, - AIL_C000_0000_0000_4000 = 3, -}; - /*****************************************************************************/ #define is_isa300(ctx) (!!(ctx->insns_flags2 & PPC2_ISA300)) diff --git a/target/ppc/excp_helper.c b/target/ppc/excp_helper.c index 344af66f66..15b2813253 100644 --- a/target/ppc/excp_helper.c +++ b/target/ppc/excp_helper.c @@ -136,25 +136,111 @@ static int powerpc_reset_wakeup(CPUState *cs, CPUPPCState *env, int excp, return POWERPC_EXCP_RESET; } -static uint64_t ppc_excp_vector_offset(CPUState *cs, int ail) +/* + * 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. + */ +static inline void ppc_excp_apply_ail(PowerPCCPU *cpu, int excp_model, int excp, + target_ulong msr, + target_ulong *new_msr, + target_ulong *vector) { - uint64_t offset = 0; +#if defined(TARGET_PPC64) + CPUPPCState *env = &cpu->env; + bool mmu_all_on = ((msr >> MSR_IR) & 1) && ((msr >> MSR_DR) & 1); + bool hv_escalation = !(msr & MSR_HVB) && (*new_msr & MSR_HVB); + int ail = 0; + + if (excp == POWERPC_EXCP_MCHECK || + excp == POWERPC_EXCP_RESET || + excp == POWERPC_EXCP_HV_MAINT) { + /* SRESET, MCE, HMI never apply AIL */ + return; + } - switch (ail) { - case AIL_NONE: - break; - case AIL_0001_8000: - offset = 0x18000; - break; - case AIL_C000_0000_0000_4000: - offset = 0xc000000000004000ull; - break; - default: - cpu_abort(cs, "Invalid AIL combination %d\n", ail); - break; + if (excp_model == POWERPC_EXCP_POWER8 || + excp_model == POWERPC_EXCP_POWER9) { + if (!mmu_all_on) { + /* AIL only works if MSR[IR] and MSR[DR] are both enabled. */ + return; + } + if (hv_escalation && !(env->spr[SPR_LPCR] & LPCR_HR)) { + /* + * AIL does not work if there is a MSR[HV] 0->1 transition and the + * partition is in HPT mode. For radix guests, such interrupts are + * allowed to be delivered to the hypervisor in ail mode. + */ + return; + } + + ail = (env->spr[SPR_LPCR] & LPCR_AIL) >> LPCR_AIL_SHIFT; + if (ail == 0) { + return; + } + if (ail == 1) { + /* AIL=1 is reserved, treat it like AIL=0 */ + return; + } + } else { + /* Other processors do not support AIL */ + return; } - return offset; + /* + * 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 } static inline void powerpc_set_excp_state(PowerPCCPU *cpu, @@ -197,7 +283,7 @@ static inline void powerpc_excp(PowerPCCPU *cpu, int excp_model, int excp) CPUState *cs = CPU(cpu); CPUPPCState *env = &cpu->env; target_ulong msr, new_msr, vector; - int srr0, srr1, asrr0, asrr1, lev = -1, ail; + int srr0, srr1, asrr0, asrr1, lev = -1; bool lpes0; qemu_log_mask(CPU_LOG_INT, "Raise exception at " TARGET_FMT_lx @@ -238,25 +324,16 @@ static inline void powerpc_excp(PowerPCCPU *cpu, int excp_model, int excp) * * On anything else, we behave as if LPES0 is 1 * (externals don't alter MSR:HV) - * - * AIL is initialized here but can be cleared by - * selected exceptions */ #if defined(TARGET_PPC64) if (excp_model == POWERPC_EXCP_POWER7 || excp_model == POWERPC_EXCP_POWER8 || excp_model == POWERPC_EXCP_POWER9) { lpes0 = !!(env->spr[SPR_LPCR] & LPCR_LPES0); - if (excp_model != POWERPC_EXCP_POWER7) { - ail = (env->spr[SPR_LPCR] & LPCR_AIL) >> LPCR_AIL_SHIFT; - } else { - ail = 0; - } } else #endif /* defined(TARGET_PPC64) */ { lpes0 = true; - ail = 0; } /* @@ -315,7 +392,6 @@ static inline void powerpc_excp(PowerPCCPU *cpu, int excp_model, int excp) */ new_msr |= (target_ulong)MSR_HVB; } - ail = 0; /* machine check exceptions don't have ME set */ new_msr &= ~((target_ulong)1 << MSR_ME); @@ -519,7 +595,6 @@ static inline void powerpc_excp(PowerPCCPU *cpu, int excp_model, int excp) "exception %d with no HV support\n", excp); } } - ail = 0; break; case POWERPC_EXCP_DSEG: /* Data segment exception */ case POWERPC_EXCP_ISEG: /* Instruction segment exception */ @@ -790,24 +865,6 @@ static inline void powerpc_excp(PowerPCCPU *cpu, int excp_model, int excp) } #endif - /* - * AIL only works if MSR[IR] and MSR[DR] are both enabled. - */ - if (!((msr >> MSR_IR) & 1) || !((msr >> MSR_DR) & 1)) { - ail = 0; - } - - /* - * 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. - */ - if ((new_msr & MSR_HVB) && !(msr & MSR_HVB)) { - if (!(env->spr[SPR_LPCR] & LPCR_HR)) { - ail = 0; - } - } - vector = env->excp_vectors[excp]; if (vector == (target_ulong)-1ULL) { cpu_abort(cs, "Raised an exception without defined vector %d\n", @@ -848,23 +905,8 @@ static inline void powerpc_excp(PowerPCCPU *cpu, int excp_model, int excp) /* Save MSR */ env->spr[srr1] = msr; - /* Handle AIL */ - if (ail) { - new_msr |= (1 << MSR_IR) | (1 << MSR_DR); - vector |= ppc_excp_vector_offset(cs, ail); - } - #if defined(TARGET_PPC64) } else { - /* scv AIL is a little different */ - if (ail) { - new_msr |= (1 << MSR_IR) | (1 << MSR_DR); - } - if (ail == AIL_C000_0000_0000_4000) { - vector |= 0xc000000000003000ull; - } else { - vector |= 0x0000000000017000ull; - } vector += lev * 0x20; env->lr = env->nip; @@ -872,6 +914,9 @@ static inline void powerpc_excp(PowerPCCPU *cpu, int excp_model, int excp) #endif } + /* This can update new_msr and vector if AIL applies */ + ppc_excp_apply_ail(cpu, excp_model, excp, msr, &new_msr, &vector); + powerpc_set_excp_state(cpu, vector, new_msr); } diff --git a/target/ppc/translate_init.c.inc b/target/ppc/translate_init.c.inc index 42b3a4fd57..65906c7e6d 100644 --- a/target/ppc/translate_init.c.inc +++ b/target/ppc/translate_init.c.inc @@ -3456,7 +3456,7 @@ static void init_excp_POWER9(CPUPPCState *env) #if !defined(CONFIG_USER_ONLY) env->excp_vectors[POWERPC_EXCP_HVIRT] = 0x00000EA0; - env->excp_vectors[POWERPC_EXCP_SYSCALL_VECTORED] = 0x00000000; + env->excp_vectors[POWERPC_EXCP_SYSCALL_VECTORED] = 0x00017000; #endif } From patchwork Tue May 4 05:53:06 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: David Gibson X-Patchwork-Id: 12237507 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-16.6 required=3.0 tests=BAYES_00,DKIM_INVALID, DKIM_SIGNED,HEADER_FROM_DIFFERENT_DOMAINS,INCLUDES_CR_TRAILER,INCLUDES_PATCH, MAILING_LIST_MULTI,SPF_HELO_NONE,SPF_PASS,USER_AGENT_GIT autolearn=ham autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id AAC64C433ED for ; Tue, 4 May 2021 06:49:01 +0000 (UTC) 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 mail.kernel.org (Postfix) with ESMTPS id 369D1613B3 for ; Tue, 4 May 2021 06:49:01 +0000 (UTC) DMARC-Filter: OpenDMARC Filter v1.3.2 mail.kernel.org 369D1613B3 Authentication-Results: mail.kernel.org; dmarc=none (p=none dis=none) header.from=gibson.dropbear.id.au Authentication-Results: mail.kernel.org; spf=pass smtp.mailfrom=qemu-devel-bounces+qemu-devel=archiver.kernel.org@nongnu.org Received: from localhost ([::1]:46614 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1ldorc-00050p-Bu for qemu-devel@archiver.kernel.org; Tue, 04 May 2021 02:49:00 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]:60906) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1ldo11-0006jL-EY; Tue, 04 May 2021 01:54:39 -0400 Received: from ozlabs.org ([203.11.71.1]:44035) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1ldo0x-0005B8-MH; Tue, 04 May 2021 01:54:38 -0400 Received: by ozlabs.org (Postfix, from userid 1007) id 4FZ8CP4lZgz9t10; Tue, 4 May 2021 15:53:21 +1000 (AEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=gibson.dropbear.id.au; s=201602; t=1620107601; bh=7s0wh9A/59HjPU6V9IWuN3aCWuxXIcM4WxtwCSfx7ug=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=kavHcnSrRl6F+mheeXclQ6DyAgqUnxactHqVL/9ZCbOi6cYutHwYpzELZlxODxgqu uryO3vCBVaekViAiJnhIAI+Ta+tSyj8LYmOcsxqbc7IsW8tTjLI1UiF6DDBHyhPHiw +d0m2quiT7I0LC4p6IUo/d3poC/vF197uRdUE/N4= From: David Gibson To: peter.maydell@linaro.org, groug@kaod.org Subject: [PULL 40/46] target/ppc: Add POWER10 exception model Date: Tue, 4 May 2021 15:53:06 +1000 Message-Id: <20210504055312.306823-41-david@gibson.dropbear.id.au> X-Mailer: git-send-email 2.31.1 In-Reply-To: <20210504055312.306823-1-david@gibson.dropbear.id.au> References: <20210504055312.306823-1-david@gibson.dropbear.id.au> MIME-Version: 1.0 Received-SPF: pass client-ip=203.11.71.1; envelope-from=dgibson@ozlabs.org; helo=ozlabs.org X-Spam_score_int: -17 X-Spam_score: -1.8 X-Spam_bar: - X-Spam_report: (-1.8 / 5.0 requ) BAYES_00=-1.9, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_AU=-0.1, HEADER_FROM_DIFFERENT_DOMAINS=0.25, SPF_HELO_PASS=-0.001, SPF_PASS=-0.001 autolearn=no autolearn_force=no X-Spam_action: no action X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: David Gibson , qemu-ppc@nongnu.org, qemu-devel@nongnu.org, Nicholas Piggin , =?utf-8?q?C?= =?utf-8?q?=C3=A9dric_Le_Goater?= Errors-To: qemu-devel-bounces+qemu-devel=archiver.kernel.org@nongnu.org Sender: "Qemu-devel" From: Nicholas Piggin POWER10 adds a new bit that modifies interrupt behaviour, LPCR[HAIL], and it removes support for the LPCR[AIL]=0b10 mode. Reviewed-by: Cédric Le Goater Tested-by: Cédric Le Goater Signed-off-by: Nicholas Piggin Message-Id: <20210501072436.145444-3-npiggin@gmail.com> [dwg: Corrected tab indenting] Signed-off-by: David Gibson --- hw/ppc/spapr_hcall.c | 7 ++++- target/ppc/cpu-qom.h | 2 ++ target/ppc/cpu.h | 5 +-- target/ppc/excp_helper.c | 54 +++++++++++++++++++++++++++++++-- target/ppc/translate.c | 3 +- target/ppc/translate_init.c.inc | 2 +- 6 files changed, 65 insertions(+), 8 deletions(-) diff --git a/hw/ppc/spapr_hcall.c b/hw/ppc/spapr_hcall.c index 2fbe04a689..7275d0bba1 100644 --- a/hw/ppc/spapr_hcall.c +++ b/hw/ppc/spapr_hcall.c @@ -1396,7 +1396,12 @@ static target_ulong h_set_mode_resource_addr_trans_mode(PowerPCCPU *cpu, } if (mflags == 1) { - /* AIL=1 is reserved */ + /* AIL=1 is reserved in POWER8/POWER9/POWER10 */ + return H_UNSUPPORTED_FLAG; + } + + if (mflags == 2 && (pcc->insns_flags2 & PPC2_ISA310)) { + /* AIL=2 is reserved in POWER10 (ISA v3.1) */ return H_UNSUPPORTED_FLAG; } diff --git a/target/ppc/cpu-qom.h b/target/ppc/cpu-qom.h index 118baf8d41..06b6571bc9 100644 --- a/target/ppc/cpu-qom.h +++ b/target/ppc/cpu-qom.h @@ -116,6 +116,8 @@ enum powerpc_excp_t { POWERPC_EXCP_POWER8, /* POWER9 exception model */ POWERPC_EXCP_POWER9, + /* POWER10 exception model */ + POWERPC_EXCP_POWER10, }; /*****************************************************************************/ diff --git a/target/ppc/cpu.h b/target/ppc/cpu.h index be24a501fc..8a076fab48 100644 --- a/target/ppc/cpu.h +++ b/target/ppc/cpu.h @@ -354,10 +354,11 @@ typedef struct ppc_v3_pate_t { #define LPCR_PECE_U_SHIFT (63 - 19) #define LPCR_PECE_U_MASK (0x7ull << LPCR_PECE_U_SHIFT) #define LPCR_HVEE PPC_BIT(17) /* Hypervisor Virt Exit Enable */ -#define LPCR_RMLS_SHIFT (63 - 37) +#define LPCR_RMLS_SHIFT (63 - 37) /* RMLS (removed in ISA v3.0) */ #define LPCR_RMLS (0xfull << LPCR_RMLS_SHIFT) +#define LPCR_HAIL PPC_BIT(37) /* ISA v3.1 HV AIL=3 equivalent */ #define LPCR_ILE PPC_BIT(38) -#define LPCR_AIL_SHIFT (63 - 40) /* Alternate interrupt location */ +#define LPCR_AIL_SHIFT (63 - 40) /* Alternate interrupt location */ #define LPCR_AIL (3ull << LPCR_AIL_SHIFT) #define LPCR_UPRT PPC_BIT(41) /* Use Process Table */ #define LPCR_EVIRT PPC_BIT(42) /* Enhanced Virtualisation */ diff --git a/target/ppc/excp_helper.c b/target/ppc/excp_helper.c index 15b2813253..f4f15279eb 100644 --- a/target/ppc/excp_helper.c +++ b/target/ppc/excp_helper.c @@ -170,7 +170,27 @@ static int powerpc_reset_wakeup(CPUState *cs, CPUPPCState *env, int excp, * +-------------------------------------------------------+ * * 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. + * the hypervisor in AIL mode if the guest is radix. This is good for + * performance but allows the guest to influence the AIL of hypervisor + * interrupts using its MSR, and also the hypervisor must disallow guest + * interrupts (MSR[HV] 0->0) from using AIL if the hypervisor does not want to + * use AIL for its MSR[HV] 0->1 interrupts. + * + * POWER10 addresses those issues with a new LPCR[HAIL] bit that is applied to + * interrupts that begin execution with MSR[HV]=1 (so both MSR[HV] 0->1 and + * MSR[HV] 1->1). + * + * HAIL=1 is equivalent to AIL=3, for interrupts delivered with MSR[HV]=1. + * + * POWER10 behaviour is + * | LPCR[AIL] | LPCR[HAIL] | MSR[IR||DR] | MSR[HV] | new MSR[HV] | AIL | + * +-----------+------------+-------------+---------+-------------+-----+ + * | a | h | 00/01/10 | 0 | 0 | 0 | + * | a | h | 11 | 0 | 0 | a | + * | a | h | x | 0 | 1 | h | + * | a | h | 00/01/10 | 1 | 1 | 0 | + * | a | h | 11 | 1 | 1 | h | + * +--------------------------------------------------------------------+ */ static inline void ppc_excp_apply_ail(PowerPCCPU *cpu, int excp_model, int excp, target_ulong msr, @@ -213,6 +233,32 @@ static inline void ppc_excp_apply_ail(PowerPCCPU *cpu, int excp_model, int excp, /* AIL=1 is reserved, treat it like AIL=0 */ return; } + + } else if (excp_model == POWERPC_EXCP_POWER10) { + if (!mmu_all_on && !hv_escalation) { + /* + * AIL works for HV interrupts even with guest MSR[IR/DR] disabled. + * Guest->guest and HV->HV interrupts do require MMU on. + */ + return; + } + + if (*new_msr & MSR_HVB) { + if (!(env->spr[SPR_LPCR] & LPCR_HAIL)) { + /* HV interrupts depend on LPCR[HAIL] */ + return; + } + ail = 3; /* HAIL=1 gives AIL=3 behaviour for HV interrupts */ + } else { + ail = (env->spr[SPR_LPCR] & LPCR_AIL) >> LPCR_AIL_SHIFT; + } + if (ail == 0) { + return; + } + if (ail == 1 || ail == 2) { + /* AIL=1 and AIL=2 are reserved, treat them like AIL=0 */ + return; + } } else { /* Other processors do not support AIL */ return; @@ -328,7 +374,8 @@ static inline void powerpc_excp(PowerPCCPU *cpu, int excp_model, int excp) #if defined(TARGET_PPC64) if (excp_model == POWERPC_EXCP_POWER7 || excp_model == POWERPC_EXCP_POWER8 || - excp_model == POWERPC_EXCP_POWER9) { + excp_model == POWERPC_EXCP_POWER9 || + excp_model == POWERPC_EXCP_POWER10) { lpes0 = !!(env->spr[SPR_LPCR] & LPCR_LPES0); } else #endif /* defined(TARGET_PPC64) */ @@ -848,7 +895,8 @@ static inline void powerpc_excp(PowerPCCPU *cpu, int excp_model, int excp) } else if (env->spr[SPR_LPCR] & LPCR_ILE) { new_msr |= (target_ulong)1 << MSR_LE; } - } else if (excp_model == POWERPC_EXCP_POWER9) { + } else if (excp_model == POWERPC_EXCP_POWER9 || + excp_model == POWERPC_EXCP_POWER10) { if (new_msr & MSR_HVB) { if (env->spr[SPR_HID0] & HID0_POWER9_HILE) { new_msr |= (target_ulong)1 << MSR_LE; diff --git a/target/ppc/translate.c b/target/ppc/translate.c index a7c568ca9c..a6381208a5 100644 --- a/target/ppc/translate.c +++ b/target/ppc/translate.c @@ -7731,7 +7731,8 @@ void ppc_cpu_dump_state(CPUState *cs, FILE *f, int flags) #if defined(TARGET_PPC64) if (env->excp_model == POWERPC_EXCP_POWER7 || env->excp_model == POWERPC_EXCP_POWER8 || - env->excp_model == POWERPC_EXCP_POWER9) { + env->excp_model == POWERPC_EXCP_POWER9 || + env->excp_model == POWERPC_EXCP_POWER10) { qemu_fprintf(f, "HSRR0 " TARGET_FMT_lx " HSRR1 " TARGET_FMT_lx "\n", env->spr[SPR_HSRR0], env->spr[SPR_HSRR1]); } diff --git a/target/ppc/translate_init.c.inc b/target/ppc/translate_init.c.inc index 65906c7e6d..f92656b2f2 100644 --- a/target/ppc/translate_init.c.inc +++ b/target/ppc/translate_init.c.inc @@ -9316,7 +9316,7 @@ POWERPC_FAMILY(POWER10)(ObjectClass *oc, void *data) pcc->radix_page_info = &POWER10_radix_page_info; pcc->lrg_decr_bits = 56; #endif - pcc->excp_model = POWERPC_EXCP_POWER9; + 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 | From patchwork Tue May 4 05:53:07 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: David Gibson X-Patchwork-Id: 12237515 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-16.6 required=3.0 tests=BAYES_00,DKIM_INVALID, DKIM_SIGNED,HEADER_FROM_DIFFERENT_DOMAINS,INCLUDES_CR_TRAILER,INCLUDES_PATCH, MAILING_LIST_MULTI,SPF_HELO_NONE,SPF_PASS,USER_AGENT_GIT autolearn=ham autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id EE8F4C433ED for ; Tue, 4 May 2021 06:54:26 +0000 (UTC) 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 mail.kernel.org (Postfix) with ESMTPS id 54404613B3 for ; Tue, 4 May 2021 06:54:26 +0000 (UTC) DMARC-Filter: OpenDMARC Filter v1.3.2 mail.kernel.org 54404613B3 Authentication-Results: mail.kernel.org; dmarc=none (p=none dis=none) header.from=gibson.dropbear.id.au Authentication-Results: mail.kernel.org; spf=pass smtp.mailfrom=qemu-devel-bounces+qemu-devel=archiver.kernel.org@nongnu.org Received: from localhost ([::1]:59380 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1ldowr-0002QZ-Dw for qemu-devel@archiver.kernel.org; Tue, 04 May 2021 02:54:25 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]:60940) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1ldo16-0006oK-Ft; Tue, 04 May 2021 01:54:45 -0400 Received: from bilbo.ozlabs.org ([2401:3900:2:1::2]:44789 helo=ozlabs.org) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1ldo13-0005EE-Iv; Tue, 04 May 2021 01:54:44 -0400 Received: by ozlabs.org (Postfix, from userid 1007) id 4FZ8CP65Xnz9t14; Tue, 4 May 2021 15:53:21 +1000 (AEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=gibson.dropbear.id.au; s=201602; t=1620107601; bh=lUbT/DZcYFCJPzC2E2B5W4lA3dAQag7zWEMrPssETfQ=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=GBwhDkUtUd3A4KGb6Ht2V2sqNxs0GDZ6F4j2grs1H1SIRme67Qyiapk25baerH1fM XDgnwvmsYMx/7x7C1OEljb4nn1G0zmGGl+gCzbQpTBborZ+f5celHsfAFRANZcBoF2 Z+ZhECR/YBDius31r/PDkA6LhOJMhiswHHWP7znk= From: David Gibson To: peter.maydell@linaro.org, groug@kaod.org Subject: [PULL 41/46] target/ppc: Clean up _spr_register et al Date: Tue, 4 May 2021 15:53:07 +1000 Message-Id: <20210504055312.306823-42-david@gibson.dropbear.id.au> X-Mailer: git-send-email 2.31.1 In-Reply-To: <20210504055312.306823-1-david@gibson.dropbear.id.au> References: <20210504055312.306823-1-david@gibson.dropbear.id.au> MIME-Version: 1.0 Received-SPF: pass client-ip=2401:3900:2:1::2; envelope-from=dgibson@ozlabs.org; helo=ozlabs.org X-Spam_score_int: -17 X-Spam_score: -1.8 X-Spam_bar: - X-Spam_report: (-1.8 / 5.0 requ) BAYES_00=-1.9, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_AU=-0.1, HEADER_FROM_DIFFERENT_DOMAINS=0.25, SPF_HELO_PASS=-0.001, SPF_PASS=-0.001 autolearn=no autolearn_force=no X-Spam_action: no action X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: Richard Henderson , qemu-ppc@nongnu.org, qemu-devel@nongnu.org, David Gibson Errors-To: qemu-devel-bounces+qemu-devel=archiver.kernel.org@nongnu.org Sender: "Qemu-devel" From: Richard Henderson Introduce 3 helper macros to elide arguments that we cannot supply. This reduces the repetition required to get the job done. Signed-off-by: Richard Henderson Message-Id: <20210501022923.1179736-2-richard.henderson@linaro.org> Signed-off-by: David Gibson --- target/ppc/translate_init.c.inc | 158 +++++++++++++++----------------- 1 file changed, 76 insertions(+), 82 deletions(-) diff --git a/target/ppc/translate_init.c.inc b/target/ppc/translate_init.c.inc index f92656b2f2..5cee94f16d 100644 --- a/target/ppc/translate_init.c.inc +++ b/target/ppc/translate_init.c.inc @@ -720,103 +720,97 @@ static inline void vscr_init(CPUPPCState *env, uint32_t val) helper_mtvscr(env, val); } -#ifdef CONFIG_USER_ONLY -#define spr_register_kvm(env, num, name, uea_read, uea_write, \ - oea_read, oea_write, one_reg_id, initial_value) \ - _spr_register(env, num, name, uea_read, uea_write, initial_value) -#define spr_register_kvm_hv(env, num, name, uea_read, uea_write, \ - oea_read, oea_write, hea_read, hea_write, \ - one_reg_id, initial_value) \ - _spr_register(env, num, name, uea_read, uea_write, initial_value) -#else -#if !defined(CONFIG_KVM) -#define spr_register_kvm(env, num, name, uea_read, uea_write, \ - oea_read, oea_write, one_reg_id, initial_value) \ - _spr_register(env, num, name, uea_read, uea_write, \ - oea_read, oea_write, oea_read, oea_write, initial_value) -#define spr_register_kvm_hv(env, num, name, uea_read, uea_write, \ - oea_read, oea_write, hea_read, hea_write, \ - one_reg_id, initial_value) \ - _spr_register(env, num, name, uea_read, uea_write, \ - oea_read, oea_write, hea_read, hea_write, initial_value) +/** + * _spr_register + * + * Register an SPR with all the callbacks required for tcg, + * and the ID number for KVM. + * + * The reason for the conditional compilation is that the tcg functions + * may be compiled out, and the system kvm header may not be available + * for supplying the ID numbers. This is ugly, but the best we can do. + */ + +#ifdef CONFIG_TCG +# define USR_ARG(X) X, +# ifdef CONFIG_USER_ONLY +# define SYS_ARG(X) +# else +# define SYS_ARG(X) X, +# endif #else -#define spr_register_kvm(env, num, name, uea_read, uea_write, \ - oea_read, oea_write, one_reg_id, initial_value) \ - _spr_register(env, num, name, uea_read, uea_write, \ - oea_read, oea_write, oea_read, oea_write, \ - one_reg_id, initial_value) -#define spr_register_kvm_hv(env, num, name, uea_read, uea_write, \ - oea_read, oea_write, hea_read, hea_write, \ - one_reg_id, initial_value) \ - _spr_register(env, num, name, uea_read, uea_write, \ - oea_read, oea_write, hea_read, hea_write, \ - one_reg_id, initial_value) +# define USR_ARG(X) +# define SYS_ARG(X) #endif +#ifdef CONFIG_KVM +# define KVM_ARG(X) X, +#else +# define KVM_ARG(X) #endif -#define spr_register(env, num, name, uea_read, uea_write, \ - oea_read, oea_write, initial_value) \ - spr_register_kvm(env, num, name, uea_read, uea_write, \ - oea_read, oea_write, 0, initial_value) - -#define spr_register_hv(env, num, name, uea_read, uea_write, \ - oea_read, oea_write, hea_read, hea_write, \ - initial_value) \ - spr_register_kvm_hv(env, num, name, uea_read, uea_write, \ - oea_read, oea_write, hea_read, hea_write, \ - 0, initial_value) - -static inline void _spr_register(CPUPPCState *env, int num, - const char *name, - void (*uea_read)(DisasContext *ctx, - int gprn, int sprn), - void (*uea_write)(DisasContext *ctx, - int sprn, int gprn), -#if !defined(CONFIG_USER_ONLY) +typedef void spr_callback(DisasContext *, int, int); - void (*oea_read)(DisasContext *ctx, - int gprn, int sprn), - void (*oea_write)(DisasContext *ctx, - int sprn, int gprn), - void (*hea_read)(DisasContext *opaque, - int gprn, int sprn), - void (*hea_write)(DisasContext *opaque, - int sprn, int gprn), -#endif -#if defined(CONFIG_KVM) - uint64_t one_reg_id, -#endif - target_ulong initial_value) +static void _spr_register(CPUPPCState *env, int num, const char *name, + USR_ARG(spr_callback *uea_read) + USR_ARG(spr_callback *uea_write) + SYS_ARG(spr_callback *oea_read) + SYS_ARG(spr_callback *oea_write) + SYS_ARG(spr_callback *hea_read) + SYS_ARG(spr_callback *hea_write) + KVM_ARG(uint64_t one_reg_id) + target_ulong initial_value) { - ppc_spr_t *spr; + ppc_spr_t *spr = &env->spr_cb[num]; + + /* No SPR should be registered twice. */ + assert(spr->name == NULL); + assert(name != NULL); - spr = &env->spr_cb[num]; - if (spr->name != NULL || env->spr[num] != 0x00000000 || -#if !defined(CONFIG_USER_ONLY) - spr->oea_read != NULL || spr->oea_write != NULL || -#endif - spr->uea_read != NULL || spr->uea_write != NULL) { - printf("Error: Trying to register SPR %d (%03x) twice !\n", num, num); - exit(1); - } -#if defined(PPC_DEBUG_SPR) - printf("*** register spr %d (%03x) %s val " TARGET_FMT_lx "\n", num, num, - name, initial_value); -#endif spr->name = name; + spr->default_value = initial_value; + env->spr[num] = initial_value; + +#ifdef CONFIG_TCG spr->uea_read = uea_read; spr->uea_write = uea_write; -#if !defined(CONFIG_USER_ONLY) +# ifndef CONFIG_USER_ONLY spr->oea_read = oea_read; spr->oea_write = oea_write; spr->hea_read = hea_read; spr->hea_write = hea_write; +# endif #endif -#if defined(CONFIG_KVM) - spr->one_reg_id = one_reg_id, -#endif - env->spr[num] = spr->default_value = initial_value; -} +#ifdef CONFIG_KVM + spr->one_reg_id = one_reg_id; +#endif +} + +/* spr_register_kvm_hv passes all required arguments. */ +#define spr_register_kvm_hv(env, num, name, uea_read, uea_write, \ + oea_read, oea_write, hea_read, hea_write, \ + one_reg_id, initial_value) \ + _spr_register(env, num, name, \ + USR_ARG(uea_read) USR_ARG(uea_write) \ + SYS_ARG(oea_read) SYS_ARG(oea_write) \ + SYS_ARG(hea_read) SYS_ARG(hea_write) \ + KVM_ARG(one_reg_id) initial_value) + +/* spr_register_kvm duplicates the oea callbacks to the hea callbacks. */ +#define spr_register_kvm(env, num, name, uea_read, uea_write, \ + oea_read, oea_write, one_reg_id, ival) \ + spr_register_kvm_hv(env, num, name, uea_read, uea_write, oea_read, \ + oea_write, oea_read, oea_write, one_reg_id, ival) + +/* spr_register_hv and spr_register are similar, except there is no kvm id. */ +#define spr_register_hv(env, num, name, uea_read, uea_write, \ + oea_read, oea_write, hea_read, hea_write, ival) \ + spr_register_kvm_hv(env, num, name, uea_read, uea_write, oea_read, \ + oea_write, hea_read, hea_write, 0, ival) + +#define spr_register(env, num, name, uea_read, uea_write, \ + oea_read, oea_write, ival) \ + spr_register_kvm(env, num, name, uea_read, uea_write, \ + oea_read, oea_write, 0, ival) /* Generic PowerPC SPRs */ static void gen_spr_generic(CPUPPCState *env) From patchwork Tue May 4 05:53:08 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: David Gibson X-Patchwork-Id: 12237483 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-16.6 required=3.0 tests=BAYES_00,DKIM_INVALID, DKIM_SIGNED,HEADER_FROM_DIFFERENT_DOMAINS,INCLUDES_CR_TRAILER,INCLUDES_PATCH, MAILING_LIST_MULTI,SPF_HELO_NONE,SPF_PASS,USER_AGENT_GIT autolearn=ham autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id 39A98C433B4 for ; Tue, 4 May 2021 06:37:15 +0000 (UTC) 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 mail.kernel.org (Postfix) with ESMTPS id D4F9D61175 for ; Tue, 4 May 2021 06:37:14 +0000 (UTC) DMARC-Filter: OpenDMARC Filter v1.3.2 mail.kernel.org D4F9D61175 Authentication-Results: mail.kernel.org; dmarc=none (p=none dis=none) header.from=gibson.dropbear.id.au Authentication-Results: mail.kernel.org; spf=pass smtp.mailfrom=qemu-devel-bounces+qemu-devel=archiver.kernel.org@nongnu.org Received: from localhost ([::1]:39518 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1ldogE-0006jF-0p for qemu-devel@archiver.kernel.org; Tue, 04 May 2021 02:37:14 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]:60986) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1ldo1F-0006w6-6Z; Tue, 04 May 2021 01:54:53 -0400 Received: from ozlabs.org ([2401:3900:2:1::2]:35131) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1ldo1D-0005JI-HC; Tue, 04 May 2021 01:54:52 -0400 Received: by ozlabs.org (Postfix, from userid 1007) id 4FZ8CQ0Stsz9t1C; Tue, 4 May 2021 15:53:21 +1000 (AEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=gibson.dropbear.id.au; s=201602; t=1620107602; bh=Waw0NZnem3odKQHfMNelimpPmlKaZSKhjMfc8vEz4Uc=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=Q//2GDmSrjB/39ZwcWkqiI5k9oBJMqS17vx9aEhVUdYHpgkL2uYsA8yCTv+Nu2MhU lEEVqIkaCrepPK/6KYOKrLnLZ7Cdj0SeQoi+11A+VUfeKwJ5bLWTXoAkUIeFzMgLy4 KU6YLyltoRLDuZjbqkiPX+w3LJHewMFoKEz2pZ/0= From: David Gibson To: peter.maydell@linaro.org, groug@kaod.org Subject: [PULL 42/46] target/ppc: Reduce the size of ppc_spr_t Date: Tue, 4 May 2021 15:53:08 +1000 Message-Id: <20210504055312.306823-43-david@gibson.dropbear.id.au> X-Mailer: git-send-email 2.31.1 In-Reply-To: <20210504055312.306823-1-david@gibson.dropbear.id.au> References: <20210504055312.306823-1-david@gibson.dropbear.id.au> MIME-Version: 1.0 Received-SPF: pass client-ip=2401:3900:2:1::2; envelope-from=dgibson@ozlabs.org; helo=ozlabs.org X-Spam_score_int: -17 X-Spam_score: -1.8 X-Spam_bar: - X-Spam_report: (-1.8 / 5.0 requ) BAYES_00=-1.9, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_AU=-0.1, HEADER_FROM_DIFFERENT_DOMAINS=0.25, SPF_HELO_PASS=-0.001, SPF_PASS=-0.001 autolearn=no autolearn_force=no X-Spam_action: no action X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: Richard Henderson , qemu-ppc@nongnu.org, qemu-devel@nongnu.org, David Gibson Errors-To: qemu-devel-bounces+qemu-devel=archiver.kernel.org@nongnu.org Sender: "Qemu-devel" From: Richard Henderson We elide values when registering sprs, we might as well save space in the array as well. Signed-off-by: Richard Henderson Message-Id: <20210501022923.1179736-3-richard.henderson@linaro.org> Signed-off-by: David Gibson --- target/ppc/cpu.h | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/target/ppc/cpu.h b/target/ppc/cpu.h index 8a076fab48..733a2168c4 100644 --- a/target/ppc/cpu.h +++ b/target/ppc/cpu.h @@ -192,17 +192,21 @@ typedef struct ppc_hash_pte64 ppc_hash_pte64_t; /* SPR access micro-ops generations callbacks */ struct ppc_spr_t { + const char *name; + target_ulong default_value; +#ifndef CONFIG_USER_ONLY + unsigned int gdb_id; +#endif +#ifdef CONFIG_TCG void (*uea_read)(DisasContext *ctx, int gpr_num, int spr_num); void (*uea_write)(DisasContext *ctx, int spr_num, int gpr_num); -#if !defined(CONFIG_USER_ONLY) +# ifndef CONFIG_USER_ONLY void (*oea_read)(DisasContext *ctx, int gpr_num, int spr_num); void (*oea_write)(DisasContext *ctx, int spr_num, int gpr_num); void (*hea_read)(DisasContext *ctx, int gpr_num, int spr_num); void (*hea_write)(DisasContext *ctx, int spr_num, int gpr_num); - unsigned int gdb_id; +# endif #endif - const char *name; - target_ulong default_value; #ifdef CONFIG_KVM /* * We (ab)use the fact that all the SPRs will have ids for the From patchwork Tue May 4 05:53:09 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: David Gibson X-Patchwork-Id: 12237509 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-16.6 required=3.0 tests=BAYES_00,DKIM_INVALID, DKIM_SIGNED,HEADER_FROM_DIFFERENT_DOMAINS,INCLUDES_CR_TRAILER,INCLUDES_PATCH, MAILING_LIST_MULTI,SPF_HELO_NONE,SPF_PASS,USER_AGENT_GIT autolearn=ham autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id 1AD47C433ED for ; Tue, 4 May 2021 06:51:36 +0000 (UTC) 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 mail.kernel.org (Postfix) with ESMTPS id C450960FD7 for ; Tue, 4 May 2021 06:51:35 +0000 (UTC) DMARC-Filter: OpenDMARC Filter v1.3.2 mail.kernel.org C450960FD7 Authentication-Results: mail.kernel.org; dmarc=none (p=none dis=none) header.from=gibson.dropbear.id.au Authentication-Results: mail.kernel.org; spf=pass smtp.mailfrom=qemu-devel-bounces+qemu-devel=archiver.kernel.org@nongnu.org Received: from localhost ([::1]:52424 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1ldou6-0007iZ-TU for qemu-devel@archiver.kernel.org; Tue, 04 May 2021 02:51:34 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]:32798) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1ldo1M-00074b-OB; Tue, 04 May 2021 01:55:00 -0400 Received: from ozlabs.org ([2401:3900:2:1::2]:56577) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1ldo1J-0005MQ-7a; Tue, 04 May 2021 01:55:00 -0400 Received: by ozlabs.org (Postfix, from userid 1007) id 4FZ8CQ1hJWz9t1Q; Tue, 4 May 2021 15:53:21 +1000 (AEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=gibson.dropbear.id.au; s=201602; t=1620107602; bh=jG3g9nrbM97zf6opwX6YAOoU0AMO/h9BaoJzHVwrdp4=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=IPWEpiyyzIshlUuWlP5nP6BF6FcmKGFITYlT4gbs2m/vABLow8EKhFmulPTSf7jmS fo5eQ1wPH5H6g5dG/OnBTtmFrESKXPVzn69eArc/JXt2O4lWAkeQhST75O/0HjftHE KOzqWwEyc0k+tjHwwMVRaq/ElwR0h+qcJTK/AaSU= From: David Gibson To: peter.maydell@linaro.org, groug@kaod.org Subject: [PULL 43/46] target/ppc: removed VSCR from SPR registration Date: Tue, 4 May 2021 15:53:09 +1000 Message-Id: <20210504055312.306823-44-david@gibson.dropbear.id.au> X-Mailer: git-send-email 2.31.1 In-Reply-To: <20210504055312.306823-1-david@gibson.dropbear.id.au> References: <20210504055312.306823-1-david@gibson.dropbear.id.au> MIME-Version: 1.0 Received-SPF: pass client-ip=2401:3900:2:1::2; envelope-from=dgibson@ozlabs.org; helo=ozlabs.org X-Spam_score_int: -17 X-Spam_score: -1.8 X-Spam_bar: - X-Spam_report: (-1.8 / 5.0 requ) BAYES_00=-1.9, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_AU=-0.1, HEADER_FROM_DIFFERENT_DOMAINS=0.25, SPF_HELO_PASS=-0.001, SPF_PASS=-0.001 autolearn=no autolearn_force=no X-Spam_action: no action X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: "Bruno Larsen \(billionai\)" , Richard Henderson , qemu-ppc@nongnu.org, qemu-devel@nongnu.org, David Gibson Errors-To: qemu-devel-bounces+qemu-devel=archiver.kernel.org@nongnu.org Sender: "Qemu-devel" From: "Bruno Larsen (billionai)" Since vscr is not an spr, its initialization was removed from the spr registration functions, and moved to the relevant init_procs. We may look into adding vscr to the reset path instead of the init path (as suggested by David Gibson), but this looked like a good enough solution for now. Signed-off-by: Bruno Larsen (billionai) Message-Id: <20210430193533.82136-6-bruno.larsen@eldorado.org.br> Reviewed-by: Richard Henderson Signed-off-by: David Gibson --- target/ppc/translate_init.c.inc | 20 +++++++++++++------- 1 file changed, 13 insertions(+), 7 deletions(-) diff --git a/target/ppc/translate_init.c.inc b/target/ppc/translate_init.c.inc index 5cee94f16d..66e6a4a746 100644 --- a/target/ppc/translate_init.c.inc +++ b/target/ppc/translate_init.c.inc @@ -1693,8 +1693,6 @@ static void gen_spr_74xx(CPUPPCState *env) SPR_NOACCESS, SPR_NOACCESS, &spr_read_generic, spr_access_nop, 0x00000000); - /* Not strictly an SPR */ - vscr_init(env, 0x00010000); } static void gen_l3_ctrl(CPUPPCState *env) @@ -6618,6 +6616,7 @@ static void init_proc_7400(CPUPPCState *env) gen_tbl(env); /* 74xx specific SPR */ gen_spr_74xx(env); + vscr_init(env, 0x00010000); /* XXX : not implemented */ spr_register(env, SPR_UBAMR, "UBAMR", &spr_read_ureg, SPR_NOACCESS, @@ -6697,6 +6696,7 @@ static void init_proc_7410(CPUPPCState *env) gen_tbl(env); /* 74xx specific SPR */ gen_spr_74xx(env); + vscr_init(env, 0x00010000); /* XXX : not implemented */ spr_register(env, SPR_UBAMR, "UBAMR", &spr_read_ureg, SPR_NOACCESS, @@ -6782,6 +6782,7 @@ static void init_proc_7440(CPUPPCState *env) gen_tbl(env); /* 74xx specific SPR */ gen_spr_74xx(env); + vscr_init(env, 0x00010000); /* XXX : not implemented */ spr_register(env, SPR_UBAMR, "UBAMR", &spr_read_ureg, SPR_NOACCESS, @@ -6890,6 +6891,7 @@ static void init_proc_7450(CPUPPCState *env) gen_tbl(env); /* 74xx specific SPR */ gen_spr_74xx(env); + vscr_init(env, 0x00010000); /* Level 3 cache control */ gen_l3_ctrl(env); /* L3ITCR1 */ @@ -7024,6 +7026,7 @@ static void init_proc_7445(CPUPPCState *env) gen_tbl(env); /* 74xx specific SPR */ gen_spr_74xx(env); + vscr_init(env, 0x00010000); /* LDSTCR */ /* XXX : not implemented */ spr_register(env, SPR_LDSTCR, "LDSTCR", @@ -7161,6 +7164,7 @@ static void init_proc_7455(CPUPPCState *env) gen_tbl(env); /* 74xx specific SPR */ gen_spr_74xx(env); + vscr_init(env, 0x00010000); /* Level 3 cache control */ gen_l3_ctrl(env); /* LDSTCR */ @@ -7300,6 +7304,7 @@ static void init_proc_7457(CPUPPCState *env) gen_tbl(env); /* 74xx specific SPR */ gen_spr_74xx(env); + vscr_init(env, 0x00010000); /* Level 3 cache control */ gen_l3_ctrl(env); /* L3ITCR1 */ @@ -7463,6 +7468,7 @@ static void init_proc_e600(CPUPPCState *env) gen_tbl(env); /* 74xx specific SPR */ gen_spr_74xx(env); + vscr_init(env, 0x00010000); /* XXX : not implemented */ spr_register(env, SPR_UBAMR, "UBAMR", &spr_read_ureg, SPR_NOACCESS, @@ -7713,11 +7719,6 @@ static void gen_spr_book3s_altivec(CPUPPCState *env) &spr_read_generic, &spr_write_generic, KVM_REG_PPC_VRSAVE, 0x00000000); - /* - * Can't find information on what this should be on reset. This - * value is the one used by 74xx processors. - */ - vscr_init(env, 0x00010000); } static void gen_spr_book3s_dbg(CPUPPCState *env) @@ -8415,6 +8416,11 @@ static void init_proc_book3s_common(CPUPPCState *env) gen_spr_book3s_pmu_sup(env); gen_spr_book3s_pmu_user(env); gen_spr_book3s_ctrl(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); } static void init_proc_970(CPUPPCState *env) From patchwork Tue May 4 05:53:10 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: David Gibson X-Patchwork-Id: 12237513 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-16.6 required=3.0 tests=BAYES_00,DKIM_INVALID, DKIM_SIGNED,HEADER_FROM_DIFFERENT_DOMAINS,INCLUDES_CR_TRAILER,INCLUDES_PATCH, MAILING_LIST_MULTI,SPF_HELO_NONE,SPF_PASS,USER_AGENT_GIT autolearn=ham autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id D68C5C433ED for ; Tue, 4 May 2021 06:51:41 +0000 (UTC) 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 mail.kernel.org (Postfix) with ESMTPS id 6AAD3611EE for ; Tue, 4 May 2021 06:51:41 +0000 (UTC) DMARC-Filter: OpenDMARC Filter v1.3.2 mail.kernel.org 6AAD3611EE Authentication-Results: mail.kernel.org; dmarc=none (p=none dis=none) header.from=gibson.dropbear.id.au Authentication-Results: mail.kernel.org; spf=pass smtp.mailfrom=qemu-devel-bounces+qemu-devel=archiver.kernel.org@nongnu.org Received: from localhost ([::1]:52810 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1ldouC-0007uH-Ca for qemu-devel@archiver.kernel.org; Tue, 04 May 2021 02:51:40 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]:60904) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1ldo11-0006jK-E9; Tue, 04 May 2021 01:54:39 -0400 Received: from ozlabs.org ([203.11.71.1]:56557) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1ldo0z-0005MS-Ae; Tue, 04 May 2021 01:54:38 -0400 Received: by ozlabs.org (Postfix, from userid 1007) id 4FZ8CQ3FMvz9sVb; Tue, 4 May 2021 15:53:22 +1000 (AEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=gibson.dropbear.id.au; s=201602; t=1620107602; bh=qTTd1acHEOLOLfCLmBJ/7G0wh8ppvnqr7BiunJk5cBw=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=KuXWazCA+HIwtktR57Act7U3z5Fm5dslu/f4x6xt+pufQ5u0FeeEbIBHfhJXAbgUo +94WUT+02G8ZVUhN+0fegWTYT+SgRNUYC2uiCnfgu0AKPVP6OlvhCeus3EYqOUMWf+ 0PISQbH4P2/+eyIkMY6kjRJHTq6D5vC/NyRtx/HM= From: David Gibson To: peter.maydell@linaro.org, groug@kaod.org Subject: [PULL 44/46] hw/intc/spapr_xive: Use device_cold_reset() instead of device_legacy_reset() Date: Tue, 4 May 2021 15:53:10 +1000 Message-Id: <20210504055312.306823-45-david@gibson.dropbear.id.au> X-Mailer: git-send-email 2.31.1 In-Reply-To: <20210504055312.306823-1-david@gibson.dropbear.id.au> References: <20210504055312.306823-1-david@gibson.dropbear.id.au> MIME-Version: 1.0 Received-SPF: pass client-ip=203.11.71.1; envelope-from=dgibson@ozlabs.org; helo=ozlabs.org X-Spam_score_int: -17 X-Spam_score: -1.8 X-Spam_bar: - X-Spam_report: (-1.8 / 5.0 requ) BAYES_00=-1.9, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_AU=-0.1, HEADER_FROM_DIFFERENT_DOMAINS=0.25, SPF_HELO_PASS=-0.001, SPF_PASS=-0.001 autolearn=no autolearn_force=no X-Spam_action: no action X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: qemu-ppc@nongnu.org, qemu-devel@nongnu.org, David Gibson Errors-To: qemu-devel-bounces+qemu-devel=archiver.kernel.org@nongnu.org Sender: "Qemu-devel" From: Peter Maydell The h_int_reset() function resets the XIVE interrupt controller via device_legacy_reset(). We know that the interrupt controller does not have a qbus of its own, so the new device_cold_reset() function (which resets both the device and its child buses) is equivalent here to device_legacy_reset() and we can just switch to the new API. Signed-off-by: Peter Maydell Message-Id: <20210503151849.8766-2-peter.maydell@linaro.org> Signed-off-by: David Gibson --- hw/intc/spapr_xive.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/hw/intc/spapr_xive.c b/hw/intc/spapr_xive.c index 801bc19341..89cfa018f5 100644 --- a/hw/intc/spapr_xive.c +++ b/hw/intc/spapr_xive.c @@ -1798,7 +1798,7 @@ static target_ulong h_int_reset(PowerPCCPU *cpu, return H_PARAMETER; } - device_legacy_reset(DEVICE(xive)); + device_cold_reset(DEVICE(xive)); if (spapr_xive_in_kernel(xive)) { Error *local_err = NULL; From patchwork Tue May 4 05:53:11 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: David Gibson X-Patchwork-Id: 12237505 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-16.6 required=3.0 tests=BAYES_00,DKIM_INVALID, DKIM_SIGNED,HEADER_FROM_DIFFERENT_DOMAINS,INCLUDES_CR_TRAILER,INCLUDES_PATCH, MAILING_LIST_MULTI,SPF_HELO_NONE,SPF_PASS,USER_AGENT_GIT autolearn=ham autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id BCC1DC433ED for ; Tue, 4 May 2021 06:48:49 +0000 (UTC) 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 mail.kernel.org (Postfix) with ESMTPS id 5EDF6613BA for ; Tue, 4 May 2021 06:48:48 +0000 (UTC) DMARC-Filter: OpenDMARC Filter v1.3.2 mail.kernel.org 5EDF6613BA Authentication-Results: mail.kernel.org; dmarc=none (p=none dis=none) header.from=gibson.dropbear.id.au Authentication-Results: mail.kernel.org; spf=pass smtp.mailfrom=qemu-devel-bounces+qemu-devel=archiver.kernel.org@nongnu.org Received: from localhost ([::1]:46270 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1ldorP-0004sB-RR for qemu-devel@archiver.kernel.org; Tue, 04 May 2021 02:48:47 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]:32808) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1ldo1N-00076i-Hx; Tue, 04 May 2021 01:55:01 -0400 Received: from ozlabs.org ([203.11.71.1]:39687) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1ldo1L-0005OH-Hw; Tue, 04 May 2021 01:55:01 -0400 Received: by ozlabs.org (Postfix, from userid 1007) id 4FZ8CQ5sbFz9t1r; Tue, 4 May 2021 15:53:22 +1000 (AEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=gibson.dropbear.id.au; s=201602; t=1620107602; bh=fCKZKsqp44tDGeu7z15Q40LoupLPDQzipln+K2O5gIY=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=VbVsBSo45rI2WhDWrQ/aMmiiPXZUrcJovC6mcbgBGR2btWBNhm/bB4TUYvfF/kXEQ +2jKTxVHFn/+nKzojZWaJ9yzgju8uXplVpUpxTrSq7TS0AlWLiGPhTpb4TiA8fExVv MkIzinG08UGtuQSHO6CaUdZYkjLw5/NgBJUc4NX4= From: David Gibson To: peter.maydell@linaro.org, groug@kaod.org Subject: [PULL 45/46] hw/ppc/spapr_vio: Reset TCE table object with device_cold_reset() Date: Tue, 4 May 2021 15:53:11 +1000 Message-Id: <20210504055312.306823-46-david@gibson.dropbear.id.au> X-Mailer: git-send-email 2.31.1 In-Reply-To: <20210504055312.306823-1-david@gibson.dropbear.id.au> References: <20210504055312.306823-1-david@gibson.dropbear.id.au> MIME-Version: 1.0 Received-SPF: pass client-ip=203.11.71.1; envelope-from=dgibson@ozlabs.org; helo=ozlabs.org X-Spam_score_int: -17 X-Spam_score: -1.8 X-Spam_bar: - X-Spam_report: (-1.8 / 5.0 requ) BAYES_00=-1.9, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_AU=-0.1, HEADER_FROM_DIFFERENT_DOMAINS=0.25, SPF_HELO_PASS=-0.001, SPF_PASS=-0.001 autolearn=no autolearn_force=no X-Spam_action: no action X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: qemu-ppc@nongnu.org, qemu-devel@nongnu.org, David Gibson Errors-To: qemu-devel-bounces+qemu-devel=archiver.kernel.org@nongnu.org Sender: "Qemu-devel" From: Peter Maydell The spapr_vio_quiesce_one() function resets the TCE table object (TYPE_SPAPR_TCE_TABLE) via device_legacy_reset(). We know that objects of that type do not have a qbus of their own, so the new device_cold_reset() function (which resets both the device and its child buses) is equivalent here to device_legacy_reset() and we can just switch to the new API. Signed-off-by: Peter Maydell Message-Id: <20210503151849.8766-3-peter.maydell@linaro.org> Signed-off-by: David Gibson --- hw/ppc/spapr_vio.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/hw/ppc/spapr_vio.c b/hw/ppc/spapr_vio.c index ef06e0362c..b59452bcd6 100644 --- a/hw/ppc/spapr_vio.c +++ b/hw/ppc/spapr_vio.c @@ -310,7 +310,7 @@ int spapr_vio_send_crq(SpaprVioDevice *dev, uint8_t *crq) static void spapr_vio_quiesce_one(SpaprVioDevice *dev) { if (dev->tcet) { - device_legacy_reset(DEVICE(dev->tcet)); + device_cold_reset(DEVICE(dev->tcet)); } free_crq(dev); } From patchwork Tue May 4 05:53:12 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: David Gibson X-Patchwork-Id: 12237511 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-16.6 required=3.0 tests=BAYES_00,DKIM_INVALID, DKIM_SIGNED,HEADER_FROM_DIFFERENT_DOMAINS,INCLUDES_CR_TRAILER,INCLUDES_PATCH, MAILING_LIST_MULTI,SPF_HELO_NONE,SPF_PASS,USER_AGENT_GIT autolearn=ham autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id B9DC5C433B4 for ; Tue, 4 May 2021 06:51:36 +0000 (UTC) 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 mail.kernel.org (Postfix) with ESMTPS id 7246360FD7 for ; Tue, 4 May 2021 06:51:36 +0000 (UTC) DMARC-Filter: OpenDMARC Filter v1.3.2 mail.kernel.org 7246360FD7 Authentication-Results: mail.kernel.org; dmarc=none (p=none dis=none) header.from=gibson.dropbear.id.au Authentication-Results: mail.kernel.org; spf=pass smtp.mailfrom=qemu-devel-bounces+qemu-devel=archiver.kernel.org@nongnu.org Received: from localhost ([::1]:52498 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1ldou7-0007kc-JF for qemu-devel@archiver.kernel.org; Tue, 04 May 2021 02:51:35 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]:32810) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1ldo1N-00077A-Ld; Tue, 04 May 2021 01:55:01 -0400 Received: from ozlabs.org ([2401:3900:2:1::2]:55873) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1ldo1L-0005OK-OX; Tue, 04 May 2021 01:55:01 -0400 Received: by ozlabs.org (Postfix, from userid 1007) id 4FZ8CQ4zFlz9t1s; Tue, 4 May 2021 15:53:22 +1000 (AEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=gibson.dropbear.id.au; s=201602; t=1620107602; bh=y9uyQJXG5pCTAYMMEsFQPkAKFM4i1KQ0n02I0GZk4yE=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=hq6T6klWkS8oHc0yWEps/9mxyicptvOKUyB3lTR75OYa69RMOoQdoO5vp2tzDApCI /jeiPcICKOtZFTi9K2EjllwX9OrdKPI0uW+7plkTtDY9C7UPw7e02UI2FC1BM6ABEb xQSBrr9DAWkS3M3MATWbSUabQHmCIZ8yCxQZ3hKo= From: David Gibson To: peter.maydell@linaro.org, groug@kaod.org Subject: [PULL 46/46] hw/ppc/pnv_psi: Use device_cold_reset() instead of device_legacy_reset() Date: Tue, 4 May 2021 15:53:12 +1000 Message-Id: <20210504055312.306823-47-david@gibson.dropbear.id.au> X-Mailer: git-send-email 2.31.1 In-Reply-To: <20210504055312.306823-1-david@gibson.dropbear.id.au> References: <20210504055312.306823-1-david@gibson.dropbear.id.au> MIME-Version: 1.0 Received-SPF: pass client-ip=2401:3900:2:1::2; envelope-from=dgibson@ozlabs.org; helo=ozlabs.org X-Spam_score_int: -17 X-Spam_score: -1.8 X-Spam_bar: - X-Spam_report: (-1.8 / 5.0 requ) BAYES_00=-1.9, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_AU=-0.1, HEADER_FROM_DIFFERENT_DOMAINS=0.25, SPF_HELO_PASS=-0.001, SPF_PASS=-0.001 autolearn=no autolearn_force=no X-Spam_action: no action X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: qemu-ppc@nongnu.org, qemu-devel@nongnu.org, David Gibson Errors-To: qemu-devel-bounces+qemu-devel=archiver.kernel.org@nongnu.org Sender: "Qemu-devel" From: Peter Maydell The pnv_psi.c code uses device_legacy_reset() for two purposes: * to reset itself from its qemu_register_reset() handler * to reset a XiveSource object it has Neither it nor the XiveSource have any qbuses, so the new device_cold_reset() function (which resets both the device and its child buses) is equivalent here to device_legacy_reset() and we can just switch to the new API. Signed-off-by: Peter Maydell Message-Id: <20210503151849.8766-4-peter.maydell@linaro.org> Signed-off-by: David Gibson --- hw/ppc/pnv_psi.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/hw/ppc/pnv_psi.c b/hw/ppc/pnv_psi.c index 3e868c8c8d..292b373f93 100644 --- a/hw/ppc/pnv_psi.c +++ b/hw/ppc/pnv_psi.c @@ -466,7 +466,7 @@ static void pnv_psi_reset(DeviceState *dev) static void pnv_psi_reset_handler(void *dev) { - device_legacy_reset(DEVICE(dev)); + device_cold_reset(DEVICE(dev)); } static void pnv_psi_realize(DeviceState *dev, Error **errp) @@ -710,7 +710,7 @@ static void pnv_psi_p9_mmio_write(void *opaque, hwaddr addr, break; case PSIHB9_INTERRUPT_CONTROL: if (val & PSIHB9_IRQ_RESET) { - device_legacy_reset(DEVICE(&psi9->source)); + device_cold_reset(DEVICE(&psi9->source)); } psi->regs[reg] = val; break;