From patchwork Tue Mar 11 12:56:55 2025 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: Nicholas Piggin X-Patchwork-Id: 14011796 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.lore.kernel.org (Postfix) with ESMTPS id 1E902C282EC for ; Tue, 11 Mar 2025 13:01:08 +0000 (UTC) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1trzC1-0000wk-7x; Tue, 11 Mar 2025 08:58:45 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1trzBs-0000vG-Ql; Tue, 11 Mar 2025 08:58:38 -0400 Received: from mail-pj1-x102d.google.com ([2607:f8b0:4864:20::102d]) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_128_GCM_SHA256:128) (Exim 4.90_1) (envelope-from ) id 1trzBo-0007oR-DD; Tue, 11 Mar 2025 08:58:35 -0400 Received: by mail-pj1-x102d.google.com with SMTP id 98e67ed59e1d1-2feae794508so8081948a91.0; Tue, 11 Mar 2025 05:58:31 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20230601; t=1741697910; x=1742302710; darn=nongnu.org; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to; bh=u7wjPkG/ntlVqsAo3bR2GeOkCsbyPnLbq91ceDRWcvk=; b=SIii28Y+MGsgzRfdpDvapK2psDdhlbbzpw1IPdEUbpA6Cz8r8pTTrB19guznzUNH23 DvNPUM0JaSQ00mNyngm58NCsysj7CIOexRVwSL7oxs2E3GIba2od2R8nd4pqe8Efoq1u wFykPqxSznAl+cVdB2Ar8/hYrtLf5D17Mv3zdl9be7GOF3/Kbjk7/fzc5fW4u5YklP6R +ALVlMgZEBlF+iZMgxUKzQ7w+I6Tr5VSf9nLhqWQRlbFCX8kqKeqm9/z/yFaOgizkDDn 6u5dZRfTJVdwDmlAgrrYgkDFG5QNCrVor3zbnQgEyAq34Tm0qIxMmQvmXFsWAmNPPbOB EmUQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1741697910; x=1742302710; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=u7wjPkG/ntlVqsAo3bR2GeOkCsbyPnLbq91ceDRWcvk=; b=Fi4LQShifCOD3jXogMDZ50JaPPEQGPhI8kxbxLS5Vg5paYhJGlMKClr9qV6nDC3sDz Z03u3nVD171K3sSF6+ewT8MX9eptSQGX1qm4Q1LofoOacIjOIxU5beXJqVS3bUsDCLLe 2eu/2ZJzP+Qt1KaJA0Oi4ml4Ggh7e92gmBqWypwTBBhWG0MIixBWUEF9RChV9AOxwBcp fpyFWT3CVtGCSJfTfDUNZHL/DsSU2bcsD53lH/ip0xbXnDl1hCNai9H9vrDMnyprRyie 1fAnzV5jJ8/gHR1hqytOVPuNFqyyNldFVaoL6nDZisac1ZdnT2Xzv7SfK5L3DKHmgPuP DJAg== X-Forwarded-Encrypted: i=1; AJvYcCUYS0NIBBX134ptewyiUy8umBUjCRLpMm8P18Le+mgi0B8m6hTlpYOjTevFNwgZxME6zOdytb568Q==@nongnu.org X-Gm-Message-State: AOJu0YzL5GbZtw0ZzuTCs/TpCiG3ol4aLiu/x/hZtEbX1vgIKYbcqchm om2QqAO+/ph+0msj3VTqoJ9MuHjG470MKDAIp5plmYZbq1qz0z961f9Y0w== X-Gm-Gg: ASbGncsCJrj7YsReHKPJazPSTfwSj251Om8+OpjIjwVmV3jmnoqQK7fqmdWGNktKIvu 058YGpzOIAuQ964NOMqBTNOxG/PzlGaq3CrSZxYfcniiInZEm4OHK3t/FBbq6F9zw318ESnlmvV g6cxqYETZypCTAJqZuf1CjIuF6g64GeWPkr0Ql+xAFD12j5tw03IXlBUiW4M/dQpYNcA0XCjeqR V1Sj7a0IFZwNWUYxcJ7dtxQtSFPP/GS/EWz7f67nUJ806Bh3YfuoevoQNC+Qh3RsJKVwmUH7Vc7 Jvp7N/alQ+udBSqRAqcYU5J04m1YcQ6l2r5BYc9d6LW3NDU5XWI= X-Google-Smtp-Source: AGHT+IGIqYa8qeyLfWBVgGoHt+p6wAsY1KCHmJ7RHjz24qW8Etm3dVWkWNWeWdinz2VYptWdxW8HjQ== X-Received: by 2002:a17:90b:2d82:b0:2ff:5357:1c7e with SMTP id 98e67ed59e1d1-2ff7ce89db6mr26355537a91.20.1741697908460; Tue, 11 Mar 2025 05:58:28 -0700 (PDT) Received: from wheely.local0.net ([118.208.151.101]) by smtp.gmail.com with ESMTPSA id 98e67ed59e1d1-2ff4e773dddsm11822318a91.12.2025.03.11.05.58.26 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 11 Mar 2025 05:58:28 -0700 (PDT) From: Nicholas Piggin To: qemu-devel@nongnu.org Cc: Nicholas Piggin , qemu-ppc@nongnu.org, =?utf-8?q?C?= =?utf-8?q?=C3=A9dric_Le_Goater?= Subject: [PULL 01/72] ppc/ppc405: Remove tests Date: Tue, 11 Mar 2025 22:56:55 +1000 Message-ID: <20250311125815.903177-2-npiggin@gmail.com> X-Mailer: git-send-email 2.47.1 In-Reply-To: <20250311125815.903177-1-npiggin@gmail.com> References: <20250311125815.903177-1-npiggin@gmail.com> MIME-Version: 1.0 Received-SPF: pass client-ip=2607:f8b0:4864:20::102d; envelope-from=npiggin@gmail.com; helo=mail-pj1-x102d.google.com X-Spam_score_int: -20 X-Spam_score: -2.1 X-Spam_bar: -- X-Spam_report: (-2.1 / 5.0 requ) BAYES_00=-1.9, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_AU=-0.1, DKIM_VALID_EF=-0.1, FREEMAIL_FROM=0.001, RCVD_IN_DNSWL_NONE=-0.0001, SPF_HELO_NONE=0.001, SPF_PASS=-0.001 autolearn=ham autolearn_force=no X-Spam_action: no action X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: qemu-devel-bounces+qemu-devel=archiver.kernel.org@nongnu.org Sender: qemu-devel-bounces+qemu-devel=archiver.kernel.org@nongnu.org From: Cédric Le Goater Since we are about to remove all support for PPC 405, start by removing the tests referring to the ref405ep machine. Link: https://lore.kernel.org/qemu-devel/20250110141800.1587589-2-clg@redhat.com Signed-off-by: Cédric Le Goater Reviewed-by: Nicholas Piggin Message-ID: <20250204080649.836155-2-clg@redhat.com> Signed-off-by: Nicholas Piggin --- tests/functional/meson.build | 1 - tests/functional/test_ppc_405.py | 37 -------------------------------- tests/qtest/m48t59-test.c | 5 ----- tests/qtest/meson.build | 1 - 4 files changed, 44 deletions(-) delete mode 100755 tests/functional/test_ppc_405.py diff --git a/tests/functional/meson.build b/tests/functional/meson.build index e78560a901..74f8414a0c 100644 --- a/tests/functional/meson.build +++ b/tests/functional/meson.build @@ -207,7 +207,6 @@ tests_ppc_system_quick = [ ] tests_ppc_system_thorough = [ - 'ppc_405', 'ppc_40p', 'ppc_amiga', 'ppc_bamboo', diff --git a/tests/functional/test_ppc_405.py b/tests/functional/test_ppc_405.py deleted file mode 100755 index 9851c03ee9..0000000000 --- a/tests/functional/test_ppc_405.py +++ /dev/null @@ -1,37 +0,0 @@ -#!/usr/bin/env python3 -# -# Test that the U-Boot firmware boots on ppc 405 machines and check the console -# -# Copyright (c) 2021 Red Hat, Inc. -# -# This work is licensed under the terms of the GNU GPL, version 2 or -# later. See the COPYING file in the top-level directory. - -from qemu_test import QemuSystemTest, Asset -from qemu_test import wait_for_console_pattern -from qemu_test import exec_command_and_wait_for_pattern - -class Ppc405Machine(QemuSystemTest): - - timeout = 90 - - ASSET_UBOOT = Asset( - ('https://gitlab.com/huth/u-boot/-/raw/taihu-2021-10-09/' - 'u-boot-taihu.bin'), - 'a076bb6cdeaafa406330e51e074b66d8878d9036d67d4caa0137be03ee4c112c') - - def do_test_ppc405(self): - file_path = self.ASSET_UBOOT.fetch() - self.vm.set_console(console_index=1) - self.vm.add_args('-bios', file_path) - self.vm.launch() - wait_for_console_pattern(self, 'AMCC PPC405EP Evaluation Board') - exec_command_and_wait_for_pattern(self, 'reset', 'AMCC PowerPC 405EP') - - def test_ppc_ref405ep(self): - self.require_accelerator("tcg") - self.set_machine('ref405ep') - self.do_test_ppc405() - -if __name__ == '__main__': - QemuSystemTest.main() diff --git a/tests/qtest/m48t59-test.c b/tests/qtest/m48t59-test.c index 605797ab78..1e39a0e8f0 100644 --- a/tests/qtest/m48t59-test.c +++ b/tests/qtest/m48t59-test.c @@ -247,11 +247,6 @@ static void base_setup(void) base_year = 1968; base_machine = "SS-5"; use_mmio = true; - } else if (g_str_equal(arch, "ppc") || g_str_equal(arch, "ppc64")) { - base = 0xF0000000; - base_year = 1968; - base_machine = "ref405ep"; - use_mmio = true; } else { g_assert_not_reached(); } diff --git a/tests/qtest/meson.build b/tests/qtest/meson.build index 8a6243382a..b23fe67db7 100644 --- a/tests/qtest/meson.build +++ b/tests/qtest/meson.build @@ -171,7 +171,6 @@ qtests_mips64el = qtests_mips qtests_ppc = \ qtests_filter + \ (config_all_devices.has_key('CONFIG_ISA_TESTDEV') ? ['endianness-test'] : []) + \ - (config_all_devices.has_key('CONFIG_M48T59') ? ['m48t59-test'] : []) + \ (config_all_accel.has_key('CONFIG_TCG') ? ['prom-env-test'] : []) + \ (config_all_accel.has_key('CONFIG_TCG') ? ['boot-serial-test'] : []) + \ ['boot-order-test'] From patchwork Tue Mar 11 12:56:56 2025 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: Nicholas Piggin X-Patchwork-Id: 14011787 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.lore.kernel.org (Postfix) with ESMTPS id 5C6CCC282EC for ; Tue, 11 Mar 2025 13:00:15 +0000 (UTC) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1trzC5-00012y-1e; Tue, 11 Mar 2025 08:58:49 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1trzC1-0000xN-NN; Tue, 11 Mar 2025 08:58:45 -0400 Received: from mail-pj1-x1033.google.com ([2607:f8b0:4864:20::1033]) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_128_GCM_SHA256:128) (Exim 4.90_1) (envelope-from ) id 1trzBr-0007ow-KC; Tue, 11 Mar 2025 08:58:45 -0400 Received: by mail-pj1-x1033.google.com with SMTP id 98e67ed59e1d1-2ff04f36fd2so9011346a91.1; Tue, 11 Mar 2025 05:58:33 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20230601; t=1741697912; x=1742302712; darn=nongnu.org; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to; bh=9qziwSp72v5bFf9UwHWA2wgeDsKZUWFBWm7xQttp+nk=; b=Y9rUxcofB1lyDLTVXfX53g+DgMeVhU/QP/yf9K44slef6CWQ3+urbBSo3lByVHwD1j 96LsjpElriziBZpwulhn7hF92Sks283E2VT5jmr8B1ONKDtXDq+Bymce67eLm6KVObuL cRBVk3RinPnCoL3hnaLFHNz6mLRmfIG895MoWEMJGNpbh1r4nmrt5PJVOVdx28n92+e3 M8X6KH9jRQLwOhguENJOniDYXW3W7JRi2qj8NXx/4/+DtYjAJjTtyMDOhQXoI1+7bKWB ru0auU6RxQ3oJFRVObzcBhaAAED5TpT0NF7Q+jqEVHHRgIJYS4ZrDbC1f3rza28Hw5MR q3TQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1741697912; x=1742302712; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=9qziwSp72v5bFf9UwHWA2wgeDsKZUWFBWm7xQttp+nk=; b=kXkqtSKRBzBgcNMKBGRxta0XnDHE5+oE8kY2zntF+4fouzF8X+JNiI9c4s1H7i6Av7 JERdcT+yBCECv0SSfic5O+KlZFBmVf8L9SFTqrDc+9TcMAvT9ONtpnHEaKOBWnNJ/HFF ePy9tZ1/1S7Mf1d/YFIZoDc3mP4bNpT4Rg0kMJlsqyTYJLtjD/VZZfAdYuxF7zDqJ3Fg 9I+jhARzf12XTTdXT0kk9LtkFH9IoJg3FoVE1O2ZGEojuntw4ITMLhW6k06qaC9wGuv1 TDIl0qt1hnAwJhow6eM2lzaGvz8Q5vhmphOmYIrG70BbiOSteyWgb9oVJvy2W0Huo5xa j1cA== X-Forwarded-Encrypted: i=1; AJvYcCX3jvOA08sY4aUH6TjbL8weBDTDhKIW50YElV1Yb5EAfOky8743eNb0v5NGrSDn+8t4HiPSpqNTpg==@nongnu.org X-Gm-Message-State: AOJu0Yzri3WHvzzRcBIi42H+jICu+0Tyqic5k8Bj6A/r24BF7e/WS6KL 9uO/vdm74YhzsrwJAez26Whiqsbjl7Rf5+iDcdl82RISsIMmo6HChT/tzQ== X-Gm-Gg: ASbGncugDOT84EbR/QqruSzfr0tpb7/x+ls5BeTvEDOoxfk7y8QEkDT6Ip/FeyMQT5D gECHgBhfSuadNaBn5VF7mNLNR5wT2FszjRr/Kh0rbXfFT+sTnNnYY4kucOA5aqP5qtLwCDUF0pE +9vkdCXoEtwf8m9xjlcHxVldcfqXWHWHhwGEFYmhl/xYP1bgks5qbXm1DeRctSHfLlzfgS/OcpO 2YWUCn44zAkYpDyupVn6D+8w91Ulht+TC5fkLQdJIjIDPYyDnu/i/vI26Odthsy9Xma715IPGxA y1IPj4DeB9rpSlRk4iQf3RkVRm5Hb6Xka4mqxS92tUnUavAECfg= X-Google-Smtp-Source: AGHT+IFjo34kHqAtrEJIIQO9nDSHx36UtediFHCmhNt2Sd9pOmgWHHuetKAcotvGwVfBoB67Iq5Org== X-Received: by 2002:a17:90b:4ad0:b0:2ff:6fc3:79c4 with SMTP id 98e67ed59e1d1-2ff7cef5cdamr26065740a91.27.1741697911557; Tue, 11 Mar 2025 05:58:31 -0700 (PDT) Received: from wheely.local0.net ([118.208.151.101]) by smtp.gmail.com with ESMTPSA id 98e67ed59e1d1-2ff4e773dddsm11822318a91.12.2025.03.11.05.58.28 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 11 Mar 2025 05:58:31 -0700 (PDT) From: Nicholas Piggin To: qemu-devel@nongnu.org Cc: Nicholas Piggin , qemu-ppc@nongnu.org, =?utf-8?q?C?= =?utf-8?q?=C3=A9dric_Le_Goater?= Subject: [PULL 02/72] ppc/ppc405: Remove boards Date: Tue, 11 Mar 2025 22:56:56 +1000 Message-ID: <20250311125815.903177-3-npiggin@gmail.com> X-Mailer: git-send-email 2.47.1 In-Reply-To: <20250311125815.903177-1-npiggin@gmail.com> References: <20250311125815.903177-1-npiggin@gmail.com> MIME-Version: 1.0 Received-SPF: pass client-ip=2607:f8b0:4864:20::1033; envelope-from=npiggin@gmail.com; helo=mail-pj1-x1033.google.com X-Spam_score_int: -20 X-Spam_score: -2.1 X-Spam_bar: -- X-Spam_report: (-2.1 / 5.0 requ) BAYES_00=-1.9, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_AU=-0.1, DKIM_VALID_EF=-0.1, FREEMAIL_FROM=0.001, RCVD_IN_DNSWL_NONE=-0.0001, SPF_HELO_NONE=0.001, SPF_PASS=-0.001 autolearn=ham autolearn_force=no X-Spam_action: no action X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: qemu-devel-bounces+qemu-devel=archiver.kernel.org@nongnu.org Sender: qemu-devel-bounces+qemu-devel=archiver.kernel.org@nongnu.org From: Cédric Le Goater The ref405ep machine is the only PPC 405 machine. Drop all support by removing the SoC and associated devices as-well as the machine. Link: https://lore.kernel.org/qemu-devel/20250110141800.1587589-3-clg@redhat.com Signed-off-by: Cédric Le Goater Reviewed-by: Nicholas Piggin Message-ID: <20250204080649.836155-3-clg@redhat.com> Signed-off-by: Nicholas Piggin --- MAINTAINERS | 6 - docs/about/deprecated.rst | 8 - docs/about/removed-features.rst | 7 + docs/system/ppc/embedded.rst | 1 - hw/ppc/Kconfig | 9 - hw/ppc/meson.build | 3 - hw/ppc/ppc405.h | 186 ----- hw/ppc/ppc405_boards.c | 520 ------------- hw/ppc/ppc405_uc.c | 1216 ------------------------------- 9 files changed, 7 insertions(+), 1949 deletions(-) delete mode 100644 hw/ppc/ppc405.h delete mode 100644 hw/ppc/ppc405_boards.c delete mode 100644 hw/ppc/ppc405_uc.c diff --git a/MAINTAINERS b/MAINTAINERS index 0e5db7a574..e2f538fc16 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -1407,12 +1407,6 @@ F: hw/openrisc/openrisc_sim.c PowerPC Machines ---------------- -405 (ref405ep) -L: qemu-ppc@nongnu.org -S: Orphan -F: hw/ppc/ppc405* -F: tests/functional/test_ppc_405.py - Bamboo L: qemu-ppc@nongnu.org S: Orphan diff --git a/docs/about/deprecated.rst b/docs/about/deprecated.rst index 589951b136..3d39d2a9da 100644 --- a/docs/about/deprecated.rst +++ b/docs/about/deprecated.rst @@ -277,14 +277,6 @@ deprecated; use the new name ``dtb-randomness`` instead. The new name better reflects the way this property affects all random data within the device tree blob, not just the ``kaslr-seed`` node. -PPC 405 ``ref405ep`` machine (since 9.1) -'''''''''''''''''''''''''''''''''''''''' - -The ``ref405ep`` machine and PPC 405 CPU have no known users, firmware -images are not available, OpenWRT dropped support in 2019, U-Boot in -2017, Linux also is dropping support in 2024. It is time to let go of -this ancient hardware and focus on newer CPUs and platforms. - Big-Endian variants of MicroBlaze ``petalogix-ml605`` and ``xlnx-zynqmp-pmu`` machines (since 9.2) '''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''' diff --git a/docs/about/removed-features.rst b/docs/about/removed-features.rst index 156c0c253c..2527a91795 100644 --- a/docs/about/removed-features.rst +++ b/docs/about/removed-features.rst @@ -1064,6 +1064,13 @@ for all machine types using the PXA2xx and OMAP2 SoCs. We are also dropping the ``cheetah`` OMAP1 board, because we don't have any test images for it and don't know of anybody who does. +ppc ``ref405ep`` machine (removed in 10.0) +'''''''''''''''''''''''''''''''''''''''''' + +This machine was removed because PPC 405 CPU have no known users, +firmware images are not available, OpenWRT dropped support in 2019, +U-Boot in 2017, and Linux in 2024. + linux-user mode CPUs -------------------- diff --git a/docs/system/ppc/embedded.rst b/docs/system/ppc/embedded.rst index af3b3d9fa4..5cb7d98b45 100644 --- a/docs/system/ppc/embedded.rst +++ b/docs/system/ppc/embedded.rst @@ -4,6 +4,5 @@ Embedded family boards - ``bamboo`` bamboo - ``mpc8544ds`` mpc8544ds - ``ppce500`` generic paravirt e500 platform -- ``ref405ep`` ref405ep - ``sam460ex`` aCube Sam460ex - ``virtex-ml507`` Xilinx Virtex ML507 reference design diff --git a/hw/ppc/Kconfig b/hw/ppc/Kconfig index b44d91bebb..ced6bbc740 100644 --- a/hw/ppc/Kconfig +++ b/hw/ppc/Kconfig @@ -44,15 +44,6 @@ config POWERNV select SSI_M25P80 select PNV_SPI -config PPC405 - bool - default y - depends on PPC - select M48T59 - select PFLASH_CFI02 - select PPC4XX - select SERIAL_MM - config PPC440 bool default y diff --git a/hw/ppc/meson.build b/hw/ppc/meson.build index 7cd9189869..9893f8adeb 100644 --- a/hw/ppc/meson.build +++ b/hw/ppc/meson.build @@ -57,9 +57,6 @@ ppc_ss.add(when: 'CONFIG_POWERNV', if_true: files( 'pnv_n1_chiplet.c', )) # PowerPC 4xx boards -ppc_ss.add(when: 'CONFIG_PPC405', if_true: files( - 'ppc405_boards.c', - 'ppc405_uc.c')) ppc_ss.add(when: 'CONFIG_PPC440', if_true: files( 'ppc440_bamboo.c', 'ppc440_uc.c')) diff --git a/hw/ppc/ppc405.h b/hw/ppc/ppc405.h deleted file mode 100644 index 9a4312691e..0000000000 --- a/hw/ppc/ppc405.h +++ /dev/null @@ -1,186 +0,0 @@ -/* - * QEMU PowerPC 405 shared definitions - * - * Copyright (c) 2007 Jocelyn Mayer - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL - * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - */ - -#ifndef PPC405_H -#define PPC405_H - -#include "qom/object.h" -#include "hw/ppc/ppc4xx.h" -#include "hw/intc/ppc-uic.h" -#include "hw/i2c/ppc4xx_i2c.h" - -/* PLB to OPB bridge */ -#define TYPE_PPC405_POB "ppc405-pob" -OBJECT_DECLARE_SIMPLE_TYPE(Ppc405PobState, PPC405_POB); -struct Ppc405PobState { - Ppc4xxDcrDeviceState parent_obj; - - uint32_t bear; - uint32_t besr0; - uint32_t besr1; -}; - -/* OPB arbitrer */ -#define TYPE_PPC405_OPBA "ppc405-opba" -OBJECT_DECLARE_SIMPLE_TYPE(Ppc405OpbaState, PPC405_OPBA); -struct Ppc405OpbaState { - SysBusDevice parent_obj; - - MemoryRegion io; - uint8_t cr; - uint8_t pr; -}; - -/* DMA controller */ -#define TYPE_PPC405_DMA "ppc405-dma" -OBJECT_DECLARE_SIMPLE_TYPE(Ppc405DmaState, PPC405_DMA); -struct Ppc405DmaState { - Ppc4xxDcrDeviceState parent_obj; - - qemu_irq irqs[4]; - uint32_t cr[4]; - uint32_t ct[4]; - uint32_t da[4]; - uint32_t sa[4]; - uint32_t sg[4]; - uint32_t sr; - uint32_t sgc; - uint32_t slp; - uint32_t pol; -}; - -/* GPIO */ -#define TYPE_PPC405_GPIO "ppc405-gpio" -OBJECT_DECLARE_SIMPLE_TYPE(Ppc405GpioState, PPC405_GPIO); -struct Ppc405GpioState { - SysBusDevice parent_obj; - - MemoryRegion io; - uint32_t or; - uint32_t tcr; - uint32_t osrh; - uint32_t osrl; - uint32_t tsrh; - uint32_t tsrl; - uint32_t odr; - uint32_t ir; - uint32_t rr1; - uint32_t isr1h; - uint32_t isr1l; -}; - -/* On Chip Memory */ -#define TYPE_PPC405_OCM "ppc405-ocm" -OBJECT_DECLARE_SIMPLE_TYPE(Ppc405OcmState, PPC405_OCM); -struct Ppc405OcmState { - Ppc4xxDcrDeviceState parent_obj; - - MemoryRegion ram; - MemoryRegion isarc_ram; - MemoryRegion dsarc_ram; - uint32_t isarc; - uint32_t isacntl; - uint32_t dsarc; - uint32_t dsacntl; -}; - -/* General purpose timers */ -#define TYPE_PPC405_GPT "ppc405-gpt" -OBJECT_DECLARE_SIMPLE_TYPE(Ppc405GptState, PPC405_GPT); -struct Ppc405GptState { - SysBusDevice parent_obj; - - MemoryRegion iomem; - - int64_t tb_offset; - uint32_t tb_freq; - QEMUTimer *timer; - qemu_irq irqs[5]; - uint32_t oe; - uint32_t ol; - uint32_t im; - uint32_t is; - uint32_t ie; - uint32_t comp[5]; - uint32_t mask[5]; -}; - -#define TYPE_PPC405_CPC "ppc405-cpc" -OBJECT_DECLARE_SIMPLE_TYPE(Ppc405CpcState, PPC405_CPC); - -enum { - PPC405EP_CPU_CLK = 0, - PPC405EP_PLB_CLK = 1, - PPC405EP_OPB_CLK = 2, - PPC405EP_EBC_CLK = 3, - PPC405EP_MAL_CLK = 4, - PPC405EP_PCI_CLK = 5, - PPC405EP_UART0_CLK = 6, - PPC405EP_UART1_CLK = 7, - PPC405EP_CLK_NB = 8, -}; - -struct Ppc405CpcState { - Ppc4xxDcrDeviceState parent_obj; - - uint32_t sysclk; - clk_setup_t clk_setup[PPC405EP_CLK_NB]; - uint32_t boot; - uint32_t epctl; - uint32_t pllmr[2]; - uint32_t ucr; - uint32_t srr; - uint32_t jtagid; - uint32_t pci; - /* Clock and power management */ - uint32_t er; - uint32_t fr; - uint32_t sr; -}; - -#define TYPE_PPC405_SOC "ppc405-soc" -OBJECT_DECLARE_SIMPLE_TYPE(Ppc405SoCState, PPC405_SOC); - -struct Ppc405SoCState { - /* Private */ - DeviceState parent_obj; - - /* Public */ - PowerPCCPU cpu; - PPCUIC uic; - Ppc405CpcState cpc; - Ppc405GptState gpt; - Ppc405OcmState ocm; - Ppc405GpioState gpio; - Ppc405DmaState dma; - PPC4xxI2CState i2c; - Ppc4xxEbcState ebc; - Ppc405OpbaState opba; - Ppc405PobState pob; - Ppc4xxPlbState plb; - Ppc4xxMalState mal; - Ppc4xxSdramDdrState sdram; -}; - -#endif /* PPC405_H */ diff --git a/hw/ppc/ppc405_boards.c b/hw/ppc/ppc405_boards.c deleted file mode 100644 index 969cac345a..0000000000 --- a/hw/ppc/ppc405_boards.c +++ /dev/null @@ -1,520 +0,0 @@ -/* - * QEMU PowerPC 405 evaluation boards emulation - * - * Copyright (c) 2007 Jocelyn Mayer - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL - * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - */ - -#include "qemu/osdep.h" -#include "qemu/units.h" -#include "qapi/error.h" -#include "qemu/datadir.h" -#include "cpu.h" -#include "hw/ppc/ppc.h" -#include "hw/qdev-properties.h" -#include "hw/sysbus.h" -#include "ppc405.h" -#include "hw/rtc/m48t59.h" -#include "hw/block/flash.h" -#include "system/qtest.h" -#include "system/reset.h" -#include "system/block-backend.h" -#include "hw/boards.h" -#include "qemu/error-report.h" -#include "hw/loader.h" -#include "qemu/cutils.h" -#include "elf.h" - -#define BIOS_FILENAME "ppc405_rom.bin" -#define BIOS_SIZE (2 * MiB) - -#define KERNEL_LOAD_ADDR 0x01000000 -#define INITRD_LOAD_ADDR 0x01800000 - -#define PPC405EP_SDRAM_BASE 0x00000000 -#define PPC405EP_SRAM_BASE 0xFFF00000 -#define PPC405EP_SRAM_SIZE (512 * KiB) - -#define USE_FLASH_BIOS - -#define TYPE_PPC405_MACHINE MACHINE_TYPE_NAME("ppc405") -OBJECT_DECLARE_SIMPLE_TYPE(Ppc405MachineState, PPC405_MACHINE); - -struct Ppc405MachineState { - /* Private */ - MachineState parent_obj; - /* Public */ - - Ppc405SoCState soc; -}; - -/* CPU reset handler when booting directly from a loaded kernel */ -static struct boot_info { - uint32_t entry; - uint32_t bdloc; - uint32_t initrd_base; - uint32_t initrd_size; - uint32_t cmdline_base; - uint32_t cmdline_size; -} boot_info; - -static void main_cpu_reset(void *opaque) -{ - PowerPCCPU *cpu = opaque; - CPUPPCState *env = &cpu->env; - struct boot_info *bi = env->load_info; - - cpu_reset(CPU(cpu)); - - /* stack: top of sram */ - env->gpr[1] = PPC405EP_SRAM_BASE + PPC405EP_SRAM_SIZE - 8; - - /* Tune our boot state */ - env->gpr[3] = bi->bdloc; - env->gpr[4] = bi->initrd_base; - env->gpr[5] = bi->initrd_base + bi->initrd_size; - env->gpr[6] = bi->cmdline_base; - env->gpr[7] = bi->cmdline_size; - - env->nip = bi->entry; -} - -/* Bootinfo as set-up by u-boot */ -typedef struct { - uint32_t bi_memstart; - uint32_t bi_memsize; - uint32_t bi_flashstart; - uint32_t bi_flashsize; - uint32_t bi_flashoffset; /* 0x10 */ - uint32_t bi_sramstart; - uint32_t bi_sramsize; - uint32_t bi_bootflags; - uint32_t bi_ipaddr; /* 0x20 */ - uint8_t bi_enetaddr[6]; - uint16_t bi_ethspeed; - uint32_t bi_intfreq; - uint32_t bi_busfreq; /* 0x30 */ - uint32_t bi_baudrate; - uint8_t bi_s_version[4]; - uint8_t bi_r_version[32]; - uint32_t bi_procfreq; - uint32_t bi_plb_busfreq; - uint32_t bi_pci_busfreq; - uint8_t bi_pci_enetaddr[6]; - uint8_t bi_pci_enetaddr2[6]; /* PPC405EP specific */ - uint32_t bi_opbfreq; - uint32_t bi_iic_fast[2]; -} ppc4xx_bd_info_t; - -static void ppc405_set_default_bootinfo(ppc4xx_bd_info_t *bd, - ram_addr_t ram_size) -{ - memset(bd, 0, sizeof(*bd)); - - bd->bi_memstart = PPC405EP_SDRAM_BASE; - bd->bi_memsize = ram_size; - bd->bi_sramstart = PPC405EP_SRAM_BASE; - bd->bi_sramsize = PPC405EP_SRAM_SIZE; - bd->bi_bootflags = 0; - bd->bi_intfreq = 133333333; - bd->bi_busfreq = 33333333; - bd->bi_baudrate = 115200; - bd->bi_s_version[0] = 'Q'; - bd->bi_s_version[1] = 'M'; - bd->bi_s_version[2] = 'U'; - bd->bi_s_version[3] = '\0'; - bd->bi_r_version[0] = 'Q'; - bd->bi_r_version[1] = 'E'; - bd->bi_r_version[2] = 'M'; - bd->bi_r_version[3] = 'U'; - bd->bi_r_version[4] = '\0'; - bd->bi_procfreq = 133333333; - bd->bi_plb_busfreq = 33333333; - bd->bi_pci_busfreq = 33333333; - bd->bi_opbfreq = 33333333; -} - -static ram_addr_t __ppc405_set_bootinfo(CPUPPCState *env, ppc4xx_bd_info_t *bd) -{ - CPUState *cs = env_cpu(env); - ram_addr_t bdloc; - int i, n; - - /* We put the bd structure at the top of memory */ - if (bd->bi_memsize >= 0x01000000UL) { - bdloc = 0x01000000UL - sizeof(ppc4xx_bd_info_t); - } else { - bdloc = bd->bi_memsize - sizeof(ppc4xx_bd_info_t); - } - stl_be_phys(cs->as, bdloc + 0x00, bd->bi_memstart); - stl_be_phys(cs->as, bdloc + 0x04, bd->bi_memsize); - stl_be_phys(cs->as, bdloc + 0x08, bd->bi_flashstart); - stl_be_phys(cs->as, bdloc + 0x0C, bd->bi_flashsize); - stl_be_phys(cs->as, bdloc + 0x10, bd->bi_flashoffset); - stl_be_phys(cs->as, bdloc + 0x14, bd->bi_sramstart); - stl_be_phys(cs->as, bdloc + 0x18, bd->bi_sramsize); - stl_be_phys(cs->as, bdloc + 0x1C, bd->bi_bootflags); - stl_be_phys(cs->as, bdloc + 0x20, bd->bi_ipaddr); - for (i = 0; i < 6; i++) { - stb_phys(cs->as, bdloc + 0x24 + i, bd->bi_enetaddr[i]); - } - stw_be_phys(cs->as, bdloc + 0x2A, bd->bi_ethspeed); - stl_be_phys(cs->as, bdloc + 0x2C, bd->bi_intfreq); - stl_be_phys(cs->as, bdloc + 0x30, bd->bi_busfreq); - stl_be_phys(cs->as, bdloc + 0x34, bd->bi_baudrate); - for (i = 0; i < 4; i++) { - stb_phys(cs->as, bdloc + 0x38 + i, bd->bi_s_version[i]); - } - for (i = 0; i < 32; i++) { - stb_phys(cs->as, bdloc + 0x3C + i, bd->bi_r_version[i]); - } - stl_be_phys(cs->as, bdloc + 0x5C, bd->bi_procfreq); - stl_be_phys(cs->as, bdloc + 0x60, bd->bi_plb_busfreq); - stl_be_phys(cs->as, bdloc + 0x64, bd->bi_pci_busfreq); - for (i = 0; i < 6; i++) { - stb_phys(cs->as, bdloc + 0x68 + i, bd->bi_pci_enetaddr[i]); - } - n = 0x70; /* includes 2 bytes hole */ - for (i = 0; i < 6; i++) { - stb_phys(cs->as, bdloc + n++, bd->bi_pci_enetaddr2[i]); - } - stl_be_phys(cs->as, bdloc + n, bd->bi_opbfreq); - n += 4; - for (i = 0; i < 2; i++) { - stl_be_phys(cs->as, bdloc + n, bd->bi_iic_fast[i]); - n += 4; - } - - return bdloc; -} - -static ram_addr_t ppc405_set_bootinfo(CPUPPCState *env, ram_addr_t ram_size) -{ - ppc4xx_bd_info_t bd; - - memset(&bd, 0, sizeof(bd)); - - ppc405_set_default_bootinfo(&bd, ram_size); - - return __ppc405_set_bootinfo(env, &bd); -} - -static void boot_from_kernel(MachineState *machine, PowerPCCPU *cpu) -{ - CPUPPCState *env = &cpu->env; - hwaddr boot_entry; - hwaddr kernel_base; - int kernel_size; - hwaddr initrd_base; - int initrd_size; - ram_addr_t bdloc; - int len; - - bdloc = ppc405_set_bootinfo(env, machine->ram_size); - boot_info.bdloc = bdloc; - - kernel_size = load_elf(machine->kernel_filename, NULL, NULL, NULL, - &boot_entry, &kernel_base, NULL, NULL, - ELFDATA2MSB, PPC_ELF_MACHINE, 0, 0); - if (kernel_size < 0) { - error_report("Could not load kernel '%s' : %s", - machine->kernel_filename, load_elf_strerror(kernel_size)); - exit(1); - } - boot_info.entry = boot_entry; - - /* load initrd */ - if (machine->initrd_filename) { - initrd_base = INITRD_LOAD_ADDR; - initrd_size = load_image_targphys(machine->initrd_filename, initrd_base, - machine->ram_size - initrd_base); - if (initrd_size < 0) { - error_report("could not load initial ram disk '%s'", - machine->initrd_filename); - exit(1); - } - - boot_info.initrd_base = initrd_base; - boot_info.initrd_size = initrd_size; - } - - if (machine->kernel_cmdline) { - len = strlen(machine->kernel_cmdline); - bdloc -= ((len + 255) & ~255); - cpu_physical_memory_write(bdloc, machine->kernel_cmdline, len + 1); - boot_info.cmdline_base = bdloc; - boot_info.cmdline_size = bdloc + len; - } - - /* Install our custom reset handler to start from Linux */ - qemu_register_reset(main_cpu_reset, cpu); - env->load_info = &boot_info; -} - -static void ppc405_init(MachineState *machine) -{ - Ppc405MachineState *ppc405 = PPC405_MACHINE(machine); - const char *kernel_filename = machine->kernel_filename; - MemoryRegion *sysmem = get_system_memory(); - - object_initialize_child(OBJECT(machine), "soc", &ppc405->soc, - TYPE_PPC405_SOC); - object_property_set_link(OBJECT(&ppc405->soc), "dram", - OBJECT(machine->ram), &error_abort); - object_property_set_uint(OBJECT(&ppc405->soc), "sys-clk", 33333333, - &error_abort); - qdev_realize(DEVICE(&ppc405->soc), NULL, &error_fatal); - - /* allocate and load BIOS */ - if (machine->firmware) { - MemoryRegion *bios = g_new(MemoryRegion, 1); - g_autofree char *filename = qemu_find_file(QEMU_FILE_TYPE_BIOS, - machine->firmware); - long bios_size; - - memory_region_init_rom(bios, NULL, "ef405ep.bios", BIOS_SIZE, - &error_fatal); - - if (!filename) { - error_report("Could not find firmware '%s'", machine->firmware); - exit(1); - } - - bios_size = load_image_size(filename, - memory_region_get_ram_ptr(bios), - BIOS_SIZE); - if (bios_size < 0) { - error_report("Could not load PowerPC BIOS '%s'", machine->firmware); - exit(1); - } - - bios_size = (bios_size + 0xfff) & ~0xfff; - memory_region_add_subregion(sysmem, (uint32_t)(-bios_size), bios); - } - - /* Load kernel and initrd using U-Boot images */ - if (kernel_filename && machine->firmware) { - target_ulong kernel_base, initrd_base; - long kernel_size, initrd_size; - - kernel_base = KERNEL_LOAD_ADDR; - kernel_size = load_image_targphys(kernel_filename, kernel_base, - machine->ram_size - kernel_base); - if (kernel_size < 0) { - error_report("could not load kernel '%s'", kernel_filename); - exit(1); - } - - /* load initrd */ - if (machine->initrd_filename) { - initrd_base = INITRD_LOAD_ADDR; - initrd_size = load_image_targphys(machine->initrd_filename, - initrd_base, - machine->ram_size - initrd_base); - if (initrd_size < 0) { - error_report("could not load initial ram disk '%s'", - machine->initrd_filename); - exit(1); - } - } - - /* Load ELF kernel and rootfs.cpio */ - } else if (kernel_filename && !machine->firmware) { - ppc4xx_sdram_ddr_enable(&ppc405->soc.sdram); - boot_from_kernel(machine, &ppc405->soc.cpu); - } -} - -static void ppc405_machine_class_init(ObjectClass *oc, void *data) -{ - MachineClass *mc = MACHINE_CLASS(oc); - - mc->desc = "PPC405 generic machine"; - mc->init = ppc405_init; - mc->default_ram_size = 128 * MiB; - mc->default_ram_id = "ppc405.ram"; - mc->deprecation_reason = "machine is old and unmaintained"; -} - -static const TypeInfo ppc405_machine_type = { - .name = TYPE_PPC405_MACHINE, - .parent = TYPE_MACHINE, - .instance_size = sizeof(Ppc405MachineState), - .class_init = ppc405_machine_class_init, - .abstract = true, -}; - -/*****************************************************************************/ -/* PPC405EP reference board (IBM) */ -/* - * Standalone board with: - * - PowerPC 405EP CPU - * - SDRAM (0x00000000) - * - Flash (0xFFF80000) - * - SRAM (0xFFF00000) - * - NVRAM (0xF0000000) - * - FPGA (0xF0300000) - */ - -#define PPC405EP_NVRAM_BASE 0xF0000000 -#define PPC405EP_FPGA_BASE 0xF0300000 -#define PPC405EP_FLASH_BASE 0xFFF80000 - -#define TYPE_REF405EP_FPGA "ref405ep-fpga" -OBJECT_DECLARE_SIMPLE_TYPE(Ref405epFpgaState, REF405EP_FPGA); -struct Ref405epFpgaState { - SysBusDevice parent_obj; - - MemoryRegion iomem; - - uint8_t reg0; - uint8_t reg1; -}; - -static uint64_t ref405ep_fpga_readb(void *opaque, hwaddr addr, unsigned size) -{ - Ref405epFpgaState *fpga = opaque; - uint32_t ret; - - switch (addr) { - case 0x0: - ret = fpga->reg0; - break; - case 0x1: - ret = fpga->reg1; - break; - default: - ret = 0; - break; - } - - return ret; -} - -static void ref405ep_fpga_writeb(void *opaque, hwaddr addr, uint64_t value, - unsigned size) -{ - Ref405epFpgaState *fpga = opaque; - - switch (addr) { - case 0x0: - /* Read only */ - break; - case 0x1: - fpga->reg1 = value; - break; - default: - break; - } -} - -static const MemoryRegionOps ref405ep_fpga_ops = { - .read = ref405ep_fpga_readb, - .write = ref405ep_fpga_writeb, - .impl.min_access_size = 1, - .impl.max_access_size = 1, - .valid.min_access_size = 1, - .valid.max_access_size = 4, - .endianness = DEVICE_BIG_ENDIAN, -}; - -static void ref405ep_fpga_reset(DeviceState *dev) -{ - Ref405epFpgaState *fpga = REF405EP_FPGA(dev); - - fpga->reg0 = 0x00; - fpga->reg1 = 0x0F; -} - -static void ref405ep_fpga_realize(DeviceState *dev, Error **errp) -{ - Ref405epFpgaState *s = REF405EP_FPGA(dev); - - memory_region_init_io(&s->iomem, OBJECT(s), &ref405ep_fpga_ops, s, - "fpga", 0x00000100); - sysbus_init_mmio(SYS_BUS_DEVICE(s), &s->iomem); -} - -static void ref405ep_fpga_class_init(ObjectClass *oc, void *data) -{ - DeviceClass *dc = DEVICE_CLASS(oc); - - dc->realize = ref405ep_fpga_realize; - device_class_set_legacy_reset(dc, ref405ep_fpga_reset); - /* Reason: only works as part of a ppc405 board */ - dc->user_creatable = false; -} - -static const TypeInfo ref405ep_fpga_type = { - .name = TYPE_REF405EP_FPGA, - .parent = TYPE_SYS_BUS_DEVICE, - .instance_size = sizeof(Ref405epFpgaState), - .class_init = ref405ep_fpga_class_init, -}; - -static void ref405ep_init(MachineState *machine) -{ - DeviceState *dev; - SysBusDevice *s; - MemoryRegion *sram = g_new(MemoryRegion, 1); - - ppc405_init(machine); - - /* allocate SRAM */ - memory_region_init_ram(sram, NULL, "ref405ep.sram", PPC405EP_SRAM_SIZE, - &error_fatal); - memory_region_add_subregion(get_system_memory(), PPC405EP_SRAM_BASE, sram); - - /* Register FPGA */ - dev = qdev_new(TYPE_REF405EP_FPGA); - object_property_add_child(OBJECT(machine), "fpga", OBJECT(dev)); - sysbus_realize_and_unref(SYS_BUS_DEVICE(dev), &error_fatal); - sysbus_mmio_map(SYS_BUS_DEVICE(dev), 0, PPC405EP_FPGA_BASE); - - /* Register NVRAM */ - dev = qdev_new("sysbus-m48t08"); - qdev_prop_set_int32(dev, "base-year", 1968); - s = SYS_BUS_DEVICE(dev); - sysbus_realize_and_unref(s, &error_fatal); - sysbus_mmio_map(s, 0, PPC405EP_NVRAM_BASE); -} - -static void ref405ep_class_init(ObjectClass *oc, void *data) -{ - MachineClass *mc = MACHINE_CLASS(oc); - - mc->desc = "ref405ep"; - mc->init = ref405ep_init; -} - -static const TypeInfo ref405ep_type = { - .name = MACHINE_TYPE_NAME("ref405ep"), - .parent = TYPE_PPC405_MACHINE, - .class_init = ref405ep_class_init, -}; - -static void ppc405_machine_init(void) -{ - type_register_static(&ppc405_machine_type); - type_register_static(&ref405ep_type); - type_register_static(&ref405ep_fpga_type); -} - -type_init(ppc405_machine_init) diff --git a/hw/ppc/ppc405_uc.c b/hw/ppc/ppc405_uc.c deleted file mode 100644 index 8250824a1a..0000000000 --- a/hw/ppc/ppc405_uc.c +++ /dev/null @@ -1,1216 +0,0 @@ -/* - * QEMU PowerPC 405 embedded processors emulation - * - * Copyright (c) 2007 Jocelyn Mayer - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL - * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - */ - -#include "qemu/osdep.h" -#include "qemu/units.h" -#include "qapi/error.h" -#include "qemu/log.h" -#include "cpu.h" -#include "hw/ppc/ppc.h" -#include "hw/i2c/ppc4xx_i2c.h" -#include "hw/irq.h" -#include "hw/qdev-properties.h" -#include "ppc405.h" -#include "hw/char/serial-mm.h" -#include "qemu/timer.h" -#include "system/reset.h" -#include "system/system.h" -#include "exec/address-spaces.h" -#include "hw/intc/ppc-uic.h" -#include "trace.h" - -/*****************************************************************************/ -/* Shared peripherals */ - -/*****************************************************************************/ -/* PLB to OPB bridge */ -enum { - POB0_BESR0 = 0x0A0, - POB0_BESR1 = 0x0A2, - POB0_BEAR = 0x0A4, -}; - -static uint32_t dcr_read_pob(void *opaque, int dcrn) -{ - Ppc405PobState *pob = opaque; - uint32_t ret; - - switch (dcrn) { - case POB0_BEAR: - ret = pob->bear; - break; - case POB0_BESR0: - ret = pob->besr0; - break; - case POB0_BESR1: - ret = pob->besr1; - break; - default: - /* Avoid gcc warning */ - ret = 0; - break; - } - - return ret; -} - -static void dcr_write_pob(void *opaque, int dcrn, uint32_t val) -{ - Ppc405PobState *pob = opaque; - - switch (dcrn) { - case POB0_BEAR: - /* Read only */ - break; - case POB0_BESR0: - /* Write-clear */ - pob->besr0 &= ~val; - break; - case POB0_BESR1: - /* Write-clear */ - pob->besr1 &= ~val; - break; - } -} - -static void ppc405_pob_reset(DeviceState *dev) -{ - Ppc405PobState *pob = PPC405_POB(dev); - - /* No error */ - pob->bear = 0x00000000; - pob->besr0 = 0x0000000; - pob->besr1 = 0x0000000; -} - -static void ppc405_pob_realize(DeviceState *dev, Error **errp) -{ - Ppc405PobState *pob = PPC405_POB(dev); - Ppc4xxDcrDeviceState *dcr = PPC4xx_DCR_DEVICE(dev); - - ppc4xx_dcr_register(dcr, POB0_BEAR, pob, &dcr_read_pob, &dcr_write_pob); - ppc4xx_dcr_register(dcr, POB0_BESR0, pob, &dcr_read_pob, &dcr_write_pob); - ppc4xx_dcr_register(dcr, POB0_BESR1, pob, &dcr_read_pob, &dcr_write_pob); -} - -static void ppc405_pob_class_init(ObjectClass *oc, void *data) -{ - DeviceClass *dc = DEVICE_CLASS(oc); - - dc->realize = ppc405_pob_realize; - device_class_set_legacy_reset(dc, ppc405_pob_reset); - /* Reason: only works as function of a ppc4xx SoC */ - dc->user_creatable = false; -} - -/*****************************************************************************/ -/* OPB arbitrer */ -static uint64_t opba_readb(void *opaque, hwaddr addr, unsigned size) -{ - Ppc405OpbaState *opba = opaque; - uint32_t ret; - - switch (addr) { - case 0x00: - ret = opba->cr; - break; - case 0x01: - ret = opba->pr; - break; - default: - ret = 0x00; - break; - } - - trace_opba_readb(addr, ret); - return ret; -} - -static void opba_writeb(void *opaque, hwaddr addr, uint64_t value, - unsigned size) -{ - Ppc405OpbaState *opba = opaque; - - trace_opba_writeb(addr, value); - - switch (addr) { - case 0x00: - opba->cr = value & 0xF8; - break; - case 0x01: - opba->pr = value & 0xFF; - break; - default: - break; - } -} -static const MemoryRegionOps opba_ops = { - .read = opba_readb, - .write = opba_writeb, - .impl.min_access_size = 1, - .impl.max_access_size = 1, - .valid.min_access_size = 1, - .valid.max_access_size = 4, - .endianness = DEVICE_BIG_ENDIAN, -}; - -static void ppc405_opba_reset(DeviceState *dev) -{ - Ppc405OpbaState *opba = PPC405_OPBA(dev); - - opba->cr = 0x00; /* No dynamic priorities - park disabled */ - opba->pr = 0x11; -} - -static void ppc405_opba_realize(DeviceState *dev, Error **errp) -{ - Ppc405OpbaState *s = PPC405_OPBA(dev); - - memory_region_init_io(&s->io, OBJECT(s), &opba_ops, s, "opba", 2); - sysbus_init_mmio(SYS_BUS_DEVICE(s), &s->io); -} - -static void ppc405_opba_class_init(ObjectClass *oc, void *data) -{ - DeviceClass *dc = DEVICE_CLASS(oc); - - dc->realize = ppc405_opba_realize; - device_class_set_legacy_reset(dc, ppc405_opba_reset); - /* Reason: only works as function of a ppc4xx SoC */ - dc->user_creatable = false; -} - -/*****************************************************************************/ -/* Code decompression controller */ -/* XXX: TODO */ - -/*****************************************************************************/ -/* DMA controller */ -enum { - DMA0_CR0 = 0x100, - DMA0_CT0 = 0x101, - DMA0_DA0 = 0x102, - DMA0_SA0 = 0x103, - DMA0_SG0 = 0x104, - DMA0_CR1 = 0x108, - DMA0_CT1 = 0x109, - DMA0_DA1 = 0x10A, - DMA0_SA1 = 0x10B, - DMA0_SG1 = 0x10C, - DMA0_CR2 = 0x110, - DMA0_CT2 = 0x111, - DMA0_DA2 = 0x112, - DMA0_SA2 = 0x113, - DMA0_SG2 = 0x114, - DMA0_CR3 = 0x118, - DMA0_CT3 = 0x119, - DMA0_DA3 = 0x11A, - DMA0_SA3 = 0x11B, - DMA0_SG3 = 0x11C, - DMA0_SR = 0x120, - DMA0_SGC = 0x123, - DMA0_SLP = 0x125, - DMA0_POL = 0x126, -}; - -static uint32_t dcr_read_dma(void *opaque, int dcrn) -{ - return 0; -} - -static void dcr_write_dma(void *opaque, int dcrn, uint32_t val) -{ -} - -static void ppc405_dma_reset(DeviceState *dev) -{ - Ppc405DmaState *dma = PPC405_DMA(dev); - int i; - - for (i = 0; i < 4; i++) { - dma->cr[i] = 0x00000000; - dma->ct[i] = 0x00000000; - dma->da[i] = 0x00000000; - dma->sa[i] = 0x00000000; - dma->sg[i] = 0x00000000; - } - dma->sr = 0x00000000; - dma->sgc = 0x00000000; - dma->slp = 0x7C000000; - dma->pol = 0x00000000; -} - -static void ppc405_dma_realize(DeviceState *dev, Error **errp) -{ - Ppc405DmaState *dma = PPC405_DMA(dev); - Ppc4xxDcrDeviceState *dcr = PPC4xx_DCR_DEVICE(dev); - int i; - - for (i = 0; i < ARRAY_SIZE(dma->irqs); i++) { - sysbus_init_irq(SYS_BUS_DEVICE(dma), &dma->irqs[i]); - } - - ppc4xx_dcr_register(dcr, DMA0_CR0, dma, &dcr_read_dma, &dcr_write_dma); - ppc4xx_dcr_register(dcr, DMA0_CT0, dma, &dcr_read_dma, &dcr_write_dma); - ppc4xx_dcr_register(dcr, DMA0_DA0, dma, &dcr_read_dma, &dcr_write_dma); - ppc4xx_dcr_register(dcr, DMA0_SA0, dma, &dcr_read_dma, &dcr_write_dma); - ppc4xx_dcr_register(dcr, DMA0_SG0, dma, &dcr_read_dma, &dcr_write_dma); - ppc4xx_dcr_register(dcr, DMA0_CR1, dma, &dcr_read_dma, &dcr_write_dma); - ppc4xx_dcr_register(dcr, DMA0_CT1, dma, &dcr_read_dma, &dcr_write_dma); - ppc4xx_dcr_register(dcr, DMA0_DA1, dma, &dcr_read_dma, &dcr_write_dma); - ppc4xx_dcr_register(dcr, DMA0_SA1, dma, &dcr_read_dma, &dcr_write_dma); - ppc4xx_dcr_register(dcr, DMA0_SG1, dma, &dcr_read_dma, &dcr_write_dma); - ppc4xx_dcr_register(dcr, DMA0_CR2, dma, &dcr_read_dma, &dcr_write_dma); - ppc4xx_dcr_register(dcr, DMA0_CT2, dma, &dcr_read_dma, &dcr_write_dma); - ppc4xx_dcr_register(dcr, DMA0_DA2, dma, &dcr_read_dma, &dcr_write_dma); - ppc4xx_dcr_register(dcr, DMA0_SA2, dma, &dcr_read_dma, &dcr_write_dma); - ppc4xx_dcr_register(dcr, DMA0_SG2, dma, &dcr_read_dma, &dcr_write_dma); - ppc4xx_dcr_register(dcr, DMA0_CR3, dma, &dcr_read_dma, &dcr_write_dma); - ppc4xx_dcr_register(dcr, DMA0_CT3, dma, &dcr_read_dma, &dcr_write_dma); - ppc4xx_dcr_register(dcr, DMA0_DA3, dma, &dcr_read_dma, &dcr_write_dma); - ppc4xx_dcr_register(dcr, DMA0_SA3, dma, &dcr_read_dma, &dcr_write_dma); - ppc4xx_dcr_register(dcr, DMA0_SG3, dma, &dcr_read_dma, &dcr_write_dma); - ppc4xx_dcr_register(dcr, DMA0_SR, dma, &dcr_read_dma, &dcr_write_dma); - ppc4xx_dcr_register(dcr, DMA0_SGC, dma, &dcr_read_dma, &dcr_write_dma); - ppc4xx_dcr_register(dcr, DMA0_SLP, dma, &dcr_read_dma, &dcr_write_dma); - ppc4xx_dcr_register(dcr, DMA0_POL, dma, &dcr_read_dma, &dcr_write_dma); -} - -static void ppc405_dma_class_init(ObjectClass *oc, void *data) -{ - DeviceClass *dc = DEVICE_CLASS(oc); - - dc->realize = ppc405_dma_realize; - device_class_set_legacy_reset(dc, ppc405_dma_reset); - /* Reason: only works as function of a ppc4xx SoC */ - dc->user_creatable = false; -} - -/*****************************************************************************/ -/* GPIO */ -static uint64_t ppc405_gpio_read(void *opaque, hwaddr addr, unsigned size) -{ - trace_ppc405_gpio_read(addr, size); - return 0; -} - -static void ppc405_gpio_write(void *opaque, hwaddr addr, uint64_t value, - unsigned size) -{ - trace_ppc405_gpio_write(addr, size, value); -} - -static const MemoryRegionOps ppc405_gpio_ops = { - .read = ppc405_gpio_read, - .write = ppc405_gpio_write, - .endianness = DEVICE_NATIVE_ENDIAN, -}; - -static void ppc405_gpio_realize(DeviceState *dev, Error **errp) -{ - Ppc405GpioState *s = PPC405_GPIO(dev); - - memory_region_init_io(&s->io, OBJECT(s), &ppc405_gpio_ops, s, "gpio", - 0x38); - sysbus_init_mmio(SYS_BUS_DEVICE(s), &s->io); -} - -static void ppc405_gpio_class_init(ObjectClass *oc, void *data) -{ - DeviceClass *dc = DEVICE_CLASS(oc); - - dc->realize = ppc405_gpio_realize; - /* Reason: only works as function of a ppc4xx SoC */ - dc->user_creatable = false; -} - -/*****************************************************************************/ -/* On Chip Memory */ -enum { - OCM0_ISARC = 0x018, - OCM0_ISACNTL = 0x019, - OCM0_DSARC = 0x01A, - OCM0_DSACNTL = 0x01B, -}; - -static void ocm_update_mappings(Ppc405OcmState *ocm, - uint32_t isarc, uint32_t isacntl, - uint32_t dsarc, uint32_t dsacntl) -{ - trace_ocm_update_mappings(isarc, isacntl, dsarc, dsacntl, ocm->isarc, - ocm->isacntl, ocm->dsarc, ocm->dsacntl); - - if (ocm->isarc != isarc || - (ocm->isacntl & 0x80000000) != (isacntl & 0x80000000)) { - if (ocm->isacntl & 0x80000000) { - /* Unmap previously assigned memory region */ - trace_ocm_unmap("ISA", ocm->isarc); - memory_region_del_subregion(get_system_memory(), &ocm->isarc_ram); - } - if (isacntl & 0x80000000) { - /* Map new instruction memory region */ - trace_ocm_map("ISA", isarc); - memory_region_add_subregion(get_system_memory(), isarc, - &ocm->isarc_ram); - } - } - if (ocm->dsarc != dsarc || - (ocm->dsacntl & 0x80000000) != (dsacntl & 0x80000000)) { - if (ocm->dsacntl & 0x80000000) { - /* Beware not to unmap the region we just mapped */ - if (!(isacntl & 0x80000000) || ocm->dsarc != isarc) { - /* Unmap previously assigned memory region */ - trace_ocm_unmap("DSA", ocm->dsarc); - memory_region_del_subregion(get_system_memory(), - &ocm->dsarc_ram); - } - } - if (dsacntl & 0x80000000) { - /* Beware not to remap the region we just mapped */ - if (!(isacntl & 0x80000000) || dsarc != isarc) { - /* Map new data memory region */ - trace_ocm_map("DSA", dsarc); - memory_region_add_subregion(get_system_memory(), dsarc, - &ocm->dsarc_ram); - } - } - } -} - -static uint32_t dcr_read_ocm(void *opaque, int dcrn) -{ - Ppc405OcmState *ocm = opaque; - uint32_t ret; - - switch (dcrn) { - case OCM0_ISARC: - ret = ocm->isarc; - break; - case OCM0_ISACNTL: - ret = ocm->isacntl; - break; - case OCM0_DSARC: - ret = ocm->dsarc; - break; - case OCM0_DSACNTL: - ret = ocm->dsacntl; - break; - default: - ret = 0; - break; - } - - return ret; -} - -static void dcr_write_ocm(void *opaque, int dcrn, uint32_t val) -{ - Ppc405OcmState *ocm = opaque; - uint32_t isarc, dsarc, isacntl, dsacntl; - - isarc = ocm->isarc; - dsarc = ocm->dsarc; - isacntl = ocm->isacntl; - dsacntl = ocm->dsacntl; - switch (dcrn) { - case OCM0_ISARC: - isarc = val & 0xFC000000; - break; - case OCM0_ISACNTL: - isacntl = val & 0xC0000000; - break; - case OCM0_DSARC: - isarc = val & 0xFC000000; - break; - case OCM0_DSACNTL: - isacntl = val & 0xC0000000; - break; - } - ocm_update_mappings(ocm, isarc, isacntl, dsarc, dsacntl); - ocm->isarc = isarc; - ocm->dsarc = dsarc; - ocm->isacntl = isacntl; - ocm->dsacntl = dsacntl; -} - -static void ppc405_ocm_reset(DeviceState *dev) -{ - Ppc405OcmState *ocm = PPC405_OCM(dev); - uint32_t isarc, dsarc, isacntl, dsacntl; - - isarc = 0x00000000; - isacntl = 0x00000000; - dsarc = 0x00000000; - dsacntl = 0x00000000; - ocm_update_mappings(ocm, isarc, isacntl, dsarc, dsacntl); - ocm->isarc = isarc; - ocm->dsarc = dsarc; - ocm->isacntl = isacntl; - ocm->dsacntl = dsacntl; -} - -static void ppc405_ocm_realize(DeviceState *dev, Error **errp) -{ - Ppc405OcmState *ocm = PPC405_OCM(dev); - Ppc4xxDcrDeviceState *dcr = PPC4xx_DCR_DEVICE(dev); - - /* XXX: Size is 4096 or 0x04000000 */ - memory_region_init_ram(&ocm->isarc_ram, OBJECT(ocm), "ppc405.ocm", 4 * KiB, - &error_fatal); - memory_region_init_alias(&ocm->dsarc_ram, OBJECT(ocm), "ppc405.dsarc", - &ocm->isarc_ram, 0, 4 * KiB); - - ppc4xx_dcr_register(dcr, OCM0_ISARC, ocm, &dcr_read_ocm, &dcr_write_ocm); - ppc4xx_dcr_register(dcr, OCM0_ISACNTL, ocm, &dcr_read_ocm, &dcr_write_ocm); - ppc4xx_dcr_register(dcr, OCM0_DSARC, ocm, &dcr_read_ocm, &dcr_write_ocm); - ppc4xx_dcr_register(dcr, OCM0_DSACNTL, ocm, &dcr_read_ocm, &dcr_write_ocm); -} - -static void ppc405_ocm_class_init(ObjectClass *oc, void *data) -{ - DeviceClass *dc = DEVICE_CLASS(oc); - - dc->realize = ppc405_ocm_realize; - device_class_set_legacy_reset(dc, ppc405_ocm_reset); - /* Reason: only works as function of a ppc4xx SoC */ - dc->user_creatable = false; -} - -/*****************************************************************************/ -/* General purpose timers */ -static int ppc4xx_gpt_compare(Ppc405GptState *gpt, int n) -{ - /* XXX: TODO */ - return 0; -} - -static void ppc4xx_gpt_set_output(Ppc405GptState *gpt, int n, int level) -{ - /* XXX: TODO */ -} - -static void ppc4xx_gpt_set_outputs(Ppc405GptState *gpt) -{ - uint32_t mask; - int i; - - mask = 0x80000000; - for (i = 0; i < 5; i++) { - if (gpt->oe & mask) { - /* Output is enabled */ - if (ppc4xx_gpt_compare(gpt, i)) { - /* Comparison is OK */ - ppc4xx_gpt_set_output(gpt, i, gpt->ol & mask); - } else { - /* Comparison is KO */ - ppc4xx_gpt_set_output(gpt, i, gpt->ol & mask ? 0 : 1); - } - } - mask = mask >> 1; - } -} - -static void ppc4xx_gpt_set_irqs(Ppc405GptState *gpt) -{ - uint32_t mask; - int i; - - mask = 0x00008000; - for (i = 0; i < 5; i++) { - if (gpt->is & gpt->im & mask) { - qemu_irq_raise(gpt->irqs[i]); - } else { - qemu_irq_lower(gpt->irqs[i]); - } - mask = mask >> 1; - } -} - -static void ppc4xx_gpt_compute_timer(Ppc405GptState *gpt) -{ - /* XXX: TODO */ -} - -static uint64_t ppc4xx_gpt_read(void *opaque, hwaddr addr, unsigned size) -{ - Ppc405GptState *gpt = opaque; - uint32_t ret; - int idx; - - trace_ppc4xx_gpt_read(addr, size); - - switch (addr) { - case 0x00: - /* Time base counter */ - ret = muldiv64(qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL) + gpt->tb_offset, - gpt->tb_freq, NANOSECONDS_PER_SECOND); - break; - case 0x10: - /* Output enable */ - ret = gpt->oe; - break; - case 0x14: - /* Output level */ - ret = gpt->ol; - break; - case 0x18: - /* Interrupt mask */ - ret = gpt->im; - break; - case 0x1C: - case 0x20: - /* Interrupt status */ - ret = gpt->is; - break; - case 0x24: - /* Interrupt enable */ - ret = gpt->ie; - break; - case 0x80 ... 0x90: - /* Compare timer */ - idx = (addr - 0x80) >> 2; - ret = gpt->comp[idx]; - break; - case 0xC0 ... 0xD0: - /* Compare mask */ - idx = (addr - 0xC0) >> 2; - ret = gpt->mask[idx]; - break; - default: - ret = -1; - break; - } - - return ret; -} - -static void ppc4xx_gpt_write(void *opaque, hwaddr addr, uint64_t value, - unsigned size) -{ - Ppc405GptState *gpt = opaque; - int idx; - - trace_ppc4xx_gpt_write(addr, size, value); - - switch (addr) { - case 0x00: - /* Time base counter */ - gpt->tb_offset = muldiv64(value, NANOSECONDS_PER_SECOND, gpt->tb_freq) - - qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL); - ppc4xx_gpt_compute_timer(gpt); - break; - case 0x10: - /* Output enable */ - gpt->oe = value & 0xF8000000; - ppc4xx_gpt_set_outputs(gpt); - break; - case 0x14: - /* Output level */ - gpt->ol = value & 0xF8000000; - ppc4xx_gpt_set_outputs(gpt); - break; - case 0x18: - /* Interrupt mask */ - gpt->im = value & 0x0000F800; - break; - case 0x1C: - /* Interrupt status set */ - gpt->is |= value & 0x0000F800; - ppc4xx_gpt_set_irqs(gpt); - break; - case 0x20: - /* Interrupt status clear */ - gpt->is &= ~(value & 0x0000F800); - ppc4xx_gpt_set_irqs(gpt); - break; - case 0x24: - /* Interrupt enable */ - gpt->ie = value & 0x0000F800; - ppc4xx_gpt_set_irqs(gpt); - break; - case 0x80 ... 0x90: - /* Compare timer */ - idx = (addr - 0x80) >> 2; - gpt->comp[idx] = value & 0xF8000000; - ppc4xx_gpt_compute_timer(gpt); - break; - case 0xC0 ... 0xD0: - /* Compare mask */ - idx = (addr - 0xC0) >> 2; - gpt->mask[idx] = value & 0xF8000000; - ppc4xx_gpt_compute_timer(gpt); - break; - } -} - -static const MemoryRegionOps gpt_ops = { - .read = ppc4xx_gpt_read, - .write = ppc4xx_gpt_write, - .valid.min_access_size = 4, - .valid.max_access_size = 4, - .endianness = DEVICE_NATIVE_ENDIAN, -}; - -static void ppc4xx_gpt_cb(void *opaque) -{ - Ppc405GptState *gpt = opaque; - - ppc4xx_gpt_set_irqs(gpt); - ppc4xx_gpt_set_outputs(gpt); - ppc4xx_gpt_compute_timer(gpt); -} - -static void ppc405_gpt_reset(DeviceState *dev) -{ - Ppc405GptState *gpt = PPC405_GPT(dev); - int i; - - timer_del(gpt->timer); - gpt->oe = 0x00000000; - gpt->ol = 0x00000000; - gpt->im = 0x00000000; - gpt->is = 0x00000000; - gpt->ie = 0x00000000; - for (i = 0; i < 5; i++) { - gpt->comp[i] = 0x00000000; - gpt->mask[i] = 0x00000000; - } -} - -static void ppc405_gpt_realize(DeviceState *dev, Error **errp) -{ - Ppc405GptState *s = PPC405_GPT(dev); - SysBusDevice *sbd = SYS_BUS_DEVICE(dev); - int i; - - s->timer = timer_new_ns(QEMU_CLOCK_VIRTUAL, &ppc4xx_gpt_cb, s); - memory_region_init_io(&s->iomem, OBJECT(s), &gpt_ops, s, "gpt", 0xd4); - sysbus_init_mmio(sbd, &s->iomem); - - for (i = 0; i < ARRAY_SIZE(s->irqs); i++) { - sysbus_init_irq(sbd, &s->irqs[i]); - } -} - -static void ppc405_gpt_finalize(Object *obj) -{ - /* timer will be NULL if the GPT wasn't realized */ - if (PPC405_GPT(obj)->timer) { - timer_del(PPC405_GPT(obj)->timer); - } -} - -static void ppc405_gpt_class_init(ObjectClass *oc, void *data) -{ - DeviceClass *dc = DEVICE_CLASS(oc); - - dc->realize = ppc405_gpt_realize; - device_class_set_legacy_reset(dc, ppc405_gpt_reset); - /* Reason: only works as function of a ppc4xx SoC */ - dc->user_creatable = false; -} - -/*****************************************************************************/ -/* PowerPC 405EP */ -/* CPU control */ -enum { - PPC405EP_CPC0_PLLMR0 = 0x0F0, - PPC405EP_CPC0_BOOT = 0x0F1, - PPC405EP_CPC0_EPCTL = 0x0F3, - PPC405EP_CPC0_PLLMR1 = 0x0F4, - PPC405EP_CPC0_UCR = 0x0F5, - PPC405EP_CPC0_SRR = 0x0F6, - PPC405EP_CPC0_JTAGID = 0x0F7, - PPC405EP_CPC0_PCI = 0x0F9, -#if 0 - PPC405EP_CPC0_ER = xxx, - PPC405EP_CPC0_FR = xxx, - PPC405EP_CPC0_SR = xxx, -#endif -}; - -static void ppc405ep_compute_clocks(Ppc405CpcState *cpc) -{ - uint32_t CPU_clk, PLB_clk, OPB_clk, EBC_clk, MAL_clk, PCI_clk; - uint32_t UART0_clk, UART1_clk; - uint64_t VCO_out, PLL_out; - int M, D; - - VCO_out = 0; - if ((cpc->pllmr[1] & 0x80000000) && !(cpc->pllmr[1] & 0x40000000)) { - M = (((cpc->pllmr[1] >> 20) - 1) & 0xF) + 1; /* FBMUL */ - trace_ppc405ep_clocks_compute("FBMUL", (cpc->pllmr[1] >> 20) & 0xF, M); - D = 8 - ((cpc->pllmr[1] >> 16) & 0x7); /* FWDA */ - trace_ppc405ep_clocks_compute("FWDA", (cpc->pllmr[1] >> 16) & 0x7, D); - VCO_out = (uint64_t)cpc->sysclk * M * D; - if (VCO_out < 500000000UL || VCO_out > 1000000000UL) { - /* Error - unlock the PLL */ - qemu_log_mask(LOG_GUEST_ERROR, "VCO out of range %" PRIu64 "\n", - VCO_out); -#if 0 - cpc->pllmr[1] &= ~0x80000000; - goto pll_bypass; -#endif - } - PLL_out = VCO_out / D; - /* Pretend the PLL is locked */ - cpc->boot |= 0x00000001; - } else { -#if 0 - pll_bypass: -#endif - PLL_out = cpc->sysclk; - if (cpc->pllmr[1] & 0x40000000) { - /* Pretend the PLL is not locked */ - cpc->boot &= ~0x00000001; - } - } - /* Now, compute all other clocks */ - D = ((cpc->pllmr[0] >> 20) & 0x3) + 1; /* CCDV */ - trace_ppc405ep_clocks_compute("CCDV", (cpc->pllmr[0] >> 20) & 0x3, D); - CPU_clk = PLL_out / D; - D = ((cpc->pllmr[0] >> 16) & 0x3) + 1; /* CBDV */ - trace_ppc405ep_clocks_compute("CBDV", (cpc->pllmr[0] >> 16) & 0x3, D); - PLB_clk = CPU_clk / D; - D = ((cpc->pllmr[0] >> 12) & 0x3) + 1; /* OPDV */ - trace_ppc405ep_clocks_compute("OPDV", (cpc->pllmr[0] >> 12) & 0x3, D); - OPB_clk = PLB_clk / D; - D = ((cpc->pllmr[0] >> 8) & 0x3) + 2; /* EPDV */ - trace_ppc405ep_clocks_compute("EPDV", (cpc->pllmr[0] >> 8) & 0x3, D); - EBC_clk = PLB_clk / D; - D = ((cpc->pllmr[0] >> 4) & 0x3) + 1; /* MPDV */ - trace_ppc405ep_clocks_compute("MPDV", (cpc->pllmr[0] >> 4) & 0x3, D); - MAL_clk = PLB_clk / D; - D = (cpc->pllmr[0] & 0x3) + 1; /* PPDV */ - trace_ppc405ep_clocks_compute("PPDV", cpc->pllmr[0] & 0x3, D); - PCI_clk = PLB_clk / D; - D = ((cpc->ucr - 1) & 0x7F) + 1; /* U0DIV */ - trace_ppc405ep_clocks_compute("U0DIV", cpc->ucr & 0x7F, D); - UART0_clk = PLL_out / D; - D = (((cpc->ucr >> 8) - 1) & 0x7F) + 1; /* U1DIV */ - trace_ppc405ep_clocks_compute("U1DIV", (cpc->ucr >> 8) & 0x7F, D); - UART1_clk = PLL_out / D; - - if (trace_event_get_state_backends(TRACE_PPC405EP_CLOCKS_SETUP)) { - g_autofree char *trace = g_strdup_printf( - "Setup PPC405EP clocks - sysclk %" PRIu32 " VCO %" PRIu64 - " PLL out %" PRIu64 " Hz\n" - "CPU %" PRIu32 " PLB %" PRIu32 " OPB %" PRIu32 " EBC %" PRIu32 - " MAL %" PRIu32 " PCI %" PRIu32 " UART0 %" PRIu32 - " UART1 %" PRIu32 "\n", - cpc->sysclk, VCO_out, PLL_out, - CPU_clk, PLB_clk, OPB_clk, EBC_clk, MAL_clk, PCI_clk, - UART0_clk, UART1_clk); - trace_ppc405ep_clocks_setup(trace); - } - - /* Setup CPU clocks */ - clk_setup(&cpc->clk_setup[PPC405EP_CPU_CLK], CPU_clk); - /* Setup PLB clock */ - clk_setup(&cpc->clk_setup[PPC405EP_PLB_CLK], PLB_clk); - /* Setup OPB clock */ - clk_setup(&cpc->clk_setup[PPC405EP_OPB_CLK], OPB_clk); - /* Setup external clock */ - clk_setup(&cpc->clk_setup[PPC405EP_EBC_CLK], EBC_clk); - /* Setup MAL clock */ - clk_setup(&cpc->clk_setup[PPC405EP_MAL_CLK], MAL_clk); - /* Setup PCI clock */ - clk_setup(&cpc->clk_setup[PPC405EP_PCI_CLK], PCI_clk); - /* Setup UART0 clock */ - clk_setup(&cpc->clk_setup[PPC405EP_UART0_CLK], UART0_clk); - /* Setup UART1 clock */ - clk_setup(&cpc->clk_setup[PPC405EP_UART1_CLK], UART1_clk); -} - -static uint32_t dcr_read_epcpc(void *opaque, int dcrn) -{ - Ppc405CpcState *cpc = opaque; - uint32_t ret; - - switch (dcrn) { - case PPC405EP_CPC0_BOOT: - ret = cpc->boot; - break; - case PPC405EP_CPC0_EPCTL: - ret = cpc->epctl; - break; - case PPC405EP_CPC0_PLLMR0: - ret = cpc->pllmr[0]; - break; - case PPC405EP_CPC0_PLLMR1: - ret = cpc->pllmr[1]; - break; - case PPC405EP_CPC0_UCR: - ret = cpc->ucr; - break; - case PPC405EP_CPC0_SRR: - ret = cpc->srr; - break; - case PPC405EP_CPC0_JTAGID: - ret = cpc->jtagid; - break; - case PPC405EP_CPC0_PCI: - ret = cpc->pci; - break; - default: - /* Avoid gcc warning */ - ret = 0; - break; - } - - return ret; -} - -static void dcr_write_epcpc(void *opaque, int dcrn, uint32_t val) -{ - Ppc405CpcState *cpc = opaque; - - switch (dcrn) { - case PPC405EP_CPC0_BOOT: - /* Read-only register */ - break; - case PPC405EP_CPC0_EPCTL: - /* Don't care for now */ - cpc->epctl = val & 0xC00000F3; - break; - case PPC405EP_CPC0_PLLMR0: - cpc->pllmr[0] = val & 0x00633333; - ppc405ep_compute_clocks(cpc); - break; - case PPC405EP_CPC0_PLLMR1: - cpc->pllmr[1] = val & 0xC0F73FFF; - ppc405ep_compute_clocks(cpc); - break; - case PPC405EP_CPC0_UCR: - /* UART control - don't care for now */ - cpc->ucr = val & 0x003F7F7F; - break; - case PPC405EP_CPC0_SRR: - cpc->srr = val; - break; - case PPC405EP_CPC0_JTAGID: - /* Read-only */ - break; - case PPC405EP_CPC0_PCI: - cpc->pci = val; - break; - } -} - -static void ppc405_cpc_reset(DeviceState *dev) -{ - Ppc405CpcState *cpc = PPC405_CPC(dev); - - cpc->boot = 0x00000010; /* Boot from PCI - IIC EEPROM disabled */ - cpc->epctl = 0x00000000; - cpc->pllmr[0] = 0x00021002; - cpc->pllmr[1] = 0x80a552be; - cpc->ucr = 0x00004646; - cpc->srr = 0x00040000; - cpc->pci = 0x00000000; - cpc->er = 0x00000000; - cpc->fr = 0x00000000; - cpc->sr = 0x00000000; - cpc->jtagid = 0x20267049; - ppc405ep_compute_clocks(cpc); -} - -/* XXX: sysclk should be between 25 and 100 MHz */ -static void ppc405_cpc_realize(DeviceState *dev, Error **errp) -{ - Ppc405CpcState *cpc = PPC405_CPC(dev); - Ppc4xxDcrDeviceState *dcr = PPC4xx_DCR_DEVICE(dev); - - assert(dcr->cpu); - cpc->clk_setup[PPC405EP_CPU_CLK].cb = - ppc_40x_timers_init(&dcr->cpu->env, cpc->sysclk, PPC_INTERRUPT_PIT); - cpc->clk_setup[PPC405EP_CPU_CLK].opaque = &dcr->cpu->env; - - ppc4xx_dcr_register(dcr, PPC405EP_CPC0_BOOT, cpc, - &dcr_read_epcpc, &dcr_write_epcpc); - ppc4xx_dcr_register(dcr, PPC405EP_CPC0_EPCTL, cpc, - &dcr_read_epcpc, &dcr_write_epcpc); - ppc4xx_dcr_register(dcr, PPC405EP_CPC0_PLLMR0, cpc, - &dcr_read_epcpc, &dcr_write_epcpc); - ppc4xx_dcr_register(dcr, PPC405EP_CPC0_PLLMR1, cpc, - &dcr_read_epcpc, &dcr_write_epcpc); - ppc4xx_dcr_register(dcr, PPC405EP_CPC0_UCR, cpc, - &dcr_read_epcpc, &dcr_write_epcpc); - ppc4xx_dcr_register(dcr, PPC405EP_CPC0_SRR, cpc, - &dcr_read_epcpc, &dcr_write_epcpc); - ppc4xx_dcr_register(dcr, PPC405EP_CPC0_JTAGID, cpc, - &dcr_read_epcpc, &dcr_write_epcpc); - ppc4xx_dcr_register(dcr, PPC405EP_CPC0_PCI, cpc, - &dcr_read_epcpc, &dcr_write_epcpc); -} - -static const Property ppc405_cpc_properties[] = { - DEFINE_PROP_UINT32("sys-clk", Ppc405CpcState, sysclk, 0), -}; - -static void ppc405_cpc_class_init(ObjectClass *oc, void *data) -{ - DeviceClass *dc = DEVICE_CLASS(oc); - - dc->realize = ppc405_cpc_realize; - device_class_set_legacy_reset(dc, ppc405_cpc_reset); - /* Reason: only works as function of a ppc4xx SoC */ - dc->user_creatable = false; - device_class_set_props(dc, ppc405_cpc_properties); -} - -/* PPC405_SOC */ - -static void ppc405_soc_instance_init(Object *obj) -{ - Ppc405SoCState *s = PPC405_SOC(obj); - - object_initialize_child(obj, "cpu", &s->cpu, - POWERPC_CPU_TYPE_NAME("405ep")); - - object_initialize_child(obj, "uic", &s->uic, TYPE_PPC_UIC); - - object_initialize_child(obj, "cpc", &s->cpc, TYPE_PPC405_CPC); - object_property_add_alias(obj, "sys-clk", OBJECT(&s->cpc), "sys-clk"); - - object_initialize_child(obj, "gpt", &s->gpt, TYPE_PPC405_GPT); - - object_initialize_child(obj, "ocm", &s->ocm, TYPE_PPC405_OCM); - - object_initialize_child(obj, "gpio", &s->gpio, TYPE_PPC405_GPIO); - - object_initialize_child(obj, "dma", &s->dma, TYPE_PPC405_DMA); - - object_initialize_child(obj, "i2c", &s->i2c, TYPE_PPC4xx_I2C); - - object_initialize_child(obj, "ebc", &s->ebc, TYPE_PPC4xx_EBC); - - object_initialize_child(obj, "opba", &s->opba, TYPE_PPC405_OPBA); - - object_initialize_child(obj, "pob", &s->pob, TYPE_PPC405_POB); - - object_initialize_child(obj, "plb", &s->plb, TYPE_PPC4xx_PLB); - - object_initialize_child(obj, "mal", &s->mal, TYPE_PPC4xx_MAL); - - object_initialize_child(obj, "sdram", &s->sdram, TYPE_PPC4xx_SDRAM_DDR); - object_property_add_alias(obj, "dram", OBJECT(&s->sdram), "dram"); -} - -static void ppc405_reset(void *opaque) -{ - cpu_reset(CPU(opaque)); -} - -static void ppc405_soc_realize(DeviceState *dev, Error **errp) -{ - Ppc405SoCState *s = PPC405_SOC(dev); - CPUPPCState *env; - SysBusDevice *sbd; - int i; - - /* init CPUs */ - if (!qdev_realize(DEVICE(&s->cpu), NULL, errp)) { - return; - } - qemu_register_reset(ppc405_reset, &s->cpu); - - env = &s->cpu.env; - - ppc_dcr_init(env, NULL, NULL); - - /* CPU control */ - if (!ppc4xx_dcr_realize(PPC4xx_DCR_DEVICE(&s->cpc), &s->cpu, errp)) { - return; - } - - /* PLB arbitrer */ - if (!ppc4xx_dcr_realize(PPC4xx_DCR_DEVICE(&s->plb), &s->cpu, errp)) { - return; - } - - /* PLB to OPB bridge */ - if (!ppc4xx_dcr_realize(PPC4xx_DCR_DEVICE(&s->pob), &s->cpu, errp)) { - return; - } - - /* OBP arbitrer */ - sbd = SYS_BUS_DEVICE(&s->opba); - if (!sysbus_realize(sbd, errp)) { - return; - } - sysbus_mmio_map(sbd, 0, 0xef600600); - - /* Universal interrupt controller */ - if (!ppc4xx_dcr_realize(PPC4xx_DCR_DEVICE(&s->uic), &s->cpu, errp)) { - return; - } - sbd = SYS_BUS_DEVICE(&s->uic); - sysbus_connect_irq(sbd, PPCUIC_OUTPUT_INT, - qdev_get_gpio_in(DEVICE(&s->cpu), PPC40x_INPUT_INT)); - sysbus_connect_irq(sbd, PPCUIC_OUTPUT_CINT, - qdev_get_gpio_in(DEVICE(&s->cpu), PPC40x_INPUT_CINT)); - - /* SDRAM controller */ - /* - * We use the 440 DDR SDRAM controller which has more regs and features - * but it's compatible enough for now - */ - object_property_set_int(OBJECT(&s->sdram), "nbanks", 2, &error_abort); - if (!ppc4xx_dcr_realize(PPC4xx_DCR_DEVICE(&s->sdram), &s->cpu, errp)) { - return; - } - /* XXX 405EP has no ECC interrupt */ - sysbus_connect_irq(SYS_BUS_DEVICE(&s->sdram), 0, - qdev_get_gpio_in(DEVICE(&s->uic), 17)); - - /* External bus controller */ - if (!ppc4xx_dcr_realize(PPC4xx_DCR_DEVICE(&s->ebc), &s->cpu, errp)) { - return; - } - - /* DMA controller */ - if (!ppc4xx_dcr_realize(PPC4xx_DCR_DEVICE(&s->dma), &s->cpu, errp)) { - return; - } - sbd = SYS_BUS_DEVICE(&s->dma); - for (i = 0; i < ARRAY_SIZE(s->dma.irqs); i++) { - sysbus_connect_irq(sbd, i, qdev_get_gpio_in(DEVICE(&s->uic), 5 + i)); - } - - /* I2C controller */ - sbd = SYS_BUS_DEVICE(&s->i2c); - if (!sysbus_realize(sbd, errp)) { - return; - } - sysbus_mmio_map(sbd, 0, 0xef600500); - sysbus_connect_irq(sbd, 0, qdev_get_gpio_in(DEVICE(&s->uic), 2)); - - /* GPIO */ - sbd = SYS_BUS_DEVICE(&s->gpio); - if (!sysbus_realize(sbd, errp)) { - return; - } - sysbus_mmio_map(sbd, 0, 0xef600700); - - /* Serial ports */ - if (serial_hd(0) != NULL) { - serial_mm_init(get_system_memory(), 0xef600300, 0, - qdev_get_gpio_in(DEVICE(&s->uic), 0), - PPC_SERIAL_MM_BAUDBASE, serial_hd(0), - DEVICE_BIG_ENDIAN); - } - if (serial_hd(1) != NULL) { - serial_mm_init(get_system_memory(), 0xef600400, 0, - qdev_get_gpio_in(DEVICE(&s->uic), 1), - PPC_SERIAL_MM_BAUDBASE, serial_hd(1), - DEVICE_BIG_ENDIAN); - } - - /* OCM */ - if (!ppc4xx_dcr_realize(PPC4xx_DCR_DEVICE(&s->ocm), &s->cpu, errp)) { - return; - } - - /* GPT */ - sbd = SYS_BUS_DEVICE(&s->gpt); - if (!sysbus_realize(sbd, errp)) { - return; - } - sysbus_mmio_map(sbd, 0, 0xef600000); - for (i = 0; i < ARRAY_SIZE(s->gpt.irqs); i++) { - sysbus_connect_irq(sbd, i, qdev_get_gpio_in(DEVICE(&s->uic), 19 + i)); - } - - /* MAL */ - object_property_set_int(OBJECT(&s->mal), "txc-num", 4, &error_abort); - object_property_set_int(OBJECT(&s->mal), "rxc-num", 2, &error_abort); - if (!ppc4xx_dcr_realize(PPC4xx_DCR_DEVICE(&s->mal), &s->cpu, errp)) { - return; - } - sbd = SYS_BUS_DEVICE(&s->mal); - for (i = 0; i < ARRAY_SIZE(s->mal.irqs); i++) { - sysbus_connect_irq(sbd, i, qdev_get_gpio_in(DEVICE(&s->uic), 11 + i)); - } - - /* Ethernet */ - /* Uses UIC IRQs 9, 15, 17 */ -} - -static void ppc405_soc_class_init(ObjectClass *oc, void *data) -{ - DeviceClass *dc = DEVICE_CLASS(oc); - - dc->realize = ppc405_soc_realize; - /* Reason: only works as part of a ppc405 board/machine */ - dc->user_creatable = false; -} - -static const TypeInfo ppc405_types[] = { - { - .name = TYPE_PPC405_POB, - .parent = TYPE_PPC4xx_DCR_DEVICE, - .instance_size = sizeof(Ppc405PobState), - .class_init = ppc405_pob_class_init, - }, { - .name = TYPE_PPC405_OPBA, - .parent = TYPE_SYS_BUS_DEVICE, - .instance_size = sizeof(Ppc405OpbaState), - .class_init = ppc405_opba_class_init, - }, { - .name = TYPE_PPC405_DMA, - .parent = TYPE_PPC4xx_DCR_DEVICE, - .instance_size = sizeof(Ppc405DmaState), - .class_init = ppc405_dma_class_init, - }, { - .name = TYPE_PPC405_GPIO, - .parent = TYPE_SYS_BUS_DEVICE, - .instance_size = sizeof(Ppc405GpioState), - .class_init = ppc405_gpio_class_init, - }, { - .name = TYPE_PPC405_OCM, - .parent = TYPE_PPC4xx_DCR_DEVICE, - .instance_size = sizeof(Ppc405OcmState), - .class_init = ppc405_ocm_class_init, - }, { - .name = TYPE_PPC405_GPT, - .parent = TYPE_SYS_BUS_DEVICE, - .instance_size = sizeof(Ppc405GptState), - .instance_finalize = ppc405_gpt_finalize, - .class_init = ppc405_gpt_class_init, - }, { - .name = TYPE_PPC405_CPC, - .parent = TYPE_PPC4xx_DCR_DEVICE, - .instance_size = sizeof(Ppc405CpcState), - .class_init = ppc405_cpc_class_init, - }, { - .name = TYPE_PPC405_SOC, - .parent = TYPE_DEVICE, - .instance_size = sizeof(Ppc405SoCState), - .instance_init = ppc405_soc_instance_init, - .class_init = ppc405_soc_class_init, - } -}; - -DEFINE_TYPES(ppc405_types) From patchwork Tue Mar 11 12:56:57 2025 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: Nicholas Piggin X-Patchwork-Id: 14011789 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.lore.kernel.org (Postfix) with ESMTPS id BD707C282EC for ; Tue, 11 Mar 2025 13:00:34 +0000 (UTC) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1trzCA-0001AZ-00; Tue, 11 Mar 2025 08:58:54 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1trzC2-0000xa-Ch; Tue, 11 Mar 2025 08:58:46 -0400 Received: from mail-pj1-x102c.google.com ([2607:f8b0:4864:20::102c]) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_128_GCM_SHA256:128) (Exim 4.90_1) (envelope-from ) id 1trzBs-0007pE-Ur; Tue, 11 Mar 2025 08:58:46 -0400 Received: by mail-pj1-x102c.google.com with SMTP id 98e67ed59e1d1-2ff80290debso7719591a91.3; Tue, 11 Mar 2025 05:58:35 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20230601; t=1741697914; x=1742302714; darn=nongnu.org; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to; bh=sBgrSU/V9kiJHYlPQWXMJ6s9y81s7RCCnVq7DtgjGLI=; b=RvCu2h6SQ4K1A5XZ/zwwX8z0ORn0Y8ZU02QGHhOCD8bPzynVdovCZ8BwP3Ae6HHHvd qnk6cmePQsD7kBDKcgOKhiP+KHSvYy7f0iH6fp++Zprqa9icIiWeYPaFOXM4Wg1FrLJT kGHW3DYmmHrs/ED064+3apWU3LhhIBv4S73FJZxsqJGbpba24kV+xdogVCTB7UjIqPNE tP2KfM/8vWlIjFFQlJkEMpdsPZMnZf1jMX9cIEAbgNu1czRHT3/Tq25AFjsGk5WRVqCw ZbCfazQA0DKhzjIMskIImMbBjJ51jDMDDx5E6cSi7jOOYOyVpiLddcK3eNAfkcYgf0Qj CNww== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1741697914; x=1742302714; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=sBgrSU/V9kiJHYlPQWXMJ6s9y81s7RCCnVq7DtgjGLI=; b=LREkTCp9j+nfWkTHTZ4RHJVs4fT1MIUT5qssqO+U5K+Ne5FgyVdQLXwRb9LB1pQG9u wnjYvwWGNsMj8FDivi2ZqeMifRZDbTese91quJcPTIul2rS43Nl5RskOuMal2lI2FxVa hKQSzdKBf/fjQKygmQpvAG54zeCOo7FnAa7g1lyVoCus6RoH8/iIa7UkGRVRZtfPaMjE QAUSMzXbBZpUS7Ckt7GlrrJlMpq19PkNlwVoCLDgSGMgyAtEV9O/Xh3RkGeqxge3unxy y9saf9Yxw97+BdD67LXwFJJAkJ0fFzL+2e38NDOyp41pwmn5NnFXw38p9QK0KOIZpAoK +qOw== X-Forwarded-Encrypted: i=1; AJvYcCWWmpsbMbZPS99fT2RdigvurkQU5rwUIuk+ybYDP2rHhUrjHCs7Rio7bwZn/6+VZtgzbji06MxstQ==@nongnu.org X-Gm-Message-State: AOJu0Yxf6LbiaDyghklLQfMMIgfmkh5mQuEwQ2FHsDiKq4c3eQNbOV5c Gdr64HAWL+sMwe7Fc8CzSYF6G5wlqi/CcP5zQ5CkSdvK0TaVJ3V7L497TA== X-Gm-Gg: ASbGncv/lo6//BXXZ7Vk4KS/LZRJmUD7hI03SLJH76v9J4pwo0oYnEx0jvUguPkqzQf gz7l0hXWAuMBvDNxxfRPoqjDysZvnZMpuNz9MFwb2hQQ+7E6PMA8wzTOoXtrF5VYSQ0xIIo56cA QCWY5td5Qf6kIrzzL2pmb7Bxh82kPKfyDBuhkkvk/w+LHcCAs8F1wbL/stuwhXwK5gSNCHl7Qpq qQ9JYYd4kCGiA21wGscQkCZzW+aQLocZIHeS0PSMZfnCdBIrjsnv6nNFMf+YIcFvPKzsp+Ke3V1 piUv7caxjwrG4sV7awfSitXFLg8vgI3mPmPc9LEKU27HOuJS11Pa0ROr2X8eMQ== X-Google-Smtp-Source: AGHT+IFjxpTwGyFJIK61Ujhn4nfL8tUwiE4L9lGL6UtH8mIRIcJfvV2tskX7D61uLejfWBGjJbpMTQ== X-Received: by 2002:a17:90b:2d82:b0:2ff:6aa6:47a3 with SMTP id 98e67ed59e1d1-2ff7ced8c45mr27732195a91.25.1741697914329; Tue, 11 Mar 2025 05:58:34 -0700 (PDT) Received: from wheely.local0.net ([118.208.151.101]) by smtp.gmail.com with ESMTPSA id 98e67ed59e1d1-2ff4e773dddsm11822318a91.12.2025.03.11.05.58.32 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 11 Mar 2025 05:58:33 -0700 (PDT) From: Nicholas Piggin To: qemu-devel@nongnu.org Cc: Nicholas Piggin , qemu-ppc@nongnu.org, =?utf-8?q?C?= =?utf-8?q?=C3=A9dric_Le_Goater?= Subject: [PULL 03/72] hw/ppc: Deprecate 405 CPUs Date: Tue, 11 Mar 2025 22:56:57 +1000 Message-ID: <20250311125815.903177-4-npiggin@gmail.com> X-Mailer: git-send-email 2.47.1 In-Reply-To: <20250311125815.903177-1-npiggin@gmail.com> References: <20250311125815.903177-1-npiggin@gmail.com> MIME-Version: 1.0 Received-SPF: pass client-ip=2607:f8b0:4864:20::102c; envelope-from=npiggin@gmail.com; helo=mail-pj1-x102c.google.com X-Spam_score_int: -20 X-Spam_score: -2.1 X-Spam_bar: -- X-Spam_report: (-2.1 / 5.0 requ) BAYES_00=-1.9, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_AU=-0.1, DKIM_VALID_EF=-0.1, FREEMAIL_FROM=0.001, RCVD_IN_DNSWL_NONE=-0.0001, SPF_HELO_NONE=0.001, SPF_PASS=-0.001 autolearn=ham autolearn_force=no X-Spam_action: no action X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: qemu-devel-bounces+qemu-devel=archiver.kernel.org@nongnu.org Sender: qemu-devel-bounces+qemu-devel=archiver.kernel.org@nongnu.org From: Cédric Le Goater The ref405ep machine is scheduled for removal in QEMU 10.0. Keep the 405 CPU implementation for a while because it is theoretically possible to model the power management (OCC) co-processor found on the IBM POWER [8-11] processors. Signed-off-by: Cédric Le Goater Reviewed-by: Nicholas Piggin Message-ID: <20250204080649.836155-4-clg@redhat.com> Signed-off-by: Nicholas Piggin --- docs/about/deprecated.rst | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/docs/about/deprecated.rst b/docs/about/deprecated.rst index 3d39d2a9da..e2b4f077d4 100644 --- a/docs/about/deprecated.rst +++ b/docs/about/deprecated.rst @@ -266,6 +266,15 @@ in the QEMU object model anymore. ``Sun-UltraSparc-IIIi+`` and but for consistency these will get removed in a future release, too. Use ``Sun-UltraSparc-IIIi-plus`` and ``Sun-UltraSparc-IV-plus`` instead. +PPC 405 CPUs (since 10.0) +''''''''''''''''''''''''' + +The PPC 405 CPU has no known users and the ``ref405ep`` machine was +removed in QEMU 10.0. Since the IBM POWER [8-11] processors uses an +embedded 405 for power management (OCC) and other internal tasks, it +is theoretically possible to use QEMU to model them. Let's keep the +CPU implementation for a while before removing all support. + System emulator machines ------------------------ From patchwork Tue Mar 11 12:56:59 2025 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Nicholas Piggin X-Patchwork-Id: 14011791 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.lore.kernel.org (Postfix) with ESMTPS id 990BAC282EC for ; Tue, 11 Mar 2025 13:00:42 +0000 (UTC) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1trzCX-0001d0-4D; Tue, 11 Mar 2025 08:59:17 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1trzCN-0001Q9-SJ; Tue, 11 Mar 2025 08:59:08 -0400 Received: from mail-pl1-x634.google.com ([2607:f8b0:4864:20::634]) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_128_GCM_SHA256:128) (Exim 4.90_1) (envelope-from ) id 1trzCE-0007rl-Ip; Tue, 11 Mar 2025 08:59:07 -0400 Received: by mail-pl1-x634.google.com with SMTP id d9443c01a7336-223594b3c6dso96002935ad.2; Tue, 11 Mar 2025 05:58:57 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20230601; t=1741697936; x=1742302736; darn=nongnu.org; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to; bh=TJXJaXt4lWuDUJpetfS2lE/I1FwD3R0NAQpy6wRY7rU=; b=cZoHg7O+APTKIAy2fdSysfHsfnzgrl7OHbTNx76lru33TT931xxnQ/+jmm4/28otIF XLoR2cgA70mqytknap8HsyxJVFQvzYvFUpTur6K20agJbmXcA52VdS/FOtCMhqrARi6G +atS1x4VHBOsd0qI+yjSXuUjZqbllXufdKIHeIAspLKnkM6m/XuEKLQOOGec1NK0cCCu 4rsE7DEZH9r9P1jzDnNJwpZZ9ag1d2SolPKvdvn4MCklOc4StEO6mmSG16gIgP1gUSaE R0cjzP+/gJoggVW3L4K+PH9bcIePieMeP793ghhrCCiJwwnJbosxnegAmHI3WYa8S8vn y6Aw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1741697936; x=1742302736; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=TJXJaXt4lWuDUJpetfS2lE/I1FwD3R0NAQpy6wRY7rU=; b=BHSmlRt3TgkLSDpJmSQNbrJcoRnwhGUgytamifDG7UNlqKxB1wzpyHPO/8wjh6bxlW PpReNqXyJx/Il1juuRP+ZITwR7y8nhQMXJk3FymyW8lx3oS0mWOEh5kEiSFSwUOKN9Za +m6tjksCP8vDMjLTx2uECLVgQ5j0VipBQi9IJ51pNPzhQoQBX5EFafvnr7alSaCEFRuM 1A5qLSdddtd2qdu4iwgZWMMNRB0eBRRqpgX+sg6W+HsjdWY2wphvJSnDKeHg+3aOrsbY CQn0BdczHtPQC27A2Nz40qqcvu5KOvSauXz+uI2ckmoHljxICGPK1xnE16YUz8b/pBik 2R6w== X-Forwarded-Encrypted: i=1; AJvYcCU5TZQ9T3d/2bklOtW9q2mzvLgtXsU2QNtCx/nQqkPfouCHRGic782yh69QV19q5WLb6ub4RWIODQ==@nongnu.org X-Gm-Message-State: AOJu0YyZv9YCAt51JFMU+3kxZdhvRKRpTiAHaNM7G+FDxjVG6VyqYD9s IcQepIMry5weeN1XqFnomtpndOeKiqAZfQN1fY82h5q33QJHmWI/XOUAhw== X-Gm-Gg: ASbGncufB+xvfSnrUricyqeIILVdedXoWGccSj1cRmMTJFe2LvA9cvJhKvZ8ajDQ+Jj srpxGZXnDxTMVvflZ5h5EBbDw3WQ+IKUjYDLuEfarXFIesVs1oAvZqGBMVa5ALH+t/xxoZQGMin CC1unxg4RNCRSjk2uHUQGiPJ1cGAXwReEdOVL2yU/fYLdOqKhgBXGJ6o7P7bSq9BGDKTDXx6Htk ChFoIkst3+jaly7N6WSaMLXKzd7Aik+px11+glGqBrIDptlWteCECBKcZboIMJtobB0AhYbKEA0 Dj/2rRn46ZapvQfTx5xoneLywitgG2KtQ8paknjhZW96T1llFdj7YrnTMDIZoQ== X-Google-Smtp-Source: AGHT+IF6f6W+2IMNdcxtuuqEbKNR9sKWoOic2G4BJ3CfWfgY9c9jZV4jGlSGCiP2rlUs7I6nssDJ3w== X-Received: by 2002:a17:90b:4c8a:b0:2f6:d266:f45e with SMTP id 98e67ed59e1d1-2ff7ce50364mr27924050a91.2.1741697933379; Tue, 11 Mar 2025 05:58:53 -0700 (PDT) Received: from wheely.local0.net ([118.208.151.101]) by smtp.gmail.com with ESMTPSA id 98e67ed59e1d1-2ff4e773dddsm11822318a91.12.2025.03.11.05.58.49 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 11 Mar 2025 05:58:52 -0700 (PDT) From: Nicholas Piggin To: qemu-devel@nongnu.org Cc: Nicholas Piggin , qemu-ppc@nongnu.org, Alexey Kardashevskiy Subject: [PULL 05/72] pseries: Update SLOF firmware image Date: Tue, 11 Mar 2025 22:56:59 +1000 Message-ID: <20250311125815.903177-6-npiggin@gmail.com> X-Mailer: git-send-email 2.47.1 In-Reply-To: <20250311125815.903177-1-npiggin@gmail.com> References: <20250311125815.903177-1-npiggin@gmail.com> MIME-Version: 1.0 Received-SPF: pass client-ip=2607:f8b0:4864:20::634; envelope-from=npiggin@gmail.com; helo=mail-pl1-x634.google.com X-Spam_score_int: -20 X-Spam_score: -2.1 X-Spam_bar: -- X-Spam_report: (-2.1 / 5.0 requ) BAYES_00=-1.9, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_AU=-0.1, DKIM_VALID_EF=-0.1, FREEMAIL_FROM=0.001, LOTS_OF_MONEY=0.001, RCVD_IN_DNSWL_NONE=-0.0001, SPF_HELO_NONE=0.001, SPF_PASS=-0.001 autolearn=ham autolearn_force=no X-Spam_action: no action X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: qemu-devel-bounces+qemu-devel=archiver.kernel.org@nongnu.org Sender: qemu-devel-bounces+qemu-devel=archiver.kernel.org@nongnu.org From: Alexey Kardashevskiy This adds TPM pass through API. Also, moves SLOF from github to gitlab. Signed-off-by: Alexey Kardashevskiy Signed-off-by: Nicholas Piggin --- pc-bios/README | 4 ++-- pc-bios/slof.bin | Bin 995000 -> 996184 bytes roms/SLOF | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/pc-bios/README b/pc-bios/README index 700dcaab52..a08e034fc3 100644 --- a/pc-bios/README +++ b/pc-bios/README @@ -13,8 +13,8 @@ - SLOF (Slimline Open Firmware) is a free IEEE 1275 Open Firmware implementation for certain IBM POWER hardware. The sources are at - https://github.com/aik/SLOF, and the image currently in qemu is - built from git tag qemu-slof-20230918. + https://gitlab.com/slof/slof, and the image currently in qemu is + built from git tag qemu-slof-20241106. - VOF (Virtual Open Firmware) is a minimalistic firmware to work with -machine pseries,x-vof=on. When enabled, the firmware acts as a slim shim and diff --git a/pc-bios/slof.bin b/pc-bios/slof.bin index 27fed09f49a79eaba394a961cce5ddf065902259..4314e17b9ddc964c905a7b107d9aa7a651a43890 100644 GIT binary patch delta 217628 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 ewBp>*H+|uGYR%fZ8P^tdE-_Os7_MVwFYu2pS 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

!JR%dh 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 GyXF5Q`0cg; diff --git a/roms/SLOF b/roms/SLOF index 3a259df244..ee03aec2c1 160000 --- a/roms/SLOF +++ b/roms/SLOF @@ -1 +1 @@ -Subproject commit 3a259df2449fc4a4e43ab5f33f0b2c66484b4bc3 +Subproject commit ee03aec2c106a699aaddd2d3dd52cbd7b7e8d544 From patchwork Tue Mar 11 12:57:00 2025 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Nicholas Piggin X-Patchwork-Id: 14011786 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.lore.kernel.org (Postfix) with ESMTPS id 31D32C282EC for ; Tue, 11 Mar 2025 13:00:12 +0000 (UTC) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1trzCO-0001Q8-QL; Tue, 11 Mar 2025 08:59:09 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1trzCJ-0001LO-HD; Tue, 11 Mar 2025 08:59:03 -0400 Received: from mail-pj1-x102a.google.com ([2607:f8b0:4864:20::102a]) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_128_GCM_SHA256:128) (Exim 4.90_1) (envelope-from ) id 1trzCE-0007rp-UE; Tue, 11 Mar 2025 08:59:03 -0400 Received: by mail-pj1-x102a.google.com with SMTP id 98e67ed59e1d1-2feb91a2492so9002009a91.2; Tue, 11 Mar 2025 05:58:58 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20230601; t=1741697936; x=1742302736; darn=nongnu.org; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to; bh=CSHGgwgOJ8bvFCtn77OMVeDfhzz9rRbWoztTbokAA7U=; b=cu0JLqMyW+QcWmnab3BDI9G0hYzqABrfUzVqDoSujd+j0njvwWp1PRL3vyGQCBnGXA AzQDnqF1pRX+nccz5DO0/l22i4DV2n7eSK5EXBCaSxqrLfFpms5shG93PLxrjOeOPiGL pSBO4iOLiAk25rtND/yn6mUe7Mk/PBXi3d1nX1whWcyLhrvZFjVK1qoG59+FPcBXqlXe 08dKQ1JqUGknhVIL8MX9etlpL3O5rFZ8XD3P4+vDk441xOe/+ZYaf+l29hd8l7rzJFdg HH6JaRK4Dqev4iebAE461ANK9qlKOzu2eh7ceQEAyw3oWb5zeZ0gxFkbGxbBeMg7LR0V mKRw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1741697936; x=1742302736; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=CSHGgwgOJ8bvFCtn77OMVeDfhzz9rRbWoztTbokAA7U=; b=IUlFPqJjfKF7tpVLs110+Fbe+cLpF8gqZEr4tF9nsaEmxxg2QSfFjkPWNUrAcyYU0Z dQkhq3NRK6z143p7KZ+WtCvdPzHK5d9zloSOF+wFGlCDot6cAlYs7jmw06dTmZLS+oFF 1idA8GUSKzbh98pdEwV0WJQZWxgPOdJJEMvhtI25zV5wrx8aB/FhDaQtQYLlKdYaXmu5 Zr59GCvCOUN9M93dKoZXGh6UmscKBC4OJdRPlVkktb8slDII5Mm4D+++YHFyV88E11QT m8VMwyFQ2jIh7wUnsOr7ZMO31Lpk56rtL1Mcp6bHY0fWsuVPJ7D1UNACBofl244OA5lE JWyA== X-Forwarded-Encrypted: i=1; AJvYcCWRbFAGUWm6S33l0Am1kemNLKlVGyxlSAY1vJpO4mXDVSSwH+83L+Ogqnbf4gZTEBGaM/sF3UUUwQ==@nongnu.org X-Gm-Message-State: AOJu0YwT2ejgGXyRqLk/2jcGDXhBpNTBDHUqWgmX3CogZw4iRLx/hHmu rHfmHSNGWU30gJ0OanSeSU6F24lzSs4Cy0Q/d4SkyoB9gR18lPwYiPXa0A== X-Gm-Gg: ASbGncvQ6vCKft5YAvZvlRIGsIRyAldkZWsiiW21rDSKTu9PTIchfIRtPImXuTQKJ8K O1RoDgzoLkqCl8s2SAf+UbPPPYrCiz69R4dNQRZzZWxQFjnEdYBq7S6pzkyXyYW2Ibw0tQNnhP4 4uYLYKefnJXm5/RnF3T+v3U/ahPGluamRjkYSfRvVhCGVE96hozsxhAZcIz9ER4KRUBbqPR9eaH 5hwIBZV1P2vy2/5QesfBcir60T1+TDo0JNqA7NjYVXSsZPbLED5KTe2Ro4IYFIX5IFfu4UOVbPv vL0pSbiu6DOLqRcYEAs+7Tt5ecILsQyoCsrVo+7n4Qpehu/L2jc= X-Google-Smtp-Source: AGHT+IE0wNuDgcv5ZTW5TzeMwA7YKz9OzyNsRJualoW7aKYhS8N9K9b58RgfwuLSJQCx8Ar70CvUEg== X-Received: by 2002:a17:90b:528e:b0:2fe:a336:fe63 with SMTP id 98e67ed59e1d1-2ff7cef5ca6mr27094454a91.24.1741697935914; Tue, 11 Mar 2025 05:58:55 -0700 (PDT) Received: from wheely.local0.net ([118.208.151.101]) by smtp.gmail.com with ESMTPSA id 98e67ed59e1d1-2ff4e773dddsm11822318a91.12.2025.03.11.05.58.53 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 11 Mar 2025 05:58:55 -0700 (PDT) From: Nicholas Piggin To: qemu-devel@nongnu.org Cc: Nicholas Piggin , qemu-ppc@nongnu.org Subject: [PULL 06/72] ppc/pnv/phb4: Add pervasive chiplet support to PHB4/5 Date: Tue, 11 Mar 2025 22:57:00 +1000 Message-ID: <20250311125815.903177-7-npiggin@gmail.com> X-Mailer: git-send-email 2.47.1 In-Reply-To: <20250311125815.903177-1-npiggin@gmail.com> References: <20250311125815.903177-1-npiggin@gmail.com> MIME-Version: 1.0 Received-SPF: pass client-ip=2607:f8b0:4864:20::102a; envelope-from=npiggin@gmail.com; helo=mail-pj1-x102a.google.com X-Spam_score_int: -20 X-Spam_score: -2.1 X-Spam_bar: -- X-Spam_report: (-2.1 / 5.0 requ) BAYES_00=-1.9, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_AU=-0.1, DKIM_VALID_EF=-0.1, FREEMAIL_FROM=0.001, RCVD_IN_DNSWL_NONE=-0.0001, SPF_HELO_NONE=0.001, SPF_PASS=-0.001 autolearn=ham autolearn_force=no X-Spam_action: no action X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: qemu-devel-bounces+qemu-devel=archiver.kernel.org@nongnu.org Sender: qemu-devel-bounces+qemu-devel=archiver.kernel.org@nongnu.org Each non-core chiplet on a chip has a "pervasive chiplet" unit and its xscom register set. This adds support for PHB4/5. skiboot reads the CPLT_CONF1 register in __phb4/5_get_max_link_width(), which shows up as unimplemented xscom reads. Set a value in PCI CONF1 register's link-width field to demonstrate skiboot doing something interesting with it. In the bigger picture, it might be better to model the pervasive chiplet type as parent that each non-core chiplet model derives from. For now this is enough to get the PHB registers implemented and working for skiboot, and provides a second example (after the N1 chiplet) that will help if the design is reworked as such. Signed-off-by: Nicholas Piggin --- hw/pci-host/pnv_phb4_pec.c | 55 +++++++++++++++++++++++++++++++++- hw/ppc/pnv.c | 8 +++++ include/hw/pci-host/pnv_phb4.h | 5 ++++ include/hw/ppc/pnv_xscom.h | 4 +++ 4 files changed, 71 insertions(+), 1 deletion(-) diff --git a/hw/pci-host/pnv_phb4_pec.c b/hw/pci-host/pnv_phb4_pec.c index a156839caf..cb8a7e3afa 100644 --- a/hw/pci-host/pnv_phb4_pec.c +++ b/hw/pci-host/pnv_phb4_pec.c @@ -197,6 +197,9 @@ static PnvPHB *pnv_pec_default_phb_realize(PnvPhb4PecState *pec, return phb; } +#define XPEC_P9_PCI_LANE_CFG PPC_BITMASK(10, 11) +#define XPEC_P10_PCI_LANE_CFG PPC_BITMASK(0, 1) + static void pnv_pec_realize(DeviceState *dev, Error **errp) { PnvPhb4PecState *pec = PNV_PHB4_PEC(dev); @@ -211,6 +214,43 @@ static void pnv_pec_realize(DeviceState *dev, Error **errp) pec->num_phbs = pecc->num_phbs[pec->index]; + /* Pervasive chiplet */ + object_initialize_child(OBJECT(pec), "nest-pervasive-common", + &pec->nest_pervasive, + TYPE_PNV_NEST_CHIPLET_PERVASIVE); + if (!qdev_realize(DEVICE(&pec->nest_pervasive), NULL, errp)) { + return; + } + + /* Set up pervasive chiplet registers */ + /* + * Most registers are not set up, this just sets the PCI CONF1 link-width + * field because skiboot probes it. + */ + if (pecc->version == PNV_PHB4_VERSION) { + /* + * On P9, PEC2 has configurable 1/2/3-furcation). + * Make it trifurcated (x8, x4, x4) to match pnv_pec_num_phbs. + */ + if (pec->index == 2) { + pec->nest_pervasive.control_regs.cplt_cfg1 = + SETFIELD(XPEC_P9_PCI_LANE_CFG, + pec->nest_pervasive.control_regs.cplt_cfg1, + 0b10); + } + } else if (pecc->version == PNV_PHB5_VERSION) { + /* + * On P10, both PECs are configurable 1/2/3-furcation). + * Both are trifurcated to match pnv_phb5_pec_num_stacks. + */ + pec->nest_pervasive.control_regs.cplt_cfg1 = + SETFIELD(XPEC_P10_PCI_LANE_CFG, + pec->nest_pervasive.control_regs.cplt_cfg1, + 0b10); + } else { + g_assert_not_reached(); + } + /* Create PHBs if running with defaults */ if (defaults_enabled()) { g_assert(pec->num_phbs <= MAX_PHBS_PER_PEC); @@ -290,9 +330,16 @@ static const Property pnv_pec_properties[] = { PnvChip *), }; +#define XPEC_PCI_CPLT_OFFSET 0x1000000ULL + +static uint32_t pnv_pec_xscom_cplt_base(PnvPhb4PecState *pec) +{ + return PNV9_XSCOM_PEC_NEST_CPLT_BASE + XPEC_PCI_CPLT_OFFSET * pec->index; +} + static uint32_t pnv_pec_xscom_pci_base(PnvPhb4PecState *pec) { - return PNV9_XSCOM_PEC_PCI_BASE + 0x1000000 * pec->index; + return PNV9_XSCOM_PEC_PCI_BASE + XPEC_PCI_CPLT_OFFSET * pec->index; } static uint32_t pnv_pec_xscom_nest_base(PnvPhb4PecState *pec) @@ -321,6 +368,7 @@ static void pnv_pec_class_init(ObjectClass *klass, void *data) device_class_set_props(dc, pnv_pec_properties); dc->user_creatable = false; + pecc->xscom_cplt_base = pnv_pec_xscom_cplt_base; pecc->xscom_nest_base = pnv_pec_xscom_nest_base; pecc->xscom_pci_base = pnv_pec_xscom_pci_base; pecc->xscom_nest_size = PNV9_XSCOM_PEC_NEST_SIZE; @@ -349,6 +397,10 @@ static const TypeInfo pnv_pec_type_info = { /* * POWER10 definitions */ +static uint32_t pnv_phb5_pec_xscom_cplt_base(PnvPhb4PecState *pec) +{ + return PNV10_XSCOM_PEC_NEST_CPLT_BASE + XPEC_PCI_CPLT_OFFSET * pec->index; +} static uint32_t pnv_phb5_pec_xscom_pci_base(PnvPhb4PecState *pec) { @@ -373,6 +425,7 @@ static void pnv_phb5_pec_class_init(ObjectClass *klass, void *data) static const char compat[] = "ibm,power10-pbcq"; static const char stk_compat[] = "ibm,power10-phb-stack"; + pecc->xscom_cplt_base = pnv_phb5_pec_xscom_cplt_base; pecc->xscom_nest_base = pnv_phb5_pec_xscom_nest_base; pecc->xscom_pci_base = pnv_phb5_pec_xscom_pci_base; pecc->xscom_nest_size = PNV10_XSCOM_PEC_NEST_SIZE; diff --git a/hw/ppc/pnv.c b/hw/ppc/pnv.c index 87607508c7..4407b3a1a2 100644 --- a/hw/ppc/pnv.c +++ b/hw/ppc/pnv.c @@ -1753,6 +1753,7 @@ static void pnv_chip_power9_pec_realize(PnvChip *chip, Error **errp) for (i = 0; i < chip->num_pecs; i++) { PnvPhb4PecState *pec = &chip9->pecs[i]; PnvPhb4PecClass *pecc = PNV_PHB4_PEC_GET_CLASS(pec); + uint32_t pec_cplt_base; uint32_t pec_nest_base; uint32_t pec_pci_base; @@ -1765,9 +1766,12 @@ static void pnv_chip_power9_pec_realize(PnvChip *chip, Error **errp) return; } + pec_cplt_base = pecc->xscom_cplt_base(pec); pec_nest_base = pecc->xscom_nest_base(pec); pec_pci_base = pecc->xscom_pci_base(pec); + pnv_xscom_add_subregion(chip, pec_cplt_base, + &pec->nest_pervasive.xscom_ctrl_regs_mr); pnv_xscom_add_subregion(chip, pec_nest_base, &pec->nest_regs_mr); pnv_xscom_add_subregion(chip, pec_pci_base, &pec->pci_regs_mr); } @@ -2027,6 +2031,7 @@ static void pnv_chip_power10_phb_realize(PnvChip *chip, Error **errp) for (i = 0; i < chip->num_pecs; i++) { PnvPhb4PecState *pec = &chip10->pecs[i]; PnvPhb4PecClass *pecc = PNV_PHB4_PEC_GET_CLASS(pec); + uint32_t pec_cplt_base; uint32_t pec_nest_base; uint32_t pec_pci_base; @@ -2039,9 +2044,12 @@ static void pnv_chip_power10_phb_realize(PnvChip *chip, Error **errp) return; } + pec_cplt_base = pecc->xscom_cplt_base(pec); pec_nest_base = pecc->xscom_nest_base(pec); pec_pci_base = pecc->xscom_pci_base(pec); + pnv_xscom_add_subregion(chip, pec_cplt_base, + &pec->nest_pervasive.xscom_ctrl_regs_mr); pnv_xscom_add_subregion(chip, pec_nest_base, &pec->nest_regs_mr); pnv_xscom_add_subregion(chip, pec_pci_base, &pec->pci_regs_mr); } diff --git a/include/hw/pci-host/pnv_phb4.h b/include/hw/pci-host/pnv_phb4.h index 8abee78e4d..8a80c0c667 100644 --- a/include/hw/pci-host/pnv_phb4.h +++ b/include/hw/pci-host/pnv_phb4.h @@ -13,6 +13,7 @@ #include "hw/pci-host/pnv_phb.h" #include "hw/pci/pci_bus.h" #include "hw/ppc/pnv.h" +#include "hw/ppc/pnv_nest_pervasive.h" #include "hw/ppc/xive.h" #include "qom/object.h" @@ -174,6 +175,9 @@ struct PnvPhb4PecState { uint32_t index; uint32_t chip_id; + /* Pervasive chiplet control */ + PnvNestChipletPervasive nest_pervasive; + /* Nest registers, excuding per-stack */ #define PHB4_PEC_NEST_REGS_COUNT 0xf uint64_t nest_regs[PHB4_PEC_NEST_REGS_COUNT]; @@ -196,6 +200,7 @@ struct PnvPhb4PecState { struct PnvPhb4PecClass { DeviceClass parent_class; + uint32_t (*xscom_cplt_base)(PnvPhb4PecState *pec); uint32_t (*xscom_nest_base)(PnvPhb4PecState *pec); uint32_t xscom_nest_size; uint32_t (*xscom_pci_base)(PnvPhb4PecState *pec); diff --git a/include/hw/ppc/pnv_xscom.h b/include/hw/ppc/pnv_xscom.h index 648388a599..a927aea1c0 100644 --- a/include/hw/ppc/pnv_xscom.h +++ b/include/hw/ppc/pnv_xscom.h @@ -126,6 +126,8 @@ struct PnvXScomInterfaceClass { #define PNV9_XSCOM_PEC_PCI_BASE 0xd010800 #define PNV9_XSCOM_PEC_PCI_SIZE 0x200 +#define PNV9_XSCOM_PEC_NEST_CPLT_BASE 0x0d000000 + /* XSCOM PCI "pass-through" window to PHB SCOM */ #define PNV9_XSCOM_PEC_PCI_STK0 0x100 #define PNV9_XSCOM_PEC_PCI_STK1 0x140 @@ -197,6 +199,8 @@ struct PnvXScomInterfaceClass { #define PNV10_XSCOM_PEC_NEST_BASE 0x3011800 /* index goes downwards ... */ #define PNV10_XSCOM_PEC_NEST_SIZE 0x100 +#define PNV10_XSCOM_PEC_NEST_CPLT_BASE 0x08000000 + #define PNV10_XSCOM_PEC_PCI_BASE 0x8010800 /* index goes upwards ... */ #define PNV10_XSCOM_PEC_PCI_SIZE 0x200 From patchwork Tue Mar 11 12:57:01 2025 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Nicholas Piggin X-Patchwork-Id: 14011802 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.lore.kernel.org (Postfix) with ESMTPS id EA33FC282EC for ; Tue, 11 Mar 2025 13:06:01 +0000 (UTC) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1trzCd-0001sZ-TF; Tue, 11 Mar 2025 08:59:24 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1trzCO-0001Qi-Rq; Tue, 11 Mar 2025 08:59:09 -0400 Received: from mail-pj1-x102d.google.com ([2607:f8b0:4864:20::102d]) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_128_GCM_SHA256:128) (Exim 4.90_1) (envelope-from ) id 1trzCH-0007s7-Iz; Tue, 11 Mar 2025 08:59:06 -0400 Received: by mail-pj1-x102d.google.com with SMTP id 98e67ed59e1d1-2fa8ada6662so11364432a91.1; Tue, 11 Mar 2025 05:58:59 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20230601; t=1741697938; x=1742302738; darn=nongnu.org; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to; bh=kcsPJBP6bO4++1h7GJpYSXw0Uff46Q4C7W6SLg5uEts=; b=cPfl47h3QH/D3Lr5jxmwwecgMvdnWqXuI0hfV2dBtjft6yLaSCS3PwJL+9Hn168/tw JzuUaEGt10cBNecVZpQllBcdcDVYL4/YO+st4q2+SQZ66mhcQJgoOLg4T5TMvu8hAyJC 0ro3eHlxTeuqdVqZam7PvsWRg1O2Xkz+taFfdK5uYn6Vf/EMfsxuUPmKZhY3kO9OEc3q KVx605FjTGjHSG1XjJme7lL1H2S+8R5Rcm2syTthefF4qRpNbXgljRKf1zGOHkXCWj0D 7gtzH0Ea+loX6AcjuvV0GfFeK0bN4e3xk6mDPKTC5u5KyXuKTYsUkBO4NGnNEsq6kQcn HuOw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1741697938; x=1742302738; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=kcsPJBP6bO4++1h7GJpYSXw0Uff46Q4C7W6SLg5uEts=; b=wc47OaogXN0H1REW8NeeWOqb768MHaNGXLh3ZBCALHlFDKBYbTt38LKwsrEn8TaNYv U/hP5l3pf5pTGp/e8Yf4JjyNa2A9kqXJtoJwlQiuqbSRnPzhPU1OjHcq90PKW2nDsdQZ UzFRdIjAbQOka/e/0yLIS3PQWdYDMekYBoXbZ5SDOk1zIjJ5y/8dT/LoGK/Nu+zEBy0v mXadyf/W2efgS5Oba0IyE4lASsxLToVz/kfzl0mJLJwGTGjyMcXR8Y6Y1HUVI7J7OERe YPMuc3bhQ/pC/6e56vw8uAwqz1cvMKylIylp+gE7nayctQ5xTkp44d0ve1bMVW14muEc x80Q== X-Forwarded-Encrypted: i=1; AJvYcCXe3wtdbookycgWIHSsKnC2djbLA4dNhRZv+h58SyJ9Ol/T3z1GPk3TMzS1vhr45ZNfx0SptopuHw==@nongnu.org X-Gm-Message-State: AOJu0YxCDd/V2eNS/DbMcXdX2z3MjF3ljeC05AQfQbbOYc3xfxy+4I1h IT0cPiCiiY8EjEdZePoU3NlAwLWGMa7GKT+C4I/zpzMQIx+3mGiKl8lMvw== X-Gm-Gg: ASbGncvkhgQ51l4UlzZoA+EYB9FukBeLrA3381BW6ljpU0tzLJ0a9FFtPunrgNB8HvK 0K0VcjuLggxHLZn7wY/zHZ69LtvmZr7pzEcFViFIyvgOLXU/fAWLideNVC6cYbDmxd8eX5zKQs6 Xbaco3aCGsYBEnhkYal/CupuQ4C8Vio3sUL4fkCa3w5nqi+4Yqcy6RZkDjBvmOZvNNEJ4ksaP2x x0KI3dfpgEqU+/gsOQ3lKTvxQk0jA9xWf/OpUMKQvzRz7nBRKiZNbOuxc+2Ru997MgZef2+0Y59 lk0nVY4syxlYLPKdks9VZhzNbCJW1U1o7CWhmZo6lwpsB40mwF0= X-Google-Smtp-Source: AGHT+IEGGlDAaDwQ0oZiGUGFomsh5DUynMHiKF2q1dA/1Lk9XGFtScknb0Pv6FUuvwx8p4UG4MPh9Q== X-Received: by 2002:a17:90b:3849:b0:2f9:c56b:6ec8 with SMTP id 98e67ed59e1d1-2ff7ce9114dmr26936375a91.10.1741697938308; Tue, 11 Mar 2025 05:58:58 -0700 (PDT) Received: from wheely.local0.net ([118.208.151.101]) by smtp.gmail.com with ESMTPSA id 98e67ed59e1d1-2ff4e773dddsm11822318a91.12.2025.03.11.05.58.56 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 11 Mar 2025 05:58:57 -0700 (PDT) From: Nicholas Piggin To: qemu-devel@nongnu.org Cc: Nicholas Piggin , qemu-ppc@nongnu.org Subject: [PULL 07/72] ppc/pnv/homer: Fix OCC registers Date: Tue, 11 Mar 2025 22:57:01 +1000 Message-ID: <20250311125815.903177-8-npiggin@gmail.com> X-Mailer: git-send-email 2.47.1 In-Reply-To: <20250311125815.903177-1-npiggin@gmail.com> References: <20250311125815.903177-1-npiggin@gmail.com> MIME-Version: 1.0 Received-SPF: pass client-ip=2607:f8b0:4864:20::102d; envelope-from=npiggin@gmail.com; helo=mail-pj1-x102d.google.com X-Spam_score_int: -20 X-Spam_score: -2.1 X-Spam_bar: -- X-Spam_report: (-2.1 / 5.0 requ) BAYES_00=-1.9, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_AU=-0.1, DKIM_VALID_EF=-0.1, FREEMAIL_FROM=0.001, RCVD_IN_DNSWL_NONE=-0.0001, SPF_HELO_NONE=0.001, SPF_PASS=-0.001 autolearn=ham autolearn_force=no X-Spam_action: no action X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: qemu-devel-bounces+qemu-devel=archiver.kernel.org@nongnu.org Sender: qemu-devel-bounces+qemu-devel=archiver.kernel.org@nongnu.org The HOMER OCC registers seem to have bitrotted and fail for various reasons on powernv8, 9, and 10. The major problems are that POWER8 has the wrong version value and its pstate ordering is incorrect. POWER9/10 have not set the OCC state to active. Non-zero chips are also set to OCC slaves for POWER9/10. Unfortunately skiboot has also bitrotted and requires fixes that are not yet in the bios files to run. With a patched skiboot, before this change, powernv9/10 report: [ 0.262050394,3] OCC: Chip: 0: OCC not active [ 0.262128603,3] OCC: Initialization on all chips did not complete(timed out) powernv8 reports: [ 0.173572100,3] OCC: Unknown OCC-OPAL interface version. [ 0.173812059,3] OCC: Initialization on all chips did not complete(timed out) After this patch, all report: [ 0.176815668,5] OCC: All Chip Rdy after 0 ms Signed-off-by: Nicholas Piggin --- hw/ppc/pnv_homer.c | 41 +++++++++++++++++++++++++++++------------ 1 file changed, 29 insertions(+), 12 deletions(-) diff --git a/hw/ppc/pnv_homer.c b/hw/ppc/pnv_homer.c index a1d83c8149..acd2f7b3a6 100644 --- a/hw/ppc/pnv_homer.c +++ b/hw/ppc/pnv_homer.c @@ -70,21 +70,24 @@ static uint64_t pnv_power8_homer_read(void *opaque, hwaddr addr, PnvHomer *homer = PNV_HOMER(opaque); switch (addr) { - case PNV8_OCC_PSTATE_VERSION: - case PNV8_OCC_PSTATE_MIN: - case PNV8_OCC_PSTATE_ID_ZERO: - return 0; case PNV8_OCC_PSTATE_VALID: + return 1; case PNV8_OCC_PSTATE_THROTTLE: + return 0; + case PNV8_OCC_PSTATE_VERSION: + return 0x02; + case PNV8_OCC_PSTATE_MIN: + return -2; case PNV8_OCC_PSTATE_NOM: case PNV8_OCC_PSTATE_TURBO: - case PNV8_OCC_PSTATE_ID_ONE: + return -1; + case PNV8_OCC_PSTATE_ULTRA_TURBO: + return 0; + case PNV8_OCC_PSTATE_ID_ZERO: + return 0; case PNV8_OCC_VDD_VOLTAGE_IDENTIFIER: case PNV8_OCC_VCS_VOLTAGE_IDENTIFIER: return 1; - case PNV8_OCC_PSTATE_ULTRA_TURBO: - case PNV8_OCC_PSTATE_ID_TWO: - return 2; case PNV8_OCC_PSTATE_DATA: return 0x1000000000000000; /* P8 frequency for 0, 1, and 2 pstates */ @@ -92,6 +95,10 @@ static uint64_t pnv_power8_homer_read(void *opaque, hwaddr addr, case PNV8_OCC_PSTATE_ONE_FREQUENCY: case PNV8_OCC_PSTATE_TWO_FREQUENCY: return 3000; + case PNV8_OCC_PSTATE_ID_ONE: + return -1; + case PNV8_OCC_PSTATE_ID_TWO: + return -2; } /* pstate table core max array */ if (core_max_array(homer, addr)) { @@ -192,11 +199,12 @@ static const TypeInfo pnv_homer_power8_type_info = { /* P9 Pstate table */ +#define PNV9_OCC_PSTATE_VALID 0xe2000 #define PNV9_OCC_PSTATE_ID_ZERO 0xe2018 #define PNV9_OCC_PSTATE_ID_ONE 0xe2020 #define PNV9_OCC_PSTATE_ID_TWO 0xe2028 #define PNV9_OCC_PSTATE_DATA 0xe2000 -#define PNV9_OCC_PSTATE_DATA_AREA 0xe2008 +#define PNV9_OCC_PSTATE_MINOR_VERSION 0xe2008 #define PNV9_OCC_PSTATE_MIN 0xe2003 #define PNV9_OCC_PSTATE_NOM 0xe2004 #define PNV9_OCC_PSTATE_TURBO 0xe2005 @@ -211,7 +219,7 @@ static const TypeInfo pnv_homer_power8_type_info = { #define PNV9_OCC_PSTATE_TWO_FREQUENCY 0xe202c #define PNV9_OCC_ROLE_MASTER_OR_SLAVE 0xe2002 #define PNV9_CORE_MAX_BASE 0xe2819 - +#define PNV9_DYNAMIC_DATA_STATE 0xe2b80 static uint64_t pnv_power9_homer_read(void *opaque, hwaddr addr, unsigned size) @@ -219,11 +227,17 @@ static uint64_t pnv_power9_homer_read(void *opaque, hwaddr addr, PnvHomer *homer = PNV_HOMER(opaque); switch (addr) { + case PNV9_OCC_PSTATE_VALID: + return 1; case PNV9_OCC_MAX_PSTATE_ULTRA_TURBO: case PNV9_OCC_PSTATE_ID_ZERO: return 0; - case PNV9_OCC_PSTATE_DATA: case PNV9_OCC_ROLE_MASTER_OR_SLAVE: + if (homer->chip->chip_id == 0) { + return 0x1; /* master */ + } else { + return 0x0; /* slave */ + } case PNV9_OCC_PSTATE_NOM: case PNV9_OCC_PSTATE_TURBO: case PNV9_OCC_PSTATE_ID_ONE: @@ -241,10 +255,13 @@ static uint64_t pnv_power9_homer_read(void *opaque, hwaddr addr, return 3000; case PNV9_OCC_PSTATE_MAJOR_VERSION: return 0x90; + case PNV9_OCC_PSTATE_MINOR_VERSION: + return 0x01; case PNV9_CHIP_HOMER_BASE: - case PNV9_OCC_PSTATE_DATA_AREA: case PNV9_CHIP_HOMER_IMAGE_POINTER: return 0x1000000000000000; + case PNV9_DYNAMIC_DATA_STATE: + return 0x03; /* active */ } /* pstate table core max array */ if (core_max_array(homer, addr)) { From patchwork Tue Mar 11 12:57:02 2025 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Nicholas Piggin X-Patchwork-Id: 14011785 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.lore.kernel.org (Postfix) with ESMTPS id 0533BC282EC for ; Tue, 11 Mar 2025 13:00:03 +0000 (UTC) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1trzCq-0002Pi-6t; Tue, 11 Mar 2025 08:59:36 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1trzCL-0001Mh-OX; Tue, 11 Mar 2025 08:59:06 -0400 Received: from mail-pj1-x102a.google.com ([2607:f8b0:4864:20::102a]) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_128_GCM_SHA256:128) (Exim 4.90_1) (envelope-from ) id 1trzCJ-0007sK-SE; Tue, 11 Mar 2025 08:59:05 -0400 Received: by mail-pj1-x102a.google.com with SMTP id 98e67ed59e1d1-2fee4d9c2efso9000099a91.3; Tue, 11 Mar 2025 05:59:01 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20230601; t=1741697941; x=1742302741; darn=nongnu.org; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to; bh=wd805KbtUJ3mYr3xoOW61EiyMaIe0guwHYCEOoqrQks=; b=GnYCc38CSjKlarRQLV1TNAiTKtvke5qo8gOewPazeRxH34A3GmTNIz+2wcSMGPvWIl GzGORteQEAMhfvjMn3axJd/U/I6+3DQ0vRKhOltK6sXSvWnOY009EqdUuIrM+pqEuIVG Mh63RXs9V6re68UWMddrXtRj4K7qkmcvTFMB55HIjoSJlVf9eOys7quE92upAvF40UOi vNJCJdH+1s3Lcs6j7bziRO0Lvx3AelAtovQqb/mhJ7kfbsE5mbSeE4xL8Qp16RJw4qIP LH8jR+vtaT9OKuBDiuRFrXR+QEEwtpkgsrGoMt/OpfM2DbD9qppKGp3DWYDD8Hork9lU XUyA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1741697941; x=1742302741; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=wd805KbtUJ3mYr3xoOW61EiyMaIe0guwHYCEOoqrQks=; b=s30YdnmHh2xnO4iwBOahJVfmLf0YN8RZnGyNqUZUuIqUZCBbkz/iLsG3qQ14L43W4N z7RGON3L60elwiL6Eq/0G8Sm8X3KX6b1XALyG6JbweIthmnZF8DRYisA/CRzIcQLhc5I /DSjHucdMcKyCqDnrbiYLpTY99iknnt3wNGYGBVfA/Hjk3VES1lTws4PqDtxVY8oC0si dq5o4YJIDK72qIet3SpUa/1ZQQvaSU+IgfdVZC5X5pHJBLdnIR3pOgbKLFy4gSM5Q0YD 8AdA2zIqmdEGyNJ74w8nU4reO5/feqr5cW3G63TaRH11V92ZDw2SB2nj+x/ohp9vaVZO gFJA== X-Forwarded-Encrypted: i=1; AJvYcCXGcFYwqEel1JPG8OF3TjADk6EXCblhzM5h6RcWNalps141dIi+HFd4ZPaDLOwyJQFMf8fhHg+tpA==@nongnu.org X-Gm-Message-State: AOJu0Yyhpggy2qFL+2hwlrW9U8O9HuNn5ikxLgdBHGXZG4ErBWgUM9y2 qzOf1zBZB3eWF8ieHYfntWp73g/ko4mA0lPOtnevDKn/42kMhmISMAst6A== X-Gm-Gg: ASbGncv5AcmUyeZClA3+/M1ud0oAegKGZYCu8/uSCXDOoX3J4KNguW4H+z9QOgDREio oSoEtBKgJN9BQn9eoKs2UhS8lZYBBi2KgPt94V9y88BCU0ea26NYU2kzn1gVDiXCpZo+pVK/lQ7 2jVuxQnDIzbLxirZ5mE13N9imMNMRDjDe2ss00ylWLitfLCptkV2nN9fYBJMvYTdG134t5ar/KS R15DHBunQ16xLbDLiYk4uTntwH3OR/tmxJoT/wbqcRiarCEZNDwspMroDY6OC7a3NeoR9ulqVGJ D3fHn3PqsK9h6ILvBRGRgBVNJe4B/KdMYN8ERQsxjt0cGcctntw= X-Google-Smtp-Source: AGHT+IEZ87898TFY5TjRDkDsFQrCZwnHYHK+prYoGxg8reddGGRazTKXy94Ck5ywDrp6T5iCmjCilQ== X-Received: by 2002:a17:90b:2fc7:b0:2ee:693e:ed7a with SMTP id 98e67ed59e1d1-2ff7cf2b591mr26976434a91.35.1741697940643; Tue, 11 Mar 2025 05:59:00 -0700 (PDT) Received: from wheely.local0.net ([118.208.151.101]) by smtp.gmail.com with ESMTPSA id 98e67ed59e1d1-2ff4e773dddsm11822318a91.12.2025.03.11.05.58.58 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 11 Mar 2025 05:59:00 -0700 (PDT) From: Nicholas Piggin To: qemu-devel@nongnu.org Cc: Nicholas Piggin , qemu-ppc@nongnu.org Subject: [PULL 08/72] ppc/pnv/homer: Make dummy reads return 0 Date: Tue, 11 Mar 2025 22:57:02 +1000 Message-ID: <20250311125815.903177-9-npiggin@gmail.com> X-Mailer: git-send-email 2.47.1 In-Reply-To: <20250311125815.903177-1-npiggin@gmail.com> References: <20250311125815.903177-1-npiggin@gmail.com> MIME-Version: 1.0 Received-SPF: pass client-ip=2607:f8b0:4864:20::102a; envelope-from=npiggin@gmail.com; helo=mail-pj1-x102a.google.com X-Spam_score_int: -20 X-Spam_score: -2.1 X-Spam_bar: -- X-Spam_report: (-2.1 / 5.0 requ) BAYES_00=-1.9, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_AU=-0.1, DKIM_VALID_EF=-0.1, FREEMAIL_FROM=0.001, RCVD_IN_DNSWL_NONE=-0.0001, SPF_HELO_NONE=0.001, SPF_PASS=-0.001 autolearn=ham autolearn_force=no X-Spam_action: no action X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: qemu-devel-bounces+qemu-devel=archiver.kernel.org@nongnu.org Sender: qemu-devel-bounces+qemu-devel=archiver.kernel.org@nongnu.org HOMER memory implements some dummy registers that return a nonsense value to satisfy skiboot accesses caused by "SLW" init and register save/restore programming that has never worked under QEMU: [ 0.265000943,3] SLW: Failed to set HRMOR for CPU 0,RC=0x1 [ 0.265356988,3] Disabling deep stop states To simplify a later change to implement HOMER as a RAM area, make these return zero, which has the same result. Signed-off-by: Nicholas Piggin --- hw/ppc/pnv_homer.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/hw/ppc/pnv_homer.c b/hw/ppc/pnv_homer.c index acd2f7b3a6..75b0ee7964 100644 --- a/hw/ppc/pnv_homer.c +++ b/hw/ppc/pnv_homer.c @@ -89,7 +89,7 @@ static uint64_t pnv_power8_homer_read(void *opaque, hwaddr addr, case PNV8_OCC_VCS_VOLTAGE_IDENTIFIER: return 1; case PNV8_OCC_PSTATE_DATA: - return 0x1000000000000000; + return 0; /* P8 frequency for 0, 1, and 2 pstates */ case PNV8_OCC_PSTATE_ZERO_FREQUENCY: case PNV8_OCC_PSTATE_ONE_FREQUENCY: @@ -259,7 +259,7 @@ static uint64_t pnv_power9_homer_read(void *opaque, hwaddr addr, return 0x01; case PNV9_CHIP_HOMER_BASE: case PNV9_CHIP_HOMER_IMAGE_POINTER: - return 0x1000000000000000; + return 0; case PNV9_DYNAMIC_DATA_STATE: return 0x03; /* active */ } From patchwork Tue Mar 11 12:57:03 2025 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Nicholas Piggin X-Patchwork-Id: 14011794 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.lore.kernel.org (Postfix) with ESMTPS id 5D4FDC35FF2 for ; Tue, 11 Mar 2025 13:01:01 +0000 (UTC) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1trzCY-0001fW-NN; Tue, 11 Mar 2025 08:59:20 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1trzCN-0001QA-SL; Tue, 11 Mar 2025 08:59:08 -0400 Received: from mail-pj1-x102a.google.com ([2607:f8b0:4864:20::102a]) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_128_GCM_SHA256:128) (Exim 4.90_1) (envelope-from ) id 1trzCL-0007tD-Rc; Tue, 11 Mar 2025 08:59:07 -0400 Received: by mail-pj1-x102a.google.com with SMTP id 98e67ed59e1d1-2ff797f8f1bso7286529a91.3; Tue, 11 Mar 2025 05:59:04 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20230601; t=1741697943; x=1742302743; darn=nongnu.org; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to; bh=YrjQAkubjW9GpsAIIJ1EX4bgybSUalPSDK9qpo5mGhU=; b=QTBPxkTZWhuzyaWXpvS21/nIa3/M3RA6HxP7irvR22pMonyeTHljrWkG1GZFojbcqY jn1ZO3+ndBpblkrOchG4oVtUvBcuaUGh1jh/Xi3Efpa3w4LQ60r+W75pVP3Y/cTTBoay D5SHB9OdQbCMX4pX68f3P+qg2GQ7NsYtxjoLM/PraLTAkeQxLISeR8oLOx8tc7NBXvkz CBgq0nUS3IqsrlzINUkJEKm0wyE65W4yZJJms0kdl7np0LdTaoRDb20pv4x2KbfAJG3i myYMJ4FEf/5zM10LKUqCwfx//3FcMCBhFQPwGP5MZhSPvzNGSMpPZwT/3e5frml4KT+r 2w5w== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1741697943; x=1742302743; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=YrjQAkubjW9GpsAIIJ1EX4bgybSUalPSDK9qpo5mGhU=; b=BH4Vofo4St+8CvwfGd6qUrEEcPXAR4OjJyeRrI5+QtOAGFp+jhEm7tJJY3INXLUneP Qm1p7wobl6srRYguxBRiLr0uN/V4YwqB4WlTZgJ1sxWGQyMQKXgLA/iJa92wAEKI3+Nk p4AUxFqGjw+kZkySwLANWVxOcQ30zo0Et5ocfjKv1RNE+Tm3diYxRSRXaAlVUe7hCe7c SMJ6Lhbm2ENyrORsshuA8vc3a2tIlJUVk0B5xmYLJ75SoKvsRqfcLgvP5sLzsJoaew0R nEgSa0T/P1HrkiyxCGiG5dESE3hJ5qfCxxBT8YiviA0eO1F5gl5AgjDvQUyrbseIrRoR +eaA== X-Forwarded-Encrypted: i=1; AJvYcCUTffL5sF38IYFuYnKKtHvHMiqzN6R2XklqABu87wklmKGYWcdfc94HNTrzaimJAX0d69d6Qlrydw==@nongnu.org X-Gm-Message-State: AOJu0Yxb4iWBpnrmbOE1MWY0RjlzWBllihHOerXvbQqWr5zD4+K65fyi y4ybWK8/roWLMMzm+5cWi/F/9tO+WYA8WiZtUqF1tUoiG8nSKtIjKPW8pw== X-Gm-Gg: ASbGncvbYgQgLd9FEMeB+xwAV2Ag9iRo2XaVwPkfFQqoy+P8SCNCJ0YLIabgV0aWXqd lHvbpwv5U4/Pq244wEy2kGlvoMrultHg1dWg9tKH5ZwkAKHxOPbpKpJd0bXNL3aQZihveKxQxrZ WbPy0xtokbCMqsvo3zc+gHxmq2j/gh+8wc205jVAJnYIV/3sAXj2qIG7IEyp04b5BuqqmJpFbrO j6gXnIOZaYue7l/x57vM/4DmxqsRQtOgoSsvq1sK8NJ0yWkwRVWqSn0Ff9N+4SRC/1RqDD6C94+ Cvt4Of9H0LECrMavFIoWRcLEJ3xl9LdG7Em4J+9E4SK+IMwwF9Q= X-Google-Smtp-Source: AGHT+IGlxVm1OVGiHo8O9YGAo0yMldwiYGsNeGlr5ba15ikp7TBijUHJ9BvvyJJqHqxpAT7ZgRLCag== X-Received: by 2002:a17:90b:180a:b0:2fe:9e6c:add9 with SMTP id 98e67ed59e1d1-300ff105730mr5520279a91.18.1741697943064; Tue, 11 Mar 2025 05:59:03 -0700 (PDT) Received: from wheely.local0.net ([118.208.151.101]) by smtp.gmail.com with ESMTPSA id 98e67ed59e1d1-2ff4e773dddsm11822318a91.12.2025.03.11.05.59.01 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 11 Mar 2025 05:59:02 -0700 (PDT) From: Nicholas Piggin To: qemu-devel@nongnu.org Cc: Nicholas Piggin , qemu-ppc@nongnu.org Subject: [PULL 09/72] ppc/pnv/occ: Fix common area sensor offsets Date: Tue, 11 Mar 2025 22:57:03 +1000 Message-ID: <20250311125815.903177-10-npiggin@gmail.com> X-Mailer: git-send-email 2.47.1 In-Reply-To: <20250311125815.903177-1-npiggin@gmail.com> References: <20250311125815.903177-1-npiggin@gmail.com> MIME-Version: 1.0 Received-SPF: pass client-ip=2607:f8b0:4864:20::102a; envelope-from=npiggin@gmail.com; helo=mail-pj1-x102a.google.com X-Spam_score_int: -20 X-Spam_score: -2.1 X-Spam_bar: -- X-Spam_report: (-2.1 / 5.0 requ) BAYES_00=-1.9, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_AU=-0.1, DKIM_VALID_EF=-0.1, FREEMAIL_FROM=0.001, RCVD_IN_DNSWL_NONE=-0.0001, SPF_HELO_NONE=0.001, SPF_PASS=-0.001 autolearn=ham autolearn_force=no X-Spam_action: no action X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: qemu-devel-bounces+qemu-devel=archiver.kernel.org@nongnu.org Sender: qemu-devel-bounces+qemu-devel=archiver.kernel.org@nongnu.org The commit to fix the OCC common area sensor mappings didn't update the register offsets to match. Before this change, skiboot reports: [ 0.347100086,3] OCC: Chip 0 sensor data invalid Afterward, there is no error and the sensor_groups directory appears under /sys/firmware/opal/. The SLW_IMAGE_BASE address looks like a workaround to intercept firmware memory accesses, but that does not seem to be required now (and would have been broken by the OCC common area region mapping change anyway). So it can be removed. Fixes: 3a1b70b66b5cb4 ("ppc/pnv: Fix OCC common area region mapping") Signed-off-by: Nicholas Piggin --- hw/ppc/pnv_occ.c | 33 +++++++++++++++------------------ 1 file changed, 15 insertions(+), 18 deletions(-) diff --git a/hw/ppc/pnv_occ.c b/hw/ppc/pnv_occ.c index 48123ceae1..c6681a035a 100644 --- a/hw/ppc/pnv_occ.c +++ b/hw/ppc/pnv_occ.c @@ -32,22 +32,21 @@ #define OCB_OCI_OCCMISC_OR 0x4022 /* OCC sensors */ -#define OCC_SENSOR_DATA_BLOCK_OFFSET 0x580000 -#define OCC_SENSOR_DATA_VALID 0x580001 -#define OCC_SENSOR_DATA_VERSION 0x580002 -#define OCC_SENSOR_DATA_READING_VERSION 0x580004 -#define OCC_SENSOR_DATA_NR_SENSORS 0x580008 -#define OCC_SENSOR_DATA_NAMES_OFFSET 0x580010 -#define OCC_SENSOR_DATA_READING_PING_OFFSET 0x580014 -#define OCC_SENSOR_DATA_READING_PONG_OFFSET 0x58000c -#define OCC_SENSOR_DATA_NAME_LENGTH 0x58000d -#define OCC_SENSOR_NAME_STRUCTURE_TYPE 0x580023 -#define OCC_SENSOR_LOC_CORE 0x580022 -#define OCC_SENSOR_LOC_GPU 0x580020 -#define OCC_SENSOR_TYPE_POWER 0x580003 -#define OCC_SENSOR_NAME 0x580005 -#define HWMON_SENSORS_MASK 0x58001e -#define SLW_IMAGE_BASE 0x0 +#define OCC_SENSOR_DATA_BLOCK_OFFSET 0x0000 +#define OCC_SENSOR_DATA_VALID 0x0001 +#define OCC_SENSOR_DATA_VERSION 0x0002 +#define OCC_SENSOR_DATA_READING_VERSION 0x0004 +#define OCC_SENSOR_DATA_NR_SENSORS 0x0008 +#define OCC_SENSOR_DATA_NAMES_OFFSET 0x0010 +#define OCC_SENSOR_DATA_READING_PING_OFFSET 0x0014 +#define OCC_SENSOR_DATA_READING_PONG_OFFSET 0x000c +#define OCC_SENSOR_DATA_NAME_LENGTH 0x000d +#define OCC_SENSOR_NAME_STRUCTURE_TYPE 0x0023 +#define OCC_SENSOR_LOC_CORE 0x0022 +#define OCC_SENSOR_LOC_GPU 0x0020 +#define OCC_SENSOR_TYPE_POWER 0x0003 +#define OCC_SENSOR_NAME 0x0005 +#define HWMON_SENSORS_MASK 0x001e static void pnv_occ_set_misc(PnvOCC *occ, uint64_t val) { @@ -129,8 +128,6 @@ static uint64_t pnv_occ_common_area_read(void *opaque, hwaddr addr, case HWMON_SENSORS_MASK: case OCC_SENSOR_LOC_GPU: return 0x8e00; - case SLW_IMAGE_BASE: - return 0x1000000000000000; } return 0; } From patchwork Tue Mar 11 12:57:04 2025 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Nicholas Piggin X-Patchwork-Id: 14011792 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.lore.kernel.org (Postfix) with ESMTPS id 4F773C28B2E for ; Tue, 11 Mar 2025 13:00:58 +0000 (UTC) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1trzCa-0001hJ-Na; Tue, 11 Mar 2025 08:59:21 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1trzCR-0001Uk-CJ; Tue, 11 Mar 2025 08:59:12 -0400 Received: from mail-pj1-x1036.google.com ([2607:f8b0:4864:20::1036]) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_128_GCM_SHA256:128) (Exim 4.90_1) (envelope-from ) id 1trzCO-0007tn-0F; Tue, 11 Mar 2025 08:59:10 -0400 Received: by mail-pj1-x1036.google.com with SMTP id 98e67ed59e1d1-2fee05829edso10575715a91.3; Tue, 11 Mar 2025 05:59:07 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20230601; t=1741697946; x=1742302746; darn=nongnu.org; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to; bh=gXU+U1l4Fd7SyqGLYuKX8zb67TDEGdub9abcDAe/vP8=; b=QjiRjuqa/W5PvadWA3sC4hvk5+4d9XVbi/eaGhr/2VuH7Zq9eVfl5MUtCg49TVeIcq wE1VWcKBAGlt/lIBQzy/K3+qObJJGdCbkrV1YwnIoX9neuiSWLObeN42gikQIy2kYWam NRLrJcQmtRiq895kFbDiydnrpWt+bOKQ6DB9WELVHNwP5lG2au6hNvmBlqiZQiOBkznI xTpnnjh/p+kh7ODxERFU6vUq3K2fYFwwwrIX9xJJdJ+fTxxUeQek77NDWA4d8rcLJk86 GQOjLq9wLTG66twik+CtwEBFOPh6Hcw1OulWNBH6YKLBRvgFPfsPTd20g8scPqstq55F PNow== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1741697946; x=1742302746; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=gXU+U1l4Fd7SyqGLYuKX8zb67TDEGdub9abcDAe/vP8=; b=fxcxdxKm4zM5zDTkRF9eE26kp2YFC12GQ0KCLjgYlh81e4KM0vmTaIy2o5/sirTmA0 g0jMZsvR3jqrIN1+WpASQVTZ44mybKxU6ysd1u3KPRmyfnHfyo/6RZsoOSvYBchoG9QM dUaAz3hKyC19XAk/AIHVhLXCLAXsELzeoNmmbH4x3xmtF2rJjmW03SNWonVWmS/WAVBy V/Iiq4JcfoemqB9wWudfKU5GNss6apNBdq/UlkAe+yn2B1/AECJaNqKhyzgbOHOI6B8R TcZ/KYAVbimoujFZ7LQuXT5DYy2YtA4fewLjnrWmz423IIy+CWamgWKpIws4afK8k+R+ j5YQ== X-Forwarded-Encrypted: i=1; AJvYcCXBfeHw9/5VCkMdToD2OIRB/XBQp77NIP9rne8P6gIITtdHH09CYSpY1/d76ra863YGlct75f0fxQ==@nongnu.org X-Gm-Message-State: AOJu0YxDQ0L+hn6tO1Xo7xyLVsybRm2B4I6lTP8ezzFSi1IQbC9CIUgY kDQg/+gTsg5O11ZFjUIB96tp986SGWu5BDtELEvxjM27YV4pietKMmX3Qw== X-Gm-Gg: ASbGnctmliHyU6iAyhW1CIMIK4uV0GoTt8QyAgRN/rpgDisYnuh91BH6QXJYh0juZee IWuPHXBg+mVG1nvk0tkH4bWp+hEj00GSbkMM+d9Kle1ZB1n/j2z4aRwbn0fOjWDFiEXFT1wbCCS wrxNIewb4O2eRQkAYGYetN/w7MieGxN+ol/bZ89yk/0yIhuyu79MAlbCnXDlktzR1lfmspDKPhv Lxq3QN/WlBsGLQueoj4jqsvhZKswiC5YLp04fLhUYWpm+/ei0xwPm9Dmb3/ZMnkfIBUCiWAVBcq atIoROxYus+1BHtH3ucBMZFgA7xNgks5M+foaitMklb+7NQ5hms= X-Google-Smtp-Source: AGHT+IG3+xr/2h+PWYIuYl/EieLYhOiHlZl8JyOV3SJZdQfC/ZcRMjL0XcvzQu4nL2m4ia/sIHtmug== X-Received: by 2002:a17:90b:1648:b0:2f9:9ddd:68b9 with SMTP id 98e67ed59e1d1-2ff7cefbc6dmr23162307a91.26.1741697945564; Tue, 11 Mar 2025 05:59:05 -0700 (PDT) Received: from wheely.local0.net ([118.208.151.101]) by smtp.gmail.com with ESMTPSA id 98e67ed59e1d1-2ff4e773dddsm11822318a91.12.2025.03.11.05.59.03 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 11 Mar 2025 05:59:05 -0700 (PDT) From: Nicholas Piggin To: qemu-devel@nongnu.org Cc: Nicholas Piggin , qemu-ppc@nongnu.org Subject: [PULL 10/72] ppc/pnv/homer: class-based base and size Date: Tue, 11 Mar 2025 22:57:04 +1000 Message-ID: <20250311125815.903177-11-npiggin@gmail.com> X-Mailer: git-send-email 2.47.1 In-Reply-To: <20250311125815.903177-1-npiggin@gmail.com> References: <20250311125815.903177-1-npiggin@gmail.com> MIME-Version: 1.0 Received-SPF: pass client-ip=2607:f8b0:4864:20::1036; envelope-from=npiggin@gmail.com; helo=mail-pj1-x1036.google.com X-Spam_score_int: -20 X-Spam_score: -2.1 X-Spam_bar: -- X-Spam_report: (-2.1 / 5.0 requ) BAYES_00=-1.9, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_AU=-0.1, DKIM_VALID_EF=-0.1, FREEMAIL_FROM=0.001, RCVD_IN_DNSWL_NONE=-0.0001, SPF_HELO_NONE=0.001, SPF_PASS=-0.001 autolearn=ham autolearn_force=no X-Spam_action: no action X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: qemu-devel-bounces+qemu-devel=archiver.kernel.org@nongnu.org Sender: qemu-devel-bounces+qemu-devel=archiver.kernel.org@nongnu.org Put HOMER memory region base and size into the class, to allow more code-reuse between different machines in later changes. Signed-off-by: Nicholas Piggin --- hw/ppc/pnv_homer.c | 46 +++++++++++++++++++++++++++----------- include/hw/ppc/pnv.h | 6 ++--- include/hw/ppc/pnv_homer.h | 7 +++++- 3 files changed, 41 insertions(+), 18 deletions(-) diff --git a/hw/ppc/pnv_homer.c b/hw/ppc/pnv_homer.c index 75b0ee7964..67a1fd77ba 100644 --- a/hw/ppc/pnv_homer.c +++ b/hw/ppc/pnv_homer.c @@ -138,16 +138,16 @@ static uint64_t pnv_homer_power8_pba_read(void *opaque, hwaddr addr, unsigned size) { PnvHomer *homer = PNV_HOMER(opaque); - PnvChip *chip = homer->chip; + PnvHomerClass *hmrc = PNV_HOMER_GET_CLASS(homer); uint32_t reg = addr >> 3; uint64_t val = 0; switch (reg) { case PBA_BAR0: - val = PNV_HOMER_BASE(chip); + val = homer->base; break; case PBA_BARMASK0: /* P8 homer region mask */ - val = (PNV_HOMER_SIZE - 1) & 0x300000; + val = (hmrc->size - 1) & 0x300000; break; case PBA_BAR3: /* P8 occ common area */ val = PNV_OCC_COMMON_AREA_BASE; @@ -179,13 +179,19 @@ static const MemoryRegionOps pnv_homer_power8_pba_ops = { .endianness = DEVICE_BIG_ENDIAN, }; +static hwaddr pnv_homer_power8_get_base(PnvChip *chip) +{ + return PNV_HOMER_BASE(chip); +} + static void pnv_homer_power8_class_init(ObjectClass *klass, void *data) { PnvHomerClass *homer = PNV_HOMER_CLASS(klass); + homer->get_base = pnv_homer_power8_get_base; + homer->size = PNV_HOMER_SIZE; homer->pba_size = PNV_XSCOM_PBA_SIZE; homer->pba_ops = &pnv_homer_power8_pba_ops; - homer->homer_size = PNV_HOMER_SIZE; homer->homer_ops = &pnv_power8_homer_ops; homer->core_max_base = PNV8_CORE_MAX_BASE; } @@ -291,16 +297,16 @@ static uint64_t pnv_homer_power9_pba_read(void *opaque, hwaddr addr, unsigned size) { PnvHomer *homer = PNV_HOMER(opaque); - PnvChip *chip = homer->chip; + PnvHomerClass *hmrc = PNV_HOMER_GET_CLASS(homer); uint32_t reg = addr >> 3; uint64_t val = 0; switch (reg) { case PBA_BAR0: - val = PNV9_HOMER_BASE(chip); + val = homer->base; break; case PBA_BARMASK0: /* P9 homer region mask */ - val = (PNV9_HOMER_SIZE - 1) & 0x300000; + val = (hmrc->size - 1) & 0x300000; break; case PBA_BAR2: /* P9 occ common area */ val = PNV9_OCC_COMMON_AREA_BASE; @@ -332,13 +338,19 @@ static const MemoryRegionOps pnv_homer_power9_pba_ops = { .endianness = DEVICE_BIG_ENDIAN, }; +static hwaddr pnv_homer_power9_get_base(PnvChip *chip) +{ + return PNV9_HOMER_BASE(chip); +} + static void pnv_homer_power9_class_init(ObjectClass *klass, void *data) { PnvHomerClass *homer = PNV_HOMER_CLASS(klass); + homer->get_base = pnv_homer_power9_get_base; + homer->size = PNV_HOMER_SIZE; homer->pba_size = PNV9_XSCOM_PBA_SIZE; homer->pba_ops = &pnv_homer_power9_pba_ops; - homer->homer_size = PNV9_HOMER_SIZE; homer->homer_ops = &pnv_power9_homer_ops; homer->core_max_base = PNV9_CORE_MAX_BASE; } @@ -354,16 +366,16 @@ static uint64_t pnv_homer_power10_pba_read(void *opaque, hwaddr addr, unsigned size) { PnvHomer *homer = PNV_HOMER(opaque); - PnvChip *chip = homer->chip; + PnvHomerClass *hmrc = PNV_HOMER_GET_CLASS(homer); uint32_t reg = addr >> 3; uint64_t val = 0; switch (reg) { case PBA_BAR0: - val = PNV10_HOMER_BASE(chip); + val = homer->base; break; case PBA_BARMASK0: /* P10 homer region mask */ - val = (PNV10_HOMER_SIZE - 1) & 0x300000; + val = (hmrc->size - 1) & 0x300000; break; case PBA_BAR2: /* P10 occ common area */ val = PNV10_OCC_COMMON_AREA_BASE; @@ -395,13 +407,19 @@ static const MemoryRegionOps pnv_homer_power10_pba_ops = { .endianness = DEVICE_BIG_ENDIAN, }; +static hwaddr pnv_homer_power10_get_base(PnvChip *chip) +{ + return PNV10_HOMER_BASE(chip); +} + static void pnv_homer_power10_class_init(ObjectClass *klass, void *data) { PnvHomerClass *homer = PNV_HOMER_CLASS(klass); + homer->get_base = pnv_homer_power10_get_base; + homer->size = PNV_HOMER_SIZE; homer->pba_size = PNV10_XSCOM_PBA_SIZE; homer->pba_ops = &pnv_homer_power10_pba_ops; - homer->homer_size = PNV10_HOMER_SIZE; homer->homer_ops = &pnv_power9_homer_ops; /* TODO */ homer->core_max_base = PNV9_CORE_MAX_BASE; } @@ -424,9 +442,11 @@ static void pnv_homer_realize(DeviceState *dev, Error **errp) homer, "xscom-pba", hmrc->pba_size); /* homer region */ + homer->base = hmrc->get_base(homer->chip); + memory_region_init_io(&homer->regs, OBJECT(dev), hmrc->homer_ops, homer, "homer-main-memory", - hmrc->homer_size); + hmrc->size); } static const Property pnv_homer_properties[] = { diff --git a/include/hw/ppc/pnv.h b/include/hw/ppc/pnv.h index fcb6699150..d8fca079f2 100644 --- a/include/hw/ppc/pnv.h +++ b/include/hw/ppc/pnv.h @@ -205,9 +205,8 @@ void pnv_bmc_set_pnor(IPMIBmc *bmc, PnvPnor *pnor); #define PNV9_OCC_SENSOR_BASE(chip) (PNV9_OCC_COMMON_AREA_BASE + \ PNV_OCC_SENSOR_DATA_BLOCK_BASE((chip)->chip_id)) -#define PNV9_HOMER_SIZE 0x0000000000400000ull #define PNV9_HOMER_BASE(chip) \ - (0x203ffd800000ull + ((uint64_t)(chip)->chip_id) * PNV9_HOMER_SIZE) + (0x203ffd800000ull + ((uint64_t)(chip)->chip_id) * PNV_HOMER_SIZE) /* * POWER10 MMIO base addresses - 16TB stride per chip @@ -250,8 +249,7 @@ void pnv_bmc_set_pnor(IPMIBmc *bmc, PnvPnor *pnor); #define PNV10_OCC_SENSOR_BASE(chip) (PNV10_OCC_COMMON_AREA_BASE + \ PNV_OCC_SENSOR_DATA_BLOCK_BASE((chip)->chip_id)) -#define PNV10_HOMER_SIZE 0x0000000000400000ull #define PNV10_HOMER_BASE(chip) \ - (0x300ffd800000ll + ((uint64_t)(chip)->chip_id) * PNV10_HOMER_SIZE) + (0x300ffd800000ll + ((uint64_t)(chip)->chip_id) * PNV_HOMER_SIZE) #endif /* PPC_PNV_H */ diff --git a/include/hw/ppc/pnv_homer.h b/include/hw/ppc/pnv_homer.h index b1c5d498dc..5ffc0c97af 100644 --- a/include/hw/ppc/pnv_homer.h +++ b/include/hw/ppc/pnv_homer.h @@ -42,15 +42,20 @@ struct PnvHomer { PnvChip *chip; MemoryRegion pba_regs; MemoryRegion regs; + hwaddr base; }; struct PnvHomerClass { DeviceClass parent_class; + /* Get base address of HOMER memory */ + hwaddr (*get_base)(PnvChip *chip); + /* Size of HOMER memory */ + int size; + int pba_size; const MemoryRegionOps *pba_ops; - int homer_size; const MemoryRegionOps *homer_ops; hwaddr core_max_base; From patchwork Tue Mar 11 12:57:05 2025 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Nicholas Piggin X-Patchwork-Id: 14011799 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.lore.kernel.org (Postfix) with ESMTPS id 81728C28B2E for ; Tue, 11 Mar 2025 13:02:49 +0000 (UTC) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1trzCv-0002iX-3p; Tue, 11 Mar 2025 08:59:42 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1trzCV-0001cG-QP; Tue, 11 Mar 2025 08:59:15 -0400 Received: from mail-pj1-x102b.google.com ([2607:f8b0:4864:20::102b]) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_128_GCM_SHA256:128) (Exim 4.90_1) (envelope-from ) id 1trzCT-0007ud-KF; Tue, 11 Mar 2025 08:59:15 -0400 Received: by mail-pj1-x102b.google.com with SMTP id 98e67ed59e1d1-2fecba90cc3so10436509a91.2; Tue, 11 Mar 2025 05:59:10 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20230601; t=1741697948; x=1742302748; darn=nongnu.org; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to; bh=VLC1n3HVZL5UFr7qSjs7PdPNKDKAAkSwrr+MO1MH/MU=; b=MCv8mRME+VlXfNIlUkk+VgeJ8WAR9LtZs8zOrTw61HXN7/obSY2AqgAQuHXuJgOAoN dRhxvyAFH7vmAQCWny3Evy2zZmWrTUA+ICzzG8Nakvd4X9Xia4i97FzNaATsdxIGnTo+ 7mt60q1xpUVSjOq4AnaIQVRxk+RChG0lKvVDYtjRlxEwpopr3YuZ2N5EMKdypoaJcmOZ 51tC28k3eKuiEECTmioAFT9RXcyvqaz5c1Mo3O5B/caKpCKRlylBEE93YyEqnBDHhHy1 5a40TU3HHg/TnkNV787saQrsVMOMhUJXliwxF1X+AqAX7XpOBSGQKZvrf60bP6++0nay ZK8g== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1741697948; x=1742302748; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=VLC1n3HVZL5UFr7qSjs7PdPNKDKAAkSwrr+MO1MH/MU=; b=LvMERcXiphMBumjc/PormHToedyDz9THUkpDBNN5F5RZBQSYyCrfNTu20hRvvwaUo9 MS7WcWYD7ow7aMsXmAAWPfFFys6oLZw3VXVwCSKnhc58zwwHZxQGMvWkM6GWsdIvFOSU kAE+J7+0RTsmgb1nC0Cf3s57ABKlfhYZnE9pB8R9USM72KkizpvO/DsWq6kei9Tv1rol AkYLySyxVBPFQ4YwMMx9qPkk5lpNGzLIh1KQPdYu9CuDlOW1Nl3Ad5adMtMaVzOFsEjt Jpus6DF7WtuzJalR1ObqbUvRJc13EWHquP+eg0QQOCOhSqMCPlXbLQeYLa9kZhuhlI91 Ft1g== X-Forwarded-Encrypted: i=1; AJvYcCUwpNyk31GEOJMnMZ10uqaHPeo18qPbHmhj9I+WLjcy0Ytvu58yNGeNdzx8Q8uGrRHQSeHbnbmvYA==@nongnu.org X-Gm-Message-State: AOJu0YyOD2a7F/pJnxbGXIhHOpG+WwmNkHCUVqMFxDDgfwg8gKuSaaeG 6OUuLeADwJc5BqifuZHTFBBYKCZDttuu20iQMexY/vk8LvcgJskT7elSDA== X-Gm-Gg: ASbGncvw+/0YK4HzErRo7nag9CM7Ao2zXskfujfqtiLmBkmRV0T4rzdf11r/i/ZLiCc vs1OsX3MZdByIfcWPqqAnQFhMA/p84wXJfHpLMIDd8uMl4wPgqCDcx+zeJYG4AE0fBA0bMG7NZP vJ+6evQY1vnPE8v1Mm266rVxg5R02B9YfdVNgyiUrV+Th9ae54TOMyZadAmajq+Xc1nFnUGGJsq tAW0ZKmD66xJKpibFK8vGARoqJ05yQatGD86hZ+wUDc4Ax71VU67rIxJAZfEcbKLMT0mcsuz3FA ejvnQyU0gwWlVpolKAp+ihzEKNfTdKRAxfk8SIEWZ02i9VLn6pw= X-Google-Smtp-Source: AGHT+IGvY8ozC/uQAizW8zsb53sHUauiNE6F8zgr5Qr3Ie/PuiDWspaTTXP6IdA7QV3HomRrGRzFuw== X-Received: by 2002:a17:90b:3887:b0:2f4:4003:f3ea with SMTP id 98e67ed59e1d1-2ff7cef99c2mr31715649a91.33.1741697947928; Tue, 11 Mar 2025 05:59:07 -0700 (PDT) Received: from wheely.local0.net ([118.208.151.101]) by smtp.gmail.com with ESMTPSA id 98e67ed59e1d1-2ff4e773dddsm11822318a91.12.2025.03.11.05.59.05 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 11 Mar 2025 05:59:07 -0700 (PDT) From: Nicholas Piggin To: qemu-devel@nongnu.org Cc: Nicholas Piggin , qemu-ppc@nongnu.org Subject: [PULL 11/72] ppc/pnv/occ: Better document OCCMISC bits Date: Tue, 11 Mar 2025 22:57:05 +1000 Message-ID: <20250311125815.903177-12-npiggin@gmail.com> X-Mailer: git-send-email 2.47.1 In-Reply-To: <20250311125815.903177-1-npiggin@gmail.com> References: <20250311125815.903177-1-npiggin@gmail.com> MIME-Version: 1.0 Received-SPF: pass client-ip=2607:f8b0:4864:20::102b; envelope-from=npiggin@gmail.com; helo=mail-pj1-x102b.google.com X-Spam_score_int: -20 X-Spam_score: -2.1 X-Spam_bar: -- X-Spam_report: (-2.1 / 5.0 requ) BAYES_00=-1.9, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_AU=-0.1, DKIM_VALID_EF=-0.1, FREEMAIL_FROM=0.001, RCVD_IN_DNSWL_NONE=-0.0001, SPF_HELO_NONE=0.001, SPF_PASS=-0.001 autolearn=ham autolearn_force=no X-Spam_action: no action X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: qemu-devel-bounces+qemu-devel=archiver.kernel.org@nongnu.org Sender: qemu-devel-bounces+qemu-devel=archiver.kernel.org@nongnu.org Use defines for the OCCMISC register bits, and add a comment about the IRQ request bit, which QEMU may not model quite correctly. Signed-off-by: Nicholas Piggin --- hw/ppc/pnv_occ.c | 14 +++++++++----- 1 file changed, 9 insertions(+), 5 deletions(-) diff --git a/hw/ppc/pnv_occ.c b/hw/ppc/pnv_occ.c index c6681a035a..5424d87ee9 100644 --- a/hw/ppc/pnv_occ.c +++ b/hw/ppc/pnv_occ.c @@ -30,6 +30,7 @@ #define OCB_OCI_OCCMISC 0x4020 #define OCB_OCI_OCCMISC_AND 0x4021 #define OCB_OCI_OCCMISC_OR 0x4022 +#define OCCMISC_PSI_IRQ PPC_BIT(0) /* OCC sensors */ #define OCC_SENSOR_DATA_BLOCK_OFFSET 0x0000 @@ -50,13 +51,16 @@ static void pnv_occ_set_misc(PnvOCC *occ, uint64_t val) { - bool irq_state; - - val &= 0xffff000000000000ull; + val &= PPC_BITMASK(0, 18); /* Mask out unimplemented bits */ occ->occmisc = val; - irq_state = !!(val >> 63); - qemu_set_irq(occ->psi_irq, irq_state); + + /* + * OCCMISC IRQ bit triggers the interrupt on a 0->1 edge, but not clear + * how that is handled in PSI so it is level-triggered here, which is not + * really correct (but skiboot is okay with it). + */ + qemu_set_irq(occ->psi_irq, !!(val & OCCMISC_PSI_IRQ)); } static uint64_t pnv_occ_power8_xscom_read(void *opaque, hwaddr addr, From patchwork Tue Mar 11 12:57:06 2025 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: Nicholas Piggin X-Patchwork-Id: 14011813 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.lore.kernel.org (Postfix) with ESMTPS id 70696C28B2E for ; Tue, 11 Mar 2025 13:07:35 +0000 (UTC) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1trzCy-00031e-3D; Tue, 11 Mar 2025 08:59:44 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1trzCX-0001ew-HI; Tue, 11 Mar 2025 08:59:17 -0400 Received: from mail-pj1-x1036.google.com ([2607:f8b0:4864:20::1036]) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_128_GCM_SHA256:128) (Exim 4.90_1) (envelope-from ) id 1trzCT-0007v7-M9; Tue, 11 Mar 2025 08:59:17 -0400 Received: by mail-pj1-x1036.google.com with SMTP id 98e67ed59e1d1-2ff615a114bso9408877a91.0; Tue, 11 Mar 2025 05:59:12 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20230601; t=1741697951; x=1742302751; darn=nongnu.org; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to; bh=Js3E974HF75tsKX3gwV22ZPIVLOl+mdYAbePvTKZzbs=; b=FIynth60jp2Y3qbvxj0vxcUoau/xLlaQBXVSZqdv5gEilNytGxNGB7P290zngaqaZd v5dCsu5fWHh+Iq8IEwU3NxAM+P4Rr//b+vRnUpntX4dqezHHVuUDOSA2p2TjaIRlfXPi GhHJf4k2SQUikKFeSfXgyDVb9aEnCeuv37qlCbcV0dvOs5cAiFDLhkH/8exo6XCNGMz1 KbXttPe2QfF/g7rNDLdEngOrSjX5+b90fj5HXQgsF1gxhHFoYc1DGpXBxqd96VujP52y ouxUTW83kz9ld6IkMNOeeR+dBiXM1t57qr0rmYggYf3xbf5vvEY9mr0Hz2zicqjz7iC1 GJMg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1741697951; x=1742302751; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=Js3E974HF75tsKX3gwV22ZPIVLOl+mdYAbePvTKZzbs=; b=QNPAKUdfPhkTsc4Ui1oBkqmXPEolSd/2KEk8wJBoObNDgfz4Q886cVJO95UeyKLoWO FAUKQecQI1u7P3fWCQyXKNBWVSUDz+XBiKTvpN5n0D5Y4LoxCXK1oOPXtkbCixPN5qTr HyQkYkx7859x8r5bk7KLrRFgHNSbqJ3dFNVW05vfcNyP+zB/v5ynBRWvPekz5pPUcZD7 AOL1uf6E23Xa6OmbE/Extr/gJMl5TIvENYUZ8X3BFxiUu3G8IlVx7+JnafrBpWIAxYT+ obqTheH9AAEsUcaVvSMpbEsBvnJZZgl0rEhgX1DsONZem/xfA64ScDiH3k3b4nCGV8FD mscg== X-Forwarded-Encrypted: i=1; AJvYcCWInkRtOjWwdy5j8ZsUp6+WBh2Q6GNNOQd9BFWke+ZkX+NsItHf1l3lQx1qajkc9Sh9XTCSJZFLrg==@nongnu.org X-Gm-Message-State: AOJu0YyD+jXnZSCMQ3zQJz4DS05uKswJSDtmOn0r3CnG5Jk3/WwVWYc0 8GwKJAxd4OaXtPN/5JfkDMpvSrWoOVTj71Tm67Rp+QxOr0rRRrGWsnP+9Q== X-Gm-Gg: ASbGncsq0NmMBEEX5LkUJr46eLnGm0fvtpYUEGkv7YcY9mHwREv7Zdja1+A7lzxjhuk t87dcNWPGG6sXOHMSlcjz/0E4yDtGzIC5LNEsULIKUDSI6zaqlS7uA95NPBIvDcsOupH/6oI/uf pkdAsFa90sJJlVljgaSzm6E536jIu72hSqlErpHqLmT5I+Xk5Op6fAKHAK5M9TL4hlgQfZJSTnd 4/LU36kr1REb2ll0EYmrBawUn6daFFGytL2IbQGgFQh0seT8P4MR6u/DYpG6NtlaN2LqTSFY1Q4 yacCuVOBRX+HpALvdVntrMu3dBF9hWZ6L/9pWDRGTtSWQz3RhG4= X-Google-Smtp-Source: AGHT+IG/FVJjYyNBQ2uhg6tLvYW64Pd1z+EWw2ar8cLKBeNhYWyWYyu8m7k8ADaUmG20OYIpgpQ0yA== X-Received: by 2002:a17:90b:1346:b0:2fb:fe21:4841 with SMTP id 98e67ed59e1d1-3010051f3famr5108789a91.8.1741697950517; Tue, 11 Mar 2025 05:59:10 -0700 (PDT) Received: from wheely.local0.net ([118.208.151.101]) by smtp.gmail.com with ESMTPSA id 98e67ed59e1d1-2ff4e773dddsm11822318a91.12.2025.03.11.05.59.08 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 11 Mar 2025 05:59:10 -0700 (PDT) From: Nicholas Piggin To: qemu-devel@nongnu.org Cc: Nicholas Piggin , qemu-ppc@nongnu.org Subject: [PULL 12/72] ppc/pnv: Make HOMER memory a RAM region Date: Tue, 11 Mar 2025 22:57:06 +1000 Message-ID: <20250311125815.903177-13-npiggin@gmail.com> X-Mailer: git-send-email 2.47.1 In-Reply-To: <20250311125815.903177-1-npiggin@gmail.com> References: <20250311125815.903177-1-npiggin@gmail.com> MIME-Version: 1.0 Received-SPF: pass client-ip=2607:f8b0:4864:20::1036; envelope-from=npiggin@gmail.com; helo=mail-pj1-x1036.google.com X-Spam_score_int: -20 X-Spam_score: -2.1 X-Spam_bar: -- X-Spam_report: (-2.1 / 5.0 requ) BAYES_00=-1.9, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_AU=-0.1, DKIM_VALID_EF=-0.1, FREEMAIL_FROM=0.001, RCVD_IN_DNSWL_NONE=-0.0001, SPF_HELO_NONE=0.001, SPF_PASS=-0.001 autolearn=ham autolearn_force=no X-Spam_action: no action X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: qemu-devel-bounces+qemu-devel=archiver.kernel.org@nongnu.org Sender: qemu-devel-bounces+qemu-devel=archiver.kernel.org@nongnu.org The HOMER is a region of memory used by host and firmware and microconrollers. It has very little logic by itself, just some BAR registers. Users of this memory should operate on it rather than have HOMER implement them with MMIO registers, which is not the right model. This change switches the implementation of HOMER from MMIO to RAM, and moves the OCC register implementation to in-memory structure accesses performed by the OCC model. This has the downside that access to unimplemented regions of HOMER are no longer flagged. Perhaps that could be done by adding a memory region for HOMER, and ram subregions under that for each implemented part. But for now this takes the simpler approach. Note: This brings some data structure definitions from skiboot, which does not match QEMU coding style but is not changed to make comparisons and updates simpler. Signed-off-by: Nicholas Piggin --- hw/ppc/pnv.c | 89 ++++---- hw/ppc/pnv_homer.c | 203 +---------------- hw/ppc/pnv_occ.c | 434 ++++++++++++++++++++++++++++++++++++- include/hw/ppc/pnv_homer.h | 5 +- include/hw/ppc/pnv_occ.h | 6 + roms/SLOF | 2 +- 6 files changed, 495 insertions(+), 244 deletions(-) diff --git a/hw/ppc/pnv.c b/hw/ppc/pnv.c index 4407b3a1a2..8c0a2d0573 100644 --- a/hw/ppc/pnv.c +++ b/hw/ppc/pnv.c @@ -1555,7 +1555,21 @@ static void pnv_chip_power8_realize(DeviceState *dev, Error **errp) return; } + /* HOMER (must be created before OCC) */ + object_property_set_link(OBJECT(&chip8->homer), "chip", OBJECT(chip), + &error_abort); + if (!qdev_realize(DEVICE(&chip8->homer), NULL, errp)) { + return; + } + /* Homer Xscom region */ + pnv_xscom_add_subregion(chip, PNV_XSCOM_PBA_BASE, &chip8->homer.pba_regs); + /* Homer RAM region */ + memory_region_add_subregion(get_system_memory(), chip8->homer.base, + &chip8->homer.mem); + /* Create the simplified OCC model */ + object_property_set_link(OBJECT(&chip8->occ), "homer", + OBJECT(&chip8->homer), &error_abort); if (!qdev_realize(DEVICE(&chip8->occ), NULL, errp)) { return; } @@ -1567,19 +1581,6 @@ static void pnv_chip_power8_realize(DeviceState *dev, Error **errp) memory_region_add_subregion(get_system_memory(), PNV_OCC_SENSOR_BASE(chip), &chip8->occ.sram_regs); - /* HOMER */ - object_property_set_link(OBJECT(&chip8->homer), "chip", OBJECT(chip), - &error_abort); - if (!qdev_realize(DEVICE(&chip8->homer), NULL, errp)) { - return; - } - /* Homer Xscom region */ - pnv_xscom_add_subregion(chip, PNV_XSCOM_PBA_BASE, &chip8->homer.pba_regs); - - /* Homer mmio region */ - memory_region_add_subregion(get_system_memory(), PNV_HOMER_BASE(chip), - &chip8->homer.regs); - /* PHB controllers */ for (i = 0; i < chip8->num_phbs; i++) { PnvPHB *phb = chip8->phbs[i]; @@ -1863,18 +1864,6 @@ static void pnv_chip_power9_realize(DeviceState *dev, Error **errp) pnv_xscom_add_subregion(chip, PNV9_XSCOM_CHIPTOD_BASE, &chip9->chiptod.xscom_regs); - /* Create the simplified OCC model */ - if (!qdev_realize(DEVICE(&chip9->occ), NULL, errp)) { - return; - } - pnv_xscom_add_subregion(chip, PNV9_XSCOM_OCC_BASE, &chip9->occ.xscom_regs); - qdev_connect_gpio_out(DEVICE(&chip9->occ), 0, qdev_get_gpio_in( - DEVICE(psi9), PSIHB9_IRQ_OCC)); - - /* OCC SRAM model */ - memory_region_add_subregion(get_system_memory(), PNV9_OCC_SENSOR_BASE(chip), - &chip9->occ.sram_regs); - /* SBE */ if (!qdev_realize(DEVICE(&chip9->sbe), NULL, errp)) { return; @@ -1886,7 +1875,7 @@ static void pnv_chip_power9_realize(DeviceState *dev, Error **errp) qdev_connect_gpio_out(DEVICE(&chip9->sbe), 0, qdev_get_gpio_in( DEVICE(psi9), PSIHB9_IRQ_PSU)); - /* HOMER */ + /* HOMER (must be created before OCC) */ object_property_set_link(OBJECT(&chip9->homer), "chip", OBJECT(chip), &error_abort); if (!qdev_realize(DEVICE(&chip9->homer), NULL, errp)) { @@ -1894,10 +1883,23 @@ static void pnv_chip_power9_realize(DeviceState *dev, Error **errp) } /* Homer Xscom region */ pnv_xscom_add_subregion(chip, PNV9_XSCOM_PBA_BASE, &chip9->homer.pba_regs); + /* Homer RAM region */ + memory_region_add_subregion(get_system_memory(), chip9->homer.base, + &chip9->homer.mem); - /* Homer mmio region */ - memory_region_add_subregion(get_system_memory(), PNV9_HOMER_BASE(chip), - &chip9->homer.regs); + /* Create the simplified OCC model */ + object_property_set_link(OBJECT(&chip9->occ), "homer", + OBJECT(&chip9->homer), &error_abort); + if (!qdev_realize(DEVICE(&chip9->occ), NULL, errp)) { + return; + } + pnv_xscom_add_subregion(chip, PNV9_XSCOM_OCC_BASE, &chip9->occ.xscom_regs); + qdev_connect_gpio_out(DEVICE(&chip9->occ), 0, qdev_get_gpio_in( + DEVICE(psi9), PSIHB9_IRQ_OCC)); + + /* OCC SRAM model */ + memory_region_add_subregion(get_system_memory(), PNV9_OCC_SENSOR_BASE(chip), + &chip9->occ.sram_regs); /* PEC PHBs */ pnv_chip_power9_pec_realize(chip, &local_err); @@ -2144,7 +2146,22 @@ static void pnv_chip_power10_realize(DeviceState *dev, Error **errp) pnv_xscom_add_subregion(chip, PNV10_XSCOM_CHIPTOD_BASE, &chip10->chiptod.xscom_regs); + /* HOMER (must be created before OCC) */ + object_property_set_link(OBJECT(&chip10->homer), "chip", OBJECT(chip), + &error_abort); + if (!qdev_realize(DEVICE(&chip10->homer), NULL, errp)) { + return; + } + /* Homer Xscom region */ + pnv_xscom_add_subregion(chip, PNV10_XSCOM_PBA_BASE, + &chip10->homer.pba_regs); + /* Homer RAM region */ + memory_region_add_subregion(get_system_memory(), chip10->homer.base, + &chip10->homer.mem); + /* Create the simplified OCC model */ + object_property_set_link(OBJECT(&chip10->occ), "homer", + OBJECT(&chip10->homer), &error_abort); if (!qdev_realize(DEVICE(&chip10->occ), NULL, errp)) { return; } @@ -2169,20 +2186,6 @@ static void pnv_chip_power10_realize(DeviceState *dev, Error **errp) qdev_connect_gpio_out(DEVICE(&chip10->sbe), 0, qdev_get_gpio_in( DEVICE(&chip10->psi), PSIHB9_IRQ_PSU)); - /* HOMER */ - object_property_set_link(OBJECT(&chip10->homer), "chip", OBJECT(chip), - &error_abort); - if (!qdev_realize(DEVICE(&chip10->homer), NULL, errp)) { - return; - } - /* Homer Xscom region */ - pnv_xscom_add_subregion(chip, PNV10_XSCOM_PBA_BASE, - &chip10->homer.pba_regs); - - /* Homer mmio region */ - memory_region_add_subregion(get_system_memory(), PNV10_HOMER_BASE(chip), - &chip10->homer.regs); - /* N1 chiplet */ if (!qdev_realize(DEVICE(&chip10->n1_chiplet), NULL, errp)) { return; diff --git a/hw/ppc/pnv_homer.c b/hw/ppc/pnv_homer.c index 67a1fd77ba..18a53a80c1 100644 --- a/hw/ppc/pnv_homer.c +++ b/hw/ppc/pnv_homer.c @@ -29,101 +29,6 @@ #include "hw/ppc/pnv_homer.h" #include "hw/ppc/pnv_xscom.h" - -static bool core_max_array(PnvHomer *homer, hwaddr addr) -{ - int i; - PnvHomerClass *hmrc = PNV_HOMER_GET_CLASS(homer); - - for (i = 0; i <= homer->chip->nr_cores; i++) { - if (addr == (hmrc->core_max_base + i)) { - return true; - } - } - return false; -} - -/* P8 Pstate table */ - -#define PNV8_OCC_PSTATE_VERSION 0x1f8001 -#define PNV8_OCC_PSTATE_MIN 0x1f8003 -#define PNV8_OCC_PSTATE_VALID 0x1f8000 -#define PNV8_OCC_PSTATE_THROTTLE 0x1f8002 -#define PNV8_OCC_PSTATE_NOM 0x1f8004 -#define PNV8_OCC_PSTATE_TURBO 0x1f8005 -#define PNV8_OCC_PSTATE_ULTRA_TURBO 0x1f8006 -#define PNV8_OCC_PSTATE_DATA 0x1f8008 -#define PNV8_OCC_PSTATE_ID_ZERO 0x1f8010 -#define PNV8_OCC_PSTATE_ID_ONE 0x1f8018 -#define PNV8_OCC_PSTATE_ID_TWO 0x1f8020 -#define PNV8_OCC_VDD_VOLTAGE_IDENTIFIER 0x1f8012 -#define PNV8_OCC_VCS_VOLTAGE_IDENTIFIER 0x1f8013 -#define PNV8_OCC_PSTATE_ZERO_FREQUENCY 0x1f8014 -#define PNV8_OCC_PSTATE_ONE_FREQUENCY 0x1f801c -#define PNV8_OCC_PSTATE_TWO_FREQUENCY 0x1f8024 -#define PNV8_CORE_MAX_BASE 0x1f8810 - - -static uint64_t pnv_power8_homer_read(void *opaque, hwaddr addr, - unsigned size) -{ - PnvHomer *homer = PNV_HOMER(opaque); - - switch (addr) { - case PNV8_OCC_PSTATE_VALID: - return 1; - case PNV8_OCC_PSTATE_THROTTLE: - return 0; - case PNV8_OCC_PSTATE_VERSION: - return 0x02; - case PNV8_OCC_PSTATE_MIN: - return -2; - case PNV8_OCC_PSTATE_NOM: - case PNV8_OCC_PSTATE_TURBO: - return -1; - case PNV8_OCC_PSTATE_ULTRA_TURBO: - return 0; - case PNV8_OCC_PSTATE_ID_ZERO: - return 0; - case PNV8_OCC_VDD_VOLTAGE_IDENTIFIER: - case PNV8_OCC_VCS_VOLTAGE_IDENTIFIER: - return 1; - case PNV8_OCC_PSTATE_DATA: - return 0; - /* P8 frequency for 0, 1, and 2 pstates */ - case PNV8_OCC_PSTATE_ZERO_FREQUENCY: - case PNV8_OCC_PSTATE_ONE_FREQUENCY: - case PNV8_OCC_PSTATE_TWO_FREQUENCY: - return 3000; - case PNV8_OCC_PSTATE_ID_ONE: - return -1; - case PNV8_OCC_PSTATE_ID_TWO: - return -2; - } - /* pstate table core max array */ - if (core_max_array(homer, addr)) { - return 1; - } - return 0; -} - -static void pnv_power8_homer_write(void *opaque, hwaddr addr, - uint64_t val, unsigned size) -{ - /* callback function defined to homer write */ - return; -} - -static const MemoryRegionOps pnv_power8_homer_ops = { - .read = pnv_power8_homer_read, - .write = pnv_power8_homer_write, - .valid.min_access_size = 1, - .valid.max_access_size = 8, - .impl.min_access_size = 1, - .impl.max_access_size = 8, - .endianness = DEVICE_BIG_ENDIAN, -}; - /* P8 PBA BARs */ #define PBA_BAR0 0x00 #define PBA_BAR1 0x01 @@ -192,8 +97,6 @@ static void pnv_homer_power8_class_init(ObjectClass *klass, void *data) homer->size = PNV_HOMER_SIZE; homer->pba_size = PNV_XSCOM_PBA_SIZE; homer->pba_ops = &pnv_homer_power8_pba_ops; - homer->homer_ops = &pnv_power8_homer_ops; - homer->core_max_base = PNV8_CORE_MAX_BASE; } static const TypeInfo pnv_homer_power8_type_info = { @@ -203,96 +106,6 @@ static const TypeInfo pnv_homer_power8_type_info = { .class_init = pnv_homer_power8_class_init, }; -/* P9 Pstate table */ - -#define PNV9_OCC_PSTATE_VALID 0xe2000 -#define PNV9_OCC_PSTATE_ID_ZERO 0xe2018 -#define PNV9_OCC_PSTATE_ID_ONE 0xe2020 -#define PNV9_OCC_PSTATE_ID_TWO 0xe2028 -#define PNV9_OCC_PSTATE_DATA 0xe2000 -#define PNV9_OCC_PSTATE_MINOR_VERSION 0xe2008 -#define PNV9_OCC_PSTATE_MIN 0xe2003 -#define PNV9_OCC_PSTATE_NOM 0xe2004 -#define PNV9_OCC_PSTATE_TURBO 0xe2005 -#define PNV9_OCC_PSTATE_ULTRA_TURBO 0xe2818 -#define PNV9_OCC_MAX_PSTATE_ULTRA_TURBO 0xe2006 -#define PNV9_OCC_PSTATE_MAJOR_VERSION 0xe2001 -#define PNV9_OCC_OPAL_RUNTIME_DATA 0xe2b85 -#define PNV9_CHIP_HOMER_IMAGE_POINTER 0x200008 -#define PNV9_CHIP_HOMER_BASE 0x0 -#define PNV9_OCC_PSTATE_ZERO_FREQUENCY 0xe201c -#define PNV9_OCC_PSTATE_ONE_FREQUENCY 0xe2024 -#define PNV9_OCC_PSTATE_TWO_FREQUENCY 0xe202c -#define PNV9_OCC_ROLE_MASTER_OR_SLAVE 0xe2002 -#define PNV9_CORE_MAX_BASE 0xe2819 -#define PNV9_DYNAMIC_DATA_STATE 0xe2b80 - -static uint64_t pnv_power9_homer_read(void *opaque, hwaddr addr, - unsigned size) -{ - PnvHomer *homer = PNV_HOMER(opaque); - - switch (addr) { - case PNV9_OCC_PSTATE_VALID: - return 1; - case PNV9_OCC_MAX_PSTATE_ULTRA_TURBO: - case PNV9_OCC_PSTATE_ID_ZERO: - return 0; - case PNV9_OCC_ROLE_MASTER_OR_SLAVE: - if (homer->chip->chip_id == 0) { - return 0x1; /* master */ - } else { - return 0x0; /* slave */ - } - case PNV9_OCC_PSTATE_NOM: - case PNV9_OCC_PSTATE_TURBO: - case PNV9_OCC_PSTATE_ID_ONE: - case PNV9_OCC_PSTATE_ULTRA_TURBO: - case PNV9_OCC_OPAL_RUNTIME_DATA: - return 1; - case PNV9_OCC_PSTATE_MIN: - case PNV9_OCC_PSTATE_ID_TWO: - return 2; - - /* 3000 khz frequency for 0, 1, and 2 pstates */ - case PNV9_OCC_PSTATE_ZERO_FREQUENCY: - case PNV9_OCC_PSTATE_ONE_FREQUENCY: - case PNV9_OCC_PSTATE_TWO_FREQUENCY: - return 3000; - case PNV9_OCC_PSTATE_MAJOR_VERSION: - return 0x90; - case PNV9_OCC_PSTATE_MINOR_VERSION: - return 0x01; - case PNV9_CHIP_HOMER_BASE: - case PNV9_CHIP_HOMER_IMAGE_POINTER: - return 0; - case PNV9_DYNAMIC_DATA_STATE: - return 0x03; /* active */ - } - /* pstate table core max array */ - if (core_max_array(homer, addr)) { - return 1; - } - return 0; -} - -static void pnv_power9_homer_write(void *opaque, hwaddr addr, - uint64_t val, unsigned size) -{ - /* callback function defined to homer write */ - return; -} - -static const MemoryRegionOps pnv_power9_homer_ops = { - .read = pnv_power9_homer_read, - .write = pnv_power9_homer_write, - .valid.min_access_size = 1, - .valid.max_access_size = 8, - .impl.min_access_size = 1, - .impl.max_access_size = 8, - .endianness = DEVICE_BIG_ENDIAN, -}; - static uint64_t pnv_homer_power9_pba_read(void *opaque, hwaddr addr, unsigned size) { @@ -351,8 +164,6 @@ static void pnv_homer_power9_class_init(ObjectClass *klass, void *data) homer->size = PNV_HOMER_SIZE; homer->pba_size = PNV9_XSCOM_PBA_SIZE; homer->pba_ops = &pnv_homer_power9_pba_ops; - homer->homer_ops = &pnv_power9_homer_ops; - homer->core_max_base = PNV9_CORE_MAX_BASE; } static const TypeInfo pnv_homer_power9_type_info = { @@ -420,8 +231,6 @@ static void pnv_homer_power10_class_init(ObjectClass *klass, void *data) homer->size = PNV_HOMER_SIZE; homer->pba_size = PNV10_XSCOM_PBA_SIZE; homer->pba_ops = &pnv_homer_power10_pba_ops; - homer->homer_ops = &pnv_power9_homer_ops; /* TODO */ - homer->core_max_base = PNV9_CORE_MAX_BASE; } static const TypeInfo pnv_homer_power10_type_info = { @@ -435,18 +244,22 @@ static void pnv_homer_realize(DeviceState *dev, Error **errp) { PnvHomer *homer = PNV_HOMER(dev); PnvHomerClass *hmrc = PNV_HOMER_GET_CLASS(homer); + char homer_str[32]; assert(homer->chip); pnv_xscom_region_init(&homer->pba_regs, OBJECT(dev), hmrc->pba_ops, homer, "xscom-pba", hmrc->pba_size); - /* homer region */ + /* Homer RAM region */ homer->base = hmrc->get_base(homer->chip); - memory_region_init_io(&homer->regs, OBJECT(dev), - hmrc->homer_ops, homer, "homer-main-memory", - hmrc->size); + snprintf(homer_str, sizeof(homer_str), "homer-chip%d-memory", + homer->chip->chip_id); + if (!memory_region_init_ram(&homer->mem, OBJECT(homer), + homer_str, hmrc->size, errp)) { + return; + } } static const Property pnv_homer_properties[] = { diff --git a/hw/ppc/pnv_occ.c b/hw/ppc/pnv_occ.c index 5424d87ee9..22b07a415a 100644 --- a/hw/ppc/pnv_occ.c +++ b/hw/ppc/pnv_occ.c @@ -24,9 +24,13 @@ #include "hw/irq.h" #include "hw/qdev-properties.h" #include "hw/ppc/pnv.h" +#include "hw/ppc/pnv_chip.h" #include "hw/ppc/pnv_xscom.h" #include "hw/ppc/pnv_occ.h" +#define P8_HOMER_OPAL_DATA_OFFSET 0x1F8000 +#define P9_HOMER_OPAL_DATA_OFFSET 0x0E2000 + #define OCB_OCI_OCCMISC 0x4020 #define OCB_OCI_OCCMISC_AND 0x4021 #define OCB_OCI_OCCMISC_OR 0x4022 @@ -166,7 +170,11 @@ const MemoryRegionOps pnv_occ_sram_ops = { static void pnv_occ_power8_class_init(ObjectClass *klass, void *data) { PnvOCCClass *poc = PNV_OCC_CLASS(klass); + DeviceClass *dc = DEVICE_CLASS(klass); + dc->desc = "PowerNV OCC Controller (POWER8)"; + poc->opal_shared_memory_offset = P8_HOMER_OPAL_DATA_OFFSET; + poc->opal_shared_memory_version = 0x02; poc->xscom_size = PNV_XSCOM_OCC_SIZE; poc->xscom_ops = &pnv_occ_power8_xscom_ops; } @@ -239,8 +247,11 @@ static void pnv_occ_power9_class_init(ObjectClass *klass, void *data) DeviceClass *dc = DEVICE_CLASS(klass); dc->desc = "PowerNV OCC Controller (POWER9)"; + poc->opal_shared_memory_offset = P9_HOMER_OPAL_DATA_OFFSET; + poc->opal_shared_memory_version = 0x90; poc->xscom_size = PNV9_XSCOM_OCC_SIZE; poc->xscom_ops = &pnv_occ_power9_xscom_ops; + assert(!dc->user_creatable); } static const TypeInfo pnv_occ_power9_type_info = { @@ -263,10 +274,19 @@ static const TypeInfo pnv_occ_power10_type_info = { .class_init = pnv_occ_power10_class_init, }; +static bool occ_init_homer_memory(PnvOCC *occ, Error **errp); + static void pnv_occ_realize(DeviceState *dev, Error **errp) { PnvOCC *occ = PNV_OCC(dev); PnvOCCClass *poc = PNV_OCC_GET_CLASS(occ); + PnvHomer *homer = occ->homer; + + assert(homer); + + if (!occ_init_homer_memory(occ, errp)) { + return; + } occ->occmisc = 0; @@ -282,12 +302,16 @@ static void pnv_occ_realize(DeviceState *dev, Error **errp) qdev_init_gpio_out(dev, &occ->psi_irq, 1); } +static const Property pnv_occ_properties[] = { + DEFINE_PROP_LINK("homer", PnvOCC, homer, TYPE_PNV_HOMER, PnvHomer *), +}; + static void pnv_occ_class_init(ObjectClass *klass, void *data) { DeviceClass *dc = DEVICE_CLASS(klass); dc->realize = pnv_occ_realize; - dc->desc = "PowerNV OCC Controller"; + device_class_set_props(dc, pnv_occ_properties); dc->user_creatable = false; } @@ -309,3 +333,411 @@ static void pnv_occ_register_types(void) } type_init(pnv_occ_register_types); + +/* From skiboot/hw/occ.c with tab to space conversion */ +/* OCC Communication Area for PStates */ + +#define OPAL_DYNAMIC_DATA_OFFSET 0x0B80 +/* relative to HOMER_OPAL_DATA_OFFSET */ + +#define MAX_PSTATES 256 +#define MAX_P8_CORES 12 +#define MAX_P9_CORES 24 +#define MAX_P10_CORES 32 + +#define MAX_OPAL_CMD_DATA_LENGTH 4090 +#define MAX_OCC_RSP_DATA_LENGTH 8698 + +#define P8_PIR_CORE_MASK 0xFFF8 +#define P9_PIR_QUAD_MASK 0xFFF0 +#define P10_PIR_CHIP_MASK 0x0000 +#define FREQ_MAX_IN_DOMAIN 0 +#define FREQ_MOST_RECENTLY_SET 1 + +#define u8 uint8_t +#define s8 int8_t +#define u16 uint16_t +#define s16 int16_t +#define u32 uint32_t +#define s32 int32_t +#define u64 uint64_t +#define s64 int64_t +#define __be16 uint16_t +#define __be32 uint32_t +#define __packed QEMU_PACKED + +/** + * OCC-OPAL Shared Memory Region + * + * Reference document : + * https://github.com/open-power/docs/blob/master/occ/OCC_OpenPwr_FW_Interfaces.pdf + * + * Supported layout versions: + * - 0x01, 0x02 : P8 + * https://github.com/open-power/occ/blob/master_p8/src/occ/proc/proc_pstate.h + * + * - 0x90 : P9 + * https://github.com/open-power/occ/blob/master/src/occ_405/proc/proc_pstate.h + * In 0x90 the data is separated into :- + * -- Static Data (struct occ_pstate_table): Data is written once by OCC + * -- Dynamic Data (struct occ_dynamic_data): Data is updated at runtime + * + * struct occ_pstate_table - Pstate table layout + * @valid: Indicates if data is valid + * @version: Layout version [Major/Minor] + * @v2.throttle: Reason for limiting the max pstate + * @v9.occ_role: OCC role (Master/Slave) + * @v#.pstate_min: Minimum pstate ever allowed + * @v#.pstate_nom: Nominal pstate + * @v#.pstate_turbo: Maximum turbo pstate + * @v#.pstate_ultra_turbo: Maximum ultra turbo pstate and the maximum + * pstate ever allowed + * @v#.pstates: Pstate-id and frequency list from Pmax to Pmin + * @v#.pstates.id: Pstate-id + * @v#.pstates.flags: Pstate-flag(reserved) + * @v2.pstates.vdd: Voltage Identifier + * @v2.pstates.vcs: Voltage Identifier + * @v#.pstates.freq_khz: Frequency in KHz + * @v#.core_max[1..N]: Max pstate with N active cores + * @spare/reserved/pad: Unused data + */ +struct occ_pstate_table { + u8 valid; + u8 version; + union __packed { + struct __packed { /* Version 0x01 and 0x02 */ + u8 throttle; + s8 pstate_min; + s8 pstate_nom; + s8 pstate_turbo; + s8 pstate_ultra_turbo; + u8 spare; + u64 reserved; + struct __packed { + s8 id; + u8 flags; + u8 vdd; + u8 vcs; + __be32 freq_khz; + } pstates[MAX_PSTATES]; + s8 core_max[MAX_P8_CORES]; + u8 pad[100]; + } v2; + struct __packed { /* Version 0x90 */ + u8 occ_role; + u8 pstate_min; + u8 pstate_nom; + u8 pstate_turbo; + u8 pstate_ultra_turbo; + u8 spare; + u64 reserved1; + u64 reserved2; + struct __packed { + u8 id; + u8 flags; + u16 reserved; + __be32 freq_khz; + } pstates[MAX_PSTATES]; + u8 core_max[MAX_P9_CORES]; + u8 pad[56]; + } v9; + struct __packed { /* Version 0xA0 */ + u8 occ_role; + u8 pstate_min; + u8 pstate_fixed_freq; + u8 pstate_base; + u8 pstate_ultra_turbo; + u8 pstate_fmax; + u8 minor; + u8 pstate_bottom_throttle; + u8 spare; + u8 spare1; + u32 reserved_32; + u64 reserved_64; + struct __packed { + u8 id; + u8 valid; + u16 reserved; + __be32 freq_khz; + } pstates[MAX_PSTATES]; + u8 core_max[MAX_P10_CORES]; + u8 pad[48]; + } v10; + }; +} __packed; + +/** + * OPAL-OCC Command Response Interface + * + * OPAL-OCC Command Buffer + * + * --------------------------------------------------------------------- + * | OPAL | Cmd | OPAL | | Cmd Data | Cmd Data | OPAL | + * | Cmd | Request | OCC | Reserved | Length | Length | Cmd | + * | Flags | ID | Cmd | | (MSB) | (LSB) | Data... | + * --------------------------------------------------------------------- + * | ….OPAL Command Data up to max of Cmd Data Length 4090 bytes | + * | | + * --------------------------------------------------------------------- + * + * OPAL Command Flag + * + * ----------------------------------------------------------------- + * | Bit 7 | Bit 6 | Bit 5 | Bit 4 | Bit 3 | Bit 2 | Bit 1 | Bit 0 | + * | (msb) | | | | | | | (lsb) | + * ----------------------------------------------------------------- + * |Cmd | | | | | | | | + * |Ready | | | | | | | | + * ----------------------------------------------------------------- + * + * struct opal_command_buffer - Defines the layout of OPAL command buffer + * @flag: Provides general status of the command + * @request_id: Token to identify request + * @cmd: Command sent + * @data_size: Command data length + * @data: Command specific data + * @spare: Unused byte + */ +struct opal_command_buffer { + u8 flag; + u8 request_id; + u8 cmd; + u8 spare; + __be16 data_size; + u8 data[MAX_OPAL_CMD_DATA_LENGTH]; +} __packed; + +/** + * OPAL-OCC Response Buffer + * + * --------------------------------------------------------------------- + * | OCC | Cmd | OPAL | Response | Rsp Data | Rsp Data | OPAL | + * | Rsp | Request | OCC | Status | Length | Length | Rsp | + * | Flags | ID | Cmd | | (MSB) | (LSB) | Data... | + * --------------------------------------------------------------------- + * | ….OPAL Response Data up to max of Rsp Data Length 8698 bytes | + * | | + * --------------------------------------------------------------------- + * + * OCC Response Flag + * + * ----------------------------------------------------------------- + * | Bit 7 | Bit 6 | Bit 5 | Bit 4 | Bit 3 | Bit 2 | Bit 1 | Bit 0 | + * | (msb) | | | | | | | (lsb) | + * ----------------------------------------------------------------- + * | | | | | | |OCC in | Rsp | + * | | | | | | |progress|Ready | + * ----------------------------------------------------------------- + * + * struct occ_response_buffer - Defines the layout of OCC response buffer + * @flag: Provides general status of the response + * @request_id: Token to identify request + * @cmd: Command requested + * @status: Indicates success/failure status of + * the command + * @data_size: Response data length + * @data: Response specific data + */ +struct occ_response_buffer { + u8 flag; + u8 request_id; + u8 cmd; + u8 status; + __be16 data_size; + u8 data[MAX_OCC_RSP_DATA_LENGTH]; +} __packed; + +/** + * OCC-OPAL Shared Memory Interface Dynamic Data Vx90 + * + * struct occ_dynamic_data - Contains runtime attributes + * @occ_state: Current state of OCC + * @major_version: Major version number + * @minor_version: Minor version number (backwards compatible) + * Version 1 indicates GPU presence populated + * @gpus_present: Bitmask of GPUs present (on systems where GPU + * presence is detected through APSS) + * @cpu_throttle: Reason for limiting the max pstate + * @mem_throttle: Reason for throttling memory + * @quick_pwr_drop: Indicates if QPD is asserted + * @pwr_shifting_ratio: Indicates the current percentage of power to + * take away from the CPU vs GPU when shifting + * power to maintain a power cap. Value of 100 + * means take all power from CPU. + * @pwr_cap_type: Indicates type of power cap in effect + * @hard_min_pwr_cap: Hard minimum system power cap in Watts. + * Guaranteed unless hardware failure + * @max_pwr_cap: Maximum allowed system power cap in Watts + * @cur_pwr_cap: Current system power cap + * @soft_min_pwr_cap: Soft powercap minimum. OCC may or may not be + * able to maintain this + * @spare/reserved: Unused data + * @cmd: Opal Command Buffer + * @rsp: OCC Response Buffer + */ +struct occ_dynamic_data { + u8 occ_state; + u8 major_version; + u8 minor_version; + u8 gpus_present; + union __packed { + struct __packed { /* Version 0x90 */ + u8 spare1; + } v9; + struct __packed { /* Version 0xA0 */ + u8 wof_enabled; + } v10; + }; + u8 cpu_throttle; + u8 mem_throttle; + u8 quick_pwr_drop; + u8 pwr_shifting_ratio; + u8 pwr_cap_type; + __be16 hard_min_pwr_cap; + __be16 max_pwr_cap; + __be16 cur_pwr_cap; + __be16 soft_min_pwr_cap; + u8 pad[110]; + struct opal_command_buffer cmd; + struct occ_response_buffer rsp; +} __packed; + +enum occ_response_status { + OCC_RSP_SUCCESS = 0x00, + OCC_RSP_INVALID_COMMAND = 0x11, + OCC_RSP_INVALID_CMD_DATA_LENGTH = 0x12, + OCC_RSP_INVALID_DATA = 0x13, + OCC_RSP_INTERNAL_ERROR = 0x15, +}; + +#define OCC_ROLE_SLAVE 0x00 +#define OCC_ROLE_MASTER 0x01 + +#define OCC_FLAG_RSP_READY 0x01 +#define OCC_FLAG_CMD_IN_PROGRESS 0x02 +#define OPAL_FLAG_CMD_READY 0x80 + +#define PCAP_MAX_POWER_W 100 +#define PCAP_SOFT_MIN_POWER_W 20 +#define PCAP_HARD_MIN_POWER_W 10 + +static bool occ_write_static_data(PnvOCC *occ, + struct occ_pstate_table *static_data, + Error **errp) +{ + PnvOCCClass *poc = PNV_OCC_GET_CLASS(occ); + PnvHomer *homer = occ->homer; + hwaddr static_addr = homer->base + poc->opal_shared_memory_offset; + MemTxResult ret; + + ret = address_space_write(&address_space_memory, static_addr, + MEMTXATTRS_UNSPECIFIED, static_data, + sizeof(*static_data)); + if (ret != MEMTX_OK) { + error_setg(errp, "OCC: cannot write OCC-OPAL static data"); + return false; + } + + return true; +} + +static bool occ_write_dynamic_data(PnvOCC *occ, + struct occ_dynamic_data *dynamic_data, + Error **errp) +{ + PnvOCCClass *poc = PNV_OCC_GET_CLASS(occ); + PnvHomer *homer = occ->homer; + hwaddr static_addr = homer->base + poc->opal_shared_memory_offset; + hwaddr dynamic_addr = static_addr + OPAL_DYNAMIC_DATA_OFFSET; + MemTxResult ret; + + ret = address_space_write(&address_space_memory, dynamic_addr, + MEMTXATTRS_UNSPECIFIED, dynamic_data, + sizeof(*dynamic_data)); + if (ret != MEMTX_OK) { + error_setg(errp, "OCC: cannot write OCC-OPAL dynamic data"); + return false; + } + + return true; +} + +static bool occ_init_homer_memory(PnvOCC *occ, Error **errp) +{ + PnvOCCClass *poc = PNV_OCC_GET_CLASS(occ); + PnvHomer *homer = occ->homer; + PnvChip *chip = homer->chip; + struct occ_pstate_table static_data; + struct occ_dynamic_data dynamic_data; + int i; + + memset(&static_data, 0, sizeof(static_data)); + static_data.valid = 1; + static_data.version = poc->opal_shared_memory_version; + switch (poc->opal_shared_memory_version) { + case 0x02: + static_data.v2.throttle = 0; + static_data.v2.pstate_min = -2; + static_data.v2.pstate_nom = -1; + static_data.v2.pstate_turbo = -1; + static_data.v2.pstate_ultra_turbo = 0; + static_data.v2.pstates[0].id = 0; + static_data.v2.pstates[1].freq_khz = cpu_to_be32(3000); + static_data.v2.pstates[1].id = -1; + static_data.v2.pstates[1].freq_khz = cpu_to_be32(3000); + static_data.v2.pstates[2].id = -2; + static_data.v2.pstates[2].freq_khz = cpu_to_be32(3000); + for (i = 0; i < chip->nr_cores; i++) { + static_data.v2.core_max[i] = 1; + } + break; + case 0x90: + if (chip->chip_id == 0) { + static_data.v9.occ_role = OCC_ROLE_MASTER; + } else { + static_data.v9.occ_role = OCC_ROLE_SLAVE; + } + static_data.v9.pstate_min = 2; + static_data.v9.pstate_nom = 1; + static_data.v9.pstate_turbo = 1; + static_data.v9.pstate_ultra_turbo = 0; + static_data.v9.pstates[0].id = 0; + static_data.v9.pstates[0].freq_khz = cpu_to_be32(3000); + static_data.v9.pstates[1].id = 1; + static_data.v9.pstates[1].freq_khz = cpu_to_be32(3000); + static_data.v9.pstates[2].id = 2; + static_data.v9.pstates[2].freq_khz = cpu_to_be32(3000); + for (i = 0; i < chip->nr_cores; i++) { + static_data.v9.core_max[i] = 1; + } + break; + default: + g_assert_not_reached(); + } + if (!occ_write_static_data(occ, &static_data, errp)) { + return false; + } + + memset(&dynamic_data, 0, sizeof(dynamic_data)); + dynamic_data.occ_state = 0x3; /* active */ + dynamic_data.major_version = 0x0; + dynamic_data.hard_min_pwr_cap = cpu_to_be16(PCAP_HARD_MIN_POWER_W); + dynamic_data.max_pwr_cap = cpu_to_be16(PCAP_MAX_POWER_W); + dynamic_data.cur_pwr_cap = cpu_to_be16(PCAP_MAX_POWER_W); + dynamic_data.soft_min_pwr_cap = cpu_to_be16(PCAP_SOFT_MIN_POWER_W); + switch (poc->opal_shared_memory_version) { + case 0x90: + dynamic_data.minor_version = 0x1; + break; + case 0x02: + dynamic_data.minor_version = 0x0; + break; + default: + g_assert_not_reached(); + } + if (!occ_write_dynamic_data(occ, &dynamic_data, errp)) { + return false; + } + + return true; +} diff --git a/include/hw/ppc/pnv_homer.h b/include/hw/ppc/pnv_homer.h index 5ffc0c97af..a6f2710fa1 100644 --- a/include/hw/ppc/pnv_homer.h +++ b/include/hw/ppc/pnv_homer.h @@ -41,7 +41,7 @@ struct PnvHomer { PnvChip *chip; MemoryRegion pba_regs; - MemoryRegion regs; + MemoryRegion mem; hwaddr base; }; @@ -56,9 +56,6 @@ struct PnvHomerClass { int pba_size; const MemoryRegionOps *pba_ops; - const MemoryRegionOps *homer_ops; - - hwaddr core_max_base; }; #endif /* PPC_PNV_HOMER_H */ diff --git a/include/hw/ppc/pnv_occ.h b/include/hw/ppc/pnv_occ.h index df321244e3..f994860980 100644 --- a/include/hw/ppc/pnv_occ.h +++ b/include/hw/ppc/pnv_occ.h @@ -46,6 +46,9 @@ struct PnvOCC { qemu_irq psi_irq; + /* OCCs operate on regions of HOMER memory */ + PnvHomer *homer; + MemoryRegion xscom_regs; MemoryRegion sram_regs; }; @@ -53,6 +56,9 @@ struct PnvOCC { struct PnvOCCClass { DeviceClass parent_class; + hwaddr opal_shared_memory_offset; /* offset in HOMER */ + uint8_t opal_shared_memory_version; + int xscom_size; const MemoryRegionOps *xscom_ops; }; diff --git a/roms/SLOF b/roms/SLOF index ee03aec2c1..3a259df244 160000 --- a/roms/SLOF +++ b/roms/SLOF @@ -1 +1 @@ -Subproject commit ee03aec2c106a699aaddd2d3dd52cbd7b7e8d544 +Subproject commit 3a259df2449fc4a4e43ab5f33f0b2c66484b4bc3 From patchwork Tue Mar 11 12:57:07 2025 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Nicholas Piggin X-Patchwork-Id: 14011843 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.lore.kernel.org (Postfix) with ESMTPS id 5F0F0C282EC for ; Tue, 11 Mar 2025 13:15:12 +0000 (UTC) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1trzD1-0003Qw-Cj; Tue, 11 Mar 2025 08:59:47 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1trzCa-0001kd-HB; Tue, 11 Mar 2025 08:59:20 -0400 Received: from mail-pj1-x102f.google.com ([2607:f8b0:4864:20::102f]) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_128_GCM_SHA256:128) (Exim 4.90_1) (envelope-from ) id 1trzCV-0007vc-9D; Tue, 11 Mar 2025 08:59:20 -0400 Received: by mail-pj1-x102f.google.com with SMTP id 98e67ed59e1d1-300fefb8e06so1880761a91.0; Tue, 11 Mar 2025 05:59:14 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20230601; t=1741697953; x=1742302753; darn=nongnu.org; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to; bh=GVJ4vU5t7PULY28jxp4RCE9dE62+yidxPTM11DiQEfw=; b=OTPFDRfXg/X/QZgjMh/pO46kaWz6LsWcSUXvE2kHkuR/T04xow5lYJ/PmOoiPCXd2P KgKQDxeg3scljGV3QiKyv95j5b+AZghJDzqykUd361LE+zNE1R34mjs8Mkx01TNMOHjj MS2FwVCMEOhWBq+dkzyUGjlMMMw7TbbGYxgGkaX0I5tj1ZFrm2JtI5idNb5dlV9Rehrp 9G0i32hbUJgCtmjnZ6+t2clPwwtoh8ptGkL49sMcaA/oqRe7b0Lp3TDXpkOrKWCACHij AlGK2q4HG2gf4Sv/+Ozw9uk6uT5uDfkgkSxmIMW/3jJfLFAnFetumqbymNzU3sMq5HvT Hu/w== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1741697953; x=1742302753; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=GVJ4vU5t7PULY28jxp4RCE9dE62+yidxPTM11DiQEfw=; b=O0Kmq55zpkJeMsLdLD8gv8H5zbZ4mwXHCj1Fz0pLC2SLcdk/p/smuPYIwDjIHYxoI1 0PmoJZ/8YumLB4r+cGeGGZEkOfKTrfuIOna8R6iFUy/yskKsDZ1BS7eWWsMcaHnsnHET aHkF5acZRJFXA0QfPqIu8Ayk0QHemrFgdLma6RM7VAgaHUayTyDa7JNC0XcWHex9pryi +cg3IqibbPt+MJa3x1hw65I19kQahdM1I0ZBG84yHmSdtaINXl0dFJbzYuN6WeGJ6V1N Ruf18+aK3JMoDSV6AjpA5ZeVaAUCwhEwG1iSkeYYvH7v0BZPmuwAJVraBw8wx0tse62c QiQA== X-Forwarded-Encrypted: i=1; AJvYcCVQzWHnLvz+kTPHINTWzbXR/2i5um/ZGZjAwm4Tv7iGkC2yoP+L52Fm9cL794u7XaTKdpdVy75z2g==@nongnu.org X-Gm-Message-State: AOJu0Yy8L9qbhBrgW+1HY/dj/ZTVzXOqDf+UnmHZ12fSOQxhX8dGEuat GgRT8UQs5Pyd7MVXE4hi8BGZk7+9q5TKSJEvaUFS71jWl8YezoHAcDBJTg== X-Gm-Gg: ASbGncs2SnXLw8JmcP0HOM2T7eYAyt/iPozcdDbYl/7NEdtRyjYIZdSUj+HGEsOVRxN DU32o52VBSTeFuC6qgO8wfBp064LHC1WDBkSRiKQSyx59xAsjCO2D/j06rMaFTEHCNBueJHZ0S/ zrk9zZyaE29416a2rAsNdtTITqwVVfCLzZr35j71vBwi2BA+RKkSE6wukG7PFDt5HZyRSIQNrYl D08abWkHFKH3aE3i3D4HR/aqoZrunMHvm6C/0K6JUgNfhRH7VC6uJEHnTov2a7fITqrg1SXi8xq BKVEY4TYgl+uR+/gV5i6yNfcWgGZSeGnTGvz0NyuX9AchfgIa38= X-Google-Smtp-Source: AGHT+IGNLQJINQzXwusTn4U7ICPr6ESQca+Ph66QOCbxdJo5yFgbbe2xy2CYoQT0eo6NkqhkohgwRQ== X-Received: by 2002:a17:90b:4c51:b0:2f9:c139:b61f with SMTP id 98e67ed59e1d1-300ff0ca64cmr5142714a91.14.1741697952924; Tue, 11 Mar 2025 05:59:12 -0700 (PDT) Received: from wheely.local0.net ([118.208.151.101]) by smtp.gmail.com with ESMTPSA id 98e67ed59e1d1-2ff4e773dddsm11822318a91.12.2025.03.11.05.59.10 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 11 Mar 2025 05:59:12 -0700 (PDT) From: Nicholas Piggin To: qemu-devel@nongnu.org Cc: Nicholas Piggin , qemu-ppc@nongnu.org Subject: [PULL 13/72] ppc/pnv/occ: Update pstate frequency tables Date: Tue, 11 Mar 2025 22:57:07 +1000 Message-ID: <20250311125815.903177-14-npiggin@gmail.com> X-Mailer: git-send-email 2.47.1 In-Reply-To: <20250311125815.903177-1-npiggin@gmail.com> References: <20250311125815.903177-1-npiggin@gmail.com> MIME-Version: 1.0 Received-SPF: pass client-ip=2607:f8b0:4864:20::102f; envelope-from=npiggin@gmail.com; helo=mail-pj1-x102f.google.com X-Spam_score_int: -20 X-Spam_score: -2.1 X-Spam_bar: -- X-Spam_report: (-2.1 / 5.0 requ) BAYES_00=-1.9, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_AU=-0.1, DKIM_VALID_EF=-0.1, FREEMAIL_FROM=0.001, RCVD_IN_DNSWL_NONE=-0.0001, SPF_HELO_NONE=0.001, SPF_PASS=-0.001 autolearn=ham autolearn_force=no X-Spam_action: no action X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: qemu-devel-bounces+qemu-devel=archiver.kernel.org@nongnu.org Sender: qemu-devel-bounces+qemu-devel=archiver.kernel.org@nongnu.org OCC pstate frequencies are in kHz, so the OCC data was 3-4MHz. Upgrade to GHz. Make each pstate have a different frequency. Signed-off-by: Nicholas Piggin --- hw/ppc/pnv_occ.c | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/hw/ppc/pnv_occ.c b/hw/ppc/pnv_occ.c index 22b07a415a..19ccfe1bbf 100644 --- a/hw/ppc/pnv_occ.c +++ b/hw/ppc/pnv_occ.c @@ -682,11 +682,11 @@ static bool occ_init_homer_memory(PnvOCC *occ, Error **errp) static_data.v2.pstate_turbo = -1; static_data.v2.pstate_ultra_turbo = 0; static_data.v2.pstates[0].id = 0; - static_data.v2.pstates[1].freq_khz = cpu_to_be32(3000); + static_data.v2.pstates[1].freq_khz = cpu_to_be32(4000000); static_data.v2.pstates[1].id = -1; - static_data.v2.pstates[1].freq_khz = cpu_to_be32(3000); + static_data.v2.pstates[1].freq_khz = cpu_to_be32(3000000); static_data.v2.pstates[2].id = -2; - static_data.v2.pstates[2].freq_khz = cpu_to_be32(3000); + static_data.v2.pstates[2].freq_khz = cpu_to_be32(2000000); for (i = 0; i < chip->nr_cores; i++) { static_data.v2.core_max[i] = 1; } @@ -702,11 +702,11 @@ static bool occ_init_homer_memory(PnvOCC *occ, Error **errp) static_data.v9.pstate_turbo = 1; static_data.v9.pstate_ultra_turbo = 0; static_data.v9.pstates[0].id = 0; - static_data.v9.pstates[0].freq_khz = cpu_to_be32(3000); + static_data.v9.pstates[0].freq_khz = cpu_to_be32(4000000); static_data.v9.pstates[1].id = 1; - static_data.v9.pstates[1].freq_khz = cpu_to_be32(3000); + static_data.v9.pstates[1].freq_khz = cpu_to_be32(3000000); static_data.v9.pstates[2].id = 2; - static_data.v9.pstates[2].freq_khz = cpu_to_be32(3000); + static_data.v9.pstates[2].freq_khz = cpu_to_be32(2000000); for (i = 0; i < chip->nr_cores; i++) { static_data.v9.core_max[i] = 1; } From patchwork Tue Mar 11 12:57:08 2025 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Nicholas Piggin X-Patchwork-Id: 14011790 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.lore.kernel.org (Postfix) with ESMTPS id 0BC58C282EC for ; Tue, 11 Mar 2025 13:00:38 +0000 (UTC) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1trzD4-0003c9-BZ; Tue, 11 Mar 2025 08:59:50 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1trzCd-0001rU-Fr; Tue, 11 Mar 2025 08:59:23 -0400 Received: from mail-pj1-x102c.google.com ([2607:f8b0:4864:20::102c]) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_128_GCM_SHA256:128) (Exim 4.90_1) (envelope-from ) id 1trzCa-0007w2-CJ; Tue, 11 Mar 2025 08:59:23 -0400 Received: by mail-pj1-x102c.google.com with SMTP id 98e67ed59e1d1-2ff80290e44so8655680a91.0; Tue, 11 Mar 2025 05:59:16 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20230601; t=1741697955; x=1742302755; darn=nongnu.org; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to; bh=VqfCGsNGemWHWOkA7UQFNXiZp9CJgWEykoLLRmbbzrQ=; b=Ib5L4qjHqCxonO6i/DOK9BRUS9kf4WALF4m5DGlcXyT2n726aAyVLr1VXqJp+wHmYq /ls3ma9/n8dGKaAx1fPsmYwJpGdqkB5oaECWCs1f1GIzgZus5CXd7FS4KhMrUvlqlhFn wpRJ9P9KfJrrBW7kb6QSRp/ywGRCSEcgUxdW0s/Dyocmvw7AsBzgMgoH3BGG6C9pUP26 fUhSOsMguxpvzSNoF2IIOtTj4BnM8c/tVewubj0lxQmtfAUMg3auczTILVIW5hvWitG4 K+lJG9wLCwF2rJoJ0IWQFqhWxzO4X7FPP/0jkthw4FG5bU2S4H4JtR9KbL5acyS+X/L7 3mlA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1741697955; x=1742302755; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=VqfCGsNGemWHWOkA7UQFNXiZp9CJgWEykoLLRmbbzrQ=; b=aC2TI/GBjXQ6++3BIOJG3R3pQLvsECPlYJtzfopCP4QIISubpICRH1VuX9j/7ziap5 VpHgzj5LOVMTqQBUAAKdMzhM90ZVJCsVLMuj2JzBYn72OGQo7OjMsZ+5O/ROO+Ge+WgO UR0Wg8LFcmL+/fEiqtxqv7SO38Ozx6QI2DjleBGIzIM/h62KBT2AZejALa7BeAJOPGcY qfEczqfEoB+tNbutuopz3oviIVr5RLuGAaDisnJa5csd4AHRZ9nujsH39B+cBhy2mrET W/mNqPi/9QvbCPi0v3T9kSXQiUdX6PRgwEtIdMSHisbUOa4UtuG90Gu9ZScuAYpq+L7l hYnw== X-Forwarded-Encrypted: i=1; AJvYcCWlKr+82Wi4HjCg/wn07nXog8xW897eQdQev15PHeq5rCm3YuYDujGhBPpeo8GLmHa9oqBPTsG2/w==@nongnu.org X-Gm-Message-State: AOJu0Yxo50kY+mWoL1t2C2dJXHPy2B4mT3lL5b0iZc8VQjxM8hTyf0FZ MmJi1Ta5LDqQ5dn1ZuC6aUSQtYueOPtLObWrjNCTA4sXXxT1ZRPMJrgdZw== X-Gm-Gg: ASbGncv4m/x/SOkbsj2FvQ6we3QJOkaFKD7tAeHt2gNW73SYe1MMw3K9a3zyB90qY5c /SK2nOt9x0phfNsar2xfvrWgqD3DKEdnyr6RAqWRB0d4+SYqRtH/OsE14xuKJew5PreLDpP4UB4 WvQwp0ehRl/ElDHen7Zpdhfs5Vob02TWIRRD5EIfJBZTVRMiMcYKMm1rkqwKOZW9TMRRNgG+LXh +UxD2xlOf26VUhPTQ65J5/OCnE5Fzn0H1qyb0DVdl4il5/Y1i7Vqryjkl7xpPJnZnBdmWC/5J0V dupk/W/inY0W/JEiLRBIaBVxyECVwZaX++mPGPhzUFbc9oaHe14= X-Google-Smtp-Source: AGHT+IHrvtF1tUwWVcOgMKICqjT5Ligq+yRnaV19JNLa4UiyGXeozI95dqmEq4ApzVgdnX9pbcmOmw== X-Received: by 2002:a17:90b:1b0b:b0:2fc:c262:ef4b with SMTP id 98e67ed59e1d1-2ff7cea9a99mr30654512a91.18.1741697955298; Tue, 11 Mar 2025 05:59:15 -0700 (PDT) Received: from wheely.local0.net ([118.208.151.101]) by smtp.gmail.com with ESMTPSA id 98e67ed59e1d1-2ff4e773dddsm11822318a91.12.2025.03.11.05.59.13 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 11 Mar 2025 05:59:14 -0700 (PDT) From: Nicholas Piggin To: qemu-devel@nongnu.org Cc: Nicholas Piggin , qemu-ppc@nongnu.org Subject: [PULL 14/72] ppc/pnv/occ: Add POWER10 OCC-OPAL data format Date: Tue, 11 Mar 2025 22:57:08 +1000 Message-ID: <20250311125815.903177-15-npiggin@gmail.com> X-Mailer: git-send-email 2.47.1 In-Reply-To: <20250311125815.903177-1-npiggin@gmail.com> References: <20250311125815.903177-1-npiggin@gmail.com> MIME-Version: 1.0 Received-SPF: pass client-ip=2607:f8b0:4864:20::102c; envelope-from=npiggin@gmail.com; helo=mail-pj1-x102c.google.com X-Spam_score_int: -20 X-Spam_score: -2.1 X-Spam_bar: -- X-Spam_report: (-2.1 / 5.0 requ) BAYES_00=-1.9, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_AU=-0.1, DKIM_VALID_EF=-0.1, FREEMAIL_FROM=0.001, RCVD_IN_DNSWL_NONE=-0.0001, SPF_HELO_NONE=0.001, SPF_PASS=-0.001 autolearn=ham autolearn_force=no X-Spam_action: no action X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: qemu-devel-bounces+qemu-devel=archiver.kernel.org@nongnu.org Sender: qemu-devel-bounces+qemu-devel=archiver.kernel.org@nongnu.org Add POWER10 OCC-OPAL data format. POWER10 changes major version and adds a few fields. Signed-off-by: Nicholas Piggin --- hw/ppc/pnv_occ.c | 43 ++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 42 insertions(+), 1 deletion(-) diff --git a/hw/ppc/pnv_occ.c b/hw/ppc/pnv_occ.c index 19ccfe1bbf..34decb1700 100644 --- a/hw/ppc/pnv_occ.c +++ b/hw/ppc/pnv_occ.c @@ -263,14 +263,20 @@ static const TypeInfo pnv_occ_power9_type_info = { static void pnv_occ_power10_class_init(ObjectClass *klass, void *data) { + PnvOCCClass *poc = PNV_OCC_CLASS(klass); DeviceClass *dc = DEVICE_CLASS(klass); dc->desc = "PowerNV OCC Controller (POWER10)"; + poc->opal_shared_memory_offset = P9_HOMER_OPAL_DATA_OFFSET; + poc->opal_shared_memory_version = 0xA0; + poc->xscom_size = PNV9_XSCOM_OCC_SIZE; + poc->xscom_ops = &pnv_occ_power9_xscom_ops; + assert(!dc->user_creatable); } static const TypeInfo pnv_occ_power10_type_info = { .name = TYPE_PNV10_OCC, - .parent = TYPE_PNV9_OCC, + .parent = TYPE_PNV_OCC, .class_init = pnv_occ_power10_class_init, }; @@ -711,6 +717,37 @@ static bool occ_init_homer_memory(PnvOCC *occ, Error **errp) static_data.v9.core_max[i] = 1; } break; + case 0xA0: + if (chip->chip_id == 0) { + static_data.v10.occ_role = OCC_ROLE_MASTER; + } else { + static_data.v10.occ_role = OCC_ROLE_SLAVE; + } + static_data.v10.pstate_min = 4; + static_data.v10.pstate_fixed_freq = 3; + static_data.v10.pstate_base = 2; + static_data.v10.pstate_ultra_turbo = 0; + static_data.v10.pstate_fmax = 1; + static_data.v10.minor = 0x01; + static_data.v10.pstates[0].valid = 1; + static_data.v10.pstates[0].id = 0; + static_data.v10.pstates[0].freq_khz = cpu_to_be32(4200000); + static_data.v10.pstates[1].valid = 1; + static_data.v10.pstates[1].id = 1; + static_data.v10.pstates[1].freq_khz = cpu_to_be32(4000000); + static_data.v10.pstates[2].valid = 1; + static_data.v10.pstates[2].id = 2; + static_data.v10.pstates[2].freq_khz = cpu_to_be32(3800000); + static_data.v10.pstates[3].valid = 1; + static_data.v10.pstates[3].id = 3; + static_data.v10.pstates[3].freq_khz = cpu_to_be32(3000000); + static_data.v10.pstates[4].valid = 1; + static_data.v10.pstates[4].id = 4; + static_data.v10.pstates[4].freq_khz = cpu_to_be32(2000000); + for (i = 0; i < chip->nr_cores; i++) { + static_data.v10.core_max[i] = 1; + } + break; default: g_assert_not_reached(); } @@ -726,6 +763,10 @@ static bool occ_init_homer_memory(PnvOCC *occ, Error **errp) dynamic_data.cur_pwr_cap = cpu_to_be16(PCAP_MAX_POWER_W); dynamic_data.soft_min_pwr_cap = cpu_to_be16(PCAP_SOFT_MIN_POWER_W); switch (poc->opal_shared_memory_version) { + case 0xA0: + dynamic_data.minor_version = 0x1; + dynamic_data.v10.wof_enabled = 0x1; + break; case 0x90: dynamic_data.minor_version = 0x1; break; From patchwork Tue Mar 11 12:57:09 2025 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Nicholas Piggin X-Patchwork-Id: 14011809 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.lore.kernel.org (Postfix) with ESMTPS id A0E06C282EC for ; Tue, 11 Mar 2025 13:06:33 +0000 (UTC) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1trzCp-0002Hj-3c; Tue, 11 Mar 2025 08:59:36 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1trzCf-0001xO-3N; Tue, 11 Mar 2025 08:59:25 -0400 Received: from mail-pj1-x1029.google.com ([2607:f8b0:4864:20::1029]) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_128_GCM_SHA256:128) (Exim 4.90_1) (envelope-from ) id 1trzCb-0007wb-3v; Tue, 11 Mar 2025 08:59:24 -0400 Received: by mail-pj1-x1029.google.com with SMTP id 98e67ed59e1d1-2ff694d2d4dso7752706a91.0; Tue, 11 Mar 2025 05:59:19 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20230601; t=1741697958; x=1742302758; darn=nongnu.org; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to; bh=UE/0F1oCsxuW6Zn4Oxkfeuhf/dmH1J3omqaeTt273/s=; b=ZOEbIlSBwYIwDAjkGnI+bqaFKpkjzdY4Mpe3ibd4e6N/zll+iFV11FaOXgIzrizC0j MLlSNdUW/yDdciS4XJ4C6gcpDmDWvJvcVqqrVmDUW51qrGvSbLfAPMW8BHbBvswFIqme d1ISZvKHNPmaB9WcfVQRGGhANCr5sv/WcU2P0yyG613xEVAYA6jKHZT0wcaoHA/mp1Zm fEnYgKQ5IaFLNC6cPhXL669Yj9Fe0Oi/W0XQANwYRbeiIb0pPsb5bMUvEV7BJvf7nKL6 hV3XZvBHOCkB6KVVhD1e3C7/iEvU8FMrX4K0WTE+BugSWNwpMbp+qqQsKeU2roCgmHKh nOUQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1741697958; x=1742302758; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=UE/0F1oCsxuW6Zn4Oxkfeuhf/dmH1J3omqaeTt273/s=; b=APUy/yphjyajt1U1wxsfe0YJ72m/loaFD6+K+D5LHo8ahVQfmmaDdN8gko+bMzdGa0 rJ1Ow6l4ZLhlwRd1VpB0nX+/VOI4Uhg4gVljoAtjOW6Vw+tWBrK1zt4YACXQ2cDRPEC/ HpECOCYZrvwLFZpCZKfK+9pKLLm8VKMWiF5GkR5iy+9yvdGVd/AyOmkV7KPtVX3P0wU6 M3lPp0Q+J5yw/2y9O2pzCRLYF+6RTKkCFXNBpEEaLmM7/ZBMaGbegBV8UhThZpIhoo24 wmS9XVWDQ7u10j4MKuVdNTg6jE7hPTGWFZYsKE/Ne0Yj/mTGqIVXP8Ihr8JOe+bnqNNj GAgg== X-Forwarded-Encrypted: i=1; AJvYcCUCO/zHWT+7g8jSm/wN9QK+SWAE81womiU5pi7CMUWHQjIjzrIbv8/uB98DM3ARLqdYEmmnwC4xhg==@nongnu.org X-Gm-Message-State: AOJu0YzvQ9Qf5XE8NIqc+eyNAmieBWdA78baRbQ1V1r6HN3pBXqw7GiZ kRy6kgdk27xze3zilEDHTZOJyOXudYyzLdTDMRgWRlHq5S90PluQYA42uQ== X-Gm-Gg: ASbGncuUlmoRcr1IrkSQ1favtSNMPl5Gebb2jvC2UnJ8mL2cZ1l4ciVeMA+JQsVo6z6 /kvnHaitqPjB5StaegMML6yIly0NZCBEUXaydN+/n0dlyGx5+XwSxW4Lj36Fjmctv90dAscZ1tu NWbia+WrfZjbJUlwKoQbLDKeyhEkHj5lm5SypPRt6GppktttbCBemgGRMsEFx4VMcUUfrMMG3d/ 6G3eKvHfieZzsF5Pgy0tQW3dtRP/bmnrb6T+kjWfcf9bL7S+bzUY2zkMiFTQM3XowEI4/xIfzP9 h/gDiqmN4Wx/luuuzYyFI9ggioL+GuhnS5TBpFgTcypeB0Hw3pU= X-Google-Smtp-Source: AGHT+IHiRLIIZjbcAFAK0jHHweWIKArYV/YLTbEn2bwKu3i8Mg4V2J0vjSwg8413tKV8DzxxyzIYNQ== X-Received: by 2002:a17:90b:3887:b0:2fe:80cb:ac05 with SMTP id 98e67ed59e1d1-2ff7ce7ac2bmr28535031a91.9.1741697957658; Tue, 11 Mar 2025 05:59:17 -0700 (PDT) Received: from wheely.local0.net ([118.208.151.101]) by smtp.gmail.com with ESMTPSA id 98e67ed59e1d1-2ff4e773dddsm11822318a91.12.2025.03.11.05.59.15 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 11 Mar 2025 05:59:17 -0700 (PDT) From: Nicholas Piggin To: qemu-devel@nongnu.org Cc: Nicholas Piggin , qemu-ppc@nongnu.org Subject: [PULL 15/72] ppc/pnv/occ: Implement a basic dynamic OCC model Date: Tue, 11 Mar 2025 22:57:09 +1000 Message-ID: <20250311125815.903177-16-npiggin@gmail.com> X-Mailer: git-send-email 2.47.1 In-Reply-To: <20250311125815.903177-1-npiggin@gmail.com> References: <20250311125815.903177-1-npiggin@gmail.com> MIME-Version: 1.0 Received-SPF: pass client-ip=2607:f8b0:4864:20::1029; envelope-from=npiggin@gmail.com; helo=mail-pj1-x1029.google.com X-Spam_score_int: -20 X-Spam_score: -2.1 X-Spam_bar: -- X-Spam_report: (-2.1 / 5.0 requ) BAYES_00=-1.9, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_AU=-0.1, DKIM_VALID_EF=-0.1, FREEMAIL_FROM=0.001, RCVD_IN_DNSWL_NONE=-0.0001, SPF_HELO_NONE=0.001, SPF_PASS=-0.001 autolearn=ham autolearn_force=no X-Spam_action: no action X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: qemu-devel-bounces+qemu-devel=archiver.kernel.org@nongnu.org Sender: qemu-devel-bounces+qemu-devel=archiver.kernel.org@nongnu.org The OCC is an On Chip Controller that handles various thermal and power management. It is a PPC405 microcontroller that runs its own firmware which is out of scope of the powernv machine model. Some dynamic behaviour and interfaces that are important for host CPU testing can be implemented with a much simpler state machine. This change adds a 100ms timer that ticks through a simple state machine that looks for "OCC command requests" coming from host firmware, and responds to them. For now the powercap command is implemented because that is used by OPAL and exported to Linux and is easy to test. $ F=/sys/firmware/opal/powercap/system-powercap/powercap-current $ cat $F 100 $ echo 50 | sudo tee $F 50 $ cat $F 50 Signed-off-by: Nicholas Piggin --- hw/ppc/pnv_occ.c | 146 +++++++++++++++++++++++++++++++++++++++ include/hw/ppc/pnv_occ.h | 3 + 2 files changed, 149 insertions(+) diff --git a/hw/ppc/pnv_occ.c b/hw/ppc/pnv_occ.c index 34decb1700..d9ce35a4d6 100644 --- a/hw/ppc/pnv_occ.c +++ b/hw/ppc/pnv_occ.c @@ -35,6 +35,7 @@ #define OCB_OCI_OCCMISC_AND 0x4021 #define OCB_OCI_OCCMISC_OR 0x4022 #define OCCMISC_PSI_IRQ PPC_BIT(0) +#define OCCMISC_IRQ_SHMEM PPC_BIT(3) /* OCC sensors */ #define OCC_SENSOR_DATA_BLOCK_OFFSET 0x0000 @@ -67,6 +68,11 @@ static void pnv_occ_set_misc(PnvOCC *occ, uint64_t val) qemu_set_irq(occ->psi_irq, !!(val & OCCMISC_PSI_IRQ)); } +static void pnv_occ_raise_msg_irq(PnvOCC *occ) +{ + pnv_occ_set_misc(occ, occ->occmisc | OCCMISC_PSI_IRQ | OCCMISC_IRQ_SHMEM); +} + static uint64_t pnv_occ_power8_xscom_read(void *opaque, hwaddr addr, unsigned size) { @@ -281,6 +287,20 @@ static const TypeInfo pnv_occ_power10_type_info = { }; static bool occ_init_homer_memory(PnvOCC *occ, Error **errp); +static bool occ_model_tick(PnvOCC *occ); + +/* Relatively arbitrary */ +#define OCC_POLL_MS 100 + +static void occ_state_machine_timer(void *opaque) +{ + PnvOCC *occ = opaque; + uint64_t next = qemu_clock_get_ms(QEMU_CLOCK_VIRTUAL) + OCC_POLL_MS; + + if (occ_model_tick(occ)) { + timer_mod(&occ->state_machine_timer, next); + } +} static void pnv_occ_realize(DeviceState *dev, Error **errp) { @@ -306,6 +326,10 @@ static void pnv_occ_realize(DeviceState *dev, Error **errp) PNV_OCC_SENSOR_DATA_BLOCK_SIZE); qdev_init_gpio_out(dev, &occ->psi_irq, 1); + + timer_init_ms(&occ->state_machine_timer, QEMU_CLOCK_VIRTUAL, + occ_state_machine_timer, occ); + timer_mod(&occ->state_machine_timer, OCC_POLL_MS); } static const Property pnv_occ_properties[] = { @@ -647,6 +671,27 @@ static bool occ_write_static_data(PnvOCC *occ, return true; } +static bool occ_read_dynamic_data(PnvOCC *occ, + struct occ_dynamic_data *dynamic_data, + Error **errp) +{ + PnvOCCClass *poc = PNV_OCC_GET_CLASS(occ); + PnvHomer *homer = occ->homer; + hwaddr static_addr = homer->base + poc->opal_shared_memory_offset; + hwaddr dynamic_addr = static_addr + OPAL_DYNAMIC_DATA_OFFSET; + MemTxResult ret; + + ret = address_space_read(&address_space_memory, dynamic_addr, + MEMTXATTRS_UNSPECIFIED, dynamic_data, + sizeof(*dynamic_data)); + if (ret != MEMTX_OK) { + error_setg(errp, "OCC: cannot read OCC-OPAL dynamic data"); + return false; + } + + return true; +} + static bool occ_write_dynamic_data(PnvOCC *occ, struct occ_dynamic_data *dynamic_data, Error **errp) @@ -668,6 +713,107 @@ static bool occ_write_dynamic_data(PnvOCC *occ, return true; } +static bool occ_opal_send_response(PnvOCC *occ, + struct occ_dynamic_data *dynamic_data, + enum occ_response_status status, + uint8_t *data, uint16_t datalen) +{ + struct opal_command_buffer *cmd = &dynamic_data->cmd; + struct occ_response_buffer *rsp = &dynamic_data->rsp; + + rsp->request_id = cmd->request_id; + rsp->cmd = cmd->cmd; + rsp->status = status; + rsp->data_size = cpu_to_be16(datalen); + if (datalen) { + memcpy(rsp->data, data, datalen); + } + if (!occ_write_dynamic_data(occ, dynamic_data, NULL)) { + return false; + } + /* Would be a memory barrier here */ + rsp->flag = OCC_FLAG_RSP_READY; + cmd->flag = 0; + if (!occ_write_dynamic_data(occ, dynamic_data, NULL)) { + return false; + } + + pnv_occ_raise_msg_irq(occ); + + return true; +} + +/* Returns error status */ +static bool occ_opal_process_command(PnvOCC *occ, + struct occ_dynamic_data *dynamic_data) +{ + struct opal_command_buffer *cmd = &dynamic_data->cmd; + struct occ_response_buffer *rsp = &dynamic_data->rsp; + + if (rsp->flag == 0) { + /* Spend one "tick" in the in-progress state */ + rsp->flag = OCC_FLAG_CMD_IN_PROGRESS; + return occ_write_dynamic_data(occ, dynamic_data, NULL); + } else if (rsp->flag != OCC_FLAG_CMD_IN_PROGRESS) { + return occ_opal_send_response(occ, dynamic_data, + OCC_RSP_INTERNAL_ERROR, + NULL, 0); + } + + switch (cmd->cmd) { + case 0xD1: { /* SET_POWER_CAP */ + uint16_t data; + if (be16_to_cpu(cmd->data_size) != 2) { + return occ_opal_send_response(occ, dynamic_data, + OCC_RSP_INVALID_CMD_DATA_LENGTH, + (uint8_t *)&dynamic_data->cur_pwr_cap, + 2); + } + data = be16_to_cpu(*(uint16_t *)cmd->data); + if (data == 0) { /* clear power cap */ + dynamic_data->pwr_cap_type = 0x00; /* none */ + data = PCAP_MAX_POWER_W; + } else { + dynamic_data->pwr_cap_type = 0x02; /* user set in-band */ + if (data < PCAP_HARD_MIN_POWER_W) { + data = PCAP_HARD_MIN_POWER_W; + } else if (data > PCAP_MAX_POWER_W) { + data = PCAP_MAX_POWER_W; + } + } + dynamic_data->cur_pwr_cap = cpu_to_be16(data); + return occ_opal_send_response(occ, dynamic_data, + OCC_RSP_SUCCESS, + (uint8_t *)&dynamic_data->cur_pwr_cap, 2); + } + + default: + return occ_opal_send_response(occ, dynamic_data, + OCC_RSP_INVALID_COMMAND, + NULL, 0); + } + g_assert_not_reached(); +} + +static bool occ_model_tick(PnvOCC *occ) +{ + struct occ_dynamic_data dynamic_data; + + if (!occ_read_dynamic_data(occ, &dynamic_data, NULL)) { + /* Can't move OCC state field to safe because we can't map it! */ + qemu_log("OCC: failed to read HOMER data, shutting down OCC\n"); + return false; + } + if (dynamic_data.cmd.flag == OPAL_FLAG_CMD_READY) { + if (!occ_opal_process_command(occ, &dynamic_data)) { + qemu_log("OCC: failed to write HOMER data, shutting down OCC\n"); + return false; + } + } + + return true; +} + static bool occ_init_homer_memory(PnvOCC *occ, Error **errp) { PnvOCCClass *poc = PNV_OCC_GET_CLASS(occ); diff --git a/include/hw/ppc/pnv_occ.h b/include/hw/ppc/pnv_occ.h index f994860980..3ec42de0ff 100644 --- a/include/hw/ppc/pnv_occ.h +++ b/include/hw/ppc/pnv_occ.h @@ -41,6 +41,9 @@ DECLARE_INSTANCE_CHECKER(PnvOCC, PNV10_OCC, TYPE_PNV10_OCC) struct PnvOCC { DeviceState xd; + /* OCC dynamic model is driven by this timer. */ + QEMUTimer state_machine_timer; + /* OCC Misc interrupt */ uint64_t occmisc; From patchwork Tue Mar 11 12:57:10 2025 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Nicholas Piggin X-Patchwork-Id: 14011795 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.lore.kernel.org (Postfix) with ESMTPS id 87CF9C35FF1 for ; Tue, 11 Mar 2025 13:01:00 +0000 (UTC) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1trzDC-0003x7-NF; Tue, 11 Mar 2025 08:59:58 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1trzCg-00021s-SG; Tue, 11 Mar 2025 08:59:28 -0400 Received: from mail-pj1-x1031.google.com ([2607:f8b0:4864:20::1031]) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_128_GCM_SHA256:128) (Exim 4.90_1) (envelope-from ) id 1trzCc-0007x4-U9; Tue, 11 Mar 2025 08:59:25 -0400 Received: by mail-pj1-x1031.google.com with SMTP id 98e67ed59e1d1-2ff64550991so8237887a91.0; Tue, 11 Mar 2025 05:59:22 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20230601; t=1741697961; x=1742302761; darn=nongnu.org; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to; bh=T1uWfwdoT5PuKunpdf5GL7Jo4UcITHEbOpLA5+y74zY=; b=S8xLiHhR/AxOxTKHERJwZy0a9kJvrtf+/pptQh5CURjBXXIbK4/u75exJ3hGRfmueg G4Pam2AbGMUkdjJ2wFx08v+Q/Tp3QD1w2h3DKdRMs5oNHFAghJOzHvic0mm4C61GypEg /bPk5Zijbzo7q5ibkJw0MFHtl3JjX+kQHHM1XNakQDscVXRztbZFdaaK9c82p7oz+L7d qr6jHROTwR/i0w9Ax+zkeXWfpE5/mjNuSWt6KxGXUa/0n8NoR1jRAT3kcEQCFR2RW21v AukZrFVqxAqZZcXO8RpY1IIzFdGW3FaD8apzKIbor6GEMFkon/nLv4ABPCzNcF+5pv0q NceA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1741697961; x=1742302761; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=T1uWfwdoT5PuKunpdf5GL7Jo4UcITHEbOpLA5+y74zY=; b=bG4z4hB/lyiC5gZzs8hNYnMNHlFbZfa9pkxKRG1VxpvDsjN9NpXChPzB2QCV8bTWcU zgk8S6VC1OhU02quN6I7Xhi3eina7CSJ3hImKxrQlAx5dM9H2WxHndX6f2TgJzhj+UhC 1oJUeJJwNbCAJD8Sxx7R7rgz6XsSrhasBhi5xTivnfAHMMgkaYRyPc0T73qilCQRU+vl HIYGmhFzCfCosWCQ8DfGsaCMVtp/zSyGc/f5+czcrWH1rqjp8JZun0SqGgT//u4CYokA rNsCprWCt74W5lL9u7AqRy3TWdkwYwqNDoPjnsG499lsB8E6UZMUlQpB2n3aq9l/DE+u K/Hw== X-Forwarded-Encrypted: i=1; AJvYcCVlg5UHPVGVLj+KDQ0MtwX5Cb5ZmWbDoceib1Iiyame9mVaHihT+LP0yWWU5ZnaEOIVWbHbhmrq6A==@nongnu.org X-Gm-Message-State: AOJu0YwNm2YzJRUfNLo9JSlg9BZOpbOTOhKC5A0+YMiY7D0O3cjdh0U5 dQfqXCW1k1iBruswKm26CC199DGC5VLvqOMafkdO8A5wtnb8s2FppACRyw== X-Gm-Gg: ASbGncuiI6JnxCntQeWIUQsLelU3vyNSxeadKEzB20G8WiLmiODA9KJfSAeCBAKzTgn a/mGGAran4iz4mBQd2Fcmvh86oD6xRjKV+A/XJXlFbBNfTM33yVAUIBjCrV0m7fhfdzOiQvFHhK qBaLJ7y8pt8sepbLLpg1yykElRJI+OFEKh98E7K6Fbk1jwuMb4Pt/yRJthCwvtIVg/9ZfLtFgsj xIC+qVBbF3U1ye12ve2vf3wk1LpIRhMsNtj5xWLA7w+02dCOgyY05/4hkIqosnIRyWWsSQL5hLE M+62i8QSnTbBfu0bpWR/qshi+cjCC0exVHKoo8tj6v4JuEHBU/w= X-Google-Smtp-Source: AGHT+IHhK3Xq0p0Gsazf9hC06zEq/EpkSQuUyC5j8Ci91L0KHHOssdLEtZOlVMMajo7ZW5PBpz4NGw== X-Received: by 2002:a17:90b:3812:b0:2ef:114d:7bf8 with SMTP id 98e67ed59e1d1-2ff7ce7277cmr24565728a91.6.1741697960456; Tue, 11 Mar 2025 05:59:20 -0700 (PDT) Received: from wheely.local0.net ([118.208.151.101]) by smtp.gmail.com with ESMTPSA id 98e67ed59e1d1-2ff4e773dddsm11822318a91.12.2025.03.11.05.59.18 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 11 Mar 2025 05:59:20 -0700 (PDT) From: Nicholas Piggin To: qemu-devel@nongnu.org Cc: Nicholas Piggin , qemu-ppc@nongnu.org Subject: [PULL 16/72] target/ppc: Add Power9/10 power management SPRs Date: Tue, 11 Mar 2025 22:57:10 +1000 Message-ID: <20250311125815.903177-17-npiggin@gmail.com> X-Mailer: git-send-email 2.47.1 In-Reply-To: <20250311125815.903177-1-npiggin@gmail.com> References: <20250311125815.903177-1-npiggin@gmail.com> MIME-Version: 1.0 Received-SPF: pass client-ip=2607:f8b0:4864:20::1031; envelope-from=npiggin@gmail.com; helo=mail-pj1-x1031.google.com X-Spam_score_int: -20 X-Spam_score: -2.1 X-Spam_bar: -- X-Spam_report: (-2.1 / 5.0 requ) BAYES_00=-1.9, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_AU=-0.1, DKIM_VALID_EF=-0.1, FREEMAIL_FROM=0.001, RCVD_IN_DNSWL_NONE=-0.0001, SPF_HELO_NONE=0.001, SPF_PASS=-0.001 autolearn=ham autolearn_force=no X-Spam_action: no action X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: qemu-devel-bounces+qemu-devel=archiver.kernel.org@nongnu.org Sender: qemu-devel-bounces+qemu-devel=archiver.kernel.org@nongnu.org Linux power management code accesses these registers for pstate management. Wire up a very simple implementation. Signed-off-by: Nicholas Piggin --- After OCC fixes in QEMU pnv model and skiboot (since they have suffered some bitrot), Linux will start performing PM SPR accesses. This is a very simple implementation that makes it a bit happier. Thanks, Nick --- target/ppc/cpu.h | 2 ++ target/ppc/cpu_init.c | 11 +++++++++ target/ppc/helper.h | 2 ++ target/ppc/misc_helper.c | 53 ++++++++++++++++++++++++++++++++++++++++ target/ppc/spr_common.h | 2 ++ target/ppc/translate.c | 16 ++++++++++++ 6 files changed, 86 insertions(+) diff --git a/target/ppc/cpu.h b/target/ppc/cpu.h index 0b8b4c0517..682583d1d1 100644 --- a/target/ppc/cpu.h +++ b/target/ppc/cpu.h @@ -2091,6 +2091,7 @@ void ppc_compat_add_property(Object *obj, const char *name, #define SPR_VTB (0x351) #define SPR_LDBAR (0x352) #define SPR_MMCRC (0x353) +#define SPR_PMSR (0x355) #define SPR_PSSCR (0x357) #define SPR_440_INV0 (0x370) #define SPR_440_INV1 (0x371) @@ -2098,6 +2099,7 @@ void ppc_compat_add_property(Object *obj, const char *name, #define SPR_440_INV2 (0x372) #define SPR_TRIG2 (0x372) #define SPR_440_INV3 (0x373) +#define SPR_PMCR (0x374) #define SPR_440_ITV0 (0x374) #define SPR_440_ITV1 (0x375) #define SPR_440_ITV2 (0x376) diff --git a/target/ppc/cpu_init.c b/target/ppc/cpu_init.c index 1780cabfc6..54035c7bbb 100644 --- a/target/ppc/cpu_init.c +++ b/target/ppc/cpu_init.c @@ -6451,6 +6451,17 @@ static void register_power9_common_sprs(CPUPPCState *env) spr_read_generic, spr_write_generic, KVM_REG_PPC_PSSCR, 0); + spr_register_hv(env, SPR_PMSR, "PMSR", + SPR_NOACCESS, SPR_NOACCESS, + SPR_NOACCESS, SPR_NOACCESS, + &spr_read_pmsr, SPR_NOACCESS, + 0); + spr_register_hv(env, SPR_PMCR, "PMCR", + SPR_NOACCESS, SPR_NOACCESS, + SPR_NOACCESS, SPR_NOACCESS, + &spr_read_generic, &spr_write_pmcr, + PPC_BIT(63)); /* Version 1 (POWER9/10) */ + } static void init_proc_POWER9(CPUPPCState *env) diff --git a/target/ppc/helper.h b/target/ppc/helper.h index 5a77e761bd..11b914e640 100644 --- a/target/ppc/helper.h +++ b/target/ppc/helper.h @@ -733,6 +733,8 @@ DEF_HELPER_2(store_tfmr, void, env, tl) DEF_HELPER_FLAGS_2(store_sprc, TCG_CALL_NO_RWG, void, env, tl) DEF_HELPER_FLAGS_1(load_sprd, TCG_CALL_NO_RWG_SE, tl, env) DEF_HELPER_FLAGS_2(store_sprd, TCG_CALL_NO_RWG, void, env, tl) +DEF_HELPER_FLAGS_1(load_pmsr, TCG_CALL_NO_RWG_SE, tl, env) +DEF_HELPER_FLAGS_2(store_pmcr, TCG_CALL_NO_RWG, void, env, tl) #endif DEF_HELPER_2(store_sdr1, void, env, tl) DEF_HELPER_2(store_pidr, void, env, tl) diff --git a/target/ppc/misc_helper.c b/target/ppc/misc_helper.c index e379da6010..190e9091fc 100644 --- a/target/ppc/misc_helper.c +++ b/target/ppc/misc_helper.c @@ -377,6 +377,59 @@ void helper_store_sprd(CPUPPCState *env, target_ulong val) break; } } + +target_ulong helper_load_pmsr(CPUPPCState *env) +{ + target_ulong lowerps = extract64(env->spr[SPR_PMCR], PPC_BIT_NR(15), 8); + target_ulong val = 0; + + val |= PPC_BIT(63); /* verion 0x1 (POWER9/10) */ + /* Pmin = 0 */ + /* XXX: POWER9 should be 3 */ + val |= 4ULL << PPC_BIT_NR(31); /* Pmax */ + val |= lowerps << PPC_BIT_NR(15); /* Local actual Pstate */ + val |= lowerps << PPC_BIT_NR(7); /* Global actual Pstate */ + + return val; +} + +static void ppc_set_pmcr(PowerPCCPU *cpu, target_ulong val) +{ + cpu->env.spr[SPR_PMCR] = val; +} + +void helper_store_pmcr(CPUPPCState *env, target_ulong val) +{ + PowerPCCPU *cpu = env_archcpu(env); + CPUState *cs = env_cpu(env); + CPUState *ccs; + + /* Leave version field unchanged (0x1) */ + val &= ~PPC_BITMASK(60, 63); + val |= PPC_BIT(63); + + val &= ~PPC_BITMASK(0, 7); /* UpperPS ignored */ + if (val & PPC_BITMASK(16, 59)) { + qemu_log_mask(LOG_GUEST_ERROR, "Non-zero PMCR reserved bits " + TARGET_FMT_lx"\n", val); + val &= ~PPC_BITMASK(16, 59); + } + + /* DPDES behaves as 1-thread in LPAR-per-thread mode */ + if (ppc_cpu_lpar_single_threaded(cs)) { + ppc_set_pmcr(cpu, val); + return; + } + + /* Does iothread need to be locked for walking CPU list? */ + bql_lock(); + THREAD_SIBLING_FOREACH(cs, ccs) { + PowerPCCPU *ccpu = POWERPC_CPU(ccs); + ppc_set_pmcr(ccpu, val); + } + bql_unlock(); +} + #endif /* defined(TARGET_PPC64) */ void helper_store_pidr(CPUPPCState *env, target_ulong val) diff --git a/target/ppc/spr_common.h b/target/ppc/spr_common.h index 01aff449bc..8e3117b463 100644 --- a/target/ppc/spr_common.h +++ b/target/ppc/spr_common.h @@ -204,6 +204,8 @@ void spr_write_hmer(DisasContext *ctx, int sprn, int gprn); void spr_read_tfmr(DisasContext *ctx, int gprn, int sprn); void spr_write_tfmr(DisasContext *ctx, int sprn, int gprn); void spr_write_lpcr(DisasContext *ctx, int sprn, int gprn); +void spr_read_pmsr(DisasContext *ctx, int gprn, int sprn); +void spr_write_pmcr(DisasContext *ctx, int sprn, int gprn); void spr_read_dexcr_ureg(DisasContext *ctx, int gprn, int sprn); void spr_read_ppr32(DisasContext *ctx, int sprn, int gprn); void spr_write_ppr32(DisasContext *ctx, int sprn, int gprn); diff --git a/target/ppc/translate.c b/target/ppc/translate.c index 80638ab535..b0cc8bf283 100644 --- a/target/ppc/translate.c +++ b/target/ppc/translate.c @@ -1326,6 +1326,22 @@ void spr_write_lpcr(DisasContext *ctx, int sprn, int gprn) translator_io_start(&ctx->base); gen_helper_store_lpcr(tcg_env, cpu_gpr[gprn]); } + +void spr_read_pmsr(DisasContext *ctx, int gprn, int sprn) +{ + translator_io_start(&ctx->base); + gen_helper_load_pmsr(cpu_gpr[gprn], tcg_env); +} + +void spr_write_pmcr(DisasContext *ctx, int sprn, int gprn) +{ + if (!gen_serialize_core_lpar(ctx)) { + return; + } + translator_io_start(&ctx->base); + gen_helper_store_pmcr(tcg_env, cpu_gpr[gprn]); +} + #endif /* !defined(CONFIG_USER_ONLY) */ void spr_read_tar(DisasContext *ctx, int gprn, int sprn) From patchwork Tue Mar 11 12:57:11 2025 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Nicholas Piggin X-Patchwork-Id: 14011804 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.lore.kernel.org (Postfix) with ESMTPS id AF692C28B30 for ; Tue, 11 Mar 2025 13:06:03 +0000 (UTC) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1trzDF-00044S-3r; Tue, 11 Mar 2025 09:00:01 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1trzCh-00022J-9H; Tue, 11 Mar 2025 08:59:28 -0400 Received: from mail-pj1-x1029.google.com ([2607:f8b0:4864:20::1029]) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_128_GCM_SHA256:128) (Exim 4.90_1) (envelope-from ) id 1trzCf-0007xX-G6; Tue, 11 Mar 2025 08:59:27 -0400 Received: by mail-pj1-x1029.google.com with SMTP id 98e67ed59e1d1-2ff69365e1dso7926330a91.3; Tue, 11 Mar 2025 05:59:24 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20230601; t=1741697963; x=1742302763; darn=nongnu.org; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to; bh=fqFuEaShL7QDMXwSHtnl81qUichOoVW19OOsjZgbiVQ=; b=HMCa47uLlBR/MQzcTgvvhVhh+aEhgGxZpok8lelz35/E56gzpLsO5QYKrq3k/06kCG j6vJr8GDF+9zk14HsskZV8Uos75QQ+4m5fgkvvOa5zgVKp4pBS9PFp6BqsQe0J+1LtLG vC8CjhqkEbOSd/3tjKbUGlxMdzzDRi6CZNEzQJoysw17aD38RQFb75ffR398xpDlIp5N xMzkwVW41JDwOs6qjL4MsozOOtXPYGtiFhaz3RrXteKnamLvrqpEhy6NFaBLHJX910PO bIGEB9J4URYWt8yj2i8z7tcaC+270PnxeJuSv7KsSY43HHfg714MSDf8KYeEMO5b6Nxq B2OQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1741697963; x=1742302763; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=fqFuEaShL7QDMXwSHtnl81qUichOoVW19OOsjZgbiVQ=; b=NgyHQbOOKSlnux+/AQZVGfDWn2PHLC2KPKTeTQkFkUinkEtljz8BoE7ypapRB9rHzh INU4AElv+uWnLoaqqNLBJ/4utsCtjp/+b5md6YJRFLm+k1FTCttDisMZ9Q6kUcB/R/ot OO91S/PgmS7dtZlJixMRnjWmBCjvAFpSlLpfJUjvOI80HPlOGuaNfp09KGw6wRToC47w LItT3AsqIVFVzKopA0JVRzvVlwlIH3c/t32+p6j8fFEtkrgJd3QxbDeZW8yh9kI265VT qk6Fifmo8Ni8elLwevrVjXLPcVgqvUya9Pup9SD4ncvUoOPunMw53DSjuAgq+63yny3J tXRg== X-Forwarded-Encrypted: i=1; AJvYcCXnnVCOW45RO17P/Iaw/fn6qxP4IfBCrh+y9BEg1X03h31UDVg2U9THTWF7y8mqroLl6RvVYVlp2g==@nongnu.org X-Gm-Message-State: AOJu0YxaTUWo0BA8d9KHU4sNX/S/G2gmnuoeaaTuuWrDYO46TbrrVV1O uLenap25hEoHUCZZ7FAkxzP+QbDCmdYUOs0masZbzKccp0mDEuwzlyaj9Q== X-Gm-Gg: ASbGncs0f2NSVDC2l4dq1cSvXXbYW1y9VqzXVq6iq4UiGMnvJ3cv/KwmPk7yTXBjZ2s MA+I9bBFP8fRBlK9RXTIFoPo4nnM91EqHauVV05bT8lAkQOJYqb5B+BHRYRq73Pe4B8pgaQDtTr zD5CGkUaYvqTDQ0n+w/Rf73rgeSj2v545yr6Qig3ho7jJXxdmSoK/cypPOYj0vdmeOawH7nsnLt iP5rofmTEf/GSrpXfpmvMlEHAlww6XkHC092ZnBlrfp0AllpWl9i8izZa4owVj1PC3WVxF9CbOl VEkJ+ntETFjqcgu1rJGP3mbsqFI05Bj1Tq+iUfsuEZw4zuvghro= X-Google-Smtp-Source: AGHT+IGI0v+NMdNqMr7la3iNW7GBB4U91RILxWfSpz+dcYrLsD/e79DcHZMqtkXSizdplmdmqa3pmA== X-Received: by 2002:a17:90b:164f:b0:2fe:baa3:b8b9 with SMTP id 98e67ed59e1d1-2ff7ce4f306mr25161149a91.4.1741697963258; Tue, 11 Mar 2025 05:59:23 -0700 (PDT) Received: from wheely.local0.net ([118.208.151.101]) by smtp.gmail.com with ESMTPSA id 98e67ed59e1d1-2ff4e773dddsm11822318a91.12.2025.03.11.05.59.20 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 11 Mar 2025 05:59:22 -0700 (PDT) From: Nicholas Piggin To: qemu-devel@nongnu.org Cc: Nicholas Piggin , qemu-ppc@nongnu.org Subject: [PULL 17/72] ppc/pnv: Support LPC host controller irqs other than serirqs Date: Tue, 11 Mar 2025 22:57:11 +1000 Message-ID: <20250311125815.903177-18-npiggin@gmail.com> X-Mailer: git-send-email 2.47.1 In-Reply-To: <20250311125815.903177-1-npiggin@gmail.com> References: <20250311125815.903177-1-npiggin@gmail.com> MIME-Version: 1.0 Received-SPF: pass client-ip=2607:f8b0:4864:20::1029; envelope-from=npiggin@gmail.com; helo=mail-pj1-x1029.google.com X-Spam_score_int: -20 X-Spam_score: -2.1 X-Spam_bar: -- X-Spam_report: (-2.1 / 5.0 requ) BAYES_00=-1.9, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_AU=-0.1, DKIM_VALID_EF=-0.1, FREEMAIL_FROM=0.001, RCVD_IN_DNSWL_NONE=-0.0001, SPF_HELO_NONE=0.001, SPF_PASS=-0.001 autolearn=ham autolearn_force=no X-Spam_action: no action X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: qemu-devel-bounces+qemu-devel=archiver.kernel.org@nongnu.org Sender: qemu-devel-bounces+qemu-devel=archiver.kernel.org@nongnu.org The LPC model has only supported serirqs (ISA device IRQs), however there are internal sources that can raise other interrupts. Update the device to handle these interrupt sources. Signed-off-by: Nicholas Piggin --- hw/ppc/pnv_lpc.c | 64 +++++++++++++++++++++++------------------------- 1 file changed, 31 insertions(+), 33 deletions(-) diff --git a/hw/ppc/pnv_lpc.c b/hw/ppc/pnv_lpc.c index 0480a60f3f..d0fccc165d 100644 --- a/hw/ppc/pnv_lpc.c +++ b/hw/ppc/pnv_lpc.c @@ -456,46 +456,18 @@ static void pnv_lpc_eval_irqs(PnvLpcController *lpc) { uint32_t active_irqs = 0; - if (lpc->lpc_hc_irqstat & PPC_BITMASK32(16, 31)) { - qemu_log_mask(LOG_UNIMP, "LPC HC Unimplemented irqs in IRQSTAT: " - "0x%08"PRIx32"\n", lpc->lpc_hc_irqstat); - } - - if (lpc->lpc_hc_irqser_ctrl & LPC_HC_IRQSER_EN) { - active_irqs = lpc->lpc_hc_irqstat & lpc->lpc_hc_irqmask; + active_irqs = lpc->lpc_hc_irqstat & lpc->lpc_hc_irqmask; + if (!(lpc->lpc_hc_irqser_ctrl & LPC_HC_IRQSER_EN)) { + active_irqs &= ~LPC_HC_IRQ_SERIRQ_ALL; } /* Reflect the interrupt */ - if (!lpc->psi_has_serirq) { - /* - * POWER8 ORs all irqs together (also with LPCHC internal interrupt - * sources) and outputs a single line that raises the PSI LPCHC irq - * which then latches an OPB IRQ status register that sends the irq - * to PSI. - * - * We don't honor the polarity register, it's pointless and unused - * anyway - */ - if (active_irqs) { - lpc->opb_irq_input |= OPB_MASTER_IRQ_LPC; - } else { - lpc->opb_irq_input &= ~OPB_MASTER_IRQ_LPC; - } - - /* Update OPB internal latch */ - lpc->opb_irq_stat |= lpc->opb_irq_input & lpc->opb_irq_mask; - - qemu_set_irq(lpc->psi_irq_lpchc, lpc->opb_irq_stat != 0); - } else { + if (lpc->psi_has_serirq) { /* - * POWER9 and POWER10 have routing fields in OPB master registers that + * POWER9 and later have routing fields in OPB master registers that * send LPC irqs to 4 output lines that raise the PSI SERIRQ irqs. * These don't appear to get latched into an OPB register like the * LPCHC irqs. - * - * POWER9 LPC controller internal irqs still go via the OPB - * and LPCHC PSI irqs like P8, but we have no such internal sources - * modelled yet. */ bool serirq_out[4] = { false, false, false, false }; int irq; @@ -510,7 +482,33 @@ static void pnv_lpc_eval_irqs(PnvLpcController *lpc) qemu_set_irq(lpc->psi_irq_serirq[1], serirq_out[1]); qemu_set_irq(lpc->psi_irq_serirq[2], serirq_out[2]); qemu_set_irq(lpc->psi_irq_serirq[3], serirq_out[3]); + + /* + * POWER9 and later LPC controller internal irqs still go via the OPB + * and LPCHC PSI irqs like P8, so take the SERIRQs out and continue. + */ + active_irqs &= ~LPC_HC_IRQ_SERIRQ_ALL; + } + + /* + * POWER8 ORs all irqs together (also with LPCHC internal interrupt + * sources) and outputs a single line that raises the PSI LPCHC irq + * which then latches an OPB IRQ status register that sends the irq + * to PSI. + * + * We don't honor the polarity register, it's pointless and unused + * anyway + */ + if (active_irqs) { + lpc->opb_irq_input |= OPB_MASTER_IRQ_LPC; + } else { + lpc->opb_irq_input &= ~OPB_MASTER_IRQ_LPC; } + + /* Update OPB internal latch */ + lpc->opb_irq_stat |= lpc->opb_irq_input & lpc->opb_irq_mask; + + qemu_set_irq(lpc->psi_irq_lpchc, lpc->opb_irq_stat != 0); } static uint64_t lpc_hc_read(void *opaque, hwaddr addr, unsigned size) From patchwork Tue Mar 11 12:57:12 2025 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Nicholas Piggin X-Patchwork-Id: 14011803 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.lore.kernel.org (Postfix) with ESMTPS id B781FC35FF1 for ; Tue, 11 Mar 2025 13:06:03 +0000 (UTC) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1trzE5-0004xf-Rw; Tue, 11 Mar 2025 09:00:55 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1trzCn-0002JI-Ku; Tue, 11 Mar 2025 08:59:34 -0400 Received: from mail-pj1-x102c.google.com ([2607:f8b0:4864:20::102c]) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_128_GCM_SHA256:128) (Exim 4.90_1) (envelope-from ) id 1trzCi-0007y9-Dm; Tue, 11 Mar 2025 08:59:33 -0400 Received: by mail-pj1-x102c.google.com with SMTP id 98e67ed59e1d1-2ff6e91cff5so7757705a91.2; Tue, 11 Mar 2025 05:59:27 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20230601; t=1741697966; x=1742302766; darn=nongnu.org; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to; bh=EhoSht0TisSg7cbroKzPBDpRepZ7Wrpxv0wxqbEmqv4=; b=initoQA76VoLv+MXY1mw1KGCP1UENAMazhjLvxhU5wXEMC417+RliIbiM5T9KvYIV3 kPDop2eGCeV5ARimT90YLTeWaPYuAHS1emozpo2Um0cCviirGf9Dr5m03vsMn6MJ7UpU SO3yalhN1s+gGHWY1UMVtL8VJKaMTd6I1OE5Q0PTRz8lJtp70OaLOI6Mpb3WtYj7HO/0 YugE4+34B0m4DIjnNuZ7lEM7JvIai97/mIaNhumFqJHVAm3hAWtGecBFHLL4Fex963o1 nZO9jKc1XSPeLBe3CsO4mOEcuUYDwTCoh+JILm0fgHEg8+mfO2EyHL0OM6CebTmXCn2M WysQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1741697966; x=1742302766; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=EhoSht0TisSg7cbroKzPBDpRepZ7Wrpxv0wxqbEmqv4=; b=JY8MTl2cwBBfud+6MApVDd3c89ZO/fK3NzgMlD7JhvI3SY72qPDBBDJKzKcwCM9bSe ji6bhWbghp3p1cT1hFbU59n7yhB/CUdxR9ezmb98fQwxAdfVQinUVoWd0JNwUmoxAgSN 8MPQ1o+XRyvxeSlUu1loauL+gKVX/5fmtwOFa3d3v3hmL1qhvsxAHOJ7AfYzGJzxz5AO bBhJu2ipHzIsr1o3B1oAxK5JpQiimh66EJOXJFo3y20q6wu7Uv3KcebNaDLUnQwSOSxf /gQf40NgjvmoQ3H0zDmxlcjVYhNFEAadrixKGZNroSDMs7jjg1nPAE740FS5SCoZYXVZ Za3A== X-Forwarded-Encrypted: i=1; AJvYcCWo7YXE0OEmW5SRtZ6xfes+ZBrAU97z/3/edC3g9WQ44A1YXY/uK2bWSkeVV6NYxXh+0lZ4I0ziKQ==@nongnu.org X-Gm-Message-State: AOJu0Yyfs7GR4bQnM+bBsZ6vn8j0JqkMCyxYDvxWXdl0zH6vlzA+bxZM gzwL+NzSOx76ZgMxW/kOGlAqazwPxUGBYHRFpwP5HY87eANQCsfmrDBesA== X-Gm-Gg: ASbGncs7H321GTd2zMMUzcAYPOyf/YRluCSAd0TS9nWrx2lU9Z68GbEZxABR29YuqP0 8WE6+Atf5672gKaOryI7ODbv7gLksV0CiGK8R191aTVxirQRyGwh2SUz2EmNEvL6xPnE/22z/yU KRwk/mymB1LkWcLqKdo7hTn2yZwD5TyNaZ5kO/dpl6CR1638NVQSDMe3WEteBXl2hWCN9yXQb/u E3y9MQQ9r7G06n2YdFPjhLgL7qNJjCyaf4jGVLETWPIeZISw9i4JjPqEmwRVeDfspJFOdiih3p3 ekE64ppPQdAW9ATxvCO8zIM6+TQfKsfVu9LimNt1ONw1FuY1yOU= X-Google-Smtp-Source: AGHT+IFMIafJM2wQ6gch2cDeaw1K/Ib/xE2lL58g/EsLcp2EJihtrxyjeceWntpOYYS9OTkpwwA6Qg== X-Received: by 2002:a17:90b:180b:b0:2ff:5357:1c7f with SMTP id 98e67ed59e1d1-2ff7cf3d0bfmr23969660a91.30.1741697965689; Tue, 11 Mar 2025 05:59:25 -0700 (PDT) Received: from wheely.local0.net ([118.208.151.101]) by smtp.gmail.com with ESMTPSA id 98e67ed59e1d1-2ff4e773dddsm11822318a91.12.2025.03.11.05.59.23 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 11 Mar 2025 05:59:25 -0700 (PDT) From: Nicholas Piggin To: qemu-devel@nongnu.org Cc: Nicholas Piggin , qemu-ppc@nongnu.org Subject: [PULL 18/72] ppc/pnv: raise no-response errors if an LPC transaction fails Date: Tue, 11 Mar 2025 22:57:12 +1000 Message-ID: <20250311125815.903177-19-npiggin@gmail.com> X-Mailer: git-send-email 2.47.1 In-Reply-To: <20250311125815.903177-1-npiggin@gmail.com> References: <20250311125815.903177-1-npiggin@gmail.com> MIME-Version: 1.0 Received-SPF: pass client-ip=2607:f8b0:4864:20::102c; envelope-from=npiggin@gmail.com; helo=mail-pj1-x102c.google.com X-Spam_score_int: -16 X-Spam_score: -1.7 X-Spam_bar: - X-Spam_report: (-1.7 / 5.0 requ) BAYES_00=-1.9, DKIM_INVALID=0.1, DKIM_SIGNED=0.1, FREEMAIL_FROM=0.001, RCVD_IN_DNSWL_NONE=-0.0001, SPF_HELO_NONE=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.29 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: qemu-devel-bounces+qemu-devel=archiver.kernel.org@nongnu.org Sender: qemu-devel-bounces+qemu-devel=archiver.kernel.org@nongnu.org If nothing responds to an LPC access, the LPC host controller should set an IRQSTAT error. Model this behaviour. skiboot uses this error to "probe" LPC accesses, among other things to determine if a SuperIO chip is present. After this change it recognizes there is no SuperIO present and does not keep trying to access it. Signed-off-by: Nicholas Piggin --- hw/ppc/pnv_lpc.c | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/hw/ppc/pnv_lpc.c b/hw/ppc/pnv_lpc.c index d0fccc165d..0e02ce6e94 100644 --- a/hw/ppc/pnv_lpc.c +++ b/hw/ppc/pnv_lpc.c @@ -353,6 +353,8 @@ static const MemoryRegionOps pnv_lpc_xscom_ops = { .endianness = DEVICE_BIG_ENDIAN, }; +static void pnv_lpc_opb_noresponse(PnvLpcController *lpc); + static uint64_t pnv_lpc_mmio_read(void *opaque, hwaddr addr, unsigned size) { PnvLpcController *lpc = PNV_LPC(opaque); @@ -376,6 +378,7 @@ static uint64_t pnv_lpc_mmio_read(void *opaque, hwaddr addr, unsigned size) } if (result != MEMTX_OK) { + pnv_lpc_opb_noresponse(lpc); qemu_log_mask(LOG_GUEST_ERROR, "OPB read failed at @0x%" HWADDR_PRIx "\n", addr); } @@ -406,6 +409,7 @@ static void pnv_lpc_mmio_write(void *opaque, hwaddr addr, } if (result != MEMTX_OK) { + pnv_lpc_opb_noresponse(lpc); qemu_log_mask(LOG_GUEST_ERROR, "OPB write failed at @0x%" HWADDR_PRIx "\n", addr); } @@ -511,6 +515,12 @@ static void pnv_lpc_eval_irqs(PnvLpcController *lpc) qemu_set_irq(lpc->psi_irq_lpchc, lpc->opb_irq_stat != 0); } +static void pnv_lpc_opb_noresponse(PnvLpcController *lpc) +{ + lpc->lpc_hc_irqstat |= LPC_HC_IRQ_SYNC_NORESP_ERR; + pnv_lpc_eval_irqs(lpc); +} + static uint64_t lpc_hc_read(void *opaque, hwaddr addr, unsigned size) { PnvLpcController *lpc = opaque; From patchwork Tue Mar 11 12:57:13 2025 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Nicholas Piggin X-Patchwork-Id: 14011788 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.lore.kernel.org (Postfix) with ESMTPS id 07C78C28B30 for ; Tue, 11 Mar 2025 13:00:19 +0000 (UTC) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1trzCw-0002sJ-T9; Tue, 11 Mar 2025 08:59:42 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1trzCs-0002al-2B; Tue, 11 Mar 2025 08:59:38 -0400 Received: from mail-pj1-x1031.google.com ([2607:f8b0:4864:20::1031]) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_128_GCM_SHA256:128) (Exim 4.90_1) (envelope-from ) id 1trzCm-0007yt-HY; Tue, 11 Mar 2025 08:59:37 -0400 Received: by mail-pj1-x1031.google.com with SMTP id 98e67ed59e1d1-2ff6ae7667dso10225697a91.0; Tue, 11 Mar 2025 05:59:30 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20230601; t=1741697968; x=1742302768; darn=nongnu.org; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to; bh=LWFZ3hhh+CauKRhvgamT4Y6yPpw/m5EE+YXGOVXnowQ=; b=fukWU700sv3SNmaskwEv76wTHdATqZeKREVlH2wOHCLLSG97Y96uRFJy62Yu4g+VTS 2YVN8WO/E2rCsyIyE2H0iurdzLzpF7I5YuwfilxIJqm9AemjKXL7vy8mZMnbNee/OxKn aycwd8/qz+AdRWZDwzCaeHlGTiTv7GvYqgNkllU1X/Ge1ou92xqyEJ0t3mTocq3h3a58 eMvrNRArneccI/ZgqES3jntZeLkkurad1aw1VIP4HTFjOfaoCSITOEWenAH2/TWskr3b dh8p/dTBrhkheYBzHnZflsZg4ZTbRCx+l3E0VNalr49hItvaUyKK9b0i2RmVBGIeSbIM i+Lg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1741697968; x=1742302768; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=LWFZ3hhh+CauKRhvgamT4Y6yPpw/m5EE+YXGOVXnowQ=; b=uBAMDKPTrwwNkw3Efj+1IBkcb7guISZFW9Gz3AQ2QJIasRlffo6pdKVJ4aFxbYfbF3 tMlKrv4FOLN8kws9LWhmCQuJQeEm2Q59om4sH9cQvzjgpgYnpbZCKVGt2xKerRl9s/O0 VSRqOg5Pitvoj6W5nM+IzrGW/B55dT2JzDtKS33x4VPR6YtF1vtqJ5LxcIQ3//KBgR7o 2uYDhev8Zz+e1XkabLMQENgVlWymva8EltNd+JNXBbEacbo7eSnXNkE8D86/EpqovYf1 iQyRtgsH6fL/lQk1/yAZdQJ/+TJnKSMGu8BGoREPvN9Wz+Jtnzmgq/Pru5ndrS3/q/lj 3wug== X-Forwarded-Encrypted: i=1; AJvYcCWjUt8OkxvbDrQzWrmZ28u6DUlo9sOpM47KKXUSWin8hRr88g2u51eFYqZISHAMVetBsDCjxbqDzA==@nongnu.org X-Gm-Message-State: AOJu0YwucRyzJJxjZpyffyVjD1xVq2wG3HuhE/DVLkKhtQoB5v2n4Cwx eK2ViLErR5P6dmoKhnfoud7A95Gymqltu+gKE37CU5V+HE1Juv+FROxSvQ== X-Gm-Gg: ASbGnctPNuIyeKmTwUn4HvbOvCl6DcYxKiarciQLkrp8jyt39oGgv7Gk03zP3d8yvMj qPrKDJ0dnfz460rN9yYhm5Ru1/SK5W0HFvVPlNPjZFndHOmCGFkqEQnm8D+j3iqkHtBlc9VuKew 086AlX+KuXkcfRDQCNIFYAEMVpGs7OsUBrdg2SKsVlHVJyszTimAsdcWecg90lAPTLVK9TXwxIz vs2ktslWBswAfqoDQdJ3h/fqtou+OUxy5nJv/sZrqFaMbQNfYBwqy1C2Wl+qpmmACqZ0WhutISJ bCbMd0RStBe4CyXg8vbRgMo45bH2OewZ7mFLKdE51ulz0oim7Ys= X-Google-Smtp-Source: AGHT+IGsmLnQ5nuz1baaSGWshuiCQAoKQNb38fSHNEUxPj5+z+qFuI1Qmib2l92ftTxdSaro4tuzNw== X-Received: by 2002:a17:90b:3c08:b0:2fc:3264:3657 with SMTP id 98e67ed59e1d1-2ff7cd45c1cmr32797426a91.0.1741697968252; Tue, 11 Mar 2025 05:59:28 -0700 (PDT) Received: from wheely.local0.net ([118.208.151.101]) by smtp.gmail.com with ESMTPSA id 98e67ed59e1d1-2ff4e773dddsm11822318a91.12.2025.03.11.05.59.26 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 11 Mar 2025 05:59:27 -0700 (PDT) From: Nicholas Piggin To: qemu-devel@nongnu.org Cc: Nicholas Piggin , qemu-ppc@nongnu.org Subject: [PULL 19/72] ppc/pnv: Implement LPC FW address space IDSEL Date: Tue, 11 Mar 2025 22:57:13 +1000 Message-ID: <20250311125815.903177-20-npiggin@gmail.com> X-Mailer: git-send-email 2.47.1 In-Reply-To: <20250311125815.903177-1-npiggin@gmail.com> References: <20250311125815.903177-1-npiggin@gmail.com> MIME-Version: 1.0 Received-SPF: pass client-ip=2607:f8b0:4864:20::1031; envelope-from=npiggin@gmail.com; helo=mail-pj1-x1031.google.com X-Spam_score_int: -20 X-Spam_score: -2.1 X-Spam_bar: -- X-Spam_report: (-2.1 / 5.0 requ) BAYES_00=-1.9, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_AU=-0.1, DKIM_VALID_EF=-0.1, FREEMAIL_FROM=0.001, RCVD_IN_DNSWL_NONE=-0.0001, SPF_HELO_NONE=0.001, SPF_PASS=-0.001 autolearn=ham autolearn_force=no X-Spam_action: no action X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: qemu-devel-bounces+qemu-devel=archiver.kernel.org@nongnu.org Sender: qemu-devel-bounces+qemu-devel=archiver.kernel.org@nongnu.org LPC FW address space is a 256MB (28-bit) region to one of 16-devices that are selected with the IDSEL register. Implement this by making the ISA FW address space 4GB, and move the 256MB OPB alias within that space according to IDSEL. Signed-off-by: Nicholas Piggin --- hw/ppc/pnv_lpc.c | 15 +++++++++------ 1 file changed, 9 insertions(+), 6 deletions(-) diff --git a/hw/ppc/pnv_lpc.c b/hw/ppc/pnv_lpc.c index 0e02ce6e94..d812dc8268 100644 --- a/hw/ppc/pnv_lpc.c +++ b/hw/ppc/pnv_lpc.c @@ -85,7 +85,7 @@ enum { #define ISA_IO_SIZE 0x00010000 #define ISA_MEM_SIZE 0x10000000 -#define ISA_FW_SIZE 0x10000000 +#define ISA_FW_SIZE 0x100000000 #define LPC_IO_OPB_ADDR 0xd0010000 #define LPC_IO_OPB_SIZE 0x00010000 #define LPC_MEM_OPB_ADDR 0xe0000000 @@ -561,10 +561,13 @@ static void lpc_hc_write(void *opaque, hwaddr addr, uint64_t val, switch (addr) { case LPC_HC_FW_SEG_IDSEL: - /* XXX Actually figure out how that works as this impact - * memory regions/aliases + /* + * ISA FW "devices" are modeled as 16x256MB windows into a + * 4GB LPC FW address space. */ + val &= 0xf; /* Selects device 0-15 */ lpc->lpc_hc_fw_seg_idsel = val; + memory_region_set_alias_offset(&lpc->opb_isa_fw, val * LPC_FW_OPB_SIZE); break; case LPC_HC_FW_RD_ACC_SIZE: lpc->lpc_hc_fw_rd_acc_size = val; @@ -798,9 +801,9 @@ static void pnv_lpc_realize(DeviceState *dev, Error **errp) memory_region_init(&lpc->opb_mr, OBJECT(dev), "lpc-opb", 0x100000000ull); address_space_init(&lpc->opb_as, &lpc->opb_mr, "lpc-opb"); - /* Create ISA IO and Mem space regions which are the root of - * the ISA bus (ie, ISA address spaces). We don't create a - * separate one for FW which we alias to memory. + /* + * Create ISA IO, Mem, and FW space regions which are the root of + * the ISA bus (ie, ISA address spaces). */ memory_region_init(&lpc->isa_io, OBJECT(dev), "isa-io", ISA_IO_SIZE); memory_region_init(&lpc->isa_mem, OBJECT(dev), "isa-mem", ISA_MEM_SIZE); From patchwork Tue Mar 11 12:57:14 2025 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Nicholas Piggin X-Patchwork-Id: 14011904 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.lore.kernel.org (Postfix) with ESMTPS id 25D60C282EC for ; Tue, 11 Mar 2025 13:28:29 +0000 (UTC) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1trzCs-0002ay-AQ; Tue, 11 Mar 2025 08:59:38 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1trzCp-0002Me-LP; Tue, 11 Mar 2025 08:59:35 -0400 Received: from mail-pj1-x102c.google.com ([2607:f8b0:4864:20::102c]) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_128_GCM_SHA256:128) (Exim 4.90_1) (envelope-from ) id 1trzCm-0007zb-UQ; Tue, 11 Mar 2025 08:59:35 -0400 Received: by mail-pj1-x102c.google.com with SMTP id 98e67ed59e1d1-2feb91a2492so9002926a91.2; Tue, 11 Mar 2025 05:59:31 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20230601; t=1741697971; x=1742302771; darn=nongnu.org; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to; bh=m8Jod93+icdv8DpO8jgqQJRsTJBpt3ebVNZMdW9CDpM=; b=FOqGKn5ZTMB6LtxA2elPNehgwIwZ2DKVFlrxF0MLK3ytnJt2pZxQWwhkfM2ddicQck +/UgyRtnuWiuxUTdAZxaWPDSjsAzZyo3j8FetMS8N/HQcGF3r8YrtFFvCY4HrawQS+oP pzf30hhmy1k0NU/VLcfyUXk+0SI/iJRAyIaHl/My9kJoaZhDiXq+vCtc+UQS9UgggCQp FxLLtpf4jy0JM6IpLl5AaKkM3HFIfh4bGkK1osHQGmcCg//pWmnZzFOTXDY8KZ2yjuGr PGPsYXyF5eAoL8oNfxbQJ6SR17+iY3hzi0fEE2gmCYXg1nBmEdq9+GMCQIa8dW3mVXXn NLdA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1741697971; x=1742302771; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=m8Jod93+icdv8DpO8jgqQJRsTJBpt3ebVNZMdW9CDpM=; b=MnRRUATcCz1WwXMlZimADK3xuPQeV7a69kIHhZ1btvxJ/AJdqrKMCcRtqAt7CqwqE5 WH8bUctId4rjyR3FVp6VNbfqKxE01mMeDebd1RoQRR/Hw+fBK+zm1R2m332l19F1sNOs G0wQH313+sEtanXvyGtCnf5/nCaEDW3TisYrtNJ/SV/3MO4UFWihUqgHILhCgya4+UC1 1z+Sid8Nn4fKdIbhxEh6icRKBtm1Wf/6UTMQeHzrDxSod4U14AQUEMNPr7A6XtzKDE6w NlhX8wAbJHw3k0yAmlutar4JBmjylkDP9EbmOaJG1nSDlQ8hCgYdROzcA05enFm+xC/j +HZQ== X-Forwarded-Encrypted: i=1; AJvYcCWNbDdxa/PpPCemZWrBSFlkkMkN9bYfvMC6Ynr+V13DEnl1I29ZwMvwYos8RP6m5KJ9PbLEwm/RLA==@nongnu.org X-Gm-Message-State: AOJu0Yw9qB3eP02wEqgCN9n5d1ze1G4TC4xVDn1HPtn1VjPcqF+2w4sZ KTT1ur3Pr+mFKFHtyc1YgtnfhlQY+mhKbKRMOhpX/WkVj9OlsWzAFMk8Cg== X-Gm-Gg: ASbGnctwd8dpVsU7yBofkZJEcSjJfM7sQdVUTkfn+JVTQ9Os9fQkicCcuzYCRHiXQmh GptwbUg+Vl1LoUjRjDWupq15avtcyooWybCtz/mXipIuU38YU0Hpeg8CwYj8tlzbb/HEU7AkFbT 7IHHT3KQmcfvfanzrR0rPWWWiCYptv8jT3GhhTBe0XDcSVzlshD+VphBmelmxfAJdv3CA/99uwL N8PKLNsS9/qFB9/1egc32Zgw+fzNMzP/QPVrJlXAu56qhEyf0/VNCSu5TRDu9WuP4xNeTGpOkBm QCdrtyOgvJw5Gju1Qo6019pmqLsuI4/zm+7EjSUymJn7g3Why2o= X-Google-Smtp-Source: AGHT+IFai/yXZpdJFENUX4ZlQiWu7uBV1XuOa5w5Wuj2R2Iud8fxrRxjN9JaeR87R9XhpZ+WRNJ6OA== X-Received: by 2002:a17:90a:d44c:b0:2ff:6488:e026 with SMTP id 98e67ed59e1d1-2ff7cf26d18mr24494146a91.30.1741697970645; Tue, 11 Mar 2025 05:59:30 -0700 (PDT) Received: from wheely.local0.net ([118.208.151.101]) by smtp.gmail.com with ESMTPSA id 98e67ed59e1d1-2ff4e773dddsm11822318a91.12.2025.03.11.05.59.28 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 11 Mar 2025 05:59:30 -0700 (PDT) From: Nicholas Piggin To: qemu-devel@nongnu.org Cc: Nicholas Piggin , qemu-ppc@nongnu.org Subject: [PULL 20/72] ppc/pnv: Move PNOR to offset 0 in the ISA FW space Date: Tue, 11 Mar 2025 22:57:14 +1000 Message-ID: <20250311125815.903177-21-npiggin@gmail.com> X-Mailer: git-send-email 2.47.1 In-Reply-To: <20250311125815.903177-1-npiggin@gmail.com> References: <20250311125815.903177-1-npiggin@gmail.com> MIME-Version: 1.0 Received-SPF: pass client-ip=2607:f8b0:4864:20::102c; envelope-from=npiggin@gmail.com; helo=mail-pj1-x102c.google.com X-Spam_score_int: -20 X-Spam_score: -2.1 X-Spam_bar: -- X-Spam_report: (-2.1 / 5.0 requ) BAYES_00=-1.9, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_AU=-0.1, DKIM_VALID_EF=-0.1, FREEMAIL_FROM=0.001, RCVD_IN_DNSWL_NONE=-0.0001, SPF_HELO_NONE=0.001, SPF_PASS=-0.001 autolearn=ham autolearn_force=no X-Spam_action: no action X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: qemu-devel-bounces+qemu-devel=archiver.kernel.org@nongnu.org Sender: qemu-devel-bounces+qemu-devel=archiver.kernel.org@nongnu.org skiboot has a bug that does not handle ISA FW access correctly for IDSEL devices > 0, and the current PNOR default address and size puts 64MB in device 0 and 64MB in device 1, which causes skiboot to hit this bug and breaks PNOR accesses. Move the PNOR address down to 0 for now, so a 256MB PNOR can be accessed via device 0. Signed-off-by: Nicholas Piggin --- include/hw/ppc/pnv_pnor.h | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/include/hw/ppc/pnv_pnor.h b/include/hw/ppc/pnv_pnor.h index 2e37ac88bf..19c2d642e8 100644 --- a/include/hw/ppc/pnv_pnor.h +++ b/include/hw/ppc/pnv_pnor.h @@ -13,9 +13,11 @@ #include "hw/sysbus.h" /* - * PNOR offset on the LPC FW address space + * PNOR offset on the LPC FW address space. For now this should be 0 because + * skiboot 7.1 has a bug where IDSEL > 0 (LPC FW address > 256MB) access is + * not performed correctly. */ -#define PNOR_SPI_OFFSET 0x0c000000UL +#define PNOR_SPI_OFFSET 0x00000000UL #define TYPE_PNV_PNOR "pnv-pnor" OBJECT_DECLARE_SIMPLE_TYPE(PnvPnor, PNV_PNOR) From patchwork Tue Mar 11 12:57:15 2025 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Nicholas Piggin X-Patchwork-Id: 14011793 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.lore.kernel.org (Postfix) with ESMTPS id 7F5C5C28B30 for ; Tue, 11 Mar 2025 13:01:00 +0000 (UTC) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1trzD0-0003L3-Eu; Tue, 11 Mar 2025 08:59:46 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1trzCv-0002mS-K6; Tue, 11 Mar 2025 08:59:41 -0400 Received: from mail-pj1-x1030.google.com ([2607:f8b0:4864:20::1030]) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_128_GCM_SHA256:128) (Exim 4.90_1) (envelope-from ) id 1trzCq-000800-OP; Tue, 11 Mar 2025 08:59:41 -0400 Received: by mail-pj1-x1030.google.com with SMTP id 98e67ed59e1d1-2ff187f027fso9043672a91.1; Tue, 11 Mar 2025 05:59:34 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20230601; t=1741697973; x=1742302773; darn=nongnu.org; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to; bh=G3M6o0HCxEonBIrEgIZJkSZItGG16Roe3OW9YD7vpN8=; b=mcPIO5HWu1+gRkFBq7e0+6pUgR2AHD7TcKKMkT9aHlPdpqRgihTj+Fj9iy5pXxSC6c 02Ioc/nytzelHle1AFRLOmIFX7iMbsTO9fMidqDTgAZlb1n3rQEigKo4bIVPw0GwCml6 KCmIaugBGHlKKwMMU8lGpKPfQbhu0V0SfcaS7d3doEl0MljDTDA3zhS2YB97GnrjtzJa HrYisApPxowVb0Dh7kmuAKzJZOSkyG6czPrfLFMry88IQB5ES5kUEZdcxhUvcETPSOr9 ot0llz34OyvnABsPnIvpb+jVIsfVXVPaxSPjuz+NTkTDHVwqxGSXkUKptRHEi3Z2a16m XQfg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1741697973; x=1742302773; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=G3M6o0HCxEonBIrEgIZJkSZItGG16Roe3OW9YD7vpN8=; b=vM5lYU71nG8XynKpfNd6ZGSb5TzuPmb+LO01bc/oDG5sEPmiMmBb1WusEUtKBxAcuL nLrYbcxs286e4E+wqFSSn6t1aQ4Tce7ZDGpoT4aEiBm82hAZgrG9S9PlGfCZjQ3fZa3X GKUDnYqzhk0CpL8r9izPVPamkCwWqsH9DKOCwMRxQ9HPHBXZazpz5Jb6oV3iSgjvGs6R EFNTVvLWZrIkj8m79CBVxyEQkA+Ly1v+XKDNEedX8T/9/ADU22Tn0pxeX42SE/878Ahn QUvAIZLp0LQVxdOquFSWRjNIrUIDPPjfPRe7wWfatgLFSrudduaQl73gysyb32K1SFwd Ob/g== X-Forwarded-Encrypted: i=1; AJvYcCWGEqRiMMBgpwycSYwDd7aqJ0O50+p408gqjhl9fpZ+e/hmuvE16hCUA2+E+EJr07dEDyk1VMba5A==@nongnu.org X-Gm-Message-State: AOJu0YxUEK/4VUm0QS2obXZViKzgHFgzb+SDLytN8ObR68r96gmh/hEG rog5v6u7HLKmQFfAt8h1FFcUdGa9Qo4lDcigdBIHkzJwpf6l1Am5ToG9GQ== X-Gm-Gg: ASbGnctq0jjEAXUXCT4Aq1GIQFXOtdfqpnWeFSwxw1wvjf/M6l9fv2emxHfIRTKAa4v zskoet/LE8KxvONmej2N+EO65/nqP9pPM9mn0k5SgZ1XAyFxDDUJdt7IyjGxhcgx5EJ687WM2kS 0ES3qo76nM+3lKYXu+JkCkkZrTRjZNFptZrlXt8AMkpwPTM0DBnzki9b6J41RT3/lPAOkutmbRj Md1PbRC6f/WI70lk5mTQtX58fSRyuzP9FvQkr1+iyADZbXR22omWCG9SnIdkF9wNJ3nu/96unWZ iqUoJXvgQ/v0wG87wMtQ6ywbCS8Ncth5wbW2E7egvTX+0IvrzX8= X-Google-Smtp-Source: AGHT+IGpJ3Abqlt0qCxF/qLDb513LeEuMoZaNufLaAoM4DtPXII8Mv+lZIYo9Iq2Puj/vACSovGHVw== X-Received: by 2002:a17:90b:5403:b0:2fa:1e56:5d82 with SMTP id 98e67ed59e1d1-301005782bbmr4506063a91.17.1741697973002; Tue, 11 Mar 2025 05:59:33 -0700 (PDT) Received: from wheely.local0.net ([118.208.151.101]) by smtp.gmail.com with ESMTPSA id 98e67ed59e1d1-2ff4e773dddsm11822318a91.12.2025.03.11.05.59.31 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 11 Mar 2025 05:59:32 -0700 (PDT) From: Nicholas Piggin To: qemu-devel@nongnu.org Cc: Nicholas Piggin , qemu-ppc@nongnu.org Subject: [PULL 21/72] ppc/pnv: Add a PNOR address and size sanity checks Date: Tue, 11 Mar 2025 22:57:15 +1000 Message-ID: <20250311125815.903177-22-npiggin@gmail.com> X-Mailer: git-send-email 2.47.1 In-Reply-To: <20250311125815.903177-1-npiggin@gmail.com> References: <20250311125815.903177-1-npiggin@gmail.com> MIME-Version: 1.0 Received-SPF: pass client-ip=2607:f8b0:4864:20::1030; envelope-from=npiggin@gmail.com; helo=mail-pj1-x1030.google.com X-Spam_score_int: -20 X-Spam_score: -2.1 X-Spam_bar: -- X-Spam_report: (-2.1 / 5.0 requ) BAYES_00=-1.9, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_AU=-0.1, DKIM_VALID_EF=-0.1, FREEMAIL_FROM=0.001, RCVD_IN_DNSWL_NONE=-0.0001, SPF_HELO_NONE=0.001, SPF_PASS=-0.001 autolearn=ham autolearn_force=no X-Spam_action: no action X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: qemu-devel-bounces+qemu-devel=archiver.kernel.org@nongnu.org Sender: qemu-devel-bounces+qemu-devel=archiver.kernel.org@nongnu.org The BMC HIOMAP PNOR access protocol has certain limits on PNOR addresses and sizes. Add some sanity checks for these so we don't get strange behaviour. Signed-off-by: Nicholas Piggin --- hw/ppc/pnv_bmc.c | 28 ++++++++++++++++++++++++++++ 1 file changed, 28 insertions(+) diff --git a/hw/ppc/pnv_bmc.c b/hw/ppc/pnv_bmc.c index 0c1274df21..811ba3d7a4 100644 --- a/hw/ppc/pnv_bmc.c +++ b/hw/ppc/pnv_bmc.c @@ -251,10 +251,38 @@ static const IPMINetfn hiomap_netfn = { void pnv_bmc_set_pnor(IPMIBmc *bmc, PnvPnor *pnor) { + uint32_t pnor_size = pnor->size; + uint32_t pnor_addr = PNOR_SPI_OFFSET; + if (!pnv_bmc_is_simulator(bmc)) { return; } + /* + * The HIOMAP protocol uses block units and 16-bit addressing. + * Prevent overflow or misalign. + */ + if (pnor_addr >= 1U << (BLOCK_SHIFT + 16)) { + warn_report("PNOR address is larger than 2^%d, disabling PNOR", + BLOCK_SHIFT + 16); + return; + } + if (pnor_addr & ((1U << BLOCK_SHIFT) - 1)) { + warn_report("PNOR address is not aligned to 2^%d, disabling PNOR", + BLOCK_SHIFT); + return; + } + if (pnor_size > 1U << (BLOCK_SHIFT + 16)) { + warn_report("PNOR size is larger than 2^%d, disabling PNOR", + BLOCK_SHIFT + 16); + return; + } + if (pnor_size & ((1U << BLOCK_SHIFT) - 1)) { + warn_report("PNOR size is not aligned to 2^%d, disabling PNOR", + BLOCK_SHIFT); + return; + } + object_ref(OBJECT(pnor)); object_property_add_const_link(OBJECT(bmc), "pnor", OBJECT(pnor)); From patchwork Tue Mar 11 12:57:16 2025 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Nicholas Piggin X-Patchwork-Id: 14011822 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.lore.kernel.org (Postfix) with ESMTPS id 897BEC28B30 for ; Tue, 11 Mar 2025 13:11:04 +0000 (UTC) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1trzFT-0006Rx-Go; Tue, 11 Mar 2025 09:02:20 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1trzCw-0002rK-Mw; Tue, 11 Mar 2025 08:59:42 -0400 Received: from mail-pj1-x102a.google.com ([2607:f8b0:4864:20::102a]) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_128_GCM_SHA256:128) (Exim 4.90_1) (envelope-from ) id 1trzCr-00080X-RV; Tue, 11 Mar 2025 08:59:42 -0400 Received: by mail-pj1-x102a.google.com with SMTP id 98e67ed59e1d1-2ff6e91cff5so7757955a91.2; Tue, 11 Mar 2025 05:59:37 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20230601; t=1741697976; x=1742302776; darn=nongnu.org; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to; bh=qsdA+qlvH8AULZPbvQGBXuXcb6N6318CN6Tmz9++ciM=; b=MYHb8kxyHNMa/Y5ypl1HSou/va667OPih0HOEPxp7RxbvEAaSJfVRIhyEBURAc06Mj dejyM9p8fRKg2xqyldtDHqtHJ6UNsO8BN6sMKhevf/i2huV3QY+Zl4m/NqHEZ+GOMe0n a0A4efIVzSw5H7IyNGr98Nj14SwnLHTH+a4D/M8H8JNF3nEl2V1NGZTlbJNq7KLdv2Mg cXSxSARzBlcBt3mSdPQmftjEOVMpEw/a8e4Ua0v8YQCTmmDRP0pWNY/6kNbePb9uq5tB fURoRh8bKasQyTbyLjr1vtIGI7NI+I5+ag/xcNOFx1BI/TnlkynXpi0WjiXnbn1Ar9sj uedQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1741697976; x=1742302776; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=qsdA+qlvH8AULZPbvQGBXuXcb6N6318CN6Tmz9++ciM=; b=rKkCzKlg914RLSJHFRhaDlX+cNgWMbsysDc7e2eYjtxyTTP08sDO1k7TexPNfbuuwk xsNNNdrkrxY1ZNIvOolO+vTy93IzIcndTaS+4SbwH7c5/d67uOVKrr1GmTa5kfY7oqN2 xcxeONTCMruJvXKBLwtSEnWVBcAHE6YsNiF3Yxas+PMNKRjyCJYUlR0MgXscTkFsCEMO 0Fx+73q6GbAdX82ZSsxlkSV0b0EQtMy9Tn/TErc+U4ECQH9slTsp+kwfupSaMxihHZnA WCVuQ3pk0TtHllrvsr3hVWWMLaOJSLD2TwXB/kQejt0UuteAiipY5mRLO0E+OkfjvEky FU0Q== X-Forwarded-Encrypted: i=1; AJvYcCXesdo2DZi/WggnUyBBoYyHyCrMmiExu8KFkr3g2gk+tS6U7BU0Fbfi3A8khTtgr8uYxUbwIp4Yzw==@nongnu.org X-Gm-Message-State: AOJu0YxCHRlG9NcQLmbExLgiJpn1soVMlJR7vrQT8xpCs3uLQOjp8tGB tC78zMakik3gH3nJuWoKcemRwKCqL9VMv/3x9qtc1eTtowrTyPtTGHPhOQ== X-Gm-Gg: ASbGncvrbhwYIokjfblYRnE+RZdQ4catvzdgsADnzuh+15Enw0saSulbR0u9ZPzsleA /XMvekMg97JIc+E3w4ewAvYwhIO4qOYa7nRMHSr2RADndjcFJ4AGPrXdAFU+ZU701FkYyI7sple zNr2c3eP69VG3HKUS83rO7saLs0nD2Co+Yj7KUGYNKfprW0BW/89fcga+W4eRqa7/qEtmhKOHgy 1TDR5hxe+gAauKqGy7e9VrjnE6rU0XeSIvpLVVrRr7c0fgMiG8ss8zExTYjIwtlSVQy/TErCnXq LYK9L413Vfqaz32hqUonAt4gHG02jfGSFpCLDHmjqstgU2JjRl0= X-Google-Smtp-Source: AGHT+IFdLrbNi3hpd6CXUKedD/MwVENAVSC6zHj6ud85qI1ON1jqf9btFYMz7TKa95/80+PCJZyP/A== X-Received: by 2002:a17:90b:3883:b0:2fe:d766:ad8e with SMTP id 98e67ed59e1d1-2ff7ce74e92mr25055771a91.4.1741697975492; Tue, 11 Mar 2025 05:59:35 -0700 (PDT) Received: from wheely.local0.net ([118.208.151.101]) by smtp.gmail.com with ESMTPSA id 98e67ed59e1d1-2ff4e773dddsm11822318a91.12.2025.03.11.05.59.33 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 11 Mar 2025 05:59:35 -0700 (PDT) From: Nicholas Piggin To: qemu-devel@nongnu.org Cc: Nicholas Piggin , qemu-ppc@nongnu.org Subject: [PULL 22/72] ppc/pnv: Add a default formatted PNOR image Date: Tue, 11 Mar 2025 22:57:16 +1000 Message-ID: <20250311125815.903177-23-npiggin@gmail.com> X-Mailer: git-send-email 2.47.1 In-Reply-To: <20250311125815.903177-1-npiggin@gmail.com> References: <20250311125815.903177-1-npiggin@gmail.com> MIME-Version: 1.0 Received-SPF: pass client-ip=2607:f8b0:4864:20::102a; envelope-from=npiggin@gmail.com; helo=mail-pj1-x102a.google.com X-Spam_score_int: -20 X-Spam_score: -2.1 X-Spam_bar: -- X-Spam_report: (-2.1 / 5.0 requ) BAYES_00=-1.9, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_AU=-0.1, DKIM_VALID_EF=-0.1, FREEMAIL_FROM=0.001, RCVD_IN_DNSWL_NONE=-0.0001, SPF_HELO_NONE=0.001, SPF_PASS=-0.001 autolearn=ham autolearn_force=no X-Spam_action: no action X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: qemu-devel-bounces+qemu-devel=archiver.kernel.org@nongnu.org Sender: qemu-devel-bounces+qemu-devel=archiver.kernel.org@nongnu.org The default PNOR image is erased and not recognised by skiboot, so NVRAM gets disabled. This change adds a tiny pnor file that is a proper FFS image with a formatted NVRAM partition. This is recognised by skiboot and will persist across machine reboots. Signed-off-by: Nicholas Piggin --- MAINTAINERS | 1 + docs/system/ppc/powernv.rst | 7 +++++++ hw/ppc/pnv.c | 16 +++++++++++++++- pc-bios/README | 13 +++++++++++++ pc-bios/meson.build | 1 + pc-bios/pnv-pnor.bin | Bin 0 -> 139264 bytes 6 files changed, 37 insertions(+), 1 deletion(-) create mode 100644 pc-bios/pnv-pnor.bin GIT binary patch literal 139264 zcmeI#F-pWh6adg4Z3XuTYGvUiB3M|su2Hsktrl6cs9>qBjb1>#fLMAT?;zU=IwKJx z*a&F???dwcWXPYH*UhM`jv}IHo|}}HBL*qOMt-$pRBkWk$LE*rZ%ti%rbu<}lm5^7 zyGJwKO}c-2yd93Ka_@J$yyjZ7{!*&*I3iaa$H()_!+57U+}$6xJFlm~&-t6P=jrax z|F(F)%jXmX2oNAZfB*pk1PBlyK;XXu2d_m;C$p`K)9IwH|GL_@uexdi1PBlyK!5-N z0t5&UAV8px0`rwYoYb>feb&d_+cN~(+J_HC5AV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF z5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk z1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs z0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZ zfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&U jAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBly&@X{6e@Sm% literal 0 HcmV?d00001 diff --git a/MAINTAINERS b/MAINTAINERS index e2f538fc16..cdb3041bb2 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -1537,6 +1537,7 @@ F: include/hw/ppc/pnv* F: include/hw/pci-host/pnv* F: include/hw/ssi/pnv_spi* F: pc-bios/skiboot.lid +F: pc-bios/pnv-pnor.bin F: tests/qtest/pnv* F: tests/functional/test_ppc64_powernv.py diff --git a/docs/system/ppc/powernv.rst b/docs/system/ppc/powernv.rst index de7a807ac7..f3ec2cc69c 100644 --- a/docs/system/ppc/powernv.rst +++ b/docs/system/ppc/powernv.rst @@ -195,6 +195,13 @@ Use a MTD drive to add a PNOR to the machine, and get a NVRAM : -drive file=./witherspoon.pnor,format=raw,if=mtd +If no mtd drive is provided, the powernv platform will create a default +PNOR device using a tiny formatted PNOR in pc-bios/pnv-pnor.bin opened +read-only (PNOR changes will be persistent across reboots but not across +invocations of QEMU). If no defaults are used, an erased 128MB PNOR is +provided (which skiboot will probably not recognize since it is not +formatted). + Maintainer contact information ------------------------------ diff --git a/hw/ppc/pnv.c b/hw/ppc/pnv.c index 8c0a2d0573..6fec455ff9 100644 --- a/hw/ppc/pnv.c +++ b/hw/ppc/pnv.c @@ -64,6 +64,8 @@ #define FW_LOAD_ADDR 0x0 #define FW_MAX_SIZE (16 * MiB) +#define PNOR_FILE_NAME "pnv-pnor.bin" + #define KERNEL_LOAD_ADDR 0x20000000 #define KERNEL_MAX_SIZE (128 * MiB) #define INITRD_LOAD_ADDR 0x28000000 @@ -941,7 +943,7 @@ static void pnv_init(MachineState *machine) uint64_t chip_ram_start = 0; int i; char *chip_typename; - DriveInfo *pnor = drive_get(IF_MTD, 0, 0); + DriveInfo *pnor; DeviceState *dev; if (kvm_enabled()) { @@ -971,6 +973,18 @@ static void pnv_init(MachineState *machine) * Create our simple PNOR device */ dev = qdev_new(TYPE_PNV_PNOR); + pnor = drive_get(IF_MTD, 0, 0); + if (!pnor && defaults_enabled()) { + fw_filename = qemu_find_file(QEMU_FILE_TYPE_BIOS, PNOR_FILE_NAME); + if (!fw_filename) { + warn_report("Could not find PNOR '%s'", PNOR_FILE_NAME); + } else { + QemuOpts *opts; + opts = drive_add(IF_MTD, -1, fw_filename, "format=raw,readonly=on"); + pnor = drive_new(opts, IF_MTD, &error_fatal); + g_free(fw_filename); + } + } if (pnor) { qdev_prop_set_drive(dev, "drive", blk_by_legacy_dinfo(pnor)); } diff --git a/pc-bios/README b/pc-bios/README index a08e034fc3..f0f13e15f2 100644 --- a/pc-bios/README +++ b/pc-bios/README @@ -43,6 +43,19 @@ run an hypervisor OS or simply a host OS on the "baremetal" platform, also known as the PowerNV (Non-Virtualized) platform. +- pnv-pnor.bin is a non-volatile RAM image used by PowerNV, which stores + NVRAM BIOS settings among other things. This image was created with the + following command (the ffspart tool can be found in the skiboot source tree): + + ffspart -s 0x1000 -c 34 -i pnv-pnor.in -p pnv-pnor.bin + + Where pnv-pnor.in contains the two lines (no leading whitespace): + + NVRAM,0x01000,0x00020000,,,/dev/zero + VERSION,0x21000,0x00001000,,,/dev/zero + + skiboot is then booted once to format the NVRAM partition. + - QemuMacDrivers (https://github.com/ozbenh/QemuMacDrivers) is a project to provide virtualised drivers for PPC MacOS guests. diff --git a/pc-bios/meson.build b/pc-bios/meson.build index 51e95cc903..34d6616c32 100644 --- a/pc-bios/meson.build +++ b/pc-bios/meson.build @@ -70,6 +70,7 @@ blobs = [ 's390-ccw.img', 'slof.bin', 'skiboot.lid', + 'pnv-pnor.bin', 'palcode-clipper', 'u-boot.e500', 'u-boot-sam460-20100605.bin', diff --git a/pc-bios/pnv-pnor.bin b/pc-bios/pnv-pnor.bin new file mode 100644 index 0000000000000000000000000000000000000000..3e6f70014408e76d5aeca758c31113f3eee2da84 From patchwork Tue Mar 11 12:57:17 2025 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Nicholas Piggin X-Patchwork-Id: 14011898 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.lore.kernel.org (Postfix) with ESMTPS id DB500C28B2E for ; Tue, 11 Mar 2025 13:26:36 +0000 (UTC) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1trzFa-000704-Up; Tue, 11 Mar 2025 09:02:28 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1trzCy-000364-Fu; Tue, 11 Mar 2025 08:59:45 -0400 Received: from mail-pj1-x1029.google.com ([2607:f8b0:4864:20::1029]) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_128_GCM_SHA256:128) (Exim 4.90_1) (envelope-from ) id 1trzCw-00080x-3m; Tue, 11 Mar 2025 08:59:44 -0400 Received: by mail-pj1-x1029.google.com with SMTP id 98e67ed59e1d1-2fee4d9c2efso9001086a91.3; Tue, 11 Mar 2025 05:59:40 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20230601; t=1741697979; x=1742302779; darn=nongnu.org; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to; bh=YqPpSFq/0fdsjmu5dGyUqROl/b/bn7/APbML/SqYVto=; b=kYojWAGgc5DUc8wymJqbAQxpCVfgANWwY8UHbfUXVHeI9sEYo4H1AIkLuyNiq8tA31 PwR0/HEDKb1ysDov1/fUKt+Kaeofe23Sgd/4I1ou9sktkp8n5CtbNKitf8WUngHUlpN+ UFS0UZz8BU4bpHRZX2uVqK8oN1D7U+QcjCwAxYkG28X6TFxO5x4+WSSJA62FcVkrl2/N +7b3pdZ5LKJNq3P5KYEPIicUe3oBayJ0xEWzkls/KFXjtu2NJKTx5MOkl0BV4JXfW5gf VrqDapPDucgvPb/2JHCHFUrbGRHuur462IjdGGHsf6+3otRpAJ1hSlXI4ZHgC9bdBsSX xeFA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1741697979; x=1742302779; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=YqPpSFq/0fdsjmu5dGyUqROl/b/bn7/APbML/SqYVto=; b=cnLI6NzE7MKpqmUanOOw15ELF2vROwOQvW+uTBwjAO/6T5WJOwD4BFwoAmVGshm9Bq eJ6HpuoNOoH1UCwNYBEdSlx0X5DKisu1zr+J+as89pOR8oK5SJ/ML4z+AJj3gto93dUd CBnUNdWSI5PHmFF1GQ66o0eaKkQ7rD05Sj2iPpyHaqmUl7qMEuo0AGQ/XwB8lwkkAR4D eDj0ZqCNByNGQNRBZAXstjjsI/iAZBS5yRSDaK/eYdzdi8mu2JFd5o+UH/nASgcdcQz9 /9GGiLOILvooJutqrKDIN/odG9xoz7nUtZ9SYHd4B8LNePi0edbK9uf1rjPz8TbvehV/ 39Hg== X-Forwarded-Encrypted: i=1; AJvYcCUOYtMj0mcsT5o4QyHkmzyZzMwkvh1NCjjz8/e6cR8NelRX36BKWH8CPn0lOktgGh+FT5lOGE3qpg==@nongnu.org X-Gm-Message-State: AOJu0Ywm5Jfl8VYFyVpXGk+zrmFv2RyCbN1Q8THxoFBPhkHTG97X6lx/ WGTjC5Y2uV6WUw+JrlZKyJjSGvkbPRC8ULz1skX0k/uD+4Due0csXMFjEQ== X-Gm-Gg: ASbGncvEYmqQrrwerTHgloAypKsReViBX6RWQNrnktbEwBIf8fAbned1rkyCV5XMYDH 80uiWNBOU41miCYogdBlvAnXlTEp0UIAsWzfBicSNQTjpEWszvpRj2gBpBx2Cxn7EVMPKvC7GRO /Ritfk5N+zMJkL5XiXTg/08yL0sVeJuZZ2NOJzHOcVR75H2/ltB4Vp9DQiWGw+ARDKbR/LpM/gi 6J791SmUvS969SN0yGC544KFVYVyegAYQ9nA5DoV7OZt0yfzoBjPMfOkkl6k0mbTDoGrZvx6Nl9 sNVSr+T6m5NbnltgkxRv77OvqSo0eQ8EimrhKkazy9bEYD8hRJYDYVTof5fBpg== X-Google-Smtp-Source: AGHT+IFCLboP2NEYVER6Ia/nktt0alb7IBxusg86yBWU41313CNd0zQswT6vFclWJ+klo6cKjlNAzw== X-Received: by 2002:a17:90b:1a8c:b0:2ee:aa28:79aa with SMTP id 98e67ed59e1d1-2ff7ce524ebmr25368424a91.6.1741697978701; Tue, 11 Mar 2025 05:59:38 -0700 (PDT) Received: from wheely.local0.net ([118.208.151.101]) by smtp.gmail.com with ESMTPSA id 98e67ed59e1d1-2ff4e773dddsm11822318a91.12.2025.03.11.05.59.36 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 11 Mar 2025 05:59:38 -0700 (PDT) From: Nicholas Piggin To: qemu-devel@nongnu.org Cc: Nicholas Piggin , qemu-ppc@nongnu.org, Frederic Barrat , Michael Kowal Subject: [PULL 23/72] ppc/xive2: Update NVP save/restore for group attributes Date: Tue, 11 Mar 2025 22:57:17 +1000 Message-ID: <20250311125815.903177-24-npiggin@gmail.com> X-Mailer: git-send-email 2.47.1 In-Reply-To: <20250311125815.903177-1-npiggin@gmail.com> References: <20250311125815.903177-1-npiggin@gmail.com> MIME-Version: 1.0 Received-SPF: pass client-ip=2607:f8b0:4864:20::1029; envelope-from=npiggin@gmail.com; helo=mail-pj1-x1029.google.com X-Spam_score_int: -20 X-Spam_score: -2.1 X-Spam_bar: -- X-Spam_report: (-2.1 / 5.0 requ) BAYES_00=-1.9, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_AU=-0.1, DKIM_VALID_EF=-0.1, FREEMAIL_FROM=0.001, RCVD_IN_DNSWL_NONE=-0.0001, SPF_HELO_NONE=0.001, SPF_PASS=-0.001 autolearn=ham autolearn_force=no X-Spam_action: no action X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: qemu-devel-bounces+qemu-devel=archiver.kernel.org@nongnu.org Sender: qemu-devel-bounces+qemu-devel=archiver.kernel.org@nongnu.org From: Frederic Barrat If the 'H' attribute is set on the NVP structure, the hardware automatically saves and restores some attributes from the TIMA in the NVP structure. The group-specific attributes LSMFB, LGS and T have an extra flag to individually control what is saved/restored. Signed-off-by: Frederic Barrat Signed-off-by: Michael Kowal Reviewed-by: Nicholas Piggin Signed-off-by: Nicholas Piggin --- hw/intc/xive2.c | 23 ++++++++++++++++++----- include/hw/ppc/xive2_regs.h | 10 +++++++--- 2 files changed, 25 insertions(+), 8 deletions(-) diff --git a/hw/intc/xive2.c b/hw/intc/xive2.c index fc5aed3315..cd075e4db9 100644 --- a/hw/intc/xive2.c +++ b/hw/intc/xive2.c @@ -1,10 +1,9 @@ /* * QEMU PowerPC XIVE2 interrupt controller model (POWER10) * - * Copyright (c) 2019-2022, IBM Corporation.. + * Copyright (c) 2019-2024, IBM Corporation.. * - * This code is licensed under the GPL version 2 or later. See the - * COPYING file in the top-level directory. + * SPDX-License-Identifier: GPL-2.0-or-later */ #include "qemu/osdep.h" @@ -313,7 +312,19 @@ static void xive2_tctx_save_ctx(Xive2Router *xrtr, XiveTCTX *tctx, nvp.w2 = xive_set_field32(NVP2_W2_IPB, nvp.w2, regs[TM_IPB]); nvp.w2 = xive_set_field32(NVP2_W2_CPPR, nvp.w2, regs[TM_CPPR]); - nvp.w2 = xive_set_field32(NVP2_W2_LSMFB, nvp.w2, regs[TM_LSMFB]); + if (nvp.w0 & NVP2_W0_L) { + /* + * Typically not used. If LSMFB is restored with 0, it will + * force a backlog rescan + */ + nvp.w2 = xive_set_field32(NVP2_W2_LSMFB, nvp.w2, regs[TM_LSMFB]); + } + if (nvp.w0 & NVP2_W0_G) { + nvp.w2 = xive_set_field32(NVP2_W2_LGS, nvp.w2, regs[TM_LGS]); + } + if (nvp.w0 & NVP2_W0_T) { + nvp.w2 = xive_set_field32(NVP2_W2_T, nvp.w2, regs[TM_T]); + } xive2_router_write_nvp(xrtr, nvp_blk, nvp_idx, &nvp, 2); nvp.w1 = xive_set_field32(NVP2_W1_CO, nvp.w1, 0); @@ -527,7 +538,9 @@ static uint8_t xive2_tctx_restore_os_ctx(Xive2Router *xrtr, XiveTCTX *tctx, xive2_router_write_nvp(xrtr, nvp_blk, nvp_idx, nvp, 2); tctx->regs[TM_QW1_OS + TM_CPPR] = cppr; - /* we don't model LSMFB */ + tctx->regs[TM_QW1_OS + TM_LSMFB] = xive_get_field32(NVP2_W2_LSMFB, nvp->w2); + tctx->regs[TM_QW1_OS + TM_LGS] = xive_get_field32(NVP2_W2_LGS, nvp->w2); + tctx->regs[TM_QW1_OS + TM_T] = xive_get_field32(NVP2_W2_T, nvp->w2); nvp->w1 = xive_set_field32(NVP2_W1_CO, nvp->w1, 1); nvp->w1 = xive_set_field32(NVP2_W1_CO_THRID_VALID, nvp->w1, 1); diff --git a/include/hw/ppc/xive2_regs.h b/include/hw/ppc/xive2_regs.h index 1d00c8df64..e88d6eab1e 100644 --- a/include/hw/ppc/xive2_regs.h +++ b/include/hw/ppc/xive2_regs.h @@ -1,10 +1,9 @@ /* * QEMU PowerPC XIVE2 internal structure definitions (POWER10) * - * Copyright (c) 2019-2022, IBM Corporation. + * Copyright (c) 2019-2024, IBM Corporation. * - * This code is licensed under the GPL version 2 or later. See the - * COPYING file in the top-level directory. + * SPDX-License-Identifier: GPL-2.0-or-later */ #ifndef PPC_XIVE2_REGS_H @@ -152,6 +151,9 @@ typedef struct Xive2Nvp { uint32_t w0; #define NVP2_W0_VALID PPC_BIT32(0) #define NVP2_W0_HW PPC_BIT32(7) +#define NVP2_W0_L PPC_BIT32(8) +#define NVP2_W0_G PPC_BIT32(9) +#define NVP2_W0_T PPC_BIT32(10) #define NVP2_W0_ESC_END PPC_BIT32(25) /* 'N' bit 0:ESB 1:END */ #define NVP2_W0_PGOFIRST PPC_BITMASK32(26, 31) uint32_t w1; @@ -163,6 +165,8 @@ typedef struct Xive2Nvp { #define NVP2_W2_CPPR PPC_BITMASK32(0, 7) #define NVP2_W2_IPB PPC_BITMASK32(8, 15) #define NVP2_W2_LSMFB PPC_BITMASK32(16, 23) +#define NVP2_W2_T PPC_BIT32(27) +#define NVP2_W2_LGS PPC_BITMASK32(28, 31) uint32_t w3; uint32_t w4; #define NVP2_W4_ESC_ESB_BLOCK PPC_BITMASK32(0, 3) /* N:0 */ From patchwork Tue Mar 11 12:57:18 2025 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Nicholas Piggin X-Patchwork-Id: 14011832 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.lore.kernel.org (Postfix) with ESMTPS id B15EFC35FF1 for ; Tue, 11 Mar 2025 13:12:21 +0000 (UTC) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1trzGR-0007yv-8D; Tue, 11 Mar 2025 09:03:20 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1trzD0-0003Hr-21; Tue, 11 Mar 2025 08:59:46 -0400 Received: from mail-pj1-x1032.google.com ([2607:f8b0:4864:20::1032]) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_128_GCM_SHA256:128) (Exim 4.90_1) (envelope-from ) id 1trzCx-00081L-UP; Tue, 11 Mar 2025 08:59:45 -0400 Received: by mail-pj1-x1032.google.com with SMTP id 98e67ed59e1d1-2ff615a114bso9409631a91.0; Tue, 11 Mar 2025 05:59:42 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20230601; t=1741697981; x=1742302781; darn=nongnu.org; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to; bh=GRjGMMyN8Fta0GJMwT6WyLidcFv71ZTmFrwphwzXpVk=; b=KBSbvW9mT9ddb5wFaCIzW/+Zb9g1GsHjFds+0t2c5SIH2RWh/0D4B2xZhrp9KSlSVD NfuRJ4Gu0bvWgHnTIQLBlx+kMgFCV3MfuZYdHKdJ+Zv1Q5TicN8giEr4ZrDoWnbySjI5 FJKyCKoey6++0Zb9Cp3x0UA4kVamRxXUHHEQwzZR9rqgRPNfGVKcieO9fLC2qRIpw5+S Is6/Aj/rI82CTPynBVtmeOcWkZWjc0FTkgbdViyn/AMRbHRC4XASYnUaRcqwzUyPZf7o g3KUvHl781TFsu6v3TgCFHXF4kQKwsijXFmJ7rZmZGzDIIv/D7Tb7msR5fE7/kIcdZDp XGfg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1741697981; x=1742302781; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=GRjGMMyN8Fta0GJMwT6WyLidcFv71ZTmFrwphwzXpVk=; b=NgBS38ndc0cKDmdy6q8Wo4vlQBEk8zqKMUlMPk51FzAGPFRsJQ8ols/95zp+PbBjpe 32bQwVOdY9G+3qZFyZI8y/TaUgutq7x2VT7ERme3XpGcke7EU5mYLkjO88x4dSfBoZ5v aWyFePsgDdkrWKgWUrzjU0gScw+4Qy0YVnGY0TDKHU5VWCkGEqw2xsjHoqrvzGP+jDQn om/D8x8BcFAaspb8w0s1meltv/GFHWzEKX3R2TrOzmEMw2KaAFV0Lmyotz9XbqzIjj9D dezy6P2iABSSCeeG807RbqzV33Q3WkCCDrc1VnC0zs9KvUV3gV/NxCPxYVyMg0Nlj9FS N10g== X-Forwarded-Encrypted: i=1; AJvYcCXOjYk6hxWTBjGMRozhQsfvztFxL6SUgPUIA1K3Fn+LctEONhq9zwdQZoVfsXzwXDpudHYAapLusw==@nongnu.org X-Gm-Message-State: AOJu0YxOMt7iAbfiDfSh1EmU6hth9GZHSLti7o4v4auFOx1UzwLAdrFd HvN5aJh5YBtRv9wdBYkKJGx1zlmCXFyUjw4yebnycbEyZHq0rxlKWlVwFQ== X-Gm-Gg: ASbGncsZ1FTJ7lQqDYA3C/z/oLoZ9Qiejw3J0hLLIXiRlvAfj4f6Vi02rryQHBsnKGr oTkwWD3BYqF5kEw6xL0PfXsNKGu1BtuE2TMtKeHGWhmkFJscMa+eacIcnv+lAhyVbfvkngbdjs6 F6RqoqsBRwcr1J6NLez1YtZfusVdkDr18CB70aecpVBhXwE/GQhMk3yg/G63bVENVIvEJQEmv4o fIAQgR/0Oz3Z7jh7DOEx8UHdwJDRxynZHtIfeEjVxE7NpdLP16Eu32Xa4urEe911EjHyPyhSBas IYUpD6f8n7p969GM7gpyNOcIRztI8FtZgxybh8UGwRnY+bZKi9c= X-Google-Smtp-Source: AGHT+IGlDc6s3YJsqfn76XrlHsjEZ1RPr/bFxF9kUztMEsytOBLmIYr82HlGHywm0x4NR18qXrtByA== X-Received: by 2002:a17:90b:384a:b0:2ee:9661:eafb with SMTP id 98e67ed59e1d1-30100546828mr4565682a91.12.1741697981420; Tue, 11 Mar 2025 05:59:41 -0700 (PDT) Received: from wheely.local0.net ([118.208.151.101]) by smtp.gmail.com with ESMTPSA id 98e67ed59e1d1-2ff4e773dddsm11822318a91.12.2025.03.11.05.59.39 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 11 Mar 2025 05:59:41 -0700 (PDT) From: Nicholas Piggin To: qemu-devel@nongnu.org Cc: Nicholas Piggin , qemu-ppc@nongnu.org, Michael Kowal Subject: [PULL 24/72] ppc/xive: Rename ipb_to_pipr() to xive_ipb_to_pipr() Date: Tue, 11 Mar 2025 22:57:18 +1000 Message-ID: <20250311125815.903177-25-npiggin@gmail.com> X-Mailer: git-send-email 2.47.1 In-Reply-To: <20250311125815.903177-1-npiggin@gmail.com> References: <20250311125815.903177-1-npiggin@gmail.com> MIME-Version: 1.0 Received-SPF: pass client-ip=2607:f8b0:4864:20::1032; envelope-from=npiggin@gmail.com; helo=mail-pj1-x1032.google.com X-Spam_score_int: -20 X-Spam_score: -2.1 X-Spam_bar: -- X-Spam_report: (-2.1 / 5.0 requ) BAYES_00=-1.9, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_AU=-0.1, DKIM_VALID_EF=-0.1, FREEMAIL_FROM=0.001, RCVD_IN_DNSWL_NONE=-0.0001, SPF_HELO_NONE=0.001, SPF_PASS=-0.001 autolearn=ham autolearn_force=no X-Spam_action: no action X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: qemu-devel-bounces+qemu-devel=archiver.kernel.org@nongnu.org Sender: qemu-devel-bounces+qemu-devel=archiver.kernel.org@nongnu.org From: Michael Kowal Rename to follow the convention of the other function names. Signed-off-by: Michael Kowal Reviewed-by: Nicholas Piggin Signed-off-by: Nicholas Piggin --- hw/intc/xive.c | 22 ++++++---------------- include/hw/ppc/xive.h | 16 ++++++++++++---- 2 files changed, 18 insertions(+), 20 deletions(-) diff --git a/hw/intc/xive.c b/hw/intc/xive.c index 139cfdf9bf..f603d9f1a5 100644 --- a/hw/intc/xive.c +++ b/hw/intc/xive.c @@ -3,8 +3,7 @@ * * Copyright (c) 2017-2018, IBM Corporation. * - * This code is licensed under the GPL version 2 or later. See the - * COPYING file in the top-level directory. + * SPDX-License-Identifier: GPL-2.0-or-later */ #include "qemu/osdep.h" @@ -27,15 +26,6 @@ * XIVE Thread Interrupt Management context */ -/* - * Convert an Interrupt Pending Buffer (IPB) register to a Pending - * Interrupt Priority Register (PIPR), which contains the priority of - * the most favored pending notification. - */ -static uint8_t ipb_to_pipr(uint8_t ibp) -{ - return ibp ? clz32((uint32_t)ibp << 24) : 0xff; -} static uint8_t exception_mask(uint8_t ring) { @@ -159,7 +149,7 @@ static void xive_tctx_set_cppr(XiveTCTX *tctx, uint8_t ring, uint8_t cppr) * Recompute the PIPR based on local pending interrupts. The PHYS * ring must take the minimum of both the PHYS and POOL PIPR values. */ - pipr_min = ipb_to_pipr(regs[TM_IPB]); + pipr_min = xive_ipb_to_pipr(regs[TM_IPB]); ring_min = ring; /* PHYS updates also depend on POOL values */ @@ -169,7 +159,7 @@ static void xive_tctx_set_cppr(XiveTCTX *tctx, uint8_t ring, uint8_t cppr) /* POOL values only matter if POOL ctx is valid */ if (pool_regs[TM_WORD2] & 0x80) { - uint8_t pool_pipr = ipb_to_pipr(pool_regs[TM_IPB]); + uint8_t pool_pipr = xive_ipb_to_pipr(pool_regs[TM_IPB]); /* * Determine highest priority interrupt and @@ -193,7 +183,7 @@ void xive_tctx_ipb_update(XiveTCTX *tctx, uint8_t ring, uint8_t ipb) uint8_t *regs = &tctx->regs[ring]; regs[TM_IPB] |= ipb; - regs[TM_PIPR] = ipb_to_pipr(regs[TM_IPB]); + regs[TM_PIPR] = xive_ipb_to_pipr(regs[TM_IPB]); xive_tctx_notify(tctx, ring); } @@ -841,9 +831,9 @@ void xive_tctx_reset(XiveTCTX *tctx) * CPPR is first set. */ tctx->regs[TM_QW1_OS + TM_PIPR] = - ipb_to_pipr(tctx->regs[TM_QW1_OS + TM_IPB]); + xive_ipb_to_pipr(tctx->regs[TM_QW1_OS + TM_IPB]); tctx->regs[TM_QW3_HV_PHYS + TM_PIPR] = - ipb_to_pipr(tctx->regs[TM_QW3_HV_PHYS + TM_IPB]); + xive_ipb_to_pipr(tctx->regs[TM_QW3_HV_PHYS + TM_IPB]); } static void xive_tctx_realize(DeviceState *dev, Error **errp) diff --git a/include/hw/ppc/xive.h b/include/hw/ppc/xive.h index ea5d03a346..75276b9ba6 100644 --- a/include/hw/ppc/xive.h +++ b/include/hw/ppc/xive.h @@ -130,11 +130,9 @@ * TCTX Thread interrupt Context * * - * Copyright (c) 2017-2018, IBM Corporation. - * - * This code is licensed under the GPL version 2 or later. See the - * COPYING file in the top-level directory. + * Copyright (c) 2017-2024, IBM Corporation. * + * SPDX-License-Identifier: GPL-2.0-or-later */ #ifndef PPC_XIVE_H @@ -510,6 +508,16 @@ static inline uint8_t xive_priority_to_ipb(uint8_t priority) 0 : 1 << (XIVE_PRIORITY_MAX - priority); } +/* + * Convert an Interrupt Pending Buffer (IPB) register to a Pending + * Interrupt Priority Register (PIPR), which contains the priority of + * the most favored pending notification. + */ +static inline uint8_t xive_ipb_to_pipr(uint8_t ibp) +{ + return ibp ? clz32((uint32_t)ibp << 24) : 0xff; +} + /* * XIVE Thread Interrupt Management Aera (TIMA) * From patchwork Tue Mar 11 12:57:19 2025 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Nicholas Piggin X-Patchwork-Id: 14011846 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.lore.kernel.org (Postfix) with ESMTPS id F410FC28B2E for ; Tue, 11 Mar 2025 13:15:28 +0000 (UTC) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1trzGZ-00008w-SH; Tue, 11 Mar 2025 09:03:28 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1trzD9-0003mH-62; Tue, 11 Mar 2025 08:59:55 -0400 Received: from mail-pj1-x1035.google.com ([2607:f8b0:4864:20::1035]) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_128_GCM_SHA256:128) (Exim 4.90_1) (envelope-from ) id 1trzD4-00082A-1R; Tue, 11 Mar 2025 08:59:54 -0400 Received: by mail-pj1-x1035.google.com with SMTP id 98e67ed59e1d1-2feb96064e4so10447910a91.1; Tue, 11 Mar 2025 05:59:47 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20230601; t=1741697985; x=1742302785; darn=nongnu.org; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to; bh=dW2SVkFDquqc+hhC+TtvF/CU3vzLH2zU4mYHOp2YaJk=; b=G+vHpizrH8bOgIuc4wOR3J/mlGpRcRFFySzFThxMXNPHNJ5E8WOl2t/t5kNP9TtNby CU1I3qGLN+EI45TATQW9voBVXAG/LKKKecsS63j7aVBWfbldMm1FdzeZzR7iD2JkOVvQ JPujZUUV+0aI6Nh6gSGTLvanXHrgdO2RH9gFpSq7kVkfn6sNPqacI8vlYc10fFOUG/m/ w3QIPdnnIoZibD0Z9iyi1Rn6xDRfibTebmunYnFWlE8q0CoWzNwLMM8J0tY3/vl+Y69G LrRKYfPxB8DV6HWBED7+JsH+99xU/rSl4WGCg1LcG5OedY7aTcjUVWSh7NtNk2FlWwWk mI7g== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1741697985; x=1742302785; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=dW2SVkFDquqc+hhC+TtvF/CU3vzLH2zU4mYHOp2YaJk=; b=ZQjLDMgRfoGBcFqpZdE5OqbknPpUwFmwlBV0jcU0joUY2bHBuWUSX1W1G3lgCCLTWa 9scBmDFiqp0cPAm4WlTl/rdH8Tct917A4pxdYuymdc1+dJ1QvZDb+xCoI0nx2wJ0g6YA j7lyhHnmGHiS3v64FafSc7UToRQKdjUo26pepVEMNH47VAKx5vjIOkOLY4ZBwXTY79X3 0u1o4Xh8YzUINcH20HflSUY5HsQCDZY8vEwgGJRbrF5jJbU3bUGQhOFBHiFvrQilr376 BeUNhnANGqfQQF3/bsZud0ryoxEzJp8TV2+A2DIlJd9IygXu8akepE9rlnAQTqjxfqbf NlQw== X-Forwarded-Encrypted: i=1; AJvYcCWXyrJ62h2PFYTbNo+bf1/++KYihOBjezpEU9fRZkqzCymTDWEArKF8jPalMKZE0Q4GWxrCc+zvow==@nongnu.org X-Gm-Message-State: AOJu0YwsUGDZbjcOBO+4Qx/x9GGETPdD48koLhwxvmvge57CtTWx0EH9 ZrwHVi/K98Yr6fIS50Xd7Mt7Lh53Q+dziuAJAGeps5MircVA03D1foUI1w== X-Gm-Gg: ASbGncvkBh4vi/EeyEKlO54uZygawr4vmxJJDjlTNxnKZHT2v6ox/Rvcu4ghDdINVyi zi3p3E/aNWazkQ2S1mBMaWuV0MBCQ8j/huxii0SfJe4hqvHz0dojkpnYA4LdlE3qnwITArWTKUz vsT1SM6fpBXL537TsklH/y9+6SnNOB6+pjDfxI76Ia1vXLMre/3g4ydNb2RttLJc+BRVgOYVPKv QVqc9K3F+kP4EQNV1VCM3QEkPK7LoEKL+ahKsx/J9fLrxeqdRJQ/lLHpFZiN5Xm8UAfgrQu+F2H cgMUhmkfIyYPVE7f3KWH1+sOfA7YSzqCOk5vM1GMrR0Rzj36300= X-Google-Smtp-Source: AGHT+IE1GT1X12NBUfBkLV7JsleMYRTncW/WdB4w+kQhbgxFUJkXymx+y5OGUa3NTuJItDyydpQOpg== X-Received: by 2002:a17:90b:2e42:b0:2ff:7cb8:6eca with SMTP id 98e67ed59e1d1-2ff7ced77eemr27811042a91.24.1741697984451; Tue, 11 Mar 2025 05:59:44 -0700 (PDT) Received: from wheely.local0.net ([118.208.151.101]) by smtp.gmail.com with ESMTPSA id 98e67ed59e1d1-2ff4e773dddsm11822318a91.12.2025.03.11.05.59.41 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 11 Mar 2025 05:59:44 -0700 (PDT) From: Nicholas Piggin To: qemu-devel@nongnu.org Cc: Nicholas Piggin , qemu-ppc@nongnu.org, Frederic Barrat , Michael Kowal Subject: [PULL 25/72] ppc/xive2: Add grouping level to notification Date: Tue, 11 Mar 2025 22:57:19 +1000 Message-ID: <20250311125815.903177-26-npiggin@gmail.com> X-Mailer: git-send-email 2.47.1 In-Reply-To: <20250311125815.903177-1-npiggin@gmail.com> References: <20250311125815.903177-1-npiggin@gmail.com> MIME-Version: 1.0 Received-SPF: pass client-ip=2607:f8b0:4864:20::1035; envelope-from=npiggin@gmail.com; helo=mail-pj1-x1035.google.com X-Spam_score_int: -20 X-Spam_score: -2.1 X-Spam_bar: -- X-Spam_report: (-2.1 / 5.0 requ) BAYES_00=-1.9, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_AU=-0.1, DKIM_VALID_EF=-0.1, FREEMAIL_FROM=0.001, RCVD_IN_DNSWL_NONE=-0.0001, SPF_HELO_NONE=0.001, SPF_PASS=-0.001 autolearn=ham autolearn_force=no X-Spam_action: no action X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: qemu-devel-bounces+qemu-devel=archiver.kernel.org@nongnu.org Sender: qemu-devel-bounces+qemu-devel=archiver.kernel.org@nongnu.org From: Frederic Barrat The NSR has a (so far unused) grouping level field. When a interrupt is presented, that field tells the hypervisor or OS if the interrupt is for an individual VP or for a VP-group/crowd. This patch reworks the presentation API to allow to set/unset the level when raising/accepting an interrupt. It also renames xive_tctx_ipb_update() to xive_tctx_pipr_update() as the IPB is only used for VP-specific target, whereas the PIPR always needs to be updated. Signed-off-by: Frederic Barrat Signed-off-by: Michael Kowal Reviewed-by: Nicholas Piggin Signed-off-by: Nicholas Piggin --- hw/intc/trace-events | 2 +- hw/intc/xive.c | 88 ++++++++++++++++++++++---------------- hw/intc/xive2.c | 19 ++++---- include/hw/ppc/xive.h | 9 +++- include/hw/ppc/xive_regs.h | 25 ++++++++--- 5 files changed, 90 insertions(+), 53 deletions(-) diff --git a/hw/intc/trace-events b/hw/intc/trace-events index 913197a181..e9fe1978f9 100644 --- a/hw/intc/trace-events +++ b/hw/intc/trace-events @@ -283,7 +283,7 @@ xive_router_end_notify(uint8_t end_blk, uint32_t end_idx, uint32_t end_data) "EN xive_router_end_escalate(uint8_t end_blk, uint32_t end_idx, uint8_t esc_blk, uint32_t esc_idx, uint32_t end_data) "END 0x%02x/0x%04x -> escalate END 0x%02x/0x%04x data 0x%08x" xive_tctx_tm_write(uint32_t index, uint64_t offset, unsigned int size, uint64_t value) "target=%d @0x%"PRIx64" sz=%d val=0x%" PRIx64 xive_tctx_tm_read(uint32_t index, uint64_t offset, unsigned int size, uint64_t value) "target=%d @0x%"PRIx64" sz=%d val=0x%" PRIx64 -xive_presenter_notify(uint8_t nvt_blk, uint32_t nvt_idx, uint8_t ring) "found NVT 0x%x/0x%x ring=0x%x" +xive_presenter_notify(uint8_t nvt_blk, uint32_t nvt_idx, uint8_t ring, uint8_t group_level) "found NVT 0x%x/0x%x ring=0x%x group_level=%d" xive_end_source_read(uint8_t end_blk, uint32_t end_idx, uint64_t addr) "END 0x%x/0x%x @0x%"PRIx64 # pnv_xive.c diff --git a/hw/intc/xive.c b/hw/intc/xive.c index f603d9f1a5..1e362f987a 100644 --- a/hw/intc/xive.c +++ b/hw/intc/xive.c @@ -26,19 +26,6 @@ * XIVE Thread Interrupt Management context */ - -static uint8_t exception_mask(uint8_t ring) -{ - switch (ring) { - case TM_QW1_OS: - return TM_QW1_NSR_EO; - case TM_QW3_HV_PHYS: - return TM_QW3_NSR_HE; - default: - g_assert_not_reached(); - } -} - static qemu_irq xive_tctx_output(XiveTCTX *tctx, uint8_t ring) { switch (ring) { @@ -58,11 +45,10 @@ static uint64_t xive_tctx_accept(XiveTCTX *tctx, uint8_t ring) { uint8_t *regs = &tctx->regs[ring]; uint8_t nsr = regs[TM_NSR]; - uint8_t mask = exception_mask(ring); qemu_irq_lower(xive_tctx_output(tctx, ring)); - if (regs[TM_NSR] & mask) { + if (regs[TM_NSR] != 0) { uint8_t cppr = regs[TM_PIPR]; uint8_t alt_ring; uint8_t *alt_regs; @@ -77,11 +63,18 @@ static uint64_t xive_tctx_accept(XiveTCTX *tctx, uint8_t ring) regs[TM_CPPR] = cppr; - /* Reset the pending buffer bit */ - alt_regs[TM_IPB] &= ~xive_priority_to_ipb(cppr); + /* + * If the interrupt was for a specific VP, reset the pending + * buffer bit, otherwise clear the logical server indicator + */ + if (regs[TM_NSR] & TM_NSR_GRP_LVL) { + regs[TM_NSR] &= ~TM_NSR_GRP_LVL; + } else { + alt_regs[TM_IPB] &= ~xive_priority_to_ipb(cppr); + } - /* Drop Exception bit */ - regs[TM_NSR] &= ~mask; + /* Drop the exception bit and any group/crowd */ + regs[TM_NSR] = 0; trace_xive_tctx_accept(tctx->cs->cpu_index, alt_ring, alt_regs[TM_IPB], regs[TM_PIPR], @@ -91,7 +84,7 @@ static uint64_t xive_tctx_accept(XiveTCTX *tctx, uint8_t ring) return ((uint64_t)nsr << 8) | regs[TM_CPPR]; } -static void xive_tctx_notify(XiveTCTX *tctx, uint8_t ring) +void xive_tctx_notify(XiveTCTX *tctx, uint8_t ring, uint8_t group_level) { /* HV_POOL ring uses HV_PHYS NSR, CPPR and PIPR registers */ uint8_t alt_ring = (ring == TM_QW2_HV_POOL) ? TM_QW3_HV_PHYS : ring; @@ -101,13 +94,13 @@ static void xive_tctx_notify(XiveTCTX *tctx, uint8_t ring) if (alt_regs[TM_PIPR] < alt_regs[TM_CPPR]) { switch (ring) { case TM_QW1_OS: - regs[TM_NSR] |= TM_QW1_NSR_EO; + regs[TM_NSR] = TM_QW1_NSR_EO | (group_level & 0x3F); break; case TM_QW2_HV_POOL: - alt_regs[TM_NSR] = (TM_QW3_NSR_HE_POOL << 6); + alt_regs[TM_NSR] = (TM_QW3_NSR_HE_POOL << 6) | (group_level & 0x3F); break; case TM_QW3_HV_PHYS: - regs[TM_NSR] |= (TM_QW3_NSR_HE_PHYS << 6); + regs[TM_NSR] = (TM_QW3_NSR_HE_PHYS << 6) | (group_level & 0x3F); break; default: g_assert_not_reached(); @@ -175,17 +168,27 @@ static void xive_tctx_set_cppr(XiveTCTX *tctx, uint8_t ring, uint8_t cppr) regs[TM_PIPR] = pipr_min; /* CPPR has changed, check if we need to raise a pending exception */ - xive_tctx_notify(tctx, ring_min); + xive_tctx_notify(tctx, ring_min, 0); } -void xive_tctx_ipb_update(XiveTCTX *tctx, uint8_t ring, uint8_t ipb) -{ +void xive_tctx_pipr_update(XiveTCTX *tctx, uint8_t ring, uint8_t priority, + uint8_t group_level) + { + /* HV_POOL ring uses HV_PHYS NSR, CPPR and PIPR registers */ + uint8_t alt_ring = (ring == TM_QW2_HV_POOL) ? TM_QW3_HV_PHYS : ring; + uint8_t *alt_regs = &tctx->regs[alt_ring]; uint8_t *regs = &tctx->regs[ring]; - regs[TM_IPB] |= ipb; - regs[TM_PIPR] = xive_ipb_to_pipr(regs[TM_IPB]); - xive_tctx_notify(tctx, ring); -} + if (group_level == 0) { + /* VP-specific */ + regs[TM_IPB] |= xive_priority_to_ipb(priority); + alt_regs[TM_PIPR] = xive_ipb_to_pipr(regs[TM_IPB]); + } else { + /* VP-group */ + alt_regs[TM_PIPR] = xive_priority_to_pipr(priority); + } + xive_tctx_notify(tctx, ring, group_level); + } /* * XIVE Thread Interrupt Management Area (TIMA) @@ -401,13 +404,13 @@ static void xive_tm_set_os_lgs(XivePresenter *xptr, XiveTCTX *tctx, } /* - * Adjust the IPB to allow a CPU to process event queues of other + * Adjust the PIPR to allow a CPU to process event queues of other * priorities during one physical interrupt cycle. */ static void xive_tm_set_os_pending(XivePresenter *xptr, XiveTCTX *tctx, hwaddr offset, uint64_t value, unsigned size) { - xive_tctx_ipb_update(tctx, TM_QW1_OS, xive_priority_to_ipb(value & 0xff)); + xive_tctx_pipr_update(tctx, TM_QW1_OS, value & 0xff, 0); } static void xive_os_cam_decode(uint32_t cam, uint8_t *nvt_blk, @@ -485,16 +488,20 @@ static void xive_tctx_need_resend(XiveRouter *xrtr, XiveTCTX *tctx, /* Reset the NVT value */ nvt.w4 = xive_set_field32(NVT_W4_IPB, nvt.w4, 0); xive_router_write_nvt(xrtr, nvt_blk, nvt_idx, &nvt, 4); + + uint8_t *regs = &tctx->regs[TM_QW1_OS]; + regs[TM_IPB] |= ipb; } + /* - * Always call xive_tctx_ipb_update(). Even if there were no + * Always call xive_tctx_pipr_update(). Even if there were no * escalation triggered, there could be a pending interrupt which * was saved when the context was pulled and that we need to take * into account by recalculating the PIPR (which is not * saved/restored). * It will also raise the External interrupt signal if needed. */ - xive_tctx_ipb_update(tctx, TM_QW1_OS, ipb); + xive_tctx_pipr_update(tctx, TM_QW1_OS, 0xFF, 0); /* fxb */ } /* @@ -1648,6 +1655,12 @@ static uint32_t xive_tctx_hw_cam_line(XivePresenter *xptr, XiveTCTX *tctx) return xive_nvt_cam_line(blk, 1 << 7 | (pir & 0x7f)); } +static uint8_t xive_get_group_level(uint32_t nvp_index) +{ + /* FIXME add crowd encoding */ + return ctz32(~nvp_index) + 1; +} + /* * The thread context register words are in big-endian format. */ @@ -1733,6 +1746,7 @@ bool xive_presenter_notify(XiveFabric *xfb, uint8_t format, { XiveFabricClass *xfc = XIVE_FABRIC_GET_CLASS(xfb); XiveTCTXMatch match = { .tctx = NULL, .ring = 0 }; + uint8_t group_level; int count; /* @@ -1746,9 +1760,9 @@ bool xive_presenter_notify(XiveFabric *xfb, uint8_t format, /* handle CPU exception delivery */ if (count) { - trace_xive_presenter_notify(nvt_blk, nvt_idx, match.ring); - xive_tctx_ipb_update(match.tctx, match.ring, - xive_priority_to_ipb(priority)); + group_level = cam_ignore ? xive_get_group_level(nvt_idx) : 0; + trace_xive_presenter_notify(nvt_blk, nvt_idx, match.ring, group_level); + xive_tctx_pipr_update(match.tctx, match.ring, priority, group_level); } return !!count; diff --git a/hw/intc/xive2.c b/hw/intc/xive2.c index cd075e4db9..62c3f05af9 100644 --- a/hw/intc/xive2.c +++ b/hw/intc/xive2.c @@ -563,8 +563,11 @@ static void xive2_tctx_need_resend(Xive2Router *xrtr, XiveTCTX *tctx, uint8_t nvp_blk, uint32_t nvp_idx, bool do_restore) { - Xive2Nvp nvp; uint8_t ipb; + uint8_t backlog_level; + uint8_t backlog_prio; + uint8_t *regs = &tctx->regs[TM_QW1_OS]; + Xive2Nvp nvp; /* * Grab the associated thread interrupt context registers in the @@ -593,15 +596,15 @@ static void xive2_tctx_need_resend(Xive2Router *xrtr, XiveTCTX *tctx, nvp.w2 = xive_set_field32(NVP2_W2_IPB, nvp.w2, 0); xive2_router_write_nvp(xrtr, nvp_blk, nvp_idx, &nvp, 2); } + regs[TM_IPB] |= ipb; + backlog_prio = xive_ipb_to_pipr(ipb); + backlog_level = 0; + /* - * Always call xive_tctx_ipb_update(). Even if there were no - * escalation triggered, there could be a pending interrupt which - * was saved when the context was pulled and that we need to take - * into account by recalculating the PIPR (which is not - * saved/restored). - * It will also raise the External interrupt signal if needed. + * Compute the PIPR based on the restored state. + * It will raise the External interrupt signal if needed. */ - xive_tctx_ipb_update(tctx, TM_QW1_OS, ipb); + xive_tctx_pipr_update(tctx, TM_QW1_OS, backlog_prio, backlog_level); } /* diff --git a/include/hw/ppc/xive.h b/include/hw/ppc/xive.h index 75276b9ba6..805b1d7b80 100644 --- a/include/hw/ppc/xive.h +++ b/include/hw/ppc/xive.h @@ -508,6 +508,11 @@ static inline uint8_t xive_priority_to_ipb(uint8_t priority) 0 : 1 << (XIVE_PRIORITY_MAX - priority); } +static inline uint8_t xive_priority_to_pipr(uint8_t priority) +{ + return priority > XIVE_PRIORITY_MAX ? 0xFF : priority; +} + /* * Convert an Interrupt Pending Buffer (IPB) register to a Pending * Interrupt Priority Register (PIPR), which contains the priority of @@ -540,8 +545,10 @@ void xive_tctx_pic_print_info(XiveTCTX *tctx, GString *buf); Object *xive_tctx_create(Object *cpu, XivePresenter *xptr, Error **errp); void xive_tctx_reset(XiveTCTX *tctx); void xive_tctx_destroy(XiveTCTX *tctx); -void xive_tctx_ipb_update(XiveTCTX *tctx, uint8_t ring, uint8_t ipb); +void xive_tctx_pipr_update(XiveTCTX *tctx, uint8_t ring, uint8_t priority, + uint8_t group_level); void xive_tctx_reset_signal(XiveTCTX *tctx, uint8_t ring); +void xive_tctx_notify(XiveTCTX *tctx, uint8_t ring, uint8_t group_level); /* * KVM XIVE device helpers diff --git a/include/hw/ppc/xive_regs.h b/include/hw/ppc/xive_regs.h index 326327fc79..54bc6c53b4 100644 --- a/include/hw/ppc/xive_regs.h +++ b/include/hw/ppc/xive_regs.h @@ -7,10 +7,9 @@ * access to the different fields. * * - * Copyright (c) 2016-2018, IBM Corporation. + * Copyright (c) 2016-2024, IBM Corporation. * - * This code is licensed under the GPL version 2 or later. See the - * COPYING file in the top-level directory. + * SPDX-License-Identifier: GPL-2.0-or-later */ #ifndef PPC_XIVE_REGS_H @@ -146,7 +145,14 @@ #define TM_SPC_PULL_PHYS_CTX_OL 0xc38 /* Pull phys ctx to odd cache line */ /* XXX more... */ -/* NSR fields for the various QW ack types */ +/* + * NSR fields for the various QW ack types + * + * P10 has an extra bit in QW3 for the group level instead of the + * reserved 'i' bit. Since it is not used and we don't support group + * interrupts on P9, we use the P10 definition for the group level so + * that we can have common macros for the NSR + */ #define TM_QW0_NSR_EB PPC_BIT8(0) #define TM_QW1_NSR_EO PPC_BIT8(0) #define TM_QW3_NSR_HE PPC_BITMASK8(0, 1) @@ -154,8 +160,15 @@ #define TM_QW3_NSR_HE_POOL 1 #define TM_QW3_NSR_HE_PHYS 2 #define TM_QW3_NSR_HE_LSI 3 -#define TM_QW3_NSR_I PPC_BIT8(2) -#define TM_QW3_NSR_GRP_LVL PPC_BIT8(3, 7) +#define TM_NSR_GRP_LVL PPC_BITMASK8(2, 7) +/* + * On P10, the format of the 6-bit group level is: 2 bits for the + * crowd size and 4 bits for the group size. Since group/crowd size is + * always a power of 2, we encode the log. For example, group_level=4 + * means crowd size = 0 and group size = 16 (2^4) + * Same encoding is used in the NVP and NVGC structures for + * PGoFirst and PGoNext fields + */ /* * EAS (Event Assignment Structure) From patchwork Tue Mar 11 12:57:20 2025 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Nicholas Piggin X-Patchwork-Id: 14011801 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.lore.kernel.org (Postfix) with ESMTPS id 806CFC282EC for ; Tue, 11 Mar 2025 13:04:39 +0000 (UTC) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1trzDF-00044h-Le; Tue, 11 Mar 2025 09:00:01 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1trzDD-0003xP-Fm; Tue, 11 Mar 2025 08:59:59 -0400 Received: from mail-pj1-x102a.google.com ([2607:f8b0:4864:20::102a]) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_128_GCM_SHA256:128) (Exim 4.90_1) (envelope-from ) id 1trzD7-00082N-Aw; Tue, 11 Mar 2025 08:59:58 -0400 Received: by mail-pj1-x102a.google.com with SMTP id 98e67ed59e1d1-2ff80290e44so8656755a91.0; Tue, 11 Mar 2025 05:59:49 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20230601; t=1741697987; x=1742302787; darn=nongnu.org; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to; bh=hMN1cLhziqhpOJDuVkl12QW9EXehxz96DoalbVVJvq0=; b=TEweNpT20gR9p+/0ewUN5vDZyR8vjxanxo2JdoR1hUhanCYPZjVmbfGwfeNcLokVBy OgjUFCLlxoASSyKPnTuOX517/cIUqac7LtubddI7XpyV6bNwC4Qr1h34hPwvDUlWJjWn O7m0PVky9AO6NDbqlkwqJX9kr8KOhpsWT7jxOMWcjOD8dIU1l6EEcL8T6Z07rfyuGAc0 66JjBmltIK1I6daLWGXlS3b1gXdq3Nn2HgW8bANdDAVN9SQUtfcEzwzS1e8XC3V2DQ9u vp+vBLQIwiAy9w2XSEMsgFcpalheQOk71m/GxeY0hW/C9/zBkk8osA0Ihu/6HGxerekl 3aOw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1741697987; x=1742302787; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=hMN1cLhziqhpOJDuVkl12QW9EXehxz96DoalbVVJvq0=; b=K2q2Pyf/t1PbTeF5A4cmgta3tgMr5ApFBVeq7n03zQt4i33WYgzvoIGsLU0P2zLnjy oNM8XC6jBUcFJ9jm9ZslKY2d/XI6hvIGgVvgfy5YA9afZ4CxHwrIV6gavV+FfQr2z+7R v+wLTF2dWSILTRGDwNg7zEzNlPj/2EOCJZ3ArOFMALNZUpCMlvsch4OgIZK99cHOdlcD TephpMFPFM1R2v3c5lRo/tSFEqpuslrALbcJYMr3dgwvCEaa8ZteNB5Ang0nAnlb5QJh yKCBLTs8Zb4jNy9C6ehdcvFye22whx54+lN2K9rrN+Q1lrWz6KfTebOOu+OfucKKSJwM 30hg== X-Forwarded-Encrypted: i=1; AJvYcCVizmK9PcwIMF+FkYpMoZ2MdKPqVW0yFbbgHbod0A7fJBkx0o/h1bj4aPqKCMeAdBibddO2NtuiOA==@nongnu.org X-Gm-Message-State: AOJu0Yy7DQjUnZXhTUwSgZrMUDSGYEU7rzKfA0KlET8YzvuLoqlIpawC kfqPNdy0E9ZqZPgDIiWEtbb8nahRnlwjUX1l9dl9GE9iPos0zz3SRVe21w== X-Gm-Gg: ASbGncvFVpJ0c+RevmfYEVVMWRRvPhiNz1b85xVYIomAJNGyx22VbCf61iplQ6fXmBQ kdNZ+5XNLsj53L8xzU4qkFhBedPHw+dvhmcf5dbgekMwM3g48sburn7dynNokxWigs4Ns+W9uGf P2BKJUrddd7LcPNcC0ZfXg7xEsyz4JPx9Y8h3uAuH1gzveWD7FgGh3qm2TidzNc4jief1D56ZND Og/g9Gy3H0aAIZCJec61a1NBNIEuLM3/rFalaXoUNqvkbFA7EU1DVJ10y5HOqz49z7+KaXNcDkQ Axqt1x+8C76mFhFctwyvMDYoBpTW3DLP/xPFyzuxCwnXRLirb6uikDEqHkgAlg== X-Google-Smtp-Source: AGHT+IE0ysSSHJbAK4sBVeloxEobHbZKuSuDoh1mll617LgWQJDxBczKLi3jFEtIs9BwkuUyBGK+Qw== X-Received: by 2002:a17:90b:4b11:b0:2ff:6ac2:c5a5 with SMTP id 98e67ed59e1d1-2ff7cf13a5emr23091757a91.26.1741697987463; Tue, 11 Mar 2025 05:59:47 -0700 (PDT) Received: from wheely.local0.net ([118.208.151.101]) by smtp.gmail.com with ESMTPSA id 98e67ed59e1d1-2ff4e773dddsm11822318a91.12.2025.03.11.05.59.44 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 11 Mar 2025 05:59:47 -0700 (PDT) From: Nicholas Piggin To: qemu-devel@nongnu.org Cc: Nicholas Piggin , qemu-ppc@nongnu.org, Frederic Barrat , Michael Kowal Subject: [PULL 26/72] ppc/xive2: Support group-matching when looking for target Date: Tue, 11 Mar 2025 22:57:20 +1000 Message-ID: <20250311125815.903177-27-npiggin@gmail.com> X-Mailer: git-send-email 2.47.1 In-Reply-To: <20250311125815.903177-1-npiggin@gmail.com> References: <20250311125815.903177-1-npiggin@gmail.com> MIME-Version: 1.0 Received-SPF: pass client-ip=2607:f8b0:4864:20::102a; envelope-from=npiggin@gmail.com; helo=mail-pj1-x102a.google.com X-Spam_score_int: -20 X-Spam_score: -2.1 X-Spam_bar: -- X-Spam_report: (-2.1 / 5.0 requ) BAYES_00=-1.9, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_AU=-0.1, DKIM_VALID_EF=-0.1, FREEMAIL_FROM=0.001, RCVD_IN_DNSWL_NONE=-0.0001, SPF_HELO_NONE=0.001, SPF_PASS=-0.001 autolearn=ham autolearn_force=no X-Spam_action: no action X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: qemu-devel-bounces+qemu-devel=archiver.kernel.org@nongnu.org Sender: qemu-devel-bounces+qemu-devel=archiver.kernel.org@nongnu.org From: Frederic Barrat If an END has the 'i' bit set (ignore), then it targets a group of VPs. The size of the group depends on the VP index of the target (first 0 found when looking at the least significant bits of the index) so a mask is applied on the VP index of a running thread to know if we have a match. Signed-off-by: Frederic Barrat Signed-off-by: Michael Kowal Reviewed-by: Nicholas Piggin Signed-off-by: Nicholas Piggin --- hw/intc/pnv_xive2.c | 38 +++++++++++++++--------- hw/intc/xive.c | 56 +++++++++++++++++++++++++----------- hw/intc/xive2.c | 65 ++++++++++++++++++++++++++++++------------ include/hw/ppc/xive.h | 5 +++- include/hw/ppc/xive2.h | 7 ++--- 5 files changed, 118 insertions(+), 53 deletions(-) diff --git a/hw/intc/pnv_xive2.c b/hw/intc/pnv_xive2.c index 9ed759417e..8429ccbd51 100644 --- a/hw/intc/pnv_xive2.c +++ b/hw/intc/pnv_xive2.c @@ -1,10 +1,9 @@ /* * QEMU PowerPC XIVE2 interrupt controller model (POWER10) * - * Copyright (c) 2019-2022, IBM Corporation. + * Copyright (c) 2019-2024, IBM Corporation. * - * This code is licensed under the GPL version 2 or later. See the - * COPYING file in the top-level directory. + * SPDX-License-Identifier: GPL-2.0-or-later */ #include "qemu/osdep.h" @@ -660,21 +659,34 @@ static int pnv_xive2_match_nvt(XivePresenter *xptr, uint8_t format, logic_serv); } - /* - * Save the context and follow on to catch duplicates, - * that we don't support yet. - */ if (ring != -1) { - if (match->tctx) { + /* + * For VP-specific match, finding more than one is a + * problem. For group notification, it's possible. + */ + if (!cam_ignore && match->tctx) { qemu_log_mask(LOG_GUEST_ERROR, "XIVE: already found a " "thread context NVT %x/%x\n", nvt_blk, nvt_idx); - return false; + /* Should set a FIR if we ever model it */ + return -1; + } + /* + * For a group notification, we need to know if the + * match is precluded first by checking the current + * thread priority. If the interrupt can be delivered, + * we always notify the first match (for now). + */ + if (cam_ignore && + xive2_tm_irq_precluded(tctx, ring, priority)) { + match->precluded = true; + } else { + if (!match->tctx) { + match->ring = ring; + match->tctx = tctx; + } + count++; } - - match->ring = ring; - match->tctx = tctx; - count++; } } } diff --git a/hw/intc/xive.c b/hw/intc/xive.c index 1e362f987a..3e4c932f19 100644 --- a/hw/intc/xive.c +++ b/hw/intc/xive.c @@ -1655,6 +1655,16 @@ static uint32_t xive_tctx_hw_cam_line(XivePresenter *xptr, XiveTCTX *tctx) return xive_nvt_cam_line(blk, 1 << 7 | (pir & 0x7f)); } +uint32_t xive_get_vpgroup_size(uint32_t nvp_index) +{ + /* + * Group size is a power of 2. The position of the first 0 + * (starting with the least significant bits) in the NVP index + * gives the size of the group. + */ + return 1 << (ctz32(~nvp_index) + 1); +} + static uint8_t xive_get_group_level(uint32_t nvp_index) { /* FIXME add crowd encoding */ @@ -1727,30 +1737,39 @@ int xive_presenter_tctx_match(XivePresenter *xptr, XiveTCTX *tctx, /* * This is our simple Xive Presenter Engine model. It is merged in the * Router as it does not require an extra object. - * - * It receives notification requests sent by the IVRE to find one - * matching NVT (or more) dispatched on the processor threads. In case - * of a single NVT notification, the process is abbreviated and the - * thread is signaled if a match is found. In case of a logical server - * notification (bits ignored at the end of the NVT identifier), the - * IVPE and IVRE select a winning thread using different filters. This - * involves 2 or 3 exchanges on the PowerBus that the model does not - * support. - * - * The parameters represent what is sent on the PowerBus */ bool xive_presenter_notify(XiveFabric *xfb, uint8_t format, uint8_t nvt_blk, uint32_t nvt_idx, bool cam_ignore, uint8_t priority, - uint32_t logic_serv) + uint32_t logic_serv, bool *precluded) { XiveFabricClass *xfc = XIVE_FABRIC_GET_CLASS(xfb); - XiveTCTXMatch match = { .tctx = NULL, .ring = 0 }; + XiveTCTXMatch match = { .tctx = NULL, .ring = 0, .precluded = false }; uint8_t group_level; int count; /* - * Ask the machine to scan the interrupt controllers for a match + * Ask the machine to scan the interrupt controllers for a match. + * + * For VP-specific notification, we expect at most one match and + * one call to the presenters is all we need (abbreviated notify + * sequence documented by the architecture). + * + * For VP-group notification, match_nvt() is the equivalent of the + * "histogram" and "poll" commands sent to the power bus to the + * presenters. 'count' could be more than one, but we always + * select the first match for now. 'precluded' tells if (at least) + * one thread matches but can't take the interrupt now because + * it's running at a more favored priority. We return the + * information to the router so that it can take appropriate + * actions (backlog, escalation, broadcast, etc...) + * + * If we were to implement a better way of dispatching the + * interrupt in case of multiple matches (instead of the first + * match), we would need a heuristic to elect a thread (for + * example, the hardware keeps track of an 'age' in the TIMA) and + * a new command to the presenters (the equivalent of the "assign" + * power bus command in the documented full notify sequence. */ count = xfc->match_nvt(xfb, format, nvt_blk, nvt_idx, cam_ignore, priority, logic_serv, &match); @@ -1763,6 +1782,8 @@ bool xive_presenter_notify(XiveFabric *xfb, uint8_t format, group_level = cam_ignore ? xive_get_group_level(nvt_idx) : 0; trace_xive_presenter_notify(nvt_blk, nvt_idx, match.ring, group_level); xive_tctx_pipr_update(match.tctx, match.ring, priority, group_level); + } else { + *precluded = match.precluded; } return !!count; @@ -1802,7 +1823,7 @@ void xive_router_end_notify(XiveRouter *xrtr, XiveEAS *eas) uint8_t nvt_blk; uint32_t nvt_idx; XiveNVT nvt; - bool found; + bool found, precluded; uint8_t end_blk = xive_get_field64(EAS_END_BLOCK, eas->w); uint32_t end_idx = xive_get_field64(EAS_END_INDEX, eas->w); @@ -1885,8 +1906,9 @@ void xive_router_end_notify(XiveRouter *xrtr, XiveEAS *eas) found = xive_presenter_notify(xrtr->xfb, format, nvt_blk, nvt_idx, xive_get_field32(END_W7_F0_IGNORE, end.w7), priority, - xive_get_field32(END_W7_F1_LOG_SERVER_ID, end.w7)); - + xive_get_field32(END_W7_F1_LOG_SERVER_ID, end.w7), + &precluded); + /* we don't support VP-group notification on P9, so precluded is not used */ /* TODO: Auto EOI. */ if (found) { diff --git a/hw/intc/xive2.c b/hw/intc/xive2.c index 62c3f05af9..41dbbdbb68 100644 --- a/hw/intc/xive2.c +++ b/hw/intc/xive2.c @@ -739,6 +739,12 @@ int xive2_router_write_nvgc(Xive2Router *xrtr, bool crowd, return xrc->write_nvgc(xrtr, crowd, nvgc_blk, nvgc_idx, nvgc); } +static bool xive2_vp_match_mask(uint32_t cam1, uint32_t cam2, + uint32_t vp_mask) +{ + return (cam1 & vp_mask) == (cam2 & vp_mask); +} + /* * The thread context register words are in big-endian format. */ @@ -753,44 +759,50 @@ int xive2_presenter_tctx_match(XivePresenter *xptr, XiveTCTX *tctx, uint32_t qw1w2 = xive_tctx_word2(&tctx->regs[TM_QW1_OS]); uint32_t qw0w2 = xive_tctx_word2(&tctx->regs[TM_QW0_USER]); - /* - * TODO (PowerNV): ignore mode. The low order bits of the NVT - * identifier are ignored in the "CAM" match. - */ + uint32_t vp_mask = 0xFFFFFFFF; if (format == 0) { - if (cam_ignore == true) { - /* - * F=0 & i=1: Logical server notification (bits ignored at - * the end of the NVT identifier) - */ - qemu_log_mask(LOG_UNIMP, "XIVE: no support for LS NVT %x/%x\n", - nvt_blk, nvt_idx); - return -1; + /* + * i=0: Specific NVT notification + * i=1: VP-group notification (bits ignored at the end of the + * NVT identifier) + */ + if (cam_ignore) { + vp_mask = ~(xive_get_vpgroup_size(nvt_idx) - 1); } - /* F=0 & i=0: Specific NVT notification */ + /* For VP-group notifications, threads with LGS=0 are excluded */ /* PHYS ring */ if ((be32_to_cpu(qw3w2) & TM2_QW3W2_VT) && - cam == xive2_tctx_hw_cam_line(xptr, tctx)) { + !(cam_ignore && tctx->regs[TM_QW3_HV_PHYS + TM_LGS] == 0) && + xive2_vp_match_mask(cam, + xive2_tctx_hw_cam_line(xptr, tctx), + vp_mask)) { return TM_QW3_HV_PHYS; } /* HV POOL ring */ if ((be32_to_cpu(qw2w2) & TM2_QW2W2_VP) && - cam == xive_get_field32(TM2_QW2W2_POOL_CAM, qw2w2)) { + !(cam_ignore && tctx->regs[TM_QW2_HV_POOL + TM_LGS] == 0) && + xive2_vp_match_mask(cam, + xive_get_field32(TM2_QW2W2_POOL_CAM, qw2w2), + vp_mask)) { return TM_QW2_HV_POOL; } /* OS ring */ if ((be32_to_cpu(qw1w2) & TM2_QW1W2_VO) && - cam == xive_get_field32(TM2_QW1W2_OS_CAM, qw1w2)) { + !(cam_ignore && tctx->regs[TM_QW1_OS + TM_LGS] == 0) && + xive2_vp_match_mask(cam, + xive_get_field32(TM2_QW1W2_OS_CAM, qw1w2), + vp_mask)) { return TM_QW1_OS; } } else { /* F=1 : User level Event-Based Branch (EBB) notification */ + /* FIXME: what if cam_ignore and LGS = 0 ? */ /* USER ring */ if ((be32_to_cpu(qw1w2) & TM2_QW1W2_VO) && (cam == xive_get_field32(TM2_QW1W2_OS_CAM, qw1w2)) && @@ -802,6 +814,22 @@ int xive2_presenter_tctx_match(XivePresenter *xptr, XiveTCTX *tctx, return -1; } +bool xive2_tm_irq_precluded(XiveTCTX *tctx, int ring, uint8_t priority) +{ + uint8_t *regs = &tctx->regs[ring]; + + /* + * The xive2_presenter_tctx_match() above tells if there's a match + * but for VP-group notification, we still need to look at the + * priority to know if the thread can take the interrupt now or if + * it is precluded. + */ + if (priority < regs[TM_CPPR]) { + return false; + } + return true; +} + static void xive2_router_realize(DeviceState *dev, Error **errp) { Xive2Router *xrtr = XIVE2_ROUTER(dev); @@ -841,7 +869,7 @@ static void xive2_router_end_notify(Xive2Router *xrtr, uint8_t end_blk, Xive2End end; uint8_t priority; uint8_t format; - bool found; + bool found, precluded; Xive2Nvp nvp; uint8_t nvp_blk; uint32_t nvp_idx; @@ -922,7 +950,8 @@ static void xive2_router_end_notify(Xive2Router *xrtr, uint8_t end_blk, found = xive_presenter_notify(xrtr->xfb, format, nvp_blk, nvp_idx, xive2_end_is_ignore(&end), priority, - xive_get_field32(END2_W7_F1_LOG_SERVER_ID, end.w7)); + xive_get_field32(END2_W7_F1_LOG_SERVER_ID, end.w7), + &precluded); /* TODO: Auto EOI. */ diff --git a/include/hw/ppc/xive.h b/include/hw/ppc/xive.h index 805b1d7b80..e78adaffa5 100644 --- a/include/hw/ppc/xive.h +++ b/include/hw/ppc/xive.h @@ -422,6 +422,7 @@ void xive_router_end_notify(XiveRouter *xrtr, XiveEAS *eas); typedef struct XiveTCTXMatch { XiveTCTX *tctx; uint8_t ring; + bool precluded; } XiveTCTXMatch; #define TYPE_XIVE_PRESENTER "xive-presenter" @@ -450,7 +451,9 @@ int xive_presenter_tctx_match(XivePresenter *xptr, XiveTCTX *tctx, bool xive_presenter_notify(XiveFabric *xfb, uint8_t format, uint8_t nvt_blk, uint32_t nvt_idx, bool cam_ignore, uint8_t priority, - uint32_t logic_serv); + uint32_t logic_serv, bool *precluded); + +uint32_t xive_get_vpgroup_size(uint32_t nvp_index); /* * XIVE Fabric (Interface between Interrupt Controller and Machine) diff --git a/include/hw/ppc/xive2.h b/include/hw/ppc/xive2.h index 5bccf41159..65154f78d8 100644 --- a/include/hw/ppc/xive2.h +++ b/include/hw/ppc/xive2.h @@ -1,11 +1,9 @@ /* * QEMU PowerPC XIVE2 interrupt controller model (POWER10) * - * Copyright (c) 2019-2022, IBM Corporation. - * - * This code is licensed under the GPL version 2 or later. See the - * COPYING file in the top-level directory. + * Copyright (c) 2019-2024, IBM Corporation. * + * SPDX-License-Identifier: GPL-2.0-or-later */ #ifndef PPC_XIVE2_H @@ -121,6 +119,7 @@ uint64_t xive2_tm_pull_os_ctx(XivePresenter *xptr, XiveTCTX *tctx, hwaddr offset, unsigned size); void xive2_tm_pull_os_ctx_ol(XivePresenter *xptr, XiveTCTX *tctx, hwaddr offset, uint64_t value, unsigned size); +bool xive2_tm_irq_precluded(XiveTCTX *tctx, int ring, uint8_t priority); void xive2_tm_set_hv_target(XivePresenter *xptr, XiveTCTX *tctx, hwaddr offset, uint64_t value, unsigned size); void xive2_tm_pull_phys_ctx_ol(XivePresenter *xptr, XiveTCTX *tctx, From patchwork Tue Mar 11 12:57:21 2025 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Nicholas Piggin X-Patchwork-Id: 14011910 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.lore.kernel.org (Postfix) with ESMTPS id 598C8C282EC for ; Tue, 11 Mar 2025 13:29:11 +0000 (UTC) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1trzGs-0000jx-NF; Tue, 11 Mar 2025 09:03:48 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1trzDE-00043v-NU; Tue, 11 Mar 2025 09:00:00 -0400 Received: from mail-pj1-x1036.google.com ([2607:f8b0:4864:20::1036]) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_128_GCM_SHA256:128) (Exim 4.90_1) (envelope-from ) id 1trzDB-00082v-Hp; Tue, 11 Mar 2025 09:00:00 -0400 Received: by mail-pj1-x1036.google.com with SMTP id 98e67ed59e1d1-2ff799d99dcso9005405a91.1; Tue, 11 Mar 2025 05:59:52 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20230601; t=1741697991; x=1742302791; darn=nongnu.org; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to; bh=xTjpRh8AshfIRm5pJ5AIa8+ub5kge53Qy5H2Kvu+cVA=; b=noBanvvLtEQvQktWO2jBxGBNNbqAQsBxKjHzU7TMfapOr6LnQgHuGjKPGWaeLv0dLu ZAfrVoee8bJNkinmugqbxRrPzCGSn9WWIrv6eN3QWWC8uBVuBzHmPLN7tXSC8WlrMFFj et5ANPBj76fjPwO8Hpycg/+fXjNgHR+pKVpm9G+957N2XlI4pGv0ICuGB+JO1sk4OEFF IQnmdmSgcX6Sf+5O7JlxBq1AEJFV2702kOlUzKz1GgvozY1TzV/UpRnR+qlV/TdaAMql q4oF98wOGKisLju3SC52ukIfGfK10kWyjOWPuRzr0NpJpsJyyf7+a9z1pK8YxB/x9kvC ANiA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1741697991; x=1742302791; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=xTjpRh8AshfIRm5pJ5AIa8+ub5kge53Qy5H2Kvu+cVA=; b=XEMIyMxhuJDbC3NZ+LUyNnnagOWhYqpzPxEyXhAnbLWKFrtX6DxH1MEk+9wRWHgUrG SlDE92D3iIju+m/TvTNrSxITdbSsy2D0gXp04guTVL20FlSZT5qFT2HynePWSxSlprcW mU2cr11v17UGZW/YN/MpElrJSKb9NH9EAV6GqI3FpzkC1BAmhtUFbMxHev5D8gKbzyPd cHTWHy5CzvVB9j0E2fQyujwURBwzXSi3J+UkGOb/PBV4CciUHlKB9sLS0BzD5RdQijYM UbbGeXJ0CbVzsho9bUuXhT9nk7aDPkByH48hRUhZA4Pp24hRTEtcKkVSyNNw2KsP7X23 stzA== X-Forwarded-Encrypted: i=1; AJvYcCVLT8855Ucfmk9D513+yfRCFTK6uxcnqS4G1SH8qIYh92gEjD+5p2I7xN9RdyRQOSIhUN5l0KPWaw==@nongnu.org X-Gm-Message-State: AOJu0YzqRC0Iz72tknHaA5w9a4YrCaCUqkAuQOAOyA4Qa6+nCMAmUPEf Q/ZegDe4S27tACnS76XIyhhI3gNmTCIPieOqbjrVm9Gy1bfoJ2y9OiTG5Q== X-Gm-Gg: ASbGncvY4WACg4mqg937Hr/iL9LcEw8yM6X/DXRMyeqxIsHXKwisn6qnMR2PCyFuFqs 7enUFO3noJsJEmJLUbiCcjTCFvj3YzOo+hSNichds2xUKlRIVFMpQkEYZkb7LgV558KL5J04II4 UA/ZvQhMx8u9E6lVKnd4uJUrsWPMDfEwhgIfH84riMRdsJJepMjX11hKa2iM7syz10amC1y8Rka NCy3C1r4uZ21NBkorBtGUmRgbgtXEaRnU36mzc/Xnd8AxUXH1SP3jwAo54uU/+aochZDpDCEcyI FxCcsUdQfbh7DGuSGGLACFEcTT/3d2CL2mlg3k3jKCu5suNzEaE= X-Google-Smtp-Source: AGHT+IEM67xUBNJBPEPT1mrvnjjezGC4Sj5o21YDfJsIN8s7vSw+oXHfHEE5Pb3+WJP0fGJhsXA+xA== X-Received: by 2002:a17:90b:4c81:b0:2fc:b40:339a with SMTP id 98e67ed59e1d1-2ff7ce7abdfmr27297036a91.10.1741697990449; Tue, 11 Mar 2025 05:59:50 -0700 (PDT) Received: from wheely.local0.net ([118.208.151.101]) by smtp.gmail.com with ESMTPSA id 98e67ed59e1d1-2ff4e773dddsm11822318a91.12.2025.03.11.05.59.47 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 11 Mar 2025 05:59:50 -0700 (PDT) From: Nicholas Piggin To: qemu-devel@nongnu.org Cc: Nicholas Piggin , qemu-ppc@nongnu.org, Frederic Barrat , Michael Kowal Subject: [PULL 27/72] ppc/xive2: Add undelivered group interrupt to backlog Date: Tue, 11 Mar 2025 22:57:21 +1000 Message-ID: <20250311125815.903177-28-npiggin@gmail.com> X-Mailer: git-send-email 2.47.1 In-Reply-To: <20250311125815.903177-1-npiggin@gmail.com> References: <20250311125815.903177-1-npiggin@gmail.com> MIME-Version: 1.0 Received-SPF: pass client-ip=2607:f8b0:4864:20::1036; envelope-from=npiggin@gmail.com; helo=mail-pj1-x1036.google.com X-Spam_score_int: -20 X-Spam_score: -2.1 X-Spam_bar: -- X-Spam_report: (-2.1 / 5.0 requ) BAYES_00=-1.9, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_AU=-0.1, DKIM_VALID_EF=-0.1, FREEMAIL_FROM=0.001, RCVD_IN_DNSWL_NONE=-0.0001, SPF_HELO_NONE=0.001, SPF_PASS=-0.001 autolearn=ham autolearn_force=no X-Spam_action: no action X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: qemu-devel-bounces+qemu-devel=archiver.kernel.org@nongnu.org Sender: qemu-devel-bounces+qemu-devel=archiver.kernel.org@nongnu.org From: Frederic Barrat When a group interrupt cannot be delivered, we need to: - increment the backlog counter for the group in the NVG table (if the END is configured to keep a backlog). - start a broadcast operation to set the LSMFB field on matching CPUs which can't take the interrupt now because they're running at too high a priority. [npiggin: squash in fixes from milesg] [milesg: only load the NVP if the END is !ignore] [milesg: always broadcast backlog, not only when there are precluded VPs] Signed-off-by: Frederic Barrat Signed-off-by: Michael Kowal Reviewed-by: Nicholas Piggin Signed-off-by: Nicholas Piggin --- hw/intc/pnv_xive2.c | 42 +++++++++++++ hw/intc/xive2.c | 136 ++++++++++++++++++++++++++++++++--------- hw/ppc/pnv.c | 22 ++++++- include/hw/ppc/xive.h | 5 ++ include/hw/ppc/xive2.h | 1 + 5 files changed, 175 insertions(+), 31 deletions(-) diff --git a/hw/intc/pnv_xive2.c b/hw/intc/pnv_xive2.c index 8429ccbd51..e7a7d1b50f 100644 --- a/hw/intc/pnv_xive2.c +++ b/hw/intc/pnv_xive2.c @@ -705,6 +705,47 @@ static uint32_t pnv_xive2_presenter_get_config(XivePresenter *xptr) return cfg; } +static int pnv_xive2_broadcast(XivePresenter *xptr, + uint8_t nvt_blk, uint32_t nvt_idx, + uint8_t priority) +{ + PnvXive2 *xive = PNV_XIVE2(xptr); + PnvChip *chip = xive->chip; + int i, j; + bool gen1_tima_os = + xive->cq_regs[CQ_XIVE_CFG >> 3] & CQ_XIVE_CFG_GEN1_TIMA_OS; + + for (i = 0; i < chip->nr_cores; i++) { + PnvCore *pc = chip->cores[i]; + CPUCore *cc = CPU_CORE(pc); + + for (j = 0; j < cc->nr_threads; j++) { + PowerPCCPU *cpu = pc->threads[j]; + XiveTCTX *tctx; + int ring; + + if (!pnv_xive2_is_cpu_enabled(xive, cpu)) { + continue; + } + + tctx = XIVE_TCTX(pnv_cpu_state(cpu)->intc); + + if (gen1_tima_os) { + ring = xive_presenter_tctx_match(xptr, tctx, 0, nvt_blk, + nvt_idx, true, 0); + } else { + ring = xive2_presenter_tctx_match(xptr, tctx, 0, nvt_blk, + nvt_idx, true, 0); + } + + if (ring != -1) { + xive2_tm_set_lsmfb(tctx, ring, priority); + } + } + } + return 0; +} + static uint8_t pnv_xive2_get_block_id(Xive2Router *xrtr) { return pnv_xive2_block_id(PNV_XIVE2(xrtr)); @@ -2444,6 +2485,7 @@ static void pnv_xive2_class_init(ObjectClass *klass, void *data) xpc->match_nvt = pnv_xive2_match_nvt; xpc->get_config = pnv_xive2_presenter_get_config; + xpc->broadcast = pnv_xive2_broadcast; }; static const TypeInfo pnv_xive2_info = { diff --git a/hw/intc/xive2.c b/hw/intc/xive2.c index 41dbbdbb68..44d891f1f6 100644 --- a/hw/intc/xive2.c +++ b/hw/intc/xive2.c @@ -53,7 +53,8 @@ static uint32_t xive2_nvgc_get_backlog(Xive2Nvgc *nvgc, uint8_t priority) /* * The per-priority backlog counters are 24-bit and the structure - * is stored in big endian + * is stored in big endian. NVGC is 32-bytes long, so 24-bytes from + * w2, which fits 8 priorities * 24-bits per priority. */ ptr = (uint8_t *)&nvgc->w2 + priority * 3; for (i = 0; i < 3; i++, ptr++) { @@ -62,6 +63,30 @@ static uint32_t xive2_nvgc_get_backlog(Xive2Nvgc *nvgc, uint8_t priority) return val; } +static void xive2_nvgc_set_backlog(Xive2Nvgc *nvgc, uint8_t priority, + uint32_t val) +{ + uint8_t *ptr, i; + uint32_t shift; + + if (priority > 7) { + return; + } + + if (val > 0xFFFFFF) { + val = 0xFFFFFF; + } + /* + * The per-priority backlog counters are 24-bit and the structure + * is stored in big endian + */ + ptr = (uint8_t *)&nvgc->w2 + priority * 3; + for (i = 0; i < 3; i++, ptr++) { + shift = 8 * (2 - i); + *ptr = (val >> shift) & 0xFF; + } +} + void xive2_eas_pic_print_info(Xive2Eas *eas, uint32_t lisn, GString *buf) { if (!xive2_eas_is_valid(eas)) { @@ -830,6 +855,19 @@ bool xive2_tm_irq_precluded(XiveTCTX *tctx, int ring, uint8_t priority) return true; } +void xive2_tm_set_lsmfb(XiveTCTX *tctx, int ring, uint8_t priority) +{ + uint8_t *regs = &tctx->regs[ring]; + + /* + * Called by the router during a VP-group notification when the + * thread matches but can't take the interrupt because it's + * already running at a more favored priority. It then stores the + * new interrupt priority in the LSMFB field. + */ + regs[TM_LSMFB] = priority; +} + static void xive2_router_realize(DeviceState *dev, Error **errp) { Xive2Router *xrtr = XIVE2_ROUTER(dev); @@ -870,7 +908,6 @@ static void xive2_router_end_notify(Xive2Router *xrtr, uint8_t end_blk, uint8_t priority; uint8_t format; bool found, precluded; - Xive2Nvp nvp; uint8_t nvp_blk; uint32_t nvp_idx; @@ -934,19 +971,6 @@ static void xive2_router_end_notify(Xive2Router *xrtr, uint8_t end_blk, nvp_blk = xive_get_field32(END2_W6_VP_BLOCK, end.w6); nvp_idx = xive_get_field32(END2_W6_VP_OFFSET, end.w6); - /* NVP cache lookup */ - if (xive2_router_get_nvp(xrtr, nvp_blk, nvp_idx, &nvp)) { - qemu_log_mask(LOG_GUEST_ERROR, "XIVE: no NVP %x/%x\n", - nvp_blk, nvp_idx); - return; - } - - if (!xive2_nvp_is_valid(&nvp)) { - qemu_log_mask(LOG_GUEST_ERROR, "XIVE: NVP %x/%x is invalid\n", - nvp_blk, nvp_idx); - return; - } - found = xive_presenter_notify(xrtr->xfb, format, nvp_blk, nvp_idx, xive2_end_is_ignore(&end), priority, @@ -962,10 +986,9 @@ static void xive2_router_end_notify(Xive2Router *xrtr, uint8_t end_blk, /* * If no matching NVP is dispatched on a HW thread : * - specific VP: update the NVP structure if backlog is activated - * - logical server : forward request to IVPE (not supported) + * - VP-group: update the backlog counter for that priority in the NVG */ if (xive2_end_is_backlog(&end)) { - uint8_t ipb; if (format == 1) { qemu_log_mask(LOG_GUEST_ERROR, @@ -974,19 +997,72 @@ static void xive2_router_end_notify(Xive2Router *xrtr, uint8_t end_blk, return; } - /* - * Record the IPB in the associated NVP structure for later - * use. The presenter will resend the interrupt when the vCPU - * is dispatched again on a HW thread. - */ - ipb = xive_get_field32(NVP2_W2_IPB, nvp.w2) | - xive_priority_to_ipb(priority); - nvp.w2 = xive_set_field32(NVP2_W2_IPB, nvp.w2, ipb); - xive2_router_write_nvp(xrtr, nvp_blk, nvp_idx, &nvp, 2); - - /* - * On HW, follows a "Broadcast Backlog" to IVPEs - */ + if (!xive2_end_is_ignore(&end)) { + uint8_t ipb; + Xive2Nvp nvp; + + /* NVP cache lookup */ + if (xive2_router_get_nvp(xrtr, nvp_blk, nvp_idx, &nvp)) { + qemu_log_mask(LOG_GUEST_ERROR, "XIVE: no NVP %x/%x\n", + nvp_blk, nvp_idx); + return; + } + + if (!xive2_nvp_is_valid(&nvp)) { + qemu_log_mask(LOG_GUEST_ERROR, "XIVE: NVP %x/%x is invalid\n", + nvp_blk, nvp_idx); + return; + } + + /* + * Record the IPB in the associated NVP structure for later + * use. The presenter will resend the interrupt when the vCPU + * is dispatched again on a HW thread. + */ + ipb = xive_get_field32(NVP2_W2_IPB, nvp.w2) | + xive_priority_to_ipb(priority); + nvp.w2 = xive_set_field32(NVP2_W2_IPB, nvp.w2, ipb); + xive2_router_write_nvp(xrtr, nvp_blk, nvp_idx, &nvp, 2); + } else { + Xive2Nvgc nvg; + uint32_t backlog; + + /* For groups, the per-priority backlog counters are in the NVG */ + if (xive2_router_get_nvgc(xrtr, false, nvp_blk, nvp_idx, &nvg)) { + qemu_log_mask(LOG_GUEST_ERROR, "XIVE: no NVG %x/%x\n", + nvp_blk, nvp_idx); + return; + } + + if (!xive2_nvgc_is_valid(&nvg)) { + qemu_log_mask(LOG_GUEST_ERROR, "XIVE: NVG %x/%x is invalid\n", + nvp_blk, nvp_idx); + return; + } + + /* + * Increment the backlog counter for that priority. + * We only call broadcast the first time the counter is + * incremented. broadcast will set the LSMFB field of the TIMA of + * relevant threads so that they know an interrupt is pending. + */ + backlog = xive2_nvgc_get_backlog(&nvg, priority) + 1; + xive2_nvgc_set_backlog(&nvg, priority, backlog); + xive2_router_write_nvgc(xrtr, false, nvp_blk, nvp_idx, &nvg); + + if (backlog == 1) { + XiveFabricClass *xfc = XIVE_FABRIC_GET_CLASS(xrtr->xfb); + xfc->broadcast(xrtr->xfb, nvp_blk, nvp_idx, priority); + + if (!xive2_end_is_precluded_escalation(&end)) { + /* + * The interrupt will be picked up when the + * matching thread lowers its priority level + */ + return; + } + } + } } do_escalation: diff --git a/hw/ppc/pnv.c b/hw/ppc/pnv.c index 6fec455ff9..af836c1388 100644 --- a/hw/ppc/pnv.c +++ b/hw/ppc/pnv.c @@ -1,7 +1,9 @@ /* * QEMU PowerPC PowerNV machine model * - * Copyright (c) 2016, IBM Corporation. + * Copyright (c) 2016-2024, IBM Corporation. + * + * SPDX-License-Identifier: GPL-2.0-or-later * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -2662,6 +2664,23 @@ static int pnv10_xive_match_nvt(XiveFabric *xfb, uint8_t format, return total_count; } +static int pnv10_xive_broadcast(XiveFabric *xfb, + uint8_t nvt_blk, uint32_t nvt_idx, + uint8_t priority) +{ + PnvMachineState *pnv = PNV_MACHINE(xfb); + int i; + + for (i = 0; i < pnv->num_chips; i++) { + Pnv10Chip *chip10 = PNV10_CHIP(pnv->chips[i]); + XivePresenter *xptr = XIVE_PRESENTER(&chip10->xive); + XivePresenterClass *xpc = XIVE_PRESENTER_GET_CLASS(xptr); + + xpc->broadcast(xptr, nvt_blk, nvt_idx, priority); + } + return 0; +} + static bool pnv_machine_get_big_core(Object *obj, Error **errp) { PnvMachineState *pnv = PNV_MACHINE(obj); @@ -2795,6 +2814,7 @@ static void pnv_machine_p10_common_class_init(ObjectClass *oc, void *data) pmc->dt_power_mgt = pnv_dt_power_mgt; xfc->match_nvt = pnv10_xive_match_nvt; + xfc->broadcast = pnv10_xive_broadcast; machine_class_allow_dynamic_sysbus_dev(mc, TYPE_PNV_PHB); } diff --git a/include/hw/ppc/xive.h b/include/hw/ppc/xive.h index e78adaffa5..6a410c6f1a 100644 --- a/include/hw/ppc/xive.h +++ b/include/hw/ppc/xive.h @@ -442,6 +442,9 @@ struct XivePresenterClass { uint32_t logic_serv, XiveTCTXMatch *match); bool (*in_kernel)(const XivePresenter *xptr); uint32_t (*get_config)(XivePresenter *xptr); + int (*broadcast)(XivePresenter *xptr, + uint8_t nvt_blk, uint32_t nvt_idx, + uint8_t priority); }; int xive_presenter_tctx_match(XivePresenter *xptr, XiveTCTX *tctx, @@ -472,6 +475,8 @@ struct XiveFabricClass { uint8_t nvt_blk, uint32_t nvt_idx, bool cam_ignore, uint8_t priority, uint32_t logic_serv, XiveTCTXMatch *match); + int (*broadcast)(XiveFabric *xfb, uint8_t nvt_blk, uint32_t nvt_idx, + uint8_t priority); }; /* diff --git a/include/hw/ppc/xive2.h b/include/hw/ppc/xive2.h index 65154f78d8..ebf301bb5b 100644 --- a/include/hw/ppc/xive2.h +++ b/include/hw/ppc/xive2.h @@ -120,6 +120,7 @@ uint64_t xive2_tm_pull_os_ctx(XivePresenter *xptr, XiveTCTX *tctx, void xive2_tm_pull_os_ctx_ol(XivePresenter *xptr, XiveTCTX *tctx, hwaddr offset, uint64_t value, unsigned size); bool xive2_tm_irq_precluded(XiveTCTX *tctx, int ring, uint8_t priority); +void xive2_tm_set_lsmfb(XiveTCTX *tctx, int ring, uint8_t priority); void xive2_tm_set_hv_target(XivePresenter *xptr, XiveTCTX *tctx, hwaddr offset, uint64_t value, unsigned size); void xive2_tm_pull_phys_ctx_ol(XivePresenter *xptr, XiveTCTX *tctx, From patchwork Tue Mar 11 12:57:22 2025 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Nicholas Piggin X-Patchwork-Id: 14011805 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.lore.kernel.org (Postfix) with ESMTPS id 16C56C28B2E for ; Tue, 11 Mar 2025 13:06:04 +0000 (UTC) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1trzGc-0000DJ-Tj; Tue, 11 Mar 2025 09:03:31 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1trzDM-0004Ff-Mc; Tue, 11 Mar 2025 09:00:13 -0400 Received: from mail-pj1-x102d.google.com ([2607:f8b0:4864:20::102d]) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_128_GCM_SHA256:128) (Exim 4.90_1) (envelope-from ) id 1trzDD-00083P-3e; Tue, 11 Mar 2025 09:00:06 -0400 Received: by mail-pj1-x102d.google.com with SMTP id 98e67ed59e1d1-2ff64550991so8238766a91.0; Tue, 11 Mar 2025 05:59:56 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20230601; t=1741697993; x=1742302793; darn=nongnu.org; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to; bh=LV73eZk7vJrbkDVPoyzfVDHfZQAl5NgriC87PEyH8zI=; b=jWBt3INKVyF7UbU/k3bt+TiuhMUSnDGqf5TVlgL0LdvsZ8iMEWMAmdsinuk5QixYzz 2div17Mvs61tdhVtZhgS9KNPEBfV990CgsjGYEuj7JEm7vol0f7cBG6hsB619V3hLNWh gQhx5yUfXdNHfZkAx0+kM0NVkor/HpzBSDOtUArEYPVmWVNI2RRpcDS7aS+9ajnfSh6M bysV2gOIhOEDTYTw3s1poY7UwMSvyK63sk8FlXXjVroibLhyhLvJD23AzrtVfAU/Ktf4 wTL3e3qw7lpR72iU1z6Z7mg7GDtbWkGbG+QPQeZbD0uicOVr7ALlIhJJnDYBeTgvkjHK pBRQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1741697993; x=1742302793; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=LV73eZk7vJrbkDVPoyzfVDHfZQAl5NgriC87PEyH8zI=; b=auihO09VU91kmmy1v9Yq0DXr6eaWuH4S7w4rgt7/qc/LWgRVCkMLHNR5UE58Q5t3HX rfN7iISiGrtlwjLXS2Q+lZtmd70wDawu3wULmqO0JPILSpH2QrV+Rh6CQg2/Mrw+TeuX TE+NWmb1G72AaGzgFQ+tBHSRGpXF0XL651adtJQ8ijCBYFDzZuIaqQWWuem59YXDSDC1 c5M8R/NBuET55nHDn6pWcC5yfF86/NkEm3I1kJJLoNeqj52bdNBDQsQfcIevy0w6xGX5 odEu7FNNsufMsiIVHbj9RU0AWqLw4AEfw42MXqsY3JfGITIDUmPfZxD9vCwIKd1qXOKX 9Tsw== X-Forwarded-Encrypted: i=1; AJvYcCXLSOCr4j/vBgZgzL2D+HO7xgGNJq3t+UgWrxYMsh0HNi746naG/tnJt2KYdp+FpOejZOiY1BMCEg==@nongnu.org X-Gm-Message-State: AOJu0YzSF0WH2jeWY9bJfxNjgNxTCfXrSWLBx7C6ghbpDqswBYESe8zv EdC0nv8Y+Do2hYntT1xDd4PNhCrEW3Dl2Xkto4QOzua6LWvG5xcA48M7WA== X-Gm-Gg: ASbGncs0wJhV9xfnocayeo/yxbX1yP/gXqEkPONlVwDknf0miFkIZNNjjuC2pl9af2t sGVp1DPw61Rxq7uhz6EWh2FnJ1YgYWw3uzuEhQSrq72kXLq+3X4gBwVe8VK6zCd6TeUIny1uB6h lDyD2gT9sIRX7prxMIfLCkarUzDr4i0AH1PX8m9rUz+8/SfeUiNktKJQ7j1fuJ/wDSwQMoQ+jLK oMWE+n5SnAbmMI8CFWBx/Tca+qForEchMRe3JsAglz+K0iAAgQugGd+2lXwfajvQIhZ09v7mtuR NC20cXp5cXDBiW2xtRpI9Rv+16RaUdBmQDZhzzcYknO701aOdFk= X-Google-Smtp-Source: AGHT+IEzdBJbCY0edAKOTyoyZsqDTvJiP3s6ENrxFsqCZXVRPsMQugUOTEY1T9ttRK/0wTha6xJnaA== X-Received: by 2002:a17:90b:1a8c:b0:2ee:94d1:7a89 with SMTP id 98e67ed59e1d1-2ff7ce6f36emr24072499a91.1.1741697993428; Tue, 11 Mar 2025 05:59:53 -0700 (PDT) Received: from wheely.local0.net ([118.208.151.101]) by smtp.gmail.com with ESMTPSA id 98e67ed59e1d1-2ff4e773dddsm11822318a91.12.2025.03.11.05.59.50 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 11 Mar 2025 05:59:53 -0700 (PDT) From: Nicholas Piggin To: qemu-devel@nongnu.org Cc: Nicholas Piggin , qemu-ppc@nongnu.org, Frederic Barrat , Michael Kowal Subject: [PULL 28/72] ppc/xive2: Process group backlog when pushing an OS context Date: Tue, 11 Mar 2025 22:57:22 +1000 Message-ID: <20250311125815.903177-29-npiggin@gmail.com> X-Mailer: git-send-email 2.47.1 In-Reply-To: <20250311125815.903177-1-npiggin@gmail.com> References: <20250311125815.903177-1-npiggin@gmail.com> MIME-Version: 1.0 Received-SPF: pass client-ip=2607:f8b0:4864:20::102d; envelope-from=npiggin@gmail.com; helo=mail-pj1-x102d.google.com X-Spam_score_int: -20 X-Spam_score: -2.1 X-Spam_bar: -- X-Spam_report: (-2.1 / 5.0 requ) BAYES_00=-1.9, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_AU=-0.1, DKIM_VALID_EF=-0.1, FREEMAIL_FROM=0.001, RCVD_IN_DNSWL_NONE=-0.0001, SPF_HELO_NONE=0.001, SPF_PASS=-0.001 autolearn=ham autolearn_force=no X-Spam_action: no action X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: qemu-devel-bounces+qemu-devel=archiver.kernel.org@nongnu.org Sender: qemu-devel-bounces+qemu-devel=archiver.kernel.org@nongnu.org From: Frederic Barrat When pushing an OS context, we were already checking if there was a pending interrupt in the IPB and sending a notification if needed. We also need to check if there is a pending group interrupt stored in the NVG table. To avoid useless backlog scans, we only scan if the NVP belongs to a group. Signed-off-by: Frederic Barrat Signed-off-by: Michael Kowal Reviewed-by: Nicholas Piggin Signed-off-by: Nicholas Piggin --- hw/intc/xive2.c | 97 +++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 97 insertions(+) diff --git a/hw/intc/xive2.c b/hw/intc/xive2.c index 44d891f1f6..2fa7b90669 100644 --- a/hw/intc/xive2.c +++ b/hw/intc/xive2.c @@ -279,6 +279,85 @@ static void xive2_end_enqueue(Xive2End *end, uint32_t data) end->w1 = xive_set_field32(END2_W1_PAGE_OFF, end->w1, qindex); } +/* + * Scan the group chain and return the highest priority and group + * level of pending group interrupts. + */ +static uint8_t xive2_presenter_backlog_scan(XivePresenter *xptr, + uint8_t nvp_blk, uint32_t nvp_idx, + uint8_t first_group, + uint8_t *out_level) +{ + Xive2Router *xrtr = XIVE2_ROUTER(xptr); + uint32_t nvgc_idx, mask; + uint32_t current_level, count; + uint8_t prio; + Xive2Nvgc nvgc; + + for (prio = 0; prio <= XIVE_PRIORITY_MAX; prio++) { + current_level = first_group & 0xF; + + while (current_level) { + mask = (1 << current_level) - 1; + nvgc_idx = nvp_idx & ~mask; + nvgc_idx |= mask >> 1; + qemu_log("fxb %s checking backlog for prio %d group idx %x\n", + __func__, prio, nvgc_idx); + + if (xive2_router_get_nvgc(xrtr, false, nvp_blk, nvgc_idx, &nvgc)) { + qemu_log_mask(LOG_GUEST_ERROR, "XIVE: No NVG %x/%x\n", + nvp_blk, nvgc_idx); + return 0xFF; + } + if (!xive2_nvgc_is_valid(&nvgc)) { + qemu_log_mask(LOG_GUEST_ERROR, "XIVE: Invalid NVG %x/%x\n", + nvp_blk, nvgc_idx); + return 0xFF; + } + + count = xive2_nvgc_get_backlog(&nvgc, prio); + if (count) { + *out_level = current_level; + return prio; + } + current_level = xive_get_field32(NVGC2_W0_PGONEXT, nvgc.w0) & 0xF; + } + } + return 0xFF; +} + +static void xive2_presenter_backlog_decr(XivePresenter *xptr, + uint8_t nvp_blk, uint32_t nvp_idx, + uint8_t group_prio, + uint8_t group_level) +{ + Xive2Router *xrtr = XIVE2_ROUTER(xptr); + uint32_t nvgc_idx, mask, count; + Xive2Nvgc nvgc; + + group_level &= 0xF; + mask = (1 << group_level) - 1; + nvgc_idx = nvp_idx & ~mask; + nvgc_idx |= mask >> 1; + + if (xive2_router_get_nvgc(xrtr, false, nvp_blk, nvgc_idx, &nvgc)) { + qemu_log_mask(LOG_GUEST_ERROR, "XIVE: No NVG %x/%x\n", + nvp_blk, nvgc_idx); + return; + } + if (!xive2_nvgc_is_valid(&nvgc)) { + qemu_log_mask(LOG_GUEST_ERROR, "XIVE: Invalid NVG %x/%x\n", + nvp_blk, nvgc_idx); + return; + } + count = xive2_nvgc_get_backlog(&nvgc, group_prio); + if (!count) { + return; + } + xive2_nvgc_set_backlog(&nvgc, group_prio, count - 1); + xive2_router_write_nvgc(xrtr, false, nvp_blk, nvgc_idx, &nvgc); +} + /* * XIVE Thread Interrupt Management Area (TIMA) - Gen2 mode * @@ -588,9 +667,13 @@ static void xive2_tctx_need_resend(Xive2Router *xrtr, XiveTCTX *tctx, uint8_t nvp_blk, uint32_t nvp_idx, bool do_restore) { + XivePresenter *xptr = XIVE_PRESENTER(xrtr); uint8_t ipb; uint8_t backlog_level; + uint8_t group_level; + uint8_t first_group; uint8_t backlog_prio; + uint8_t group_prio; uint8_t *regs = &tctx->regs[TM_QW1_OS]; Xive2Nvp nvp; @@ -625,6 +708,20 @@ static void xive2_tctx_need_resend(Xive2Router *xrtr, XiveTCTX *tctx, backlog_prio = xive_ipb_to_pipr(ipb); backlog_level = 0; + first_group = xive_get_field32(NVP2_W0_PGOFIRST, nvp.w0); + if (first_group && regs[TM_LSMFB] < backlog_prio) { + group_prio = xive2_presenter_backlog_scan(xptr, nvp_blk, nvp_idx, + first_group, &group_level); + regs[TM_LSMFB] = group_prio; + if (regs[TM_LGS] && group_prio < backlog_prio) { + /* VP can take a group interrupt */ + xive2_presenter_backlog_decr(xptr, nvp_blk, nvp_idx, + group_prio, group_level); + backlog_prio = group_prio; + backlog_level = group_level; + } + } + /* * Compute the PIPR based on the restored state. * It will raise the External interrupt signal if needed. From patchwork Tue Mar 11 12:57:23 2025 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Nicholas Piggin X-Patchwork-Id: 14011826 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.lore.kernel.org (Postfix) with ESMTPS id D7B54C282EC for ; Tue, 11 Mar 2025 13:11:44 +0000 (UTC) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1trzDx-0004p6-2b; Tue, 11 Mar 2025 09:00:50 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1trzDL-0004Fh-PI; Tue, 11 Mar 2025 09:00:08 -0400 Received: from mail-pj1-x102c.google.com ([2607:f8b0:4864:20::102c]) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_128_GCM_SHA256:128) (Exim 4.90_1) (envelope-from ) id 1trzDF-000840-QC; Tue, 11 Mar 2025 09:00:06 -0400 Received: by mail-pj1-x102c.google.com with SMTP id 98e67ed59e1d1-2feb96064e4so10448206a91.1; Tue, 11 Mar 2025 05:59:59 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20230601; t=1741697997; x=1742302797; darn=nongnu.org; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to; bh=vHn+7OUywAbF6FO5dZ4T4+uIeHrdZtwa40tDfqPgy7A=; b=Psudf4yGVd2ZJITxMYM22OKN0cf70PcUSaNfLZDlKFCPeauA09m6KI9dmQowjthw+y 5JPQwb7/CCsHkmAgyjmCb9HFsZLh99g3k6tnjvnlpryBeAxhb5qwipgQ7oahWTKIO54x +C4ajFGjVtUtY7MELLFTbQ5GmApI57mQmjghLei35WhdW3TJnm66MmjWLFXZEqOJ5lup uauQylig3fMCqgmV8oklQ13PIGH3RFV9wIxAM8odX9z/T64jA0sUICl/D0XHVXjm6h2+ HPF88wQa0PNq87pqL/yyW0Dde4sVr0+SxNkigudXf3ghfU2OzIpUT+1EvEe1wU5uAMCO um7g== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1741697997; x=1742302797; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=vHn+7OUywAbF6FO5dZ4T4+uIeHrdZtwa40tDfqPgy7A=; b=EPYp/Ipx3GWX52i4yWND+obdd1o20yunktW7k/xEu1XbDISNi2cE2DXBL9V1ru0FHD 77+GTNprkw2yb4vzA//z00N/BuvSZewS9okhy0HS06QF/dIgiln1TEh//WiinqQ4jAnd ZY20G8GesKOi74rHvMtxJ9D3pOxPocqv0bRDDdbtp2RoZKqZQQZQK7fznxxYzrmRAH/c OcWtytQhBJEvnlKi0eAhvik748pACApx2E+wfrZNLxsZXN3pjd/EyadpB54kV6AEMhLa jYlU1u+UZBTLZQsiabxf05ALl/zokNCgOU65CR53uSoiUglzvA1sfHIs1iAWB8ZquLsp SvxQ== X-Forwarded-Encrypted: i=1; AJvYcCXfAsWG+lGNNlJrHlMsvwu9pMWgufkfqKDt67ktkMeZ3CNK4teDcAdZuc4mFWrcujo0Ng6eNR6TuA==@nongnu.org X-Gm-Message-State: AOJu0Yy9iVMlu7y5KAW4zJfX3zlVOpeDWFWTHaW5wyk+g7I2G6E+MOD8 zHJHnHyq7raRWHA47rcCUliouOcXir8xuRZlH1NIwPcRtX6I0UWNsZdp1g== X-Gm-Gg: ASbGncvoMXzMEa3ODJDevpnpZUVbhgZiGLCTSyB7NTtE3g7/q9GbzALAFi7wEQp1kBc iNDLu8y3utjvQhisvRYLVdbm6I8lUV5r1SPM5VuhBZog8/JzA24RIW8HiseNfJ76eKhY3eu5qEQ DrVbfLbA72EkqXJIUZhA9/C/P+VfvTYMlS1PH/6mTTNJS2GfYvvW8GP9zC46pnOkAce6t63GGyO WZjpyGwcFvsFyICb+Wq/KNg4476GadZ6AdgWMFazC46R+XohdnoEyrH7Mon+pAnPgv78B6A+KX1 P77UaKWtn+cdT/8CwagiQUvAkGHHM4jF0ISXOK3UWcQdzQ3mJQc= X-Google-Smtp-Source: AGHT+IEWWLTlPLkk0d6vRY14TnrdFBc0oc0LqTtBycsYZpBwaZb3VOwD/4MqE5ApmwUm0Pi0FHb/fw== X-Received: by 2002:a17:90b:2883:b0:2ff:52e1:c49f with SMTP id 98e67ed59e1d1-2ff7ced8c0amr23219572a91.26.1741697996495; Tue, 11 Mar 2025 05:59:56 -0700 (PDT) Received: from wheely.local0.net ([118.208.151.101]) by smtp.gmail.com with ESMTPSA id 98e67ed59e1d1-2ff4e773dddsm11822318a91.12.2025.03.11.05.59.53 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 11 Mar 2025 05:59:56 -0700 (PDT) From: Nicholas Piggin To: qemu-devel@nongnu.org Cc: Nicholas Piggin , qemu-ppc@nongnu.org, Frederic Barrat , Michael Kowal Subject: [PULL 29/72] ppc/xive2: Process group backlog when updating the CPPR Date: Tue, 11 Mar 2025 22:57:23 +1000 Message-ID: <20250311125815.903177-30-npiggin@gmail.com> X-Mailer: git-send-email 2.47.1 In-Reply-To: <20250311125815.903177-1-npiggin@gmail.com> References: <20250311125815.903177-1-npiggin@gmail.com> MIME-Version: 1.0 Received-SPF: pass client-ip=2607:f8b0:4864:20::102c; envelope-from=npiggin@gmail.com; helo=mail-pj1-x102c.google.com X-Spam_score_int: -20 X-Spam_score: -2.1 X-Spam_bar: -- X-Spam_report: (-2.1 / 5.0 requ) BAYES_00=-1.9, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_AU=-0.1, DKIM_VALID_EF=-0.1, FREEMAIL_FROM=0.001, RCVD_IN_DNSWL_NONE=-0.0001, SPF_HELO_NONE=0.001, SPF_PASS=-0.001 autolearn=ham autolearn_force=no X-Spam_action: no action X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: qemu-devel-bounces+qemu-devel=archiver.kernel.org@nongnu.org Sender: qemu-devel-bounces+qemu-devel=archiver.kernel.org@nongnu.org From: Frederic Barrat When the hypervisor or OS pushes a new value to the CPPR, if the LSMFB value is lower than the new CPPR value, there could be a pending group interrupt in the backlog, so it needs to be scanned. Signed-off-by: Frederic Barrat Signed-off-by: Michael Kowal Reviewed-by: Nicholas Piggin Signed-off-by: Nicholas Piggin --- hw/intc/xive.c | 4 +- hw/intc/xive2.c | 173 ++++++++++++++++++++++++++++++++++++++++- include/hw/ppc/xive2.h | 4 + 3 files changed, 177 insertions(+), 4 deletions(-) diff --git a/hw/intc/xive.c b/hw/intc/xive.c index 3e4c932f19..535e59646f 100644 --- a/hw/intc/xive.c +++ b/hw/intc/xive.c @@ -589,7 +589,7 @@ static const XiveTmOp xive2_tm_operations[] = { * MMIOs below 2K : raw values and special operations without side * effects */ - { XIVE_TM_OS_PAGE, TM_QW1_OS + TM_CPPR, 1, xive_tm_set_os_cppr, + { XIVE_TM_OS_PAGE, TM_QW1_OS + TM_CPPR, 1, xive2_tm_set_os_cppr, NULL }, { XIVE_TM_HV_PAGE, TM_QW1_OS + TM_WORD2, 4, xive2_tm_push_os_ctx, NULL }, @@ -597,7 +597,7 @@ static const XiveTmOp xive2_tm_operations[] = { NULL }, { XIVE_TM_OS_PAGE, TM_QW1_OS + TM_LGS, 1, xive_tm_set_os_lgs, NULL }, - { XIVE_TM_HV_PAGE, TM_QW3_HV_PHYS + TM_CPPR, 1, xive_tm_set_hv_cppr, + { XIVE_TM_HV_PAGE, TM_QW3_HV_PHYS + TM_CPPR, 1, xive2_tm_set_hv_cppr, NULL }, { XIVE_TM_HV_PAGE, TM_QW3_HV_PHYS + TM_WORD2, 1, xive_tm_vt_push, NULL }, diff --git a/hw/intc/xive2.c b/hw/intc/xive2.c index 2fa7b90669..017c0f8bb4 100644 --- a/hw/intc/xive2.c +++ b/hw/intc/xive2.c @@ -17,6 +17,7 @@ #include "hw/ppc/xive.h" #include "hw/ppc/xive2.h" #include "hw/ppc/xive2_regs.h" +#include "trace.h" uint32_t xive2_router_get_config(Xive2Router *xrtr) { @@ -768,6 +769,172 @@ void xive2_tm_push_os_ctx(XivePresenter *xptr, XiveTCTX *tctx, } } +static int xive2_tctx_get_nvp_indexes(XiveTCTX *tctx, uint8_t ring, + uint32_t *nvp_blk, uint32_t *nvp_idx) +{ + uint32_t w2, cam; + + w2 = xive_tctx_word2(&tctx->regs[ring]); + switch (ring) { + case TM_QW1_OS: + if (!(be32_to_cpu(w2) & TM2_QW1W2_VO)) { + return -1; + } + cam = xive_get_field32(TM2_QW1W2_OS_CAM, w2); + break; + case TM_QW2_HV_POOL: + if (!(be32_to_cpu(w2) & TM2_QW2W2_VP)) { + return -1; + } + cam = xive_get_field32(TM2_QW2W2_POOL_CAM, w2); + break; + case TM_QW3_HV_PHYS: + if (!(be32_to_cpu(w2) & TM2_QW3W2_VT)) { + return -1; + } + cam = xive2_tctx_hw_cam_line(tctx->xptr, tctx); + break; + default: + return -1; + } + *nvp_blk = xive2_nvp_blk(cam); + *nvp_idx = xive2_nvp_idx(cam); + return 0; +} + +static void xive2_tctx_set_cppr(XiveTCTX *tctx, uint8_t ring, uint8_t cppr) +{ + uint8_t *regs = &tctx->regs[ring]; + Xive2Router *xrtr = XIVE2_ROUTER(tctx->xptr); + uint8_t old_cppr, backlog_prio, first_group, group_level = 0; + uint8_t pipr_min, lsmfb_min, ring_min; + bool group_enabled; + uint32_t nvp_blk, nvp_idx; + Xive2Nvp nvp; + int rc; + + trace_xive_tctx_set_cppr(tctx->cs->cpu_index, ring, + regs[TM_IPB], regs[TM_PIPR], + cppr, regs[TM_NSR]); + + if (cppr > XIVE_PRIORITY_MAX) { + cppr = 0xff; + } + + old_cppr = regs[TM_CPPR]; + regs[TM_CPPR] = cppr; + + /* + * Recompute the PIPR based on local pending interrupts. It will + * be adjusted below if needed in case of pending group interrupts. + */ + pipr_min = xive_ipb_to_pipr(regs[TM_IPB]); + group_enabled = !!regs[TM_LGS]; + lsmfb_min = (group_enabled) ? regs[TM_LSMFB] : 0xff; + ring_min = ring; + + /* PHYS updates also depend on POOL values */ + if (ring == TM_QW3_HV_PHYS) { + uint8_t *pregs = &tctx->regs[TM_QW2_HV_POOL]; + + /* POOL values only matter if POOL ctx is valid */ + if (pregs[TM_WORD2] & 0x80) { + + uint8_t pool_pipr = xive_ipb_to_pipr(pregs[TM_IPB]); + uint8_t pool_lsmfb = pregs[TM_LSMFB]; + + /* + * Determine highest priority interrupt and + * remember which ring has it. + */ + if (pool_pipr < pipr_min) { + pipr_min = pool_pipr; + if (pool_pipr < lsmfb_min) { + ring_min = TM_QW2_HV_POOL; + } + } + + /* Values needed for group priority calculation */ + if (pregs[TM_LGS] && (pool_lsmfb < lsmfb_min)) { + group_enabled = true; + lsmfb_min = pool_lsmfb; + if (lsmfb_min < pipr_min) { + ring_min = TM_QW2_HV_POOL; + } + } + } + } + regs[TM_PIPR] = pipr_min; + + rc = xive2_tctx_get_nvp_indexes(tctx, ring_min, &nvp_blk, &nvp_idx); + if (rc) { + qemu_log_mask(LOG_GUEST_ERROR, "XIVE: set CPPR on invalid context\n"); + return; + } + + if (cppr < old_cppr) { + /* + * FIXME: check if there's a group interrupt being presented + * and if the new cppr prevents it. If so, then the group + * interrupt needs to be re-added to the backlog and + * re-triggered (see re-trigger END info in the NVGC + * structure) + */ + } + + if (group_enabled && + lsmfb_min < cppr && + lsmfb_min < regs[TM_PIPR]) { + /* + * Thread has seen a group interrupt with a higher priority + * than the new cppr or pending local interrupt. Check the + * backlog + */ + if (xive2_router_get_nvp(xrtr, nvp_blk, nvp_idx, &nvp)) { + qemu_log_mask(LOG_GUEST_ERROR, "XIVE: No NVP %x/%x\n", + nvp_blk, nvp_idx); + return; + } + + if (!xive2_nvp_is_valid(&nvp)) { + qemu_log_mask(LOG_GUEST_ERROR, "XIVE: invalid NVP %x/%x\n", + nvp_blk, nvp_idx); + return; + } + + first_group = xive_get_field32(NVP2_W0_PGOFIRST, nvp.w0); + if (!first_group) { + qemu_log_mask(LOG_GUEST_ERROR, "XIVE: invalid NVP %x/%x\n", + nvp_blk, nvp_idx); + return; + } + + backlog_prio = xive2_presenter_backlog_scan(tctx->xptr, + nvp_blk, nvp_idx, + first_group, &group_level); + tctx->regs[ring_min + TM_LSMFB] = backlog_prio; + if (backlog_prio != 0xFF) { + xive2_presenter_backlog_decr(tctx->xptr, nvp_blk, nvp_idx, + backlog_prio, group_level); + regs[TM_PIPR] = backlog_prio; + } + } + /* CPPR has changed, check if we need to raise a pending exception */ + xive_tctx_notify(tctx, ring_min, group_level); +} + +void xive2_tm_set_hv_cppr(XivePresenter *xptr, XiveTCTX *tctx, + hwaddr offset, uint64_t value, unsigned size) +{ + xive2_tctx_set_cppr(tctx, TM_QW3_HV_PHYS, value & 0xff); +} + +void xive2_tm_set_os_cppr(XivePresenter *xptr, XiveTCTX *tctx, + hwaddr offset, uint64_t value, unsigned size) +{ + xive2_tctx_set_cppr(tctx, TM_QW1_OS, value & 0xff); +} + static void xive2_tctx_set_target(XiveTCTX *tctx, uint8_t ring, uint8_t target) { uint8_t *regs = &tctx->regs[ring]; @@ -938,7 +1105,9 @@ int xive2_presenter_tctx_match(XivePresenter *xptr, XiveTCTX *tctx, bool xive2_tm_irq_precluded(XiveTCTX *tctx, int ring, uint8_t priority) { - uint8_t *regs = &tctx->regs[ring]; + /* HV_POOL ring uses HV_PHYS NSR, CPPR and PIPR registers */ + uint8_t alt_ring = (ring == TM_QW2_HV_POOL) ? TM_QW3_HV_PHYS : ring; + uint8_t *alt_regs = &tctx->regs[alt_ring]; /* * The xive2_presenter_tctx_match() above tells if there's a match @@ -946,7 +1115,7 @@ bool xive2_tm_irq_precluded(XiveTCTX *tctx, int ring, uint8_t priority) * priority to know if the thread can take the interrupt now or if * it is precluded. */ - if (priority < regs[TM_CPPR]) { + if (priority < alt_regs[TM_CPPR]) { return false; } return true; diff --git a/include/hw/ppc/xive2.h b/include/hw/ppc/xive2.h index ebf301bb5b..fc7422fea7 100644 --- a/include/hw/ppc/xive2.h +++ b/include/hw/ppc/xive2.h @@ -113,6 +113,10 @@ typedef struct Xive2EndSource { * XIVE2 Thread Interrupt Management Area (POWER10) */ +void xive2_tm_set_hv_cppr(XivePresenter *xptr, XiveTCTX *tctx, + hwaddr offset, uint64_t value, unsigned size); +void xive2_tm_set_os_cppr(XivePresenter *xptr, XiveTCTX *tctx, + hwaddr offset, uint64_t value, unsigned size); void xive2_tm_push_os_ctx(XivePresenter *xptr, XiveTCTX *tctx, hwaddr offset, uint64_t value, unsigned size); uint64_t xive2_tm_pull_os_ctx(XivePresenter *xptr, XiveTCTX *tctx, From patchwork Tue Mar 11 12:57:24 2025 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Nicholas Piggin X-Patchwork-Id: 14011798 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.lore.kernel.org (Postfix) with ESMTPS id 5762FC282EC for ; Tue, 11 Mar 2025 13:02:45 +0000 (UTC) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1trzEg-0005UY-5M; Tue, 11 Mar 2025 09:01:34 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1trzDQ-0004Lp-1C; Tue, 11 Mar 2025 09:00:15 -0400 Received: from mail-pj1-x1030.google.com ([2607:f8b0:4864:20::1030]) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_128_GCM_SHA256:128) (Exim 4.90_1) (envelope-from ) id 1trzDH-00084T-Ld; Tue, 11 Mar 2025 09:00:10 -0400 Received: by mail-pj1-x1030.google.com with SMTP id 98e67ed59e1d1-300fefb8e06so1881870a91.0; Tue, 11 Mar 2025 06:00:00 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20230601; t=1741697999; x=1742302799; darn=nongnu.org; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to; bh=WWZ6jXzWeTg9f0TMcRn568DCYUVFZ/Q8jdAM6fw8ow0=; b=U1bfh1OOCKIZzbHXzVSR4BpSIYP2qUSkVsw3KG0t/WE50B5KkPh0MbOK3BrsVRoT4K 8KtL2XLs9d4QtKzvuHx6h/3kZCKBD9F30A9qo2IhnDBtztOXc0R1gppsrMoPnwUWV7qI 2i0E/Eto/uZr/dPkVwDslT2eMOFKg04VOfCbs0Y7GbmKvlNeVN00UNOiRGlliyR66UXR Adul+2e+oynEd2lrVIIBNeBMldeuow6xfNPE0k061bC0JEU5JV8GNcFDojAJPwBTFsnn Y5D13qSOH+5T8MdvN2AUlz8wbp59WWGVpBr8AtuZqci6nYL2TKfDaLOJeLoERCMo2rQG A1ng== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1741697999; x=1742302799; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=WWZ6jXzWeTg9f0TMcRn568DCYUVFZ/Q8jdAM6fw8ow0=; b=L661rPbGNnbiPXpxNvqMMlfl29XlzUrh/CJvl7G23178qsaJmQ+b1va2GBDlQq9Noz AK5fCBw4muRAf9cy+TDCB96VLV+vFn0K/cDsNoit4ieTlMhDaqIZlhxD++cEwIA/YcmD eNxTCy+T23Np9RUYRipfIzmEtB8grcj+ORENzB/dgoufZSMS8wGAWF8sFFh1hBAiboVg 2K66T8FW4lauE/Uvk1RjwMzlQsr7N88CLM3+hQH4jtpBOabObm8POf7dGe06okCCBQpE ZEaiSJT0VHesg3BMoMXe4MCRv+HnyGQiARtN+vyw+z0V1NOeEFhcVFXY+9oE7TZNIlu1 mqHg== X-Forwarded-Encrypted: i=1; AJvYcCW7eYhW58Rrek6Z+EMOTfCrpcDiQVEXZh3JofbVJZPTXRENNwuH7iP7vMGzvcwTEOTFAWFxamAQKQ==@nongnu.org X-Gm-Message-State: AOJu0Yw3fri5JD9Mpf3NUjOGQe395nSxQxFifCbdN4qHX8+ms69XB6C4 hLYHFBL+FFBROHPY1sMdndqu3ykwzqKhRW+kpK0RY2QcAgPQobQjvAtXLA== X-Gm-Gg: ASbGncsdJsoSS8EJQSSFtJyIuHBc/YC4ctbaTjfOJQc0PC9/CG5mtlu9HVzdLYn2DTI vw0BUPvno7UXTm39m5ehtSeW6RyWdD+eXGoeAZmezAG0iy2m5IPJNCBPU1gukWMuvU29lcJmkzM qJBJ+9vSKV991gf4GgeRNa3kAMmbcMJH5n71txYCzBDBDaAbUOXF3heZEGnJysI3VuHA+YfKtUC SM6S+Y/qjvnsPO4Z97bAUgdz4PoLxIzj8/Isu44AAGUQpSk736Fna1P+JnGOyFKbFdF1/RAyiUi 7imclgU1EG7bbYXz1TE6XrukurrysOeasOdSwCls/xfng1+MWm4= X-Google-Smtp-Source: AGHT+IFis6Ard7BrObSIFYYxBdA/Z2a3tRl3ETjHPZW5AOeookzEcW5d3AEBe22dGlAf8OZzt0TyTA== X-Received: by 2002:a17:90b:264e:b0:2fe:a336:fe65 with SMTP id 98e67ed59e1d1-300ff0ca8c9mr4849182a91.10.1741697999464; Tue, 11 Mar 2025 05:59:59 -0700 (PDT) Received: from wheely.local0.net ([118.208.151.101]) by smtp.gmail.com with ESMTPSA id 98e67ed59e1d1-2ff4e773dddsm11822318a91.12.2025.03.11.05.59.56 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 11 Mar 2025 05:59:59 -0700 (PDT) From: Nicholas Piggin To: qemu-devel@nongnu.org Cc: Nicholas Piggin , qemu-ppc@nongnu.org, Frederic Barrat , Michael Kowal Subject: [PULL 30/72] qtest/xive: Add group-interrupt test Date: Tue, 11 Mar 2025 22:57:24 +1000 Message-ID: <20250311125815.903177-31-npiggin@gmail.com> X-Mailer: git-send-email 2.47.1 In-Reply-To: <20250311125815.903177-1-npiggin@gmail.com> References: <20250311125815.903177-1-npiggin@gmail.com> MIME-Version: 1.0 Received-SPF: pass client-ip=2607:f8b0:4864:20::1030; envelope-from=npiggin@gmail.com; helo=mail-pj1-x1030.google.com X-Spam_score_int: -20 X-Spam_score: -2.1 X-Spam_bar: -- X-Spam_report: (-2.1 / 5.0 requ) BAYES_00=-1.9, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_AU=-0.1, DKIM_VALID_EF=-0.1, FREEMAIL_FROM=0.001, RCVD_IN_DNSWL_NONE=-0.0001, SPF_HELO_NONE=0.001, SPF_PASS=-0.001 autolearn=ham autolearn_force=no X-Spam_action: no action X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: qemu-devel-bounces+qemu-devel=archiver.kernel.org@nongnu.org Sender: qemu-devel-bounces+qemu-devel=archiver.kernel.org@nongnu.org From: Frederic Barrat Add XIVE2 tests for group interrupts and group interrupts that have been backlogged. Signed-off-by: Frederic Barrat Signed-off-by: Michael Kowal Reviewed-by: Nicholas Piggin Signed-off-by: Nicholas Piggin --- tests/qtest/pnv-xive2-test.c | 160 +++++++++++++++++++++++++++++++++++ 1 file changed, 160 insertions(+) diff --git a/tests/qtest/pnv-xive2-test.c b/tests/qtest/pnv-xive2-test.c index dd19e88861..a4d06550ee 100644 --- a/tests/qtest/pnv-xive2-test.c +++ b/tests/qtest/pnv-xive2-test.c @@ -2,6 +2,8 @@ * QTest testcase for PowerNV 10 interrupt controller (xive2) * - Test irq to hardware thread * - Test 'Pull Thread Context to Odd Thread Reporting Line' + * - Test irq to hardware group + * - Test irq to hardware group going through backlog * * Copyright (c) 2024, IBM Corporation. * @@ -315,6 +317,158 @@ static void test_pull_thread_ctx_to_odd_thread_cl(QTestState *qts) word2 = get_tima32(qts, target_pir, TM_QW3_HV_PHYS + TM_WORD2); g_assert_cmphex(xive_get_field32(TM_QW3W2_VT, word2), ==, 0); } + +static void test_hw_group_irq(QTestState *qts) +{ + uint32_t irq = 100; + uint32_t irq_data = 0xdeadbeef; + uint32_t end_index = 23; + uint32_t chosen_one; + uint32_t target_nvp = 0x81; /* group size = 4 */ + uint8_t priority = 6; + uint32_t reg32; + uint16_t reg16; + uint8_t pq, nsr, cppr; + + printf("# ============================================================\n"); + printf("# Testing irq %d to hardware group of size 4\n", irq); + + /* irq config */ + set_eas(qts, irq, end_index, irq_data); + set_end(qts, end_index, target_nvp, priority, true /* group */); + + /* enable and trigger irq */ + get_esb(qts, irq, XIVE_EOI_PAGE, XIVE_ESB_SET_PQ_00); + set_esb(qts, irq, XIVE_TRIGGER_PAGE, 0, 0); + + /* check irq is raised on cpu */ + pq = get_esb(qts, irq, XIVE_EOI_PAGE, XIVE_ESB_GET); + g_assert_cmpuint(pq, ==, XIVE_ESB_PENDING); + + /* find the targeted vCPU */ + for (chosen_one = 0; chosen_one < SMT; chosen_one++) { + reg32 = get_tima32(qts, chosen_one, TM_QW3_HV_PHYS + TM_WORD0); + nsr = reg32 >> 24; + if (nsr == 0x82) { + break; + } + } + g_assert_cmphex(chosen_one, <, SMT); + cppr = (reg32 >> 16) & 0xFF; + g_assert_cmphex(nsr, ==, 0x82); + g_assert_cmphex(cppr, ==, 0xFF); + + /* ack the irq */ + reg16 = get_tima16(qts, chosen_one, TM_SPC_ACK_HV_REG); + nsr = reg16 >> 8; + cppr = reg16 & 0xFF; + g_assert_cmphex(nsr, ==, 0x82); + g_assert_cmphex(cppr, ==, priority); + + /* check irq data is what was configured */ + reg32 = qtest_readl(qts, xive_get_queue_addr(end_index)); + g_assert_cmphex((reg32 & 0x7fffffff), ==, (irq_data & 0x7fffffff)); + + /* End Of Interrupt */ + set_esb(qts, irq, XIVE_EOI_PAGE, XIVE_ESB_STORE_EOI, 0); + pq = get_esb(qts, irq, XIVE_EOI_PAGE, XIVE_ESB_GET); + g_assert_cmpuint(pq, ==, XIVE_ESB_RESET); + + /* reset CPPR */ + set_tima8(qts, chosen_one, TM_QW3_HV_PHYS + TM_CPPR, 0xFF); + reg32 = get_tima32(qts, chosen_one, TM_QW3_HV_PHYS + TM_WORD0); + nsr = reg32 >> 24; + cppr = (reg32 >> 16) & 0xFF; + g_assert_cmphex(nsr, ==, 0x00); + g_assert_cmphex(cppr, ==, 0xFF); +} + +static void test_hw_group_irq_backlog(QTestState *qts) +{ + uint32_t irq = 31; + uint32_t irq_data = 0x01234567; + uint32_t end_index = 129; + uint32_t target_nvp = 0x81; /* group size = 4 */ + uint32_t chosen_one = 3; + uint8_t blocking_priority, priority = 3; + uint32_t reg32; + uint16_t reg16; + uint8_t pq, nsr, cppr, lsmfb, i; + + printf("# ============================================================\n"); + printf("# Testing irq %d to hardware group of size 4 going through " \ + "backlog\n", + irq); + + /* + * set current priority of all threads in the group to something + * higher than what we're about to trigger + */ + blocking_priority = priority - 1; + for (i = 0; i < SMT; i++) { + set_tima8(qts, i, TM_QW3_HV_PHYS + TM_CPPR, blocking_priority); + } + + /* irq config */ + set_eas(qts, irq, end_index, irq_data); + set_end(qts, end_index, target_nvp, priority, true /* group */); + + /* enable and trigger irq */ + get_esb(qts, irq, XIVE_EOI_PAGE, XIVE_ESB_SET_PQ_00); + set_esb(qts, irq, XIVE_TRIGGER_PAGE, 0, 0); + + /* check irq is raised on cpu */ + pq = get_esb(qts, irq, XIVE_EOI_PAGE, XIVE_ESB_GET); + g_assert_cmpuint(pq, ==, XIVE_ESB_PENDING); + + /* check no interrupt is pending on the 2 possible targets */ + for (i = 0; i < SMT; i++) { + reg32 = get_tima32(qts, i, TM_QW3_HV_PHYS + TM_WORD0); + nsr = reg32 >> 24; + cppr = (reg32 >> 16) & 0xFF; + lsmfb = reg32 & 0xFF; + g_assert_cmphex(nsr, ==, 0x0); + g_assert_cmphex(cppr, ==, blocking_priority); + g_assert_cmphex(lsmfb, ==, priority); + } + + /* lower priority of one thread */ + set_tima8(qts, chosen_one, TM_QW3_HV_PHYS + TM_CPPR, priority + 1); + + /* check backlogged interrupt is presented */ + reg32 = get_tima32(qts, chosen_one, TM_QW3_HV_PHYS + TM_WORD0); + nsr = reg32 >> 24; + cppr = (reg32 >> 16) & 0xFF; + g_assert_cmphex(nsr, ==, 0x82); + g_assert_cmphex(cppr, ==, priority + 1); + + /* ack the irq */ + reg16 = get_tima16(qts, chosen_one, TM_SPC_ACK_HV_REG); + nsr = reg16 >> 8; + cppr = reg16 & 0xFF; + g_assert_cmphex(nsr, ==, 0x82); + g_assert_cmphex(cppr, ==, priority); + + /* check irq data is what was configured */ + reg32 = qtest_readl(qts, xive_get_queue_addr(end_index)); + g_assert_cmphex((reg32 & 0x7fffffff), ==, (irq_data & 0x7fffffff)); + + /* End Of Interrupt */ + set_esb(qts, irq, XIVE_EOI_PAGE, XIVE_ESB_STORE_EOI, 0); + pq = get_esb(qts, irq, XIVE_EOI_PAGE, XIVE_ESB_GET); + g_assert_cmpuint(pq, ==, XIVE_ESB_RESET); + + /* reset CPPR */ + set_tima8(qts, chosen_one, TM_QW3_HV_PHYS + TM_CPPR, 0xFF); + reg32 = get_tima32(qts, chosen_one, TM_QW3_HV_PHYS + TM_WORD0); + nsr = reg32 >> 24; + cppr = (reg32 >> 16) & 0xFF; + lsmfb = reg32 & 0xFF; + g_assert_cmphex(nsr, ==, 0x00); + g_assert_cmphex(cppr, ==, 0xFF); + g_assert_cmphex(lsmfb, ==, 0xFF); +} + static void test_xive(void) { QTestState *qts; @@ -330,6 +484,12 @@ static void test_xive(void) /* omit reset_state here and use settings from test_hw_irq */ test_pull_thread_ctx_to_odd_thread_cl(qts); + reset_state(qts); + test_hw_group_irq(qts); + + reset_state(qts); + test_hw_group_irq_backlog(qts); + reset_state(qts); test_flush_sync_inject(qts); From patchwork Tue Mar 11 12:57:25 2025 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Nicholas Piggin X-Patchwork-Id: 14011800 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.lore.kernel.org (Postfix) with ESMTPS id A12D0C28B2E for ; Tue, 11 Mar 2025 13:03:26 +0000 (UTC) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1trzF3-00060f-A0; Tue, 11 Mar 2025 09:01:54 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1trzDX-0004bJ-DJ; Tue, 11 Mar 2025 09:00:23 -0400 Received: from mail-pj1-x1034.google.com ([2607:f8b0:4864:20::1034]) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_128_GCM_SHA256:128) (Exim 4.90_1) (envelope-from ) id 1trzDM-00086E-2A; Tue, 11 Mar 2025 09:00:18 -0400 Received: by mail-pj1-x1034.google.com with SMTP id 98e67ed59e1d1-2ff6cf448b8so10792074a91.3; Tue, 11 Mar 2025 06:00:04 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20230601; t=1741698002; x=1742302802; darn=nongnu.org; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to; bh=by3/ZI8Vkw6A3nNqZvSfEcf780vJNiwWvMG40uDK0x8=; b=FkTHtluBCmu8Fb+XRMfU9juHCRqhUDEBTrsn2JWTE1mVdAmyN5VcQmM+3TFrKFxIq7 Me4rsZshA3f7ShH9XlRzbsrMXszrNCUZUxxw8i4swBWeqE27O5RV4hB8J3wRBUaEhoT7 ONmj7MyDuUGP9AQSO5Wykkqn6mA9IF9NmVLJ5nhbM62lqZ3c5gqlIrdbTKndQMBqdjK1 FKbJ0nMDF7m9qygKdn3tmpqzWB6A0KGWCfn9E4Nl0k88W/dsao2CwHj+ts8KLEi52/NC PbNQGyQwbvYEvsyFAaMKsmkzewTSzJb8sb0QUSE1lAObc3EbU+sxN1tgd4JflcF8kKWh wSlw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1741698002; x=1742302802; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=by3/ZI8Vkw6A3nNqZvSfEcf780vJNiwWvMG40uDK0x8=; b=vsEO1UXtQddw3YR4azBN0beCY+UZFtdFQdKWLxstuR2LvMpuQP9xlvkhGyUjMM3pwk ACSzI8V68XJZ8Pgs5DI+kRonPd8zJMdltraMxpc7BvrHXeZC1U0a0uLx//Gf2z9EQYEN gsf5h80Vu5krhsIzFZ0oHLNy2T8g4yJqqbBs7BN3Rz2ftocNGbXc9eEytNP8BcBgRGS1 L6Xku3zQp8BrTfrAS7WyN7KJl3I+pqueE6Br3CEmK3b32MqF29hYSR7bJ0uEnRJX4fqT AAlAhwWcxjGEMERtVPLGrRX09ttC0fzmiTKHcRH1C4Xvb4gXN3T3qDSY8RvTk+K09F10 qgLw== X-Forwarded-Encrypted: i=1; AJvYcCWEYKBSUpWfLL9l6T/DYrgj33T4DclM4LxCaNb8WpMAsra1jVLCP6ztgAh9MDVHfaBSr0gyJM1vyg==@nongnu.org X-Gm-Message-State: AOJu0YxewOb21H9pW7dgIocBZYqjcGuBDVXJhtk4Zf+AReShSblw9WiD Mwa5+iSlIf5N1WWTdGQjZJDrfH1WODV4reibBzFbVkoRaCtVmmcNhM6vzg== X-Gm-Gg: ASbGncsNj0F1rf7mSXnHyCjj8rNhV87v8ucYAbiig888rifEi997ISv2MKehOFULyoe 63BPzhfPG8RQybeMFzl7kBX/340MOozNCEVk5IhOkmQhnnKZb0isruHqBhH10s9BS6t1/T/PsDK u2IbfH1E7G+ASdlYMxLiRur/hwjD9ZEsJHVHIYOk6pLqk82jXPFV14hkOoIfEXiO3u9rB2ozoCr U+UIcwSVj7pprNzzipd0UhFLYrDtUyBvsqkc/h0mdiBX+6OYpyBR2dzQ+knao9UyTL/wa4LOMjr O5E/qkqU0GCXVNe2N2jerYRxbMf8NASyu9FCif7CHO/pGyT6ZEqUGmjQ7eAc2w== X-Google-Smtp-Source: AGHT+IFFev1f83NDL/uuWb5ctq6PRHelu6ZBjZNhO9IoU+0pOqaK1j1KPPfzBSRu9zdhHzFS5zLy1A== X-Received: by 2002:a17:90b:3849:b0:2f9:c56b:6ec8 with SMTP id 98e67ed59e1d1-2ff7ce9114dmr26940394a91.10.1741698002458; Tue, 11 Mar 2025 06:00:02 -0700 (PDT) Received: from wheely.local0.net ([118.208.151.101]) by smtp.gmail.com with ESMTPSA id 98e67ed59e1d1-2ff4e773dddsm11822318a91.12.2025.03.11.05.59.59 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 11 Mar 2025 06:00:02 -0700 (PDT) From: Nicholas Piggin To: qemu-devel@nongnu.org Cc: Nicholas Piggin , qemu-ppc@nongnu.org, Frederic Barrat , Michael Kowal Subject: [PULL 31/72] ppc/xive2: Add support for MMIO operations on the NVPG/NVC BAR Date: Tue, 11 Mar 2025 22:57:25 +1000 Message-ID: <20250311125815.903177-32-npiggin@gmail.com> X-Mailer: git-send-email 2.47.1 In-Reply-To: <20250311125815.903177-1-npiggin@gmail.com> References: <20250311125815.903177-1-npiggin@gmail.com> MIME-Version: 1.0 Received-SPF: pass client-ip=2607:f8b0:4864:20::1034; envelope-from=npiggin@gmail.com; helo=mail-pj1-x1034.google.com X-Spam_score_int: -20 X-Spam_score: -2.1 X-Spam_bar: -- X-Spam_report: (-2.1 / 5.0 requ) BAYES_00=-1.9, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_AU=-0.1, DKIM_VALID_EF=-0.1, FREEMAIL_FROM=0.001, RCVD_IN_DNSWL_NONE=-0.0001, SPF_HELO_NONE=0.001, T_SPF_TEMPERROR=0.01 autolearn=ham autolearn_force=no X-Spam_action: no action X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: qemu-devel-bounces+qemu-devel=archiver.kernel.org@nongnu.org Sender: qemu-devel-bounces+qemu-devel=archiver.kernel.org@nongnu.org From: Frederic Barrat Add support for the NVPG and NVC BARs. Access to the BAR pages will cause backlog counter operations to either increment or decriment the counter. Also added qtests for the same. Signed-off-by: Frederic Barrat Signed-off-by: Michael Kowal Reviewed-by: Nicholas Piggin Signed-off-by: Nicholas Piggin --- hw/intc/pnv_xive2.c | 80 +++++++++++++--- hw/intc/trace-events | 4 + hw/intc/xive2.c | 87 ++++++++++++++++++ include/hw/ppc/xive2.h | 9 ++ include/hw/ppc/xive2_regs.h | 3 + tests/qtest/meson.build | 3 +- tests/qtest/pnv-xive2-common.h | 1 + tests/qtest/pnv-xive2-nvpg_bar.c | 153 +++++++++++++++++++++++++++++++ tests/qtest/pnv-xive2-test.c | 3 + 9 files changed, 328 insertions(+), 15 deletions(-) create mode 100644 tests/qtest/pnv-xive2-nvpg_bar.c diff --git a/hw/intc/pnv_xive2.c b/hw/intc/pnv_xive2.c index e7a7d1b50f..c55d596e48 100644 --- a/hw/intc/pnv_xive2.c +++ b/hw/intc/pnv_xive2.c @@ -2202,21 +2202,40 @@ static const MemoryRegionOps pnv_xive2_tm_ops = { }, }; -static uint64_t pnv_xive2_nvc_read(void *opaque, hwaddr offset, +static uint64_t pnv_xive2_nvc_read(void *opaque, hwaddr addr, unsigned size) { PnvXive2 *xive = PNV_XIVE2(opaque); + XivePresenter *xptr = XIVE_PRESENTER(xive); + uint32_t page = addr >> xive->nvpg_shift; + uint16_t op = addr & 0xFFF; + uint8_t blk = pnv_xive2_block_id(xive); - xive2_error(xive, "NVC: invalid read @%"HWADDR_PRIx, offset); - return -1; + if (size != 2) { + qemu_log_mask(LOG_GUEST_ERROR, "XIVE: invalid nvc load size %d\n", + size); + return -1; + } + + return xive2_presenter_nvgc_backlog_op(xptr, true, blk, page, op, 1); } -static void pnv_xive2_nvc_write(void *opaque, hwaddr offset, +static void pnv_xive2_nvc_write(void *opaque, hwaddr addr, uint64_t val, unsigned size) { PnvXive2 *xive = PNV_XIVE2(opaque); + XivePresenter *xptr = XIVE_PRESENTER(xive); + uint32_t page = addr >> xive->nvc_shift; + uint16_t op = addr & 0xFFF; + uint8_t blk = pnv_xive2_block_id(xive); - xive2_error(xive, "NVC: invalid write @%"HWADDR_PRIx, offset); + if (size != 1) { + qemu_log_mask(LOG_GUEST_ERROR, "XIVE: invalid nvc write size %d\n", + size); + return; + } + + (void)xive2_presenter_nvgc_backlog_op(xptr, true, blk, page, op, val); } static const MemoryRegionOps pnv_xive2_nvc_ops = { @@ -2224,30 +2243,63 @@ static const MemoryRegionOps pnv_xive2_nvc_ops = { .write = pnv_xive2_nvc_write, .endianness = DEVICE_BIG_ENDIAN, .valid = { - .min_access_size = 8, + .min_access_size = 1, .max_access_size = 8, }, .impl = { - .min_access_size = 8, + .min_access_size = 1, .max_access_size = 8, }, }; -static uint64_t pnv_xive2_nvpg_read(void *opaque, hwaddr offset, +static uint64_t pnv_xive2_nvpg_read(void *opaque, hwaddr addr, unsigned size) { PnvXive2 *xive = PNV_XIVE2(opaque); + XivePresenter *xptr = XIVE_PRESENTER(xive); + uint32_t page = addr >> xive->nvpg_shift; + uint16_t op = addr & 0xFFF; + uint32_t index = page >> 1; + uint8_t blk = pnv_xive2_block_id(xive); - xive2_error(xive, "NVPG: invalid read @%"HWADDR_PRIx, offset); - return -1; + if (size != 2) { + qemu_log_mask(LOG_GUEST_ERROR, "XIVE: invalid nvpg load size %d\n", + size); + return -1; + } + + if (page % 2) { + /* odd page - NVG */ + return xive2_presenter_nvgc_backlog_op(xptr, false, blk, index, op, 1); + } else { + /* even page - NVP */ + return xive2_presenter_nvp_backlog_op(xptr, blk, index, op); + } } -static void pnv_xive2_nvpg_write(void *opaque, hwaddr offset, +static void pnv_xive2_nvpg_write(void *opaque, hwaddr addr, uint64_t val, unsigned size) { PnvXive2 *xive = PNV_XIVE2(opaque); + XivePresenter *xptr = XIVE_PRESENTER(xive); + uint32_t page = addr >> xive->nvpg_shift; + uint16_t op = addr & 0xFFF; + uint32_t index = page >> 1; + uint8_t blk = pnv_xive2_block_id(xive); - xive2_error(xive, "NVPG: invalid write @%"HWADDR_PRIx, offset); + if (size != 1) { + qemu_log_mask(LOG_GUEST_ERROR, "XIVE: invalid nvpg write size %d\n", + size); + return; + } + + if (page % 2) { + /* odd page - NVG */ + (void)xive2_presenter_nvgc_backlog_op(xptr, false, blk, index, op, val); + } else { + /* even page - NVP */ + (void)xive2_presenter_nvp_backlog_op(xptr, blk, index, op); + } } static const MemoryRegionOps pnv_xive2_nvpg_ops = { @@ -2255,11 +2307,11 @@ static const MemoryRegionOps pnv_xive2_nvpg_ops = { .write = pnv_xive2_nvpg_write, .endianness = DEVICE_BIG_ENDIAN, .valid = { - .min_access_size = 8, + .min_access_size = 1, .max_access_size = 8, }, .impl = { - .min_access_size = 8, + .min_access_size = 1, .max_access_size = 8, }, }; diff --git a/hw/intc/trace-events b/hw/intc/trace-events index e9fe1978f9..0ba9a02e73 100644 --- a/hw/intc/trace-events +++ b/hw/intc/trace-events @@ -286,6 +286,10 @@ xive_tctx_tm_read(uint32_t index, uint64_t offset, unsigned int size, uint64_t v xive_presenter_notify(uint8_t nvt_blk, uint32_t nvt_idx, uint8_t ring, uint8_t group_level) "found NVT 0x%x/0x%x ring=0x%x group_level=%d" xive_end_source_read(uint8_t end_blk, uint32_t end_idx, uint64_t addr) "END 0x%x/0x%x @0x%"PRIx64 +# xive2.c +xive_nvp_backlog_op(uint8_t blk, uint32_t idx, uint8_t op, uint8_t priority, uint8_t rc) "NVP 0x%x/0x%x operation=%d priority=%d rc=%d" +xive_nvgc_backlog_op(bool c, uint8_t blk, uint32_t idx, uint8_t op, uint8_t priority, uint32_t rc) "NVGC crowd=%d 0x%x/0x%x operation=%d priority=%d rc=%d" + # pnv_xive.c pnv_xive_ic_hw_trigger(uint64_t addr, uint64_t val) "@0x%"PRIx64" val=0x%"PRIx64 diff --git a/hw/intc/xive2.c b/hw/intc/xive2.c index 017c0f8bb4..34628f2922 100644 --- a/hw/intc/xive2.c +++ b/hw/intc/xive2.c @@ -88,6 +88,93 @@ static void xive2_nvgc_set_backlog(Xive2Nvgc *nvgc, uint8_t priority, } } +uint64_t xive2_presenter_nvgc_backlog_op(XivePresenter *xptr, + bool crowd, + uint8_t blk, uint32_t idx, + uint16_t offset, uint16_t val) +{ + Xive2Router *xrtr = XIVE2_ROUTER(xptr); + uint8_t priority = GETFIELD(NVx_BACKLOG_PRIO, offset); + uint8_t op = GETFIELD(NVx_BACKLOG_OP, offset); + Xive2Nvgc nvgc; + uint32_t count, old_count; + + if (xive2_router_get_nvgc(xrtr, crowd, blk, idx, &nvgc)) { + qemu_log_mask(LOG_GUEST_ERROR, "XIVE: No %s %x/%x\n", + crowd ? "NVC" : "NVG", blk, idx); + return -1; + } + if (!xive2_nvgc_is_valid(&nvgc)) { + qemu_log_mask(LOG_GUEST_ERROR, "XIVE: Invalid NVG %x/%x\n", blk, idx); + return -1; + } + + old_count = xive2_nvgc_get_backlog(&nvgc, priority); + count = old_count; + /* + * op: + * 0b00 => increment + * 0b01 => decrement + * 0b1- => read + */ + if (op == 0b00 || op == 0b01) { + if (op == 0b00) { + count += val; + } else { + if (count > val) { + count -= val; + } else { + count = 0; + } + } + xive2_nvgc_set_backlog(&nvgc, priority, count); + xive2_router_write_nvgc(xrtr, crowd, blk, idx, &nvgc); + } + trace_xive_nvgc_backlog_op(crowd, blk, idx, op, priority, old_count); + return old_count; +} + +uint64_t xive2_presenter_nvp_backlog_op(XivePresenter *xptr, + uint8_t blk, uint32_t idx, + uint16_t offset) +{ + Xive2Router *xrtr = XIVE2_ROUTER(xptr); + uint8_t priority = GETFIELD(NVx_BACKLOG_PRIO, offset); + uint8_t op = GETFIELD(NVx_BACKLOG_OP, offset); + Xive2Nvp nvp; + uint8_t ipb, old_ipb, rc; + + if (xive2_router_get_nvp(xrtr, blk, idx, &nvp)) { + qemu_log_mask(LOG_GUEST_ERROR, "XIVE: No NVP %x/%x\n", blk, idx); + return -1; + } + if (!xive2_nvp_is_valid(&nvp)) { + qemu_log_mask(LOG_GUEST_ERROR, "XIVE: Invalid NVP %x/%x\n", blk, idx); + return -1; + } + + old_ipb = xive_get_field32(NVP2_W2_IPB, nvp.w2); + ipb = old_ipb; + /* + * op: + * 0b00 => set priority bit + * 0b01 => reset priority bit + * 0b1- => read + */ + if (op == 0b00 || op == 0b01) { + if (op == 0b00) { + ipb |= xive_priority_to_ipb(priority); + } else { + ipb &= ~xive_priority_to_ipb(priority); + } + nvp.w2 = xive_set_field32(NVP2_W2_IPB, nvp.w2, ipb); + xive2_router_write_nvp(xrtr, blk, idx, &nvp, 2); + } + rc = !!(old_ipb & xive_priority_to_ipb(priority)); + trace_xive_nvp_backlog_op(blk, idx, op, priority, rc); + return rc; +} + void xive2_eas_pic_print_info(Xive2Eas *eas, uint32_t lisn, GString *buf) { if (!xive2_eas_is_valid(eas)) { diff --git a/include/hw/ppc/xive2.h b/include/hw/ppc/xive2.h index fc7422fea7..c07e23e1d3 100644 --- a/include/hw/ppc/xive2.h +++ b/include/hw/ppc/xive2.h @@ -90,6 +90,15 @@ int xive2_presenter_tctx_match(XivePresenter *xptr, XiveTCTX *tctx, uint8_t nvt_blk, uint32_t nvt_idx, bool cam_ignore, uint32_t logic_serv); +uint64_t xive2_presenter_nvp_backlog_op(XivePresenter *xptr, + uint8_t blk, uint32_t idx, + uint16_t offset); + +uint64_t xive2_presenter_nvgc_backlog_op(XivePresenter *xptr, + bool crowd, + uint8_t blk, uint32_t idx, + uint16_t offset, uint16_t val); + /* * XIVE2 END ESBs (POWER10) */ diff --git a/include/hw/ppc/xive2_regs.h b/include/hw/ppc/xive2_regs.h index e88d6eab1e..9bcf7a8a6f 100644 --- a/include/hw/ppc/xive2_regs.h +++ b/include/hw/ppc/xive2_regs.h @@ -233,4 +233,7 @@ typedef struct Xive2Nvgc { void xive2_nvgc_pic_print_info(Xive2Nvgc *nvgc, uint32_t nvgc_idx, GString *buf); +#define NVx_BACKLOG_OP PPC_BITMASK(52, 53) +#define NVx_BACKLOG_PRIO PPC_BITMASK(57, 59) + #endif /* PPC_XIVE2_REGS_H */ diff --git a/tests/qtest/meson.build b/tests/qtest/meson.build index b23fe67db7..3ecb23e610 100644 --- a/tests/qtest/meson.build +++ b/tests/qtest/meson.build @@ -368,7 +368,8 @@ qtests = { 'ivshmem-test': [rt, '../../contrib/ivshmem-server/ivshmem-server.c'], 'migration-test': migration_files + migration_tls_files, 'pxe-test': files('boot-sector.c'), - 'pnv-xive2-test': files('pnv-xive2-common.c', 'pnv-xive2-flush-sync.c'), + 'pnv-xive2-test': files('pnv-xive2-common.c', 'pnv-xive2-flush-sync.c', + 'pnv-xive2-nvpg_bar.c'), 'qos-test': [chardev, io, qos_test_ss.apply({}).sources()], 'tpm-crb-swtpm-test': [io, tpmemu_files], 'tpm-crb-test': [io, tpmemu_files], diff --git a/tests/qtest/pnv-xive2-common.h b/tests/qtest/pnv-xive2-common.h index 9ae34771aa..2077c05ebc 100644 --- a/tests/qtest/pnv-xive2-common.h +++ b/tests/qtest/pnv-xive2-common.h @@ -107,5 +107,6 @@ extern void set_end(QTestState *qts, uint32_t index, uint32_t nvp_index, void test_flush_sync_inject(QTestState *qts); +void test_nvpg_bar(QTestState *qts); #endif /* TEST_PNV_XIVE2_COMMON_H */ diff --git a/tests/qtest/pnv-xive2-nvpg_bar.c b/tests/qtest/pnv-xive2-nvpg_bar.c new file mode 100644 index 0000000000..028512bddc --- /dev/null +++ b/tests/qtest/pnv-xive2-nvpg_bar.c @@ -0,0 +1,153 @@ +/* + * QTest testcase for PowerNV 10 interrupt controller (xive2) + * - Test NVPG BAR MMIO operations + * + * Copyright (c) 2024, IBM Corporation. + * + * This work is licensed under the terms of the GNU GPL, version 2 or + * later. See the COPYING file in the top-level directory. + */ +#include "qemu/osdep.h" +#include "libqtest.h" + +#include "pnv-xive2-common.h" + +#define NVPG_BACKLOG_OP_SHIFT 10 +#define NVPG_BACKLOG_PRIO_SHIFT 4 + +#define XIVE_PRIORITY_MAX 7 + +enum NVx { + NVP, + NVG, + NVC +}; + +typedef enum { + INCR_STORE = 0b100, + INCR_LOAD = 0b000, + DECR_STORE = 0b101, + DECR_LOAD = 0b001, + READ_x = 0b010, + READ_y = 0b011, +} backlog_op; + +static uint32_t nvpg_backlog_op(QTestState *qts, backlog_op op, + enum NVx type, uint64_t index, + uint8_t priority, uint8_t delta) +{ + uint64_t addr, offset; + uint32_t count = 0; + + switch (type) { + case NVP: + addr = XIVE_NVPG_ADDR + (index << (XIVE_PAGE_SHIFT + 1)); + break; + case NVG: + addr = XIVE_NVPG_ADDR + (index << (XIVE_PAGE_SHIFT + 1)) + + (1 << XIVE_PAGE_SHIFT); + break; + case NVC: + addr = XIVE_NVC_ADDR + (index << XIVE_PAGE_SHIFT); + break; + default: + g_assert_not_reached(); + } + + offset = (op & 0b11) << NVPG_BACKLOG_OP_SHIFT; + offset |= priority << NVPG_BACKLOG_PRIO_SHIFT; + if (op >> 2) { + qtest_writeb(qts, addr + offset, delta); + } else { + count = qtest_readw(qts, addr + offset); + } + return count; +} + +void test_nvpg_bar(QTestState *qts) +{ + uint32_t nvp_target = 0x11; + uint32_t group_target = 0x17; /* size 16 */ + uint32_t vp_irq = 33, group_irq = 47; + uint32_t vp_end = 3, group_end = 97; + uint32_t vp_irq_data = 0x33333333; + uint32_t group_irq_data = 0x66666666; + uint8_t vp_priority = 0, group_priority = 5; + uint32_t vp_count[XIVE_PRIORITY_MAX + 1] = { 0 }; + uint32_t group_count[XIVE_PRIORITY_MAX + 1] = { 0 }; + uint32_t count, delta; + uint8_t i; + + printf("# ============================================================\n"); + printf("# Testing NVPG BAR operations\n"); + + set_nvg(qts, group_target, 0); + set_nvp(qts, nvp_target, 0x04); + set_nvp(qts, group_target, 0x04); + + /* + * Setup: trigger a VP-specific interrupt and a group interrupt + * so that the backlog counters are initialized to something else + * than 0 for at least one priority level + */ + set_eas(qts, vp_irq, vp_end, vp_irq_data); + set_end(qts, vp_end, nvp_target, vp_priority, false /* group */); + + set_eas(qts, group_irq, group_end, group_irq_data); + set_end(qts, group_end, group_target, group_priority, true /* group */); + + get_esb(qts, vp_irq, XIVE_EOI_PAGE, XIVE_ESB_SET_PQ_00); + set_esb(qts, vp_irq, XIVE_TRIGGER_PAGE, 0, 0); + vp_count[vp_priority]++; + + get_esb(qts, group_irq, XIVE_EOI_PAGE, XIVE_ESB_SET_PQ_00); + set_esb(qts, group_irq, XIVE_TRIGGER_PAGE, 0, 0); + group_count[group_priority]++; + + /* check the initial counters */ + for (i = 0; i <= XIVE_PRIORITY_MAX; i++) { + count = nvpg_backlog_op(qts, READ_x, NVP, nvp_target, i, 0); + g_assert_cmpuint(count, ==, vp_count[i]); + + count = nvpg_backlog_op(qts, READ_y, NVG, group_target, i, 0); + g_assert_cmpuint(count, ==, group_count[i]); + } + + /* do a few ops on the VP. Counter can only be 0 and 1 */ + vp_priority = 2; + delta = 7; + nvpg_backlog_op(qts, INCR_STORE, NVP, nvp_target, vp_priority, delta); + vp_count[vp_priority] = 1; + count = nvpg_backlog_op(qts, INCR_LOAD, NVP, nvp_target, vp_priority, 0); + g_assert_cmpuint(count, ==, vp_count[vp_priority]); + count = nvpg_backlog_op(qts, READ_y, NVP, nvp_target, vp_priority, 0); + g_assert_cmpuint(count, ==, vp_count[vp_priority]); + + count = nvpg_backlog_op(qts, DECR_LOAD, NVP, nvp_target, vp_priority, 0); + g_assert_cmpuint(count, ==, vp_count[vp_priority]); + vp_count[vp_priority] = 0; + nvpg_backlog_op(qts, DECR_STORE, NVP, nvp_target, vp_priority, delta); + count = nvpg_backlog_op(qts, READ_x, NVP, nvp_target, vp_priority, 0); + g_assert_cmpuint(count, ==, vp_count[vp_priority]); + + /* do a few ops on the group */ + group_priority = 2; + delta = 9; + /* can't go negative */ + nvpg_backlog_op(qts, DECR_STORE, NVG, group_target, group_priority, delta); + count = nvpg_backlog_op(qts, READ_y, NVG, group_target, group_priority, 0); + g_assert_cmpuint(count, ==, 0); + nvpg_backlog_op(qts, INCR_STORE, NVG, group_target, group_priority, delta); + group_count[group_priority] += delta; + count = nvpg_backlog_op(qts, INCR_LOAD, NVG, group_target, + group_priority, delta); + g_assert_cmpuint(count, ==, group_count[group_priority]); + group_count[group_priority]++; + + count = nvpg_backlog_op(qts, DECR_LOAD, NVG, group_target, + group_priority, delta); + g_assert_cmpuint(count, ==, group_count[group_priority]); + group_count[group_priority]--; + count = nvpg_backlog_op(qts, READ_x, NVG, group_target, group_priority, 0); + g_assert_cmpuint(count, ==, group_count[group_priority]); +} diff --git a/tests/qtest/pnv-xive2-test.c b/tests/qtest/pnv-xive2-test.c index a4d06550ee..a0e9f19313 100644 --- a/tests/qtest/pnv-xive2-test.c +++ b/tests/qtest/pnv-xive2-test.c @@ -493,6 +493,9 @@ static void test_xive(void) reset_state(qts); test_flush_sync_inject(qts); + reset_state(qts); + test_nvpg_bar(qts); + qtest_quit(qts); } From patchwork Tue Mar 11 12:57:26 2025 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Nicholas Piggin X-Patchwork-Id: 14011819 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.lore.kernel.org (Postfix) with ESMTPS id 7C41BC28B2E for ; Tue, 11 Mar 2025 13:08:19 +0000 (UTC) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1trzFU-0006Sl-JQ; Tue, 11 Mar 2025 09:02:20 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1trzDc-0004i6-N0; Tue, 11 Mar 2025 09:00:25 -0400 Received: from mail-pj1-x1035.google.com ([2607:f8b0:4864:20::1035]) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_128_GCM_SHA256:128) (Exim 4.90_1) (envelope-from ) id 1trzDQ-0008Hk-7O; Tue, 11 Mar 2025 09:00:19 -0400 Received: by mail-pj1-x1035.google.com with SMTP id 98e67ed59e1d1-2ff797f8f1bso7288104a91.3; Tue, 11 Mar 2025 06:00:08 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20230601; t=1741698006; x=1742302806; darn=nongnu.org; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to; bh=V66yWUqp8rsmJBZEyKf71sM70wBJJD9B0Sphx+ooMzc=; b=B6S2o2joT4KT4l8Kj3Y39htmR9o9iOV7o7mFm+tX/yNhUWPAhbb3HT/1B1iZGc4b+M 2jBccjUMpNquPL90yA1pEmz3wfRsIYHc0zGgzHzVVOZbMcGmzn7G9YOwOzaDOnk7dyQn lzW+E7U9Lc81GtNu527hUU2lLeIOjgeINahwkvHJEfA5kCHN4Irqe5RN/LizijmEPJ2z 8oMowmNzpvBRDgZoXUuPmylRjb6m+EhHjAq5LpM0oCaGA9kNTxi/t3x2jWX8FRoL55yt u+0IZU3pg4WkPUmp+a61bDROhs2bXk9e0ti5lt0MQQs9Ja7e/GlQy51sOFqFyzxpGP3C aXNg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1741698006; x=1742302806; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=V66yWUqp8rsmJBZEyKf71sM70wBJJD9B0Sphx+ooMzc=; b=TP3dy+cdBuMSrMmyf7exJa9Ulu5OwGDGfTGHyQWqxtLCSH4yF8u4yG7NsKrterbFbO 73oenjrPKx1X4wZ0/L5CqhtgbSqmMVtzoXZYVCtiHjleSgBMnScFcwvt+9/f1yYPz5ZR z6xoKE1g6kuttVUaI36M9y624abSwhLwdgO6cWkk4IJNV+gXaNxCcSDs8ekFiJBcU3au qSeJuJGTKP9EplyisEuJ5IYn49NolpOnPbYTT4G7qfH0n41lQ9D7wr7ngxpXNT1CDkQh dFqnRkRZBMhWUTyib1oxb6KtOTuqSyT+Wi/mVMfcSVqzKgIJrCGFw/ZITksM10MSRq7s P/vQ== X-Forwarded-Encrypted: i=1; AJvYcCVVDIjHYTocUHhIkXSi8RViJwokROXohxFQ2JcneSP+6FK7FwrCeLIv3bgYRuUYIMBotEW3pP83Wg==@nongnu.org X-Gm-Message-State: AOJu0YwwX7ZIEf9L1tNa7IzyRm+gWQdZ1WCxILC/4sE4qvK3YUoRzvsL Dmwf2yebN+/iFyK/rQ3VTmp7QQPIU5+UBb5W2pAUOA74D375+Uu1M4uc7A== X-Gm-Gg: ASbGnctjg/rih+IPAYfBbRQdshExiSzw+NIZ6Jw9vFJWFw8Q11Mr5RX/G3J0tLRvTxa vk6kksfnXogqh1c0UIlzC2za7rp7J2kUPdgareI7e2H5/N5QdqelnLyAGeLYWWKmbe/1OuJ0B0N D/PZR5QXENfWZDT8TQlQFi8Utf7GGopSMQpN+u39kOmIf4nkdqCAW5NEG7Y72zQbitqxTh6R2X0 rmuUuZCR20YSX4Z8mJoTQFFNAyeAT1R9TMdzrOj5t9o37CJcO6dghtLoLjOT/lFp+0hb6qB7OPJ wGRn04mlPvCZE22PfrwZHIMYAEJbMDLg6n+eP73UD1TGzK0U1cc= X-Google-Smtp-Source: AGHT+IEfrVJuXfc+XS2CthpcI9JwyvsXeVDA2ClnnJjxtMLLYI0Lr9dO9PM/c4FEKPHb6mkYHmAwQA== X-Received: by 2002:a17:90b:2742:b0:2fe:a8b1:7d8 with SMTP id 98e67ed59e1d1-300ff34d643mr4825311a91.25.1741698006292; Tue, 11 Mar 2025 06:00:06 -0700 (PDT) Received: from wheely.local0.net ([118.208.151.101]) by smtp.gmail.com with ESMTPSA id 98e67ed59e1d1-2ff4e773dddsm11822318a91.12.2025.03.11.06.00.02 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 11 Mar 2025 06:00:05 -0700 (PDT) From: Nicholas Piggin To: qemu-devel@nongnu.org Cc: Nicholas Piggin , qemu-ppc@nongnu.org, Frederic Barrat , Glenn Miles , Michael Kowal Subject: [PULL 32/72] ppc/xive2: Support crowd-matching when looking for target Date: Tue, 11 Mar 2025 22:57:26 +1000 Message-ID: <20250311125815.903177-33-npiggin@gmail.com> X-Mailer: git-send-email 2.47.1 In-Reply-To: <20250311125815.903177-1-npiggin@gmail.com> References: <20250311125815.903177-1-npiggin@gmail.com> MIME-Version: 1.0 Received-SPF: pass client-ip=2607:f8b0:4864:20::1035; envelope-from=npiggin@gmail.com; helo=mail-pj1-x1035.google.com X-Spam_score_int: -20 X-Spam_score: -2.1 X-Spam_bar: -- X-Spam_report: (-2.1 / 5.0 requ) BAYES_00=-1.9, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_AU=-0.1, DKIM_VALID_EF=-0.1, FREEMAIL_FROM=0.001, RCVD_IN_DNSWL_NONE=-0.0001, SPF_HELO_NONE=0.001, SPF_PASS=-0.001 autolearn=ham autolearn_force=no X-Spam_action: no action X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: qemu-devel-bounces+qemu-devel=archiver.kernel.org@nongnu.org Sender: qemu-devel-bounces+qemu-devel=archiver.kernel.org@nongnu.org From: Frederic Barrat XIVE crowd sizes are encoded into a 2-bit field as follows: 0: 0b00 2: 0b01 4: 0b10 16: 0b11 A crowd size of 8 is not supported. If an END is defined with the 'crowd' bit set, then a target can be running on different blocks. It means that some bits from the block VP are masked when looking for a match. It is similar to groups, but on the block instead of the VP index. Most of the changes are due to passing the extra argument 'crowd' all the way to the function checking for matches. Signed-off-by: Frederic Barrat Signed-off-by: Glenn Miles Signed-off-by: Michael Kowal Reviewed-by: Nicholas Piggin Signed-off-by: Nicholas Piggin --- hw/intc/pnv_xive.c | 10 +++--- hw/intc/pnv_xive2.c | 12 +++---- hw/intc/spapr_xive.c | 8 ++--- hw/intc/xive.c | 45 +++++++++++++++++++++---- hw/intc/xive2.c | 76 +++++++++++++++++++++++++++++++++--------- hw/ppc/pnv.c | 15 +++++---- hw/ppc/spapr.c | 7 ++-- include/hw/ppc/xive.h | 10 +++--- include/hw/ppc/xive2.h | 3 +- 9 files changed, 134 insertions(+), 52 deletions(-) diff --git a/hw/intc/pnv_xive.c b/hw/intc/pnv_xive.c index b755ddf0ff..ccbe95a58e 100644 --- a/hw/intc/pnv_xive.c +++ b/hw/intc/pnv_xive.c @@ -1,10 +1,9 @@ /* * QEMU PowerPC XIVE interrupt controller model * - * Copyright (c) 2017-2019, IBM Corporation. + * Copyright (c) 2017-2024, IBM Corporation. * - * This code is licensed under the GPL version 2 or later. See the - * COPYING file in the top-level directory. + * SPDX-License-Identifier: GPL-2.0-or-later */ #include "qemu/osdep.h" @@ -473,7 +472,7 @@ static bool pnv_xive_is_cpu_enabled(PnvXive *xive, PowerPCCPU *cpu) static int pnv_xive_match_nvt(XivePresenter *xptr, uint8_t format, uint8_t nvt_blk, uint32_t nvt_idx, - bool cam_ignore, uint8_t priority, + bool crowd, bool cam_ignore, uint8_t priority, uint32_t logic_serv, XiveTCTXMatch *match) { PnvXive *xive = PNV_XIVE(xptr); @@ -500,7 +499,8 @@ static int pnv_xive_match_nvt(XivePresenter *xptr, uint8_t format, * Check the thread context CAM lines and record matches. */ ring = xive_presenter_tctx_match(xptr, tctx, format, nvt_blk, - nvt_idx, cam_ignore, logic_serv); + nvt_idx, cam_ignore, + logic_serv); /* * Save the context and follow on to catch duplicates, that we * don't support yet. diff --git a/hw/intc/pnv_xive2.c b/hw/intc/pnv_xive2.c index c55d596e48..0b81dad6ba 100644 --- a/hw/intc/pnv_xive2.c +++ b/hw/intc/pnv_xive2.c @@ -624,7 +624,7 @@ static bool pnv_xive2_is_cpu_enabled(PnvXive2 *xive, PowerPCCPU *cpu) static int pnv_xive2_match_nvt(XivePresenter *xptr, uint8_t format, uint8_t nvt_blk, uint32_t nvt_idx, - bool cam_ignore, uint8_t priority, + bool crowd, bool cam_ignore, uint8_t priority, uint32_t logic_serv, XiveTCTXMatch *match) { PnvXive2 *xive = PNV_XIVE2(xptr); @@ -655,8 +655,8 @@ static int pnv_xive2_match_nvt(XivePresenter *xptr, uint8_t format, logic_serv); } else { ring = xive2_presenter_tctx_match(xptr, tctx, format, nvt_blk, - nvt_idx, cam_ignore, - logic_serv); + nvt_idx, crowd, cam_ignore, + logic_serv); } if (ring != -1) { @@ -707,7 +707,7 @@ static uint32_t pnv_xive2_presenter_get_config(XivePresenter *xptr) static int pnv_xive2_broadcast(XivePresenter *xptr, uint8_t nvt_blk, uint32_t nvt_idx, - uint8_t priority) + bool crowd, bool ignore, uint8_t priority) { PnvXive2 *xive = PNV_XIVE2(xptr); PnvChip *chip = xive->chip; @@ -732,10 +732,10 @@ static int pnv_xive2_broadcast(XivePresenter *xptr, if (gen1_tima_os) { ring = xive_presenter_tctx_match(xptr, tctx, 0, nvt_blk, - nvt_idx, true, 0); + nvt_idx, ignore, 0); } else { ring = xive2_presenter_tctx_match(xptr, tctx, 0, nvt_blk, - nvt_idx, true, 0); + nvt_idx, crowd, ignore, 0); } if (ring != -1) { diff --git a/hw/intc/spapr_xive.c b/hw/intc/spapr_xive.c index a764c0bb57..ce734b03ab 100644 --- a/hw/intc/spapr_xive.c +++ b/hw/intc/spapr_xive.c @@ -1,10 +1,9 @@ /* * QEMU PowerPC sPAPR XIVE interrupt controller model * - * Copyright (c) 2017-2018, IBM Corporation. + * Copyright (c) 2017-2024, IBM Corporation. * - * This code is licensed under the GPL version 2 or later. See the - * COPYING file in the top-level directory. + * SPDX-License-Identifier: GPL-2.0-or-later */ #include "qemu/osdep.h" @@ -431,7 +430,8 @@ static int spapr_xive_write_nvt(XiveRouter *xrtr, uint8_t nvt_blk, static int spapr_xive_match_nvt(XivePresenter *xptr, uint8_t format, uint8_t nvt_blk, uint32_t nvt_idx, - bool cam_ignore, uint8_t priority, + bool crowd, bool cam_ignore, + uint8_t priority, uint32_t logic_serv, XiveTCTXMatch *match) { CPUState *cs; diff --git a/hw/intc/xive.c b/hw/intc/xive.c index 535e59646f..c77df2c1f8 100644 --- a/hw/intc/xive.c +++ b/hw/intc/xive.c @@ -1665,10 +1665,42 @@ uint32_t xive_get_vpgroup_size(uint32_t nvp_index) return 1 << (ctz32(~nvp_index) + 1); } -static uint8_t xive_get_group_level(uint32_t nvp_index) +static uint8_t xive_get_group_level(bool crowd, bool ignore, + uint32_t nvp_blk, uint32_t nvp_index) { - /* FIXME add crowd encoding */ - return ctz32(~nvp_index) + 1; + uint8_t level; + + if (!ignore) { + g_assert(!crowd); + return 0; + } + + level = (ctz32(~nvp_index) + 1) & 0b1111; + if (crowd) { + uint32_t blk; + + /* crowd level is bit position of first 0 from the right in nvp_blk */ + blk = ctz32(~nvp_blk) + 1; + + /* + * Supported crowd sizes are 2^1, 2^2, and 2^4. 2^3 is not supported. + * HW will encode level 4 as the value 3. See xive2_pgofnext(). + */ + switch (level) { + case 1: + case 2: + break; + case 4: + blk = 3; + break; + default: + g_assert_not_reached(); + } + + /* Crowd level bits reside in upper 2 bits of the 6 bit group level */ + level |= blk << 4; + } + return level; } /* @@ -1740,7 +1772,7 @@ int xive_presenter_tctx_match(XivePresenter *xptr, XiveTCTX *tctx, */ bool xive_presenter_notify(XiveFabric *xfb, uint8_t format, uint8_t nvt_blk, uint32_t nvt_idx, - bool cam_ignore, uint8_t priority, + bool crowd, bool cam_ignore, uint8_t priority, uint32_t logic_serv, bool *precluded) { XiveFabricClass *xfc = XIVE_FABRIC_GET_CLASS(xfb); @@ -1771,7 +1803,7 @@ bool xive_presenter_notify(XiveFabric *xfb, uint8_t format, * a new command to the presenters (the equivalent of the "assign" * power bus command in the documented full notify sequence. */ - count = xfc->match_nvt(xfb, format, nvt_blk, nvt_idx, cam_ignore, + count = xfc->match_nvt(xfb, format, nvt_blk, nvt_idx, crowd, cam_ignore, priority, logic_serv, &match); if (count < 0) { return false; @@ -1779,7 +1811,7 @@ bool xive_presenter_notify(XiveFabric *xfb, uint8_t format, /* handle CPU exception delivery */ if (count) { - group_level = cam_ignore ? xive_get_group_level(nvt_idx) : 0; + group_level = xive_get_group_level(crowd, cam_ignore, nvt_blk, nvt_idx); trace_xive_presenter_notify(nvt_blk, nvt_idx, match.ring, group_level); xive_tctx_pipr_update(match.tctx, match.ring, priority, group_level); } else { @@ -1904,6 +1936,7 @@ void xive_router_end_notify(XiveRouter *xrtr, XiveEAS *eas) } found = xive_presenter_notify(xrtr->xfb, format, nvt_blk, nvt_idx, + false /* crowd */, xive_get_field32(END_W7_F0_IGNORE, end.w7), priority, xive_get_field32(END_W7_F1_LOG_SERVER_ID, end.w7), diff --git a/hw/intc/xive2.c b/hw/intc/xive2.c index 34628f2922..5fa8e1b3fb 100644 --- a/hw/intc/xive2.c +++ b/hw/intc/xive2.c @@ -1121,13 +1121,40 @@ static bool xive2_vp_match_mask(uint32_t cam1, uint32_t cam2, return (cam1 & vp_mask) == (cam2 & vp_mask); } +static uint8_t xive2_get_vp_block_mask(uint32_t nvt_blk, bool crowd) +{ + uint8_t size, block_mask = 0b1111; + + /* 3 supported crowd sizes: 2, 4, 16 */ + if (crowd) { + size = xive_get_vpgroup_size(nvt_blk); + if (size == 8) { + qemu_log_mask(LOG_GUEST_ERROR, "XIVE: Invalid crowd size of 8n"); + return block_mask; + } + block_mask &= ~(size - 1); + } + return block_mask; +} + +static uint32_t xive2_get_vp_index_mask(uint32_t nvt_index, bool cam_ignore) +{ + uint32_t index_mask = 0xFFFFFF; /* 24 bits */ + + if (cam_ignore) { + index_mask &= ~(xive_get_vpgroup_size(nvt_index) - 1); + } + return index_mask; +} + /* * The thread context register words are in big-endian format. */ int xive2_presenter_tctx_match(XivePresenter *xptr, XiveTCTX *tctx, uint8_t format, uint8_t nvt_blk, uint32_t nvt_idx, - bool cam_ignore, uint32_t logic_serv) + bool crowd, bool cam_ignore, + uint32_t logic_serv) { uint32_t cam = xive2_nvp_cam_line(nvt_blk, nvt_idx); uint32_t qw3w2 = xive_tctx_word2(&tctx->regs[TM_QW3_HV_PHYS]); @@ -1135,7 +1162,8 @@ int xive2_presenter_tctx_match(XivePresenter *xptr, XiveTCTX *tctx, uint32_t qw1w2 = xive_tctx_word2(&tctx->regs[TM_QW1_OS]); uint32_t qw0w2 = xive_tctx_word2(&tctx->regs[TM_QW0_USER]); - uint32_t vp_mask = 0xFFFFFFFF; + uint32_t index_mask, vp_mask; + uint8_t block_mask; if (format == 0) { /* @@ -1143,9 +1171,9 @@ int xive2_presenter_tctx_match(XivePresenter *xptr, XiveTCTX *tctx, * i=1: VP-group notification (bits ignored at the end of the * NVT identifier) */ - if (cam_ignore) { - vp_mask = ~(xive_get_vpgroup_size(nvt_idx) - 1); - } + block_mask = xive2_get_vp_block_mask(nvt_blk, crowd); + index_mask = xive2_get_vp_index_mask(nvt_idx, cam_ignore); + vp_mask = xive2_nvp_cam_line(block_mask, index_mask); /* For VP-group notifications, threads with LGS=0 are excluded */ @@ -1277,6 +1305,12 @@ static void xive2_router_end_notify(Xive2Router *xrtr, uint8_t end_blk, return; } + if (xive2_end_is_crowd(&end) & !xive2_end_is_ignore(&end)) { + qemu_log_mask(LOG_GUEST_ERROR, + "XIVE: invalid END, 'crowd' bit requires 'ignore' bit\n"); + return; + } + if (xive2_end_is_enqueue(&end)) { xive2_end_enqueue(&end, end_data); /* Enqueuing event data modifies the EQ toggle and index */ @@ -1325,7 +1359,7 @@ static void xive2_router_end_notify(Xive2Router *xrtr, uint8_t end_blk, nvp_idx = xive_get_field32(END2_W6_VP_OFFSET, end.w6); found = xive_presenter_notify(xrtr->xfb, format, nvp_blk, nvp_idx, - xive2_end_is_ignore(&end), + xive2_end_is_crowd(&end), xive2_end_is_ignore(&end), priority, xive_get_field32(END2_W7_F1_LOG_SERVER_ID, end.w7), &precluded); @@ -1377,17 +1411,24 @@ static void xive2_router_end_notify(Xive2Router *xrtr, uint8_t end_blk, nvp.w2 = xive_set_field32(NVP2_W2_IPB, nvp.w2, ipb); xive2_router_write_nvp(xrtr, nvp_blk, nvp_idx, &nvp, 2); } else { - Xive2Nvgc nvg; + Xive2Nvgc nvgc; uint32_t backlog; + bool crowd; - /* For groups, the per-priority backlog counters are in the NVG */ - if (xive2_router_get_nvgc(xrtr, false, nvp_blk, nvp_idx, &nvg)) { - qemu_log_mask(LOG_GUEST_ERROR, "XIVE: no NVG %x/%x\n", - nvp_blk, nvp_idx); + crowd = xive2_end_is_crowd(&end); + + /* + * For groups and crowds, the per-priority backlog + * counters are stored in the NVG/NVC structures + */ + if (xive2_router_get_nvgc(xrtr, crowd, + nvp_blk, nvp_idx, &nvgc)) { + qemu_log_mask(LOG_GUEST_ERROR, "XIVE: no %s %x/%x\n", + crowd ? "NVC" : "NVG", nvp_blk, nvp_idx); return; } - if (!xive2_nvgc_is_valid(&nvg)) { + if (!xive2_nvgc_is_valid(&nvgc)) { qemu_log_mask(LOG_GUEST_ERROR, "XIVE: NVG %x/%x is invalid\n", nvp_blk, nvp_idx); return; @@ -1399,13 +1440,16 @@ static void xive2_router_end_notify(Xive2Router *xrtr, uint8_t end_blk, * incremented. broadcast will set the LSMFB field of the TIMA of * relevant threads so that they know an interrupt is pending. */ - backlog = xive2_nvgc_get_backlog(&nvg, priority) + 1; - xive2_nvgc_set_backlog(&nvg, priority, backlog); - xive2_router_write_nvgc(xrtr, false, nvp_blk, nvp_idx, &nvg); + backlog = xive2_nvgc_get_backlog(&nvgc, priority) + 1; + xive2_nvgc_set_backlog(&nvgc, priority, backlog); + xive2_router_write_nvgc(xrtr, crowd, nvp_blk, nvp_idx, &nvgc); if (backlog == 1) { XiveFabricClass *xfc = XIVE_FABRIC_GET_CLASS(xrtr->xfb); - xfc->broadcast(xrtr->xfb, nvp_blk, nvp_idx, priority); + xfc->broadcast(xrtr->xfb, nvp_blk, nvp_idx, + xive2_end_is_crowd(&end), + xive2_end_is_ignore(&end), + priority); if (!xive2_end_is_precluded_escalation(&end)) { /* diff --git a/hw/ppc/pnv.c b/hw/ppc/pnv.c index af836c1388..d60574d601 100644 --- a/hw/ppc/pnv.c +++ b/hw/ppc/pnv.c @@ -2608,7 +2608,7 @@ static void pnv_pic_print_info(InterruptStatsProvider *obj, GString *buf) static int pnv_match_nvt(XiveFabric *xfb, uint8_t format, uint8_t nvt_blk, uint32_t nvt_idx, - bool cam_ignore, uint8_t priority, + bool crowd, bool cam_ignore, uint8_t priority, uint32_t logic_serv, XiveTCTXMatch *match) { @@ -2622,8 +2622,8 @@ static int pnv_match_nvt(XiveFabric *xfb, uint8_t format, XivePresenterClass *xpc = XIVE_PRESENTER_GET_CLASS(xptr); int count; - count = xpc->match_nvt(xptr, format, nvt_blk, nvt_idx, cam_ignore, - priority, logic_serv, match); + count = xpc->match_nvt(xptr, format, nvt_blk, nvt_idx, crowd, + cam_ignore, priority, logic_serv, match); if (count < 0) { return count; @@ -2637,7 +2637,7 @@ static int pnv_match_nvt(XiveFabric *xfb, uint8_t format, static int pnv10_xive_match_nvt(XiveFabric *xfb, uint8_t format, uint8_t nvt_blk, uint32_t nvt_idx, - bool cam_ignore, uint8_t priority, + bool crowd, bool cam_ignore, uint8_t priority, uint32_t logic_serv, XiveTCTXMatch *match) { @@ -2651,8 +2651,8 @@ static int pnv10_xive_match_nvt(XiveFabric *xfb, uint8_t format, XivePresenterClass *xpc = XIVE_PRESENTER_GET_CLASS(xptr); int count; - count = xpc->match_nvt(xptr, format, nvt_blk, nvt_idx, cam_ignore, - priority, logic_serv, match); + count = xpc->match_nvt(xptr, format, nvt_blk, nvt_idx, crowd, + cam_ignore, priority, logic_serv, match); if (count < 0) { return count; @@ -2666,6 +2666,7 @@ static int pnv10_xive_match_nvt(XiveFabric *xfb, uint8_t format, static int pnv10_xive_broadcast(XiveFabric *xfb, uint8_t nvt_blk, uint32_t nvt_idx, + bool crowd, bool cam_ignore, uint8_t priority) { PnvMachineState *pnv = PNV_MACHINE(xfb); @@ -2676,7 +2677,7 @@ static int pnv10_xive_broadcast(XiveFabric *xfb, XivePresenter *xptr = XIVE_PRESENTER(&chip10->xive); XivePresenterClass *xpc = XIVE_PRESENTER_GET_CLASS(xptr); - xpc->broadcast(xptr, nvt_blk, nvt_idx, priority); + xpc->broadcast(xptr, nvt_blk, nvt_idx, crowd, cam_ignore, priority); } return 0; } diff --git a/hw/ppc/spapr.c b/hw/ppc/spapr.c index c15340a58d..c7cf04e063 100644 --- a/hw/ppc/spapr.c +++ b/hw/ppc/spapr.c @@ -4,6 +4,9 @@ * Copyright (c) 2004-2007 Fabrice Bellard * Copyright (c) 2007 Jocelyn Mayer * Copyright (c) 2010 David Gibson, IBM Corporation. + * Copyright (c) 2010-2024, IBM Corporation.. + * + * SPDX-License-Identifier: GPL-2.0-or-later * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -4436,7 +4439,7 @@ static void spapr_pic_print_info(InterruptStatsProvider *obj, GString *buf) */ static int spapr_match_nvt(XiveFabric *xfb, uint8_t format, uint8_t nvt_blk, uint32_t nvt_idx, - bool cam_ignore, uint8_t priority, + bool crowd, bool cam_ignore, uint8_t priority, uint32_t logic_serv, XiveTCTXMatch *match) { SpaprMachineState *spapr = SPAPR_MACHINE(xfb); @@ -4444,7 +4447,7 @@ static int spapr_match_nvt(XiveFabric *xfb, uint8_t format, XivePresenterClass *xpc = XIVE_PRESENTER_GET_CLASS(xptr); int count; - count = xpc->match_nvt(xptr, format, nvt_blk, nvt_idx, cam_ignore, + count = xpc->match_nvt(xptr, format, nvt_blk, nvt_idx, crowd, cam_ignore, priority, logic_serv, match); if (count < 0) { return count; diff --git a/include/hw/ppc/xive.h b/include/hw/ppc/xive.h index 6a410c6f1a..538f438681 100644 --- a/include/hw/ppc/xive.h +++ b/include/hw/ppc/xive.h @@ -438,13 +438,13 @@ struct XivePresenterClass { InterfaceClass parent; int (*match_nvt)(XivePresenter *xptr, uint8_t format, uint8_t nvt_blk, uint32_t nvt_idx, - bool cam_ignore, uint8_t priority, + bool crowd, bool cam_ignore, uint8_t priority, uint32_t logic_serv, XiveTCTXMatch *match); bool (*in_kernel)(const XivePresenter *xptr); uint32_t (*get_config)(XivePresenter *xptr); int (*broadcast)(XivePresenter *xptr, uint8_t nvt_blk, uint32_t nvt_idx, - uint8_t priority); + bool crowd, bool cam_ignore, uint8_t priority); }; int xive_presenter_tctx_match(XivePresenter *xptr, XiveTCTX *tctx, @@ -453,7 +453,7 @@ int xive_presenter_tctx_match(XivePresenter *xptr, XiveTCTX *tctx, bool cam_ignore, uint32_t logic_serv); bool xive_presenter_notify(XiveFabric *xfb, uint8_t format, uint8_t nvt_blk, uint32_t nvt_idx, - bool cam_ignore, uint8_t priority, + bool crowd, bool cam_ignore, uint8_t priority, uint32_t logic_serv, bool *precluded); uint32_t xive_get_vpgroup_size(uint32_t nvp_index); @@ -473,10 +473,10 @@ struct XiveFabricClass { InterfaceClass parent; int (*match_nvt)(XiveFabric *xfb, uint8_t format, uint8_t nvt_blk, uint32_t nvt_idx, - bool cam_ignore, uint8_t priority, + bool crowd, bool cam_ignore, uint8_t priority, uint32_t logic_serv, XiveTCTXMatch *match); int (*broadcast)(XiveFabric *xfb, uint8_t nvt_blk, uint32_t nvt_idx, - uint8_t priority); + bool crowd, bool cam_ignore, uint8_t priority); }; /* diff --git a/include/hw/ppc/xive2.h b/include/hw/ppc/xive2.h index c07e23e1d3..8cdf819174 100644 --- a/include/hw/ppc/xive2.h +++ b/include/hw/ppc/xive2.h @@ -88,7 +88,8 @@ void xive2_router_notify(XiveNotifier *xn, uint32_t lisn, bool pq_checked); int xive2_presenter_tctx_match(XivePresenter *xptr, XiveTCTX *tctx, uint8_t format, uint8_t nvt_blk, uint32_t nvt_idx, - bool cam_ignore, uint32_t logic_serv); + bool crowd, bool cam_ignore, + uint32_t logic_serv); uint64_t xive2_presenter_nvp_backlog_op(XivePresenter *xptr, uint8_t blk, uint32_t idx, From patchwork Tue Mar 11 12:57:27 2025 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Nicholas Piggin X-Patchwork-Id: 14011830 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.lore.kernel.org (Postfix) with ESMTPS id CA0A8C282EC for ; Tue, 11 Mar 2025 13:12:13 +0000 (UTC) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1trzKG-000741-Dm; Tue, 11 Mar 2025 09:07:22 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1trzDW-0004aS-H6; Tue, 11 Mar 2025 09:00:23 -0400 Received: from mail-pl1-x62b.google.com ([2607:f8b0:4864:20::62b]) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_128_GCM_SHA256:128) (Exim 4.90_1) (envelope-from ) id 1trzDS-0008IS-9b; Tue, 11 Mar 2025 09:00:18 -0400 Received: by mail-pl1-x62b.google.com with SMTP id d9443c01a7336-224341bbc1dso67975095ad.3; Tue, 11 Mar 2025 06:00:11 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20230601; t=1741698009; x=1742302809; darn=nongnu.org; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to; bh=s/XBvKPmghhbKFfzwm85aRAZZaLgzLWVK0EV9GNbOE4=; b=A4yTrPFCvwtbO/SEY6UeeeKqTYgJRD0oP3aNJIMWaXyhxJ94/5Rc2V/TA8LFzfpI9L gEeOgS+OnpbmaQ8LI76paYJs1aH7ogMvGjpKWWkKmjBVbEukuIGpjenjANAC5ixDc5CM xsdPFwyHDJWM0B97kyUPWDRsm1itnFZOLMLZJIbcEPfF/qGHm36ky3Wk/RIzX790TKuf auYvfwy4GAjoIIkj/oofI4MAnp4ntOnSbcaPKvYsK+BnwcX8kZaF/Y14u6TDCcsBpvKQ 41/nor1Wd4VhZjJ79kSuN1alEN6UZitydDgNUAPbCxcxRw+2NTh9SoYQx4hkMr9Z/edt 4PUw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1741698009; x=1742302809; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=s/XBvKPmghhbKFfzwm85aRAZZaLgzLWVK0EV9GNbOE4=; b=HAkr3Xz9/Hg+FmNW+P5vRQ+8F1nyhZpM5xDkIPYvxLzvBkPffAzHsNH7To/HGu5aBX 08aXzcebvO460OrPeEVFpfEvrn60/oHw387S9xILb42N3emcWDUNQOxfxUe10Lx6PiCV VqKKXZucjWxaIFlRlod8krqfNTHQxeCa/wpU861v93OyMU6cdOLHv/MvEO3q7KUeUcw4 xGaqIoj1LrPkiSfeSMkuM0c5KJybgkRpAKEk3QLfU48rHQvo0PKhFMQPGhPxHz2ns3Gg Ov0biT+hsvZZ3n62vdj+TORhiEhLwcJbsARW65nqMxEObrvON/FpZxWm5mWBFpFfKiuH 8isg== X-Forwarded-Encrypted: i=1; AJvYcCWhRU4PHEWFynbcTilie8T/+BK95hYccZNR9Mc8YgilhLt/L8phirT6sgnSX82xbgz4jqVMoOJ9HA==@nongnu.org X-Gm-Message-State: AOJu0YzekYfY+WwnbhfAZWVY2wch9D1ZGMhMll3k5TJe8U0md2CP4RE9 bQj4PWVIL045vLDXVBI/EBbxnPd8tfTDl+u5gxabVOpAqOMdsxGVwkqa9g== X-Gm-Gg: ASbGncubJFjaHH3BDfu/pdgtM25sB7VhwpaeU4kIVNxLRaM69uo3li5Kcc0kVwdayes nnPSWDoV9Aa7WrAQc81hvpmhhvmYJnzSYFEpWR4yoWFTH0wLZiKxvrIFiXW4R9VDahl8TcMd6ZM aO85yS8GDoUqAjJvM01HeXzHDagT5LFJ16pqAx5K9Jq9a07GAGQVNHFM/JTM2XVySM5fxdxR0Pw RfftX3PiptKYDc0M6yuSRRJMhSs1kuxso89CwtT5l4eDBRdFUctwRaMdQHFy11yNBTpWB8dG25m SiX9neP6IQ4ANYMD377rmOLyZIZj7ODXI2z0Sy3o2po9jIVDXXM= X-Google-Smtp-Source: AGHT+IF1qSFvQdY4aQMYNsKVRb3BvJiV+sYcoOGgGY4PNlhMGzMIka3DoYXRPPzXncEghUctBhYk2A== X-Received: by 2002:a17:902:c949:b0:224:78e:4ebe with SMTP id d9443c01a7336-22593183ec4mr45122475ad.33.1741698009287; Tue, 11 Mar 2025 06:00:09 -0700 (PDT) Received: from wheely.local0.net ([118.208.151.101]) by smtp.gmail.com with ESMTPSA id 98e67ed59e1d1-2ff4e773dddsm11822318a91.12.2025.03.11.06.00.06 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 11 Mar 2025 06:00:08 -0700 (PDT) From: Nicholas Piggin To: qemu-devel@nongnu.org Cc: Nicholas Piggin , qemu-ppc@nongnu.org, Glenn Miles , Glenn Miles Subject: [PULL 33/72] pnv/xive2: Rename nvp_ to nvx_ if they can refer to NVP or NVGC Date: Tue, 11 Mar 2025 22:57:27 +1000 Message-ID: <20250311125815.903177-34-npiggin@gmail.com> X-Mailer: git-send-email 2.47.1 In-Reply-To: <20250311125815.903177-1-npiggin@gmail.com> References: <20250311125815.903177-1-npiggin@gmail.com> MIME-Version: 1.0 Received-SPF: pass client-ip=2607:f8b0:4864:20::62b; envelope-from=npiggin@gmail.com; helo=mail-pl1-x62b.google.com X-Spam_score_int: -20 X-Spam_score: -2.1 X-Spam_bar: -- X-Spam_report: (-2.1 / 5.0 requ) BAYES_00=-1.9, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_AU=-0.1, DKIM_VALID_EF=-0.1, FREEMAIL_FROM=0.001, RCVD_IN_DNSWL_NONE=-0.0001, SPF_HELO_NONE=0.001, SPF_PASS=-0.001 autolearn=ham autolearn_force=no X-Spam_action: no action X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: qemu-devel-bounces+qemu-devel=archiver.kernel.org@nongnu.org Sender: qemu-devel-bounces+qemu-devel=archiver.kernel.org@nongnu.org From: Glenn Miles The blk/index in some paths may refer to an NVP or an NVGC. When it is not known ahead of time, use the nvx_ prefix to prevent confusion. [npiggin: split out of larger fix patch and reworded] Signed-off-by: Glenn Miles Reviewed-by: Nicholas Piggin Signed-off-by: Nicholas Piggin --- hw/intc/xive2.c | 56 ++++++++++++++++++++++++------------------------- 1 file changed, 28 insertions(+), 28 deletions(-) diff --git a/hw/intc/xive2.c b/hw/intc/xive2.c index 5fa8e1b3fb..e925307d0f 100644 --- a/hw/intc/xive2.c +++ b/hw/intc/xive2.c @@ -226,8 +226,8 @@ void xive2_end_pic_print_info(Xive2End *end, uint32_t end_idx, GString *buf) uint32_t qsize = xive_get_field32(END2_W3_QSIZE, end->w3); uint32_t qentries = 1 << (qsize + 10); - uint32_t nvp_blk = xive_get_field32(END2_W6_VP_BLOCK, end->w6); - uint32_t nvp_idx = xive_get_field32(END2_W6_VP_OFFSET, end->w6); + uint32_t nvx_blk = xive_get_field32(END2_W6_VP_BLOCK, end->w6); + uint32_t nvx_idx = xive_get_field32(END2_W6_VP_OFFSET, end->w6); uint8_t priority = xive_get_field32(END2_W7_F0_PRIORITY, end->w7); uint8_t pq; @@ -256,7 +256,7 @@ void xive2_end_pic_print_info(Xive2End *end, uint32_t end_idx, GString *buf) xive2_end_is_firmware2(end) ? 'F' : '-', xive2_end_is_ignore(end) ? 'i' : '-', xive2_end_is_crowd(end) ? 'c' : '-', - priority, nvp_blk, nvp_idx); + priority, nvx_blk, nvx_idx); if (qaddr_base) { g_string_append_printf(buf, " eq:@%08"PRIx64"% 6d/%5d ^%d", @@ -372,7 +372,7 @@ static void xive2_end_enqueue(Xive2End *end, uint32_t data) * level of pending group interrupts. */ static uint8_t xive2_presenter_backlog_scan(XivePresenter *xptr, - uint8_t nvp_blk, uint32_t nvp_idx, + uint8_t nvx_blk, uint32_t nvx_idx, uint8_t first_group, uint8_t *out_level) { @@ -387,19 +387,19 @@ static uint8_t xive2_presenter_backlog_scan(XivePresenter *xptr, while (current_level) { mask = (1 << current_level) - 1; - nvgc_idx = nvp_idx & ~mask; + nvgc_idx = nvx_idx & ~mask; nvgc_idx |= mask >> 1; qemu_log("fxb %s checking backlog for prio %d group idx %x\n", __func__, prio, nvgc_idx); - if (xive2_router_get_nvgc(xrtr, false, nvp_blk, nvgc_idx, &nvgc)) { + if (xive2_router_get_nvgc(xrtr, false, nvx_blk, nvgc_idx, &nvgc)) { qemu_log_mask(LOG_GUEST_ERROR, "XIVE: No NVG %x/%x\n", - nvp_blk, nvgc_idx); + nvx_blk, nvgc_idx); return 0xFF; } if (!xive2_nvgc_is_valid(&nvgc)) { qemu_log_mask(LOG_GUEST_ERROR, "XIVE: Invalid NVG %x/%x\n", - nvp_blk, nvgc_idx); + nvx_blk, nvgc_idx); return 0xFF; } @@ -415,7 +415,7 @@ static uint8_t xive2_presenter_backlog_scan(XivePresenter *xptr, } static void xive2_presenter_backlog_decr(XivePresenter *xptr, - uint8_t nvp_blk, uint32_t nvp_idx, + uint8_t nvx_blk, uint32_t nvx_idx, uint8_t group_prio, uint8_t group_level) { @@ -425,17 +425,17 @@ static void xive2_presenter_backlog_decr(XivePresenter *xptr, group_level &= 0xF; mask = (1 << group_level) - 1; - nvgc_idx = nvp_idx & ~mask; + nvgc_idx = nvx_idx & ~mask; nvgc_idx |= mask >> 1; - if (xive2_router_get_nvgc(xrtr, false, nvp_blk, nvgc_idx, &nvgc)) { + if (xive2_router_get_nvgc(xrtr, false, nvx_blk, nvgc_idx, &nvgc)) { qemu_log_mask(LOG_GUEST_ERROR, "XIVE: No NVG %x/%x\n", - nvp_blk, nvgc_idx); + nvx_blk, nvgc_idx); return; } if (!xive2_nvgc_is_valid(&nvgc)) { qemu_log_mask(LOG_GUEST_ERROR, "XIVE: Invalid NVG %x/%x\n", - nvp_blk, nvgc_idx); + nvx_blk, nvgc_idx); return; } count = xive2_nvgc_get_backlog(&nvgc, group_prio); @@ -443,7 +443,7 @@ static void xive2_presenter_backlog_decr(XivePresenter *xptr, return; } xive2_nvgc_set_backlog(&nvgc, group_prio, count - 1); - xive2_router_write_nvgc(xrtr, false, nvp_blk, nvgc_idx, &nvgc); + xive2_router_write_nvgc(xrtr, false, nvx_blk, nvgc_idx, &nvgc); } /* @@ -1289,8 +1289,8 @@ static void xive2_router_end_notify(Xive2Router *xrtr, uint8_t end_blk, uint8_t priority; uint8_t format; bool found, precluded; - uint8_t nvp_blk; - uint32_t nvp_idx; + uint8_t nvx_blk; + uint32_t nvx_idx; /* END cache lookup */ if (xive2_router_get_end(xrtr, end_blk, end_idx, &end)) { @@ -1355,10 +1355,10 @@ static void xive2_router_end_notify(Xive2Router *xrtr, uint8_t end_blk, /* * Follows IVPE notification */ - nvp_blk = xive_get_field32(END2_W6_VP_BLOCK, end.w6); - nvp_idx = xive_get_field32(END2_W6_VP_OFFSET, end.w6); + nvx_blk = xive_get_field32(END2_W6_VP_BLOCK, end.w6); + nvx_idx = xive_get_field32(END2_W6_VP_OFFSET, end.w6); - found = xive_presenter_notify(xrtr->xfb, format, nvp_blk, nvp_idx, + found = xive_presenter_notify(xrtr->xfb, format, nvx_blk, nvx_idx, xive2_end_is_crowd(&end), xive2_end_is_ignore(&end), priority, xive_get_field32(END2_W7_F1_LOG_SERVER_ID, end.w7), @@ -1389,15 +1389,15 @@ static void xive2_router_end_notify(Xive2Router *xrtr, uint8_t end_blk, Xive2Nvp nvp; /* NVP cache lookup */ - if (xive2_router_get_nvp(xrtr, nvp_blk, nvp_idx, &nvp)) { + if (xive2_router_get_nvp(xrtr, nvx_blk, nvx_idx, &nvp)) { qemu_log_mask(LOG_GUEST_ERROR, "XIVE: no NVP %x/%x\n", - nvp_blk, nvp_idx); + nvx_blk, nvx_idx); return; } if (!xive2_nvp_is_valid(&nvp)) { qemu_log_mask(LOG_GUEST_ERROR, "XIVE: NVP %x/%x is invalid\n", - nvp_blk, nvp_idx); + nvx_blk, nvx_idx); return; } @@ -1409,7 +1409,7 @@ static void xive2_router_end_notify(Xive2Router *xrtr, uint8_t end_blk, ipb = xive_get_field32(NVP2_W2_IPB, nvp.w2) | xive_priority_to_ipb(priority); nvp.w2 = xive_set_field32(NVP2_W2_IPB, nvp.w2, ipb); - xive2_router_write_nvp(xrtr, nvp_blk, nvp_idx, &nvp, 2); + xive2_router_write_nvp(xrtr, nvx_blk, nvx_idx, &nvp, 2); } else { Xive2Nvgc nvgc; uint32_t backlog; @@ -1422,15 +1422,15 @@ static void xive2_router_end_notify(Xive2Router *xrtr, uint8_t end_blk, * counters are stored in the NVG/NVC structures */ if (xive2_router_get_nvgc(xrtr, crowd, - nvp_blk, nvp_idx, &nvgc)) { + nvx_blk, nvx_idx, &nvgc)) { qemu_log_mask(LOG_GUEST_ERROR, "XIVE: no %s %x/%x\n", - crowd ? "NVC" : "NVG", nvp_blk, nvp_idx); + crowd ? "NVC" : "NVG", nvx_blk, nvx_idx); return; } if (!xive2_nvgc_is_valid(&nvgc)) { qemu_log_mask(LOG_GUEST_ERROR, "XIVE: NVG %x/%x is invalid\n", - nvp_blk, nvp_idx); + nvx_blk, nvx_idx); return; } @@ -1442,11 +1442,11 @@ static void xive2_router_end_notify(Xive2Router *xrtr, uint8_t end_blk, */ backlog = xive2_nvgc_get_backlog(&nvgc, priority) + 1; xive2_nvgc_set_backlog(&nvgc, priority, backlog); - xive2_router_write_nvgc(xrtr, crowd, nvp_blk, nvp_idx, &nvgc); + xive2_router_write_nvgc(xrtr, crowd, nvx_blk, nvx_idx, &nvgc); if (backlog == 1) { XiveFabricClass *xfc = XIVE_FABRIC_GET_CLASS(xrtr->xfb); - xfc->broadcast(xrtr->xfb, nvp_blk, nvp_idx, + xfc->broadcast(xrtr->xfb, nvx_blk, nvx_idx, xive2_end_is_crowd(&end), xive2_end_is_ignore(&end), priority); From patchwork Tue Mar 11 12:57:28 2025 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Nicholas Piggin X-Patchwork-Id: 14011817 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.lore.kernel.org (Postfix) with ESMTPS id 8B598C28B30 for ; Tue, 11 Mar 2025 13:07:49 +0000 (UTC) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1trzF5-00066f-GR; Tue, 11 Mar 2025 09:02:00 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1trzDc-0004i3-Hl; Tue, 11 Mar 2025 09:00:25 -0400 Received: from mail-pj1-x1034.google.com ([2607:f8b0:4864:20::1034]) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_128_GCM_SHA256:128) (Exim 4.90_1) (envelope-from ) id 1trzDW-0008JI-5r; Tue, 11 Mar 2025 09:00:21 -0400 Received: by mail-pj1-x1034.google.com with SMTP id 98e67ed59e1d1-2fee4d9c2efso9001913a91.3; Tue, 11 Mar 2025 06:00:13 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20230601; t=1741698012; x=1742302812; darn=nongnu.org; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to; bh=WONqQrZcwlp8hZGRfUQfRRo9qkCGxQct+x79CzVQ1Sk=; b=ZIV41OYTk5AJo+39WPqgjZBze6c4C9cd9fX09Uw0hlMSmT9s7wozivaWfYThsbMznJ aplUh0bRA7cCckjDRt+qyFAvva8fJ18m8b+uMFFiF32z5Ma/eVx0eFwLgnLNlfshq9tt Ux8Ql+qwvUmMIQyzQ5+CFOvJ8rdgobRu0P5BbBE5SI9XNRjldSFVeV8/XgU0uff1Yvp+ kK+vWoxvBqoKSWS8sU3HfoxpeUcP82eG/iL1MdiYF1Jxexk0OO4BlBRj95NgFvaZJPip J5hl6AAo+nsO3XBHAej/GywqXk/IDxZW6kZQ7SpYGOAbvBAfAKiDTstj3TSkb5rJmMRM I5Rw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1741698012; x=1742302812; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=WONqQrZcwlp8hZGRfUQfRRo9qkCGxQct+x79CzVQ1Sk=; b=P69hScfqykVy3sklPYLvUvQqTLW879uSfPAmAY3Qb4gLbkA7jQCdOt0fNg5U3WEO6v 0DewdvIEcySzeJdsvGJUUcjGXUZ77DBuOCMQgKw9HIX9yV+PRr34A2ywaXvtaS8AfUPO SL7imw368FjX0agzlVoBoqalgNYuE0BuMrbQtQM043zlcyOrJN0o8c04BGHujvsj1czA tiXIOAOnW0YuRe4U3aOlXPtRkTIZ7uuMdJ4/GzVHvqsEU6fxqG5cZSRqiH/51VLPOEt2 V1+5S3vL2nveRV5vFeZbtXwRyGNulo8ZCZ8QU4b1cCcncnKvEGXDjmU4QvyKRpnbct/F 6XGg== X-Forwarded-Encrypted: i=1; AJvYcCWIXT2OJImLPh+6dxunVgrrw0FJG7d2XXeDwF5VS2jBNBLLBX+zI0Q5185s97qJ0Vzhf3GCC3szMw==@nongnu.org X-Gm-Message-State: AOJu0Yyz9EttYr8AfMqlR8hOalmgajBh/i0y40+EXdE9br/UOh74xokm BnP605tcm1+yescWWsNV+DcdfeE5F53C6axDIsxkoRHbmu3STqEYbJmi9g== X-Gm-Gg: ASbGncsKdueB2YZ4+XhQu4Q+5prJvZWVp1XgGxbpHp65df8GQisJnNoTXgglc9lTpq2 XInjNIxdBNTcH7qd/jys/NXIF6YubZmlP/sKVb4soTgPv72E/eTjF0JIUMQuqKfZHYFQ9mKhd7Y 9Z3wUZDoWZTnBARkqlsSIbnfKGRPUXHiwzGwSbfa2y+ZromQWyNKJydxPKa3/eEY4sLAaWaW767 v8T8KWX+gRfVrF6D2GhfHOuh43Rccd6FN8BUi/yPne1vaaDgXbaJarVwR7+fv0OJO7ZTlHT78wq vuPI9EGbPpci4q2JlyojLlFQZrsH8vxerfFzyniZ0ZFTL+EjAZQ= X-Google-Smtp-Source: AGHT+IEgV0fqBE6Z9BPqEchYJbCJvBp74KhJbKiEch9XoY6eS3Igccqlk+FjtY1eWACnQZKNFNeYvg== X-Received: by 2002:a17:90b:52c3:b0:2fe:9581:fbea with SMTP id 98e67ed59e1d1-2ff7cf22de4mr26426610a91.29.1741698012303; Tue, 11 Mar 2025 06:00:12 -0700 (PDT) Received: from wheely.local0.net ([118.208.151.101]) by smtp.gmail.com with ESMTPSA id 98e67ed59e1d1-2ff4e773dddsm11822318a91.12.2025.03.11.06.00.09 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 11 Mar 2025 06:00:11 -0700 (PDT) From: Nicholas Piggin To: qemu-devel@nongnu.org Cc: Nicholas Piggin , qemu-ppc@nongnu.org, Frederic Barrat , Michael Kowal Subject: [PULL 34/72] ppc/xive2: Check crowd backlog when scanning group backlog Date: Tue, 11 Mar 2025 22:57:28 +1000 Message-ID: <20250311125815.903177-35-npiggin@gmail.com> X-Mailer: git-send-email 2.47.1 In-Reply-To: <20250311125815.903177-1-npiggin@gmail.com> References: <20250311125815.903177-1-npiggin@gmail.com> MIME-Version: 1.0 Received-SPF: pass client-ip=2607:f8b0:4864:20::1034; envelope-from=npiggin@gmail.com; helo=mail-pj1-x1034.google.com X-Spam_score_int: -20 X-Spam_score: -2.1 X-Spam_bar: -- X-Spam_report: (-2.1 / 5.0 requ) BAYES_00=-1.9, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_AU=-0.1, DKIM_VALID_EF=-0.1, FREEMAIL_FROM=0.001, RCVD_IN_DNSWL_NONE=-0.0001, SPF_HELO_NONE=0.001, SPF_PASS=-0.001 autolearn=ham autolearn_force=no X-Spam_action: no action X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: qemu-devel-bounces+qemu-devel=archiver.kernel.org@nongnu.org Sender: qemu-devel-bounces+qemu-devel=archiver.kernel.org@nongnu.org From: Frederic Barrat When processing a backlog scan for group interrupts, also take into account crowd interrupts. Signed-off-by: Frederic Barrat Signed-off-by: Michael Kowal Reviewed-by: Nicholas Piggin Signed-off-by: Nicholas Piggin --- hw/intc/xive2.c | 82 +++++++++++++++++++++++++------------ include/hw/ppc/xive2_regs.h | 4 ++ 2 files changed, 60 insertions(+), 26 deletions(-) diff --git a/hw/intc/xive2.c b/hw/intc/xive2.c index e925307d0f..f8ef615487 100644 --- a/hw/intc/xive2.c +++ b/hw/intc/xive2.c @@ -367,6 +367,35 @@ static void xive2_end_enqueue(Xive2End *end, uint32_t data) end->w1 = xive_set_field32(END2_W1_PAGE_OFF, end->w1, qindex); } +static void xive2_pgofnext(uint8_t *nvgc_blk, uint32_t *nvgc_idx, + uint8_t next_level) +{ + uint32_t mask, next_idx; + uint8_t next_blk; + + /* + * Adjust the block and index of a VP for the next group/crowd + * size (PGofFirst/PGofNext field in the NVP and NVGC structures). + * + * The 6-bit group level is split into a 2-bit crowd and 4-bit + * group levels. Encoding is similar. However, we don't support + * crowd size of 8. So a crowd level of 0b11 is bumped to a crowd + * size of 16. + */ + next_blk = NVx_CROWD_LVL(next_level); + if (next_blk == 3) { + next_blk = 4; + } + mask = (1 << next_blk) - 1; + *nvgc_blk &= ~mask; + *nvgc_blk |= mask >> 1; + + next_idx = NVx_GROUP_LVL(next_level); + mask = (1 << next_idx) - 1; + *nvgc_idx &= ~mask; + *nvgc_idx |= mask >> 1; +} + /* * Scan the group chain and return the highest priority and group * level of pending group interrupts. @@ -377,29 +406,28 @@ static uint8_t xive2_presenter_backlog_scan(XivePresenter *xptr, uint8_t *out_level) { Xive2Router *xrtr = XIVE2_ROUTER(xptr); - uint32_t nvgc_idx, mask; + uint32_t nvgc_idx; uint32_t current_level, count; - uint8_t prio; + uint8_t nvgc_blk, prio; Xive2Nvgc nvgc; for (prio = 0; prio <= XIVE_PRIORITY_MAX; prio++) { - current_level = first_group & 0xF; + current_level = first_group & 0x3F; + nvgc_blk = nvx_blk; + nvgc_idx = nvx_idx; while (current_level) { - mask = (1 << current_level) - 1; - nvgc_idx = nvx_idx & ~mask; - nvgc_idx |= mask >> 1; - qemu_log("fxb %s checking backlog for prio %d group idx %x\n", - __func__, prio, nvgc_idx); - - if (xive2_router_get_nvgc(xrtr, false, nvx_blk, nvgc_idx, &nvgc)) { - qemu_log_mask(LOG_GUEST_ERROR, "XIVE: No NVG %x/%x\n", - nvx_blk, nvgc_idx); + xive2_pgofnext(&nvgc_blk, &nvgc_idx, current_level); + + if (xive2_router_get_nvgc(xrtr, NVx_CROWD_LVL(current_level), + nvgc_blk, nvgc_idx, &nvgc)) { + qemu_log_mask(LOG_GUEST_ERROR, "XIVE: No NVGC %x/%x\n", + nvgc_blk, nvgc_idx); return 0xFF; } if (!xive2_nvgc_is_valid(&nvgc)) { - qemu_log_mask(LOG_GUEST_ERROR, "XIVE: Invalid NVG %x/%x\n", - nvx_blk, nvgc_idx); + qemu_log_mask(LOG_GUEST_ERROR, "XIVE: Invalid NVGC %x/%x\n", + nvgc_blk, nvgc_idx); return 0xFF; } @@ -408,7 +436,7 @@ static uint8_t xive2_presenter_backlog_scan(XivePresenter *xptr, *out_level = current_level; return prio; } - current_level = xive_get_field32(NVGC2_W0_PGONEXT, nvgc.w0) & 0xF; + current_level = xive_get_field32(NVGC2_W0_PGONEXT, nvgc.w0) & 0x3F; } } return 0xFF; @@ -420,22 +448,23 @@ static void xive2_presenter_backlog_decr(XivePresenter *xptr, uint8_t group_level) { Xive2Router *xrtr = XIVE2_ROUTER(xptr); - uint32_t nvgc_idx, mask, count; + uint32_t nvgc_idx, count; + uint8_t nvgc_blk; Xive2Nvgc nvgc; - group_level &= 0xF; - mask = (1 << group_level) - 1; - nvgc_idx = nvx_idx & ~mask; - nvgc_idx |= mask >> 1; + nvgc_blk = nvx_blk; + nvgc_idx = nvx_idx; + xive2_pgofnext(&nvgc_blk, &nvgc_idx, group_level); - if (xive2_router_get_nvgc(xrtr, false, nvx_blk, nvgc_idx, &nvgc)) { - qemu_log_mask(LOG_GUEST_ERROR, "XIVE: No NVG %x/%x\n", - nvx_blk, nvgc_idx); + if (xive2_router_get_nvgc(xrtr, NVx_CROWD_LVL(group_level), + nvgc_blk, nvgc_idx, &nvgc)) { + qemu_log_mask(LOG_GUEST_ERROR, "XIVE: No NVGC %x/%x\n", + nvgc_blk, nvgc_idx); return; } if (!xive2_nvgc_is_valid(&nvgc)) { - qemu_log_mask(LOG_GUEST_ERROR, "XIVE: Invalid NVG %x/%x\n", - nvx_blk, nvgc_idx); + qemu_log_mask(LOG_GUEST_ERROR, "XIVE: Invalid NVGC %x/%x\n", + nvgc_blk, nvgc_idx); return; } count = xive2_nvgc_get_backlog(&nvgc, group_prio); @@ -443,7 +472,8 @@ static void xive2_presenter_backlog_decr(XivePresenter *xptr, return; } xive2_nvgc_set_backlog(&nvgc, group_prio, count - 1); - xive2_router_write_nvgc(xrtr, false, nvx_blk, nvgc_idx, &nvgc); + xive2_router_write_nvgc(xrtr, NVx_CROWD_LVL(group_level), + nvgc_blk, nvgc_idx, &nvgc); } /* diff --git a/include/hw/ppc/xive2_regs.h b/include/hw/ppc/xive2_regs.h index 9bcf7a8a6f..b11395c563 100644 --- a/include/hw/ppc/xive2_regs.h +++ b/include/hw/ppc/xive2_regs.h @@ -236,4 +236,8 @@ void xive2_nvgc_pic_print_info(Xive2Nvgc *nvgc, uint32_t nvgc_idx, #define NVx_BACKLOG_OP PPC_BITMASK(52, 53) #define NVx_BACKLOG_PRIO PPC_BITMASK(57, 59) +/* split the 6-bit crowd/group level */ +#define NVx_CROWD_LVL(level) ((level >> 4) & 0b11) +#define NVx_GROUP_LVL(level) (level & 0b1111) + #endif /* PPC_XIVE2_REGS_H */ From patchwork Tue Mar 11 12:57:29 2025 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Nicholas Piggin X-Patchwork-Id: 14011815 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.lore.kernel.org (Postfix) with ESMTPS id D52FDC282EC for ; Tue, 11 Mar 2025 13:07:47 +0000 (UTC) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1trzJ0-0003Rl-2y; Tue, 11 Mar 2025 09:05:58 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1trzDi-0004sr-5x; Tue, 11 Mar 2025 09:00:42 -0400 Received: from mail-pj1-x102a.google.com ([2607:f8b0:4864:20::102a]) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_128_GCM_SHA256:128) (Exim 4.90_1) (envelope-from ) id 1trzDc-0008Lt-JW; Tue, 11 Mar 2025 09:00:29 -0400 Received: by mail-pj1-x102a.google.com with SMTP id 98e67ed59e1d1-2ff6cf448b8so10792609a91.3; Tue, 11 Mar 2025 06:00:17 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20230601; t=1741698016; x=1742302816; darn=nongnu.org; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to; bh=3NFBpDCgw8d0BEXG761d1mgdF1JZURhwF8ApqY/UDtY=; b=PGc90jcxSmvqXURPRKwYdAgyLdM+WmjwRvILUPHG3UwzCH7dw/z+k+F8aZsnKN7tIA dNKtQV1Hkpm0LLlfjFSievC7lOfzThmq9Rt8elpwjnF0aiGipwSE/FRmwveYz7SN3Qgv hnNKcpU5yzfgbXDWO4DS33ztXkVfjfD9POmAOQ4dmtTTclw2FayfEHA1keWE+7V5Mtcq rt5KzJg3KP5I/4FJb/ygmL8/ZJkVx1KjCNdK0r1oR/ecP20BCCxRFJk4jiCxoztAls04 lY14HPsvpPJOSi+JkVm0xnQb/rLP0cMgPF8eM+Y4fIwUBA94zv0F9MaAkHMqXlqe9d75 9AJA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1741698016; x=1742302816; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=3NFBpDCgw8d0BEXG761d1mgdF1JZURhwF8ApqY/UDtY=; b=ddPNVrfO4UPp8HltRS7xVFVzHI18FGVOE4jgqsXGo7a+3R4tBtA2OexxJPfiW7f7Rm pWXj9i2sQ8Uscb0kEE/38gOjr81RqmYBHY0qJaIuJUozq48ZVe1iKrSPlkYFBBLcYTb/ IfgxH01lzfgGt4ftf1vEpPsnyAtss86Ov2rWnS21u3bQs3CPbb0fh4gaOMyJjJRrXXAX XSiREtFr1m/nc1mqIU70Z3TUj7BMMjFQiFnAIHiqXjVlFUJKYw9VfoL4Hw6KoFVSl810 mS0n8qTD/CBDNBfLj1XtGHnwqD+kJfWfC9S2v7V+xdRCu2DqHGGnXrVsrEhWNEKNpaHx SvRQ== X-Forwarded-Encrypted: i=1; AJvYcCVUfzyHkhQQPSpmfxZ2KDKI2l47DUMI8IdAM5LvWb4TmRjuNSE4ePXPARaQERDsHe9THoup3lBlqg==@nongnu.org X-Gm-Message-State: AOJu0YwABmbfYbFUcgho14LnjiQQiMUqroxXl+Ok10gGP32jksE5MxUZ x4cvUhTsSTRRXHQShX8EWD8/js0afcO7XnCOGit3R0EvVEAooXPJDiP/vQ== X-Gm-Gg: ASbGncvdsuJX1orqFL0Dm14hz7+Yg2KPGHpcM5sbB+QtXYHeCBDAyWXQxRwMCBP7mcz XQ1WsGMI0PO/WMSWARVn2QYcrQNlMUndhsaHrCRHbv6OZ7VI7Sog1c/4uzZuvKWgNA2trAM7FBM 89jDvaAq4+cPbSUB9h3KYPhup4UmE7HnkZV+4OBI/moRP4lM1e+i/G7c9IbU7eHz3n45cZ+TZY/ a5lucpcIzJHprd68oQ1IdDbh4mlAS/WukqlUDRH00puDUKhwfsWR25cGtxFXoPO5H60IupqStEJ PwTBp7Y3nN8p7/oNYP0jSWWSDUJ3jG2qPIGv5jFhIavm/j0mye0= X-Google-Smtp-Source: AGHT+IF43HxN2P31K8G+t/cSb3/L+nf1oz6ZZpz33m3yXYQtvJY/YH4lsoJRQnrudacpP+fLG3ehKw== X-Received: by 2002:a17:90b:1d0a:b0:2fe:a614:5cf7 with SMTP id 98e67ed59e1d1-2ff7ce7b451mr24523889a91.3.1741698015593; Tue, 11 Mar 2025 06:00:15 -0700 (PDT) Received: from wheely.local0.net ([118.208.151.101]) by smtp.gmail.com with ESMTPSA id 98e67ed59e1d1-2ff4e773dddsm11822318a91.12.2025.03.11.06.00.12 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 11 Mar 2025 06:00:15 -0700 (PDT) From: Nicholas Piggin To: qemu-devel@nongnu.org Cc: Nicholas Piggin , qemu-ppc@nongnu.org, Glenn Miles , Glenn Miles , Michael Kowal Subject: [PULL 35/72] qtest/xive: Change printf to g_test_message Date: Tue, 11 Mar 2025 22:57:29 +1000 Message-ID: <20250311125815.903177-36-npiggin@gmail.com> X-Mailer: git-send-email 2.47.1 In-Reply-To: <20250311125815.903177-1-npiggin@gmail.com> References: <20250311125815.903177-1-npiggin@gmail.com> MIME-Version: 1.0 Received-SPF: pass client-ip=2607:f8b0:4864:20::102a; envelope-from=npiggin@gmail.com; helo=mail-pj1-x102a.google.com X-Spam_score_int: -20 X-Spam_score: -2.1 X-Spam_bar: -- X-Spam_report: (-2.1 / 5.0 requ) BAYES_00=-1.9, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_AU=-0.1, DKIM_VALID_EF=-0.1, FREEMAIL_FROM=0.001, RCVD_IN_DNSWL_NONE=-0.0001, SPF_HELO_NONE=0.001, T_SPF_TEMPERROR=0.01 autolearn=ham autolearn_force=no X-Spam_action: no action X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: qemu-devel-bounces+qemu-devel=archiver.kernel.org@nongnu.org Sender: qemu-devel-bounces+qemu-devel=archiver.kernel.org@nongnu.org From: Glenn Miles Change all printf() in pnv-xive2-* qtests to g_test_message() [npiggin: split from pool qtest] Signed-off-by: Glenn Miles Signed-off-by: Michael Kowal Reviewed-by: Nicholas Piggin Signed-off-by: Nicholas Piggin --- tests/qtest/pnv-xive2-flush-sync.c | 6 +++--- tests/qtest/pnv-xive2-nvpg_bar.c | 7 +++---- tests/qtest/pnv-xive2-test.c | 22 ++++++++++++---------- 3 files changed, 18 insertions(+), 17 deletions(-) diff --git a/tests/qtest/pnv-xive2-flush-sync.c b/tests/qtest/pnv-xive2-flush-sync.c index 3b32446adb..142826bad0 100644 --- a/tests/qtest/pnv-xive2-flush-sync.c +++ b/tests/qtest/pnv-xive2-flush-sync.c @@ -178,14 +178,14 @@ void test_flush_sync_inject(QTestState *qts) int test_nr; uint8_t byte; - printf("# ============================================================\n"); - printf("# Starting cache flush/queue sync injection tests...\n"); + g_test_message("========================================================="); + g_test_message("Starting cache flush/queue sync injection tests..."); for (test_nr = 0; test_nr < sizeof(xive_inject_tests); test_nr++) { int op_type = xive_inject_tests[test_nr]; - printf("# Running test %d\n", test_nr); + g_test_message("Running test %d", test_nr); /* start with status byte set to 0 */ clr_sync(qts, src_pir, ic_topo_id, op_type); diff --git a/tests/qtest/pnv-xive2-nvpg_bar.c b/tests/qtest/pnv-xive2-nvpg_bar.c index 028512bddc..6ac8d36c82 100644 --- a/tests/qtest/pnv-xive2-nvpg_bar.c +++ b/tests/qtest/pnv-xive2-nvpg_bar.c @@ -4,8 +4,7 @@ * * Copyright (c) 2024, IBM Corporation. * - * This work is licensed under the terms of the GNU GPL, version 2 or - * later. See the COPYING file in the top-level directory. + * SPDX-License-Identifier: GPL-2.0-or-later */ #include "qemu/osdep.h" #include "libqtest.h" @@ -78,8 +77,8 @@ void test_nvpg_bar(QTestState *qts) uint32_t count, delta; uint8_t i; - printf("# ============================================================\n"); - printf("# Testing NVPG BAR operations\n"); + g_test_message("========================================================="); + g_test_message("Testing NVPG BAR operations"); set_nvg(qts, group_target, 0); set_nvp(qts, nvp_target, 0x04); diff --git a/tests/qtest/pnv-xive2-test.c b/tests/qtest/pnv-xive2-test.c index a0e9f19313..7e7b1e79c0 100644 --- a/tests/qtest/pnv-xive2-test.c +++ b/tests/qtest/pnv-xive2-test.c @@ -4,6 +4,7 @@ * - Test 'Pull Thread Context to Odd Thread Reporting Line' * - Test irq to hardware group * - Test irq to hardware group going through backlog + * - Test irq to pool thread * * Copyright (c) 2024, IBM Corporation. * @@ -220,8 +221,8 @@ static void test_hw_irq(QTestState *qts) uint16_t reg16; uint8_t pq, nsr, cppr; - printf("# ============================================================\n"); - printf("# Testing irq %d to hardware thread %d\n", irq, target_pir); + g_test_message("========================================================="); + g_test_message("Testing irq %d to hardware thread %d", irq, target_pir); /* irq config */ set_eas(qts, irq, end_index, irq_data); @@ -278,8 +279,9 @@ static void test_pull_thread_ctx_to_odd_thread_cl(QTestState *qts) uint32_t cl_word; uint32_t word2; - printf("# ============================================================\n"); - printf("# Testing 'Pull Thread Context to Odd Thread Reporting Line'\n"); + g_test_message("========================================================="); + g_test_message("Testing 'Pull Thread Context to Odd Thread Reporting " \ + "Line'"); /* clear odd cache line prior to pull operation */ memset(cl_pair, 0, sizeof(cl_pair)); @@ -330,8 +332,8 @@ static void test_hw_group_irq(QTestState *qts) uint16_t reg16; uint8_t pq, nsr, cppr; - printf("# ============================================================\n"); - printf("# Testing irq %d to hardware group of size 4\n", irq); + g_test_message("========================================================="); + g_test_message("Testing irq %d to hardware group of size 4", irq); /* irq config */ set_eas(qts, irq, end_index, irq_data); @@ -395,10 +397,10 @@ static void test_hw_group_irq_backlog(QTestState *qts) uint16_t reg16; uint8_t pq, nsr, cppr, lsmfb, i; - printf("# ============================================================\n"); - printf("# Testing irq %d to hardware group of size 4 going through " \ - "backlog\n", - irq); + g_test_message("========================================================="); + g_test_message("Testing irq %d to hardware group of size 4 going " \ + "through backlog", + irq); /* * set current priority of all threads in the group to something From patchwork Tue Mar 11 12:57:30 2025 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Nicholas Piggin X-Patchwork-Id: 14011884 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.lore.kernel.org (Postfix) with ESMTPS id B0798C282EC for ; Tue, 11 Mar 2025 13:23:04 +0000 (UTC) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1trzFb-00073e-3R; Tue, 11 Mar 2025 09:02:27 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1trzDi-0004su-Ka; Tue, 11 Mar 2025 09:00:42 -0400 Received: from mail-pj1-x102f.google.com ([2607:f8b0:4864:20::102f]) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_128_GCM_SHA256:128) (Exim 4.90_1) (envelope-from ) id 1trzDd-0008Ne-UU; Tue, 11 Mar 2025 09:00:30 -0400 Received: by mail-pj1-x102f.google.com with SMTP id 98e67ed59e1d1-2ff615a114bso9410930a91.0; Tue, 11 Mar 2025 06:00:20 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20230601; t=1741698019; x=1742302819; darn=nongnu.org; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to; bh=bW/i37H/kqxxMLYWVFi5dKIqqFLw8+mO4T5YC2Hj02M=; b=jtjUL4Yd9Ncb3H4IGqQnecw3gAh45sv4Bg9B4V1S7Pp/llsv8bnn7MUCLWcSV5cV+m zRa8Yvp176Z+seKf7UCDQUaaGLZuPFWLoM2qyvhO+UBqehf/Fz/kkdzwDJky5vspHBvV VYpl+xWUvHjfJPhWOqWaBKMpbfp8mNUl5Q3xCMOOKSxZSRmnP04rpBbdOZfJjPu9jpO3 +pqBZAriXYqqIzEeJuRY0wrtU9B28q+Ha/xj+eMrkeKTOYoUbpbK/HGtpVIvCeOn3DQG zzfsyVjnQzLBYvraoKdRi7dMbfIwg0iHP1DBlLxiFUSobEibmaNXyqg+yBa4vcyzV2Zs xiLA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1741698019; x=1742302819; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=bW/i37H/kqxxMLYWVFi5dKIqqFLw8+mO4T5YC2Hj02M=; b=ZkaN0374zydXStFn8C7pkTdvQZYq+OsS8XSRAqa3eqSATYEzGBntd4re9+hwANj9SQ XizaOSOQ0bMx29APtwMQnb1cWmdtaUEKi6SJJV/LbnTUmryGJupgllsUXfFGHdmQnP/C M0Cw3n+Z0eoE7kA6VOS9KO43Iel2XYh0BZkKyxZLZu15+jFVXmc0ciMmdSUS6DiylImV 50b2kq3kl0o3++98uwKWkcOzEnjLwYLTQ2oV/VjaHRXynPVLUNlm0iSAlKjrKZrrEOtS BRpqMcPL5B3J1c4uNO9mUzPpjt8QoCdab3Oy4cmRkHujav2HP0djkSAkxeeaEC8RhRXT +Q6A== X-Forwarded-Encrypted: i=1; AJvYcCUHrdZ1yuPU66Rn4sxinrmE+bOdxvAkEyksCW1BiBxRcqlmvUj8wLBXsibwUK/+suMvrI6O9qKY8Q==@nongnu.org X-Gm-Message-State: AOJu0YxHhhfziUUKifmWlepdi7KNQG3CQYxZNqmfBd08Z6xSjFCVIX8J GGZTzosswkOPQBTU5oK8rrXNRfIeByEu6TB/KgqcbgWOB4ZcVKc9DHhChw== X-Gm-Gg: ASbGncuFGXY8wKSgv9FDALvqclRrYFZsIobl2Iup7D15zrhP3BYYDFlOu0Ko0OrynVB bO83X9LFRjJ+RjHwERAjEwJOXUnRWP9ic6gERij3MFH1fB5gdxkkrvptHKqN/fxjvmX+CVfawyA XUcJ70qxc50GuY1IgUdbdLPZlJUTqGnnY/NmnS+RT2LOHtaV9Z4xtIT0AaNLJhcfco5aPlBgljT jLfq8qC+YacgaWD9Lnf9WZcSGT2slmq7BguWXyvIitF6nBUjzJouVn3rzcB2Ax3nxxr1mWgb7CU PnJTPesnDb6lmG5qZ/sA2GFWwe7+4ko8mLFQ1NVPBZ2im1ed0K4= X-Google-Smtp-Source: AGHT+IFht5oBBKw3ggcDUXirydsLyedSR5nBJcEZkoJgMjN3aHGigSX5ctDGNbRB5dM+InUV0kr0Kg== X-Received: by 2002:a17:90b:1d46:b0:2fa:2133:bc87 with SMTP id 98e67ed59e1d1-3010051f268mr4508383a91.6.1741698018880; Tue, 11 Mar 2025 06:00:18 -0700 (PDT) Received: from wheely.local0.net ([118.208.151.101]) by smtp.gmail.com with ESMTPSA id 98e67ed59e1d1-2ff4e773dddsm11822318a91.12.2025.03.11.06.00.16 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 11 Mar 2025 06:00:18 -0700 (PDT) From: Nicholas Piggin To: qemu-devel@nongnu.org Cc: Nicholas Piggin , qemu-ppc@nongnu.org, Glenn Miles , Glenn Miles , Michael Kowal Subject: [PULL 36/72] qtest/xive: Add test of pool interrupts Date: Tue, 11 Mar 2025 22:57:30 +1000 Message-ID: <20250311125815.903177-37-npiggin@gmail.com> X-Mailer: git-send-email 2.47.1 In-Reply-To: <20250311125815.903177-1-npiggin@gmail.com> References: <20250311125815.903177-1-npiggin@gmail.com> MIME-Version: 1.0 Received-SPF: pass client-ip=2607:f8b0:4864:20::102f; envelope-from=npiggin@gmail.com; helo=mail-pj1-x102f.google.com X-Spam_score_int: -20 X-Spam_score: -2.1 X-Spam_bar: -- X-Spam_report: (-2.1 / 5.0 requ) BAYES_00=-1.9, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_AU=-0.1, DKIM_VALID_EF=-0.1, FREEMAIL_FROM=0.001, RCVD_IN_DNSWL_NONE=-0.0001, SPF_HELO_NONE=0.001, SPF_PASS=-0.001 autolearn=ham autolearn_force=no X-Spam_action: no action X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: qemu-devel-bounces+qemu-devel=archiver.kernel.org@nongnu.org Sender: qemu-devel-bounces+qemu-devel=archiver.kernel.org@nongnu.org From: Glenn Miles Added new test for pool interrupts. Removed all printfs from pnv-xive2-* qtests. Signed-off-by: Glenn Miles Signed-off-by: Michael Kowal Reviewed-by: Nicholas Piggin Signed-off-by: Nicholas Piggin --- tests/qtest/pnv-xive2-test.c | 76 ++++++++++++++++++++++++++++++++++++ 1 file changed, 76 insertions(+) diff --git a/tests/qtest/pnv-xive2-test.c b/tests/qtest/pnv-xive2-test.c index 7e7b1e79c0..5313d4ef18 100644 --- a/tests/qtest/pnv-xive2-test.c +++ b/tests/qtest/pnv-xive2-test.c @@ -267,6 +267,79 @@ static void test_hw_irq(QTestState *qts) g_assert_cmphex(cppr, ==, 0xFF); } +static void test_pool_irq(QTestState *qts) +{ + uint32_t irq = 2; + uint32_t irq_data = 0x600d0d06; + uint32_t end_index = 5; + uint32_t target_pir = 1; + uint32_t target_nvp = 0x100 + target_pir; + uint8_t priority = 5; + uint32_t reg32; + uint16_t reg16; + uint8_t pq, nsr, cppr, ipb; + + g_test_message("========================================================="); + g_test_message("Testing irq %d to pool thread %d", irq, target_pir); + + /* irq config */ + set_eas(qts, irq, end_index, irq_data); + set_end(qts, end_index, target_nvp, priority, false /* group */); + + /* enable and trigger irq */ + get_esb(qts, irq, XIVE_EOI_PAGE, XIVE_ESB_SET_PQ_00); + set_esb(qts, irq, XIVE_TRIGGER_PAGE, 0, 0); + + /* check irq is raised on cpu */ + pq = get_esb(qts, irq, XIVE_EOI_PAGE, XIVE_ESB_GET); + g_assert_cmpuint(pq, ==, XIVE_ESB_PENDING); + + /* check TIMA values in the PHYS ring (shared by POOL ring) */ + reg32 = get_tima32(qts, target_pir, TM_QW3_HV_PHYS + TM_WORD0); + nsr = reg32 >> 24; + cppr = (reg32 >> 16) & 0xFF; + g_assert_cmphex(nsr, ==, 0x40); + g_assert_cmphex(cppr, ==, 0xFF); + + /* check TIMA values in the POOL ring */ + reg32 = get_tima32(qts, target_pir, TM_QW2_HV_POOL + TM_WORD0); + nsr = reg32 >> 24; + cppr = (reg32 >> 16) & 0xFF; + ipb = (reg32 >> 8) & 0xFF; + g_assert_cmphex(nsr, ==, 0); + g_assert_cmphex(cppr, ==, 0); + g_assert_cmphex(ipb, ==, 0x80 >> priority); + + /* ack the irq */ + reg16 = get_tima16(qts, target_pir, TM_SPC_ACK_HV_REG); + nsr = reg16 >> 8; + cppr = reg16 & 0xFF; + g_assert_cmphex(nsr, ==, 0x40); + g_assert_cmphex(cppr, ==, priority); + + /* check irq data is what was configured */ + reg32 = qtest_readl(qts, xive_get_queue_addr(end_index)); + g_assert_cmphex((reg32 & 0x7fffffff), ==, (irq_data & 0x7fffffff)); + + /* check IPB is cleared in the POOL ring */ + reg32 = get_tima32(qts, target_pir, TM_QW2_HV_POOL + TM_WORD0); + ipb = (reg32 >> 8) & 0xFF; + g_assert_cmphex(ipb, ==, 0); + + /* End Of Interrupt */ + set_esb(qts, irq, XIVE_EOI_PAGE, XIVE_ESB_STORE_EOI, 0); + pq = get_esb(qts, irq, XIVE_EOI_PAGE, XIVE_ESB_GET); + g_assert_cmpuint(pq, ==, XIVE_ESB_RESET); + + /* reset CPPR */ + set_tima8(qts, target_pir, TM_QW3_HV_PHYS + TM_CPPR, 0xFF); + reg32 = get_tima32(qts, target_pir, TM_QW3_HV_PHYS + TM_WORD0); + nsr = reg32 >> 24; + cppr = (reg32 >> 16) & 0xFF; + g_assert_cmphex(nsr, ==, 0x00); + g_assert_cmphex(cppr, ==, 0xFF); +} + #define XIVE_ODD_CL 0x80 static void test_pull_thread_ctx_to_odd_thread_cl(QTestState *qts) { @@ -486,6 +559,9 @@ static void test_xive(void) /* omit reset_state here and use settings from test_hw_irq */ test_pull_thread_ctx_to_odd_thread_cl(qts); + reset_state(qts); + test_pool_irq(qts); + reset_state(qts); test_hw_group_irq(qts); From patchwork Tue Mar 11 12:57:31 2025 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Nicholas Piggin X-Patchwork-Id: 14011816 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.lore.kernel.org (Postfix) with ESMTPS id 47471C28B2E for ; Tue, 11 Mar 2025 13:07:48 +0000 (UTC) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1trzKW-00080f-6Q; Tue, 11 Mar 2025 09:07:32 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1trzDh-0004rV-KP; Tue, 11 Mar 2025 09:00:39 -0400 Received: from mail-pj1-x1033.google.com ([2607:f8b0:4864:20::1033]) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_128_GCM_SHA256:128) (Exim 4.90_1) (envelope-from ) id 1trzDc-0008Pn-TK; Tue, 11 Mar 2025 09:00:29 -0400 Received: by mail-pj1-x1033.google.com with SMTP id 98e67ed59e1d1-2ff69365e1dso7927732a91.3; Tue, 11 Mar 2025 06:00:23 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20230601; t=1741698022; x=1742302822; darn=nongnu.org; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to; bh=1oeqcWSYzaX2aoHg4HxvXmQxGkn+hGDZWQYQTvy2CSk=; b=nSghJ0zeLeGbL3s/RkeylT2kTzIHrZLwM2neW+NDaN6K2bgjqV3V5RjppFfEziXFXQ cv0f5wIwdRfDnhBfsM6jiuiOZh7EqMLEABRGCehf1NK16UoZBasy9pJSIeD4wDVhALdi rDhzBE8zfSTq5SHlMs7LSqk5FgEl3ISAFxtDOMtdDMlGI6nd4Y8U0QiLOeEHy6C/9JVe dNUIav69HVxWCCnYyH3b3nQjS2pTDzjibLDAba/JEKf2bBmImEA8KpgWvxhtL39H1o2w XsOPS5r9pcz5Zl6kWeH2CtUuNCgGo6hgKzc48gZBgUq5+tpRQbYOoRvkaT1uE+tgZzyJ qRDg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1741698022; x=1742302822; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=1oeqcWSYzaX2aoHg4HxvXmQxGkn+hGDZWQYQTvy2CSk=; b=Y+GB7HOgYFJBduFGhJmUG/IuWdg+a3/X9mI8wSnwuQDxguCq9cR+j9nBAZwYf15eSw 2fFIAbqodVb1daFAvJMfx7ey9wZ2XDXEMYQAvCxRwxxmRK0I5ZBT0zjfJ70cSE5uAFSx gt5OjDkYI/vclXLdQaAQ2Ws7dA2g5bsxv9vQBPPp0gXPSCKt8KIWWP1uGh37slDoK24W rMFiVp6R1DcEY1r2Ic5slKMu+L8C2PS83I/tP/P7KVK3BFfk8lf8qXiITKomZ3LWTwt+ mAW7fl9DZXt+EwVUgKUOnn4bPxbRYvCWO3wB31N8QNd3OQbYdohfe0QDgtMfi/RUdxSm nNpg== X-Forwarded-Encrypted: i=1; AJvYcCU3AGdYUDWR/5b6wtB6Y14iBJZ6gXONinv2euzLJIwv0Q5TPxPldW95rvWbU/nrAFpSSwqIOiisaw==@nongnu.org X-Gm-Message-State: AOJu0Yxg30eP3LbVyL+QJJ5xrMWbiEdICddcc64WHQmRSWUY3aP1FX32 uKBQRQQHLH7W0ZVccaFS8UJcGrl/HGJcFT1LOBBKkhPgAThXKhQ1BY1q2A== X-Gm-Gg: ASbGnctRM5u+bRmDPcAY0T90wDoEH+Es1thJFZLeVM87RGnxi8dZreCPTTHoh9gVdxw laAxqbLrnQJIilZXLcWrgFtdZUTUr99ywSDe4VvDPXaB59Yb3LPn2iqzGGw76aERm273B0I0JIw /kFlNE4Za9/KrG6ooFcR504tjp/q257orCjKTWBGMMkScGTWJG15Yisv5KybE6gxZFElNOpAWvQ WvwktaG1d9w/LJUrEzRRKYDGSq+ZkPnVUXyK39uhsb6ZtohbxU/h7alqC7OD38BEVAeSSVKNrge FpT8zNzPEZ7+zfb8R9PRq+oouqNnb2sh39kQrmrPlXGmW1ju2Mw= X-Google-Smtp-Source: AGHT+IFiX0aQPF90w+RCqJFRVSt+PKTcuNo2HkonEv/t9CZ6rGlJ8DkC7x7c5GOlZzMCne3JX+fwvg== X-Received: by 2002:a17:90b:278f:b0:2f7:4cce:ae37 with SMTP id 98e67ed59e1d1-2ff7ce8958fmr30252261a91.18.1741698021825; Tue, 11 Mar 2025 06:00:21 -0700 (PDT) Received: from wheely.local0.net ([118.208.151.101]) by smtp.gmail.com with ESMTPSA id 98e67ed59e1d1-2ff4e773dddsm11822318a91.12.2025.03.11.06.00.19 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 11 Mar 2025 06:00:21 -0700 (PDT) From: Nicholas Piggin To: qemu-devel@nongnu.org Cc: Nicholas Piggin , qemu-ppc@nongnu.org, Chalapathi V Subject: [PULL 37/72] hw/ssi/pnv_spi: Replace PnvXferBuffer with Fifo8 structure Date: Tue, 11 Mar 2025 22:57:31 +1000 Message-ID: <20250311125815.903177-38-npiggin@gmail.com> X-Mailer: git-send-email 2.47.1 In-Reply-To: <20250311125815.903177-1-npiggin@gmail.com> References: <20250311125815.903177-1-npiggin@gmail.com> MIME-Version: 1.0 Received-SPF: pass client-ip=2607:f8b0:4864:20::1033; envelope-from=npiggin@gmail.com; helo=mail-pj1-x1033.google.com X-Spam_score_int: -20 X-Spam_score: -2.1 X-Spam_bar: -- X-Spam_report: (-2.1 / 5.0 requ) BAYES_00=-1.9, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_AU=-0.1, DKIM_VALID_EF=-0.1, FREEMAIL_FROM=0.001, RCVD_IN_DNSWL_NONE=-0.0001, SPF_HELO_NONE=0.001, SPF_PASS=-0.001 autolearn=ham autolearn_force=no X-Spam_action: no action X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: qemu-devel-bounces+qemu-devel=archiver.kernel.org@nongnu.org Sender: qemu-devel-bounces+qemu-devel=archiver.kernel.org@nongnu.org From: Chalapathi V In PnvXferBuffer dynamically allocating and freeing is a process overhead. Hence used an existing Fifo8 buffer with capacity of 16 bytes. Signed-off-by: Chalapathi V Message-ID: <20250303141328.23991-2-chalapathi.v@linux.ibm.com> Signed-off-by: Nicholas Piggin --- hw/ssi/pnv_spi.c | 264 ++++++++++++++++----------------------- include/hw/ssi/pnv_spi.h | 3 + 2 files changed, 108 insertions(+), 159 deletions(-) diff --git a/hw/ssi/pnv_spi.c b/hw/ssi/pnv_spi.c index 15e25bd1be..388b425157 100644 --- a/hw/ssi/pnv_spi.c +++ b/hw/ssi/pnv_spi.c @@ -19,6 +19,7 @@ #define PNV_SPI_OPCODE_LO_NIBBLE(x) (x & 0x0F) #define PNV_SPI_MASKED_OPCODE(x) (x & 0xF0) +#define PNV_SPI_FIFO_SIZE 16 /* * Macro from include/hw/ppc/fdt.h @@ -35,48 +36,14 @@ } \ } while (0) -/* PnvXferBuffer */ -typedef struct PnvXferBuffer { - - uint32_t len; - uint8_t *data; - -} PnvXferBuffer; - -/* pnv_spi_xfer_buffer_methods */ -static PnvXferBuffer *pnv_spi_xfer_buffer_new(void) -{ - PnvXferBuffer *payload = g_malloc0(sizeof(*payload)); - - return payload; -} - -static void pnv_spi_xfer_buffer_free(PnvXferBuffer *payload) -{ - g_free(payload->data); - g_free(payload); -} - -static uint8_t *pnv_spi_xfer_buffer_write_ptr(PnvXferBuffer *payload, - uint32_t offset, uint32_t length) -{ - if (payload->len < (offset + length)) { - payload->len = offset + length; - payload->data = g_realloc(payload->data, payload->len); - } - return &payload->data[offset]; -} - static bool does_rdr_match(PnvSpi *s) { /* * According to spec, the mask bits that are 0 are compared and the * bits that are 1 are ignored. */ - uint16_t rdr_match_mask = GETFIELD(SPI_MM_RDR_MATCH_MASK, - s->regs[SPI_MM_REG]); - uint16_t rdr_match_val = GETFIELD(SPI_MM_RDR_MATCH_VAL, - s->regs[SPI_MM_REG]); + uint16_t rdr_match_mask = GETFIELD(SPI_MM_RDR_MATCH_MASK, s->regs[SPI_MM_REG]); + uint16_t rdr_match_val = GETFIELD(SPI_MM_RDR_MATCH_VAL, s->regs[SPI_MM_REG]); if ((~rdr_match_mask & rdr_match_val) == ((~rdr_match_mask) & GETFIELD(PPC_BITMASK(48, 63), s->regs[SPI_RCV_DATA_REG]))) { @@ -107,8 +74,8 @@ static uint8_t get_from_offset(PnvSpi *s, uint8_t offset) return byte; } -static uint8_t read_from_frame(PnvSpi *s, uint8_t *read_buf, uint8_t nr_bytes, - uint8_t ecc_count, uint8_t shift_in_count) +static uint8_t read_from_frame(PnvSpi *s, uint8_t nr_bytes, uint8_t ecc_count, + uint8_t shift_in_count) { uint8_t byte; int count = 0; @@ -118,20 +85,24 @@ static uint8_t read_from_frame(PnvSpi *s, uint8_t *read_buf, uint8_t nr_bytes, if ((ecc_count != 0) && (shift_in_count == (PNV_SPI_REG_SIZE + ecc_count))) { shift_in_count = 0; - } else { - byte = read_buf[count]; + } else if (!fifo8_is_empty(&s->rx_fifo)) { + byte = fifo8_pop(&s->rx_fifo); trace_pnv_spi_shift_rx(byte, count); s->regs[SPI_RCV_DATA_REG] = (s->regs[SPI_RCV_DATA_REG] << 8) | byte; + } else { + qemu_log_mask(LOG_GUEST_ERROR, "pnv_spi: Reading empty RX_FIFO\n"); } count++; } /* end of while */ return shift_in_count; } -static void spi_response(PnvSpi *s, int bits, PnvXferBuffer *rsp_payload) +static void spi_response(PnvSpi *s) { uint8_t ecc_count; uint8_t shift_in_count; + uint32_t rx_len; + int i; /* * Processing here must handle: @@ -144,13 +115,14 @@ static void spi_response(PnvSpi *s, int bits, PnvXferBuffer *rsp_payload) * First check that the response payload is the exact same * number of bytes as the request payload was */ - if (rsp_payload->len != (s->N1_bytes + s->N2_bytes)) { + rx_len = fifo8_num_used(&s->rx_fifo); + if (rx_len != (s->N1_bytes + s->N2_bytes)) { qemu_log_mask(LOG_GUEST_ERROR, "Invalid response payload size in " "bytes, expected %d, got %d\n", - (s->N1_bytes + s->N2_bytes), rsp_payload->len); + (s->N1_bytes + s->N2_bytes), rx_len); } else { uint8_t ecc_control; - trace_pnv_spi_rx_received(rsp_payload->len); + trace_pnv_spi_rx_received(rx_len); trace_pnv_spi_log_Ncounts(s->N1_bits, s->N1_bytes, s->N1_tx, s->N1_rx, s->N2_bits, s->N2_bytes, s->N2_tx, s->N2_rx); /* @@ -175,15 +147,23 @@ static void spi_response(PnvSpi *s, int bits, PnvXferBuffer *rsp_payload) /* Handle the N1 portion of the frame first */ if (s->N1_rx != 0) { trace_pnv_spi_rx_read_N1frame(); - shift_in_count = read_from_frame(s, &rsp_payload->data[0], - s->N1_bytes, ecc_count, shift_in_count); + shift_in_count = read_from_frame(s, s->N1_bytes, ecc_count, shift_in_count); } /* Handle the N2 portion of the frame */ if (s->N2_rx != 0) { + /* pop out N1_bytes from rx_fifo if not already */ + if (s->N1_rx == 0) { + for (i = 0; i < s->N1_bytes; i++) { + if (!fifo8_is_empty(&s->rx_fifo)) { + fifo8_pop(&s->rx_fifo); + } else { + qemu_log_mask(LOG_GUEST_ERROR, "pnv_spi: Reading empty" + " RX_FIFO\n"); + } + } + } trace_pnv_spi_rx_read_N2frame(); - shift_in_count = read_from_frame(s, - &rsp_payload->data[s->N1_bytes], s->N2_bytes, - ecc_count, shift_in_count); + shift_in_count = read_from_frame(s, s->N2_bytes, ecc_count, shift_in_count); } if ((s->N1_rx + s->N2_rx) > 0) { /* @@ -210,36 +190,41 @@ static void spi_response(PnvSpi *s, int bits, PnvXferBuffer *rsp_payload) } /* end of else */ } /* end of spi_response() */ -static void transfer(PnvSpi *s, PnvXferBuffer *payload) +static void transfer(PnvSpi *s) { - uint32_t tx; - uint32_t rx; - PnvXferBuffer *rsp_payload = NULL; + uint32_t tx, rx, payload_len; + uint8_t rx_byte; - rsp_payload = pnv_spi_xfer_buffer_new(); - if (!rsp_payload) { - return; - } - for (int offset = 0; offset < payload->len; offset += s->transfer_len) { + payload_len = fifo8_num_used(&s->tx_fifo); + for (int offset = 0; offset < payload_len; offset += s->transfer_len) { tx = 0; for (int i = 0; i < s->transfer_len; i++) { - if ((offset + i) >= payload->len) { + if ((offset + i) >= payload_len) { tx <<= 8; + } else if (!fifo8_is_empty(&s->tx_fifo)) { + tx = (tx << 8) | fifo8_pop(&s->tx_fifo); } else { - tx = (tx << 8) | payload->data[offset + i]; + qemu_log_mask(LOG_GUEST_ERROR, "pnv_spi: TX_FIFO underflow\n"); } } rx = ssi_transfer(s->ssi_bus, tx); for (int i = 0; i < s->transfer_len; i++) { - if ((offset + i) >= payload->len) { + if ((offset + i) >= payload_len) { + break; + } + rx_byte = (rx >> (8 * (s->transfer_len - 1) - i * 8)) & 0xFF; + if (!fifo8_is_full(&s->rx_fifo)) { + fifo8_push(&s->rx_fifo, rx_byte); + } else { + qemu_log_mask(LOG_GUEST_ERROR, "pnv_spi: RX_FIFO is full\n"); break; } - *(pnv_spi_xfer_buffer_write_ptr(rsp_payload, rsp_payload->len, 1)) = - (rx >> (8 * (s->transfer_len - 1) - i * 8)) & 0xFF; } } - spi_response(s, s->N1_bits, rsp_payload); - pnv_spi_xfer_buffer_free(rsp_payload); + spi_response(s); + /* Reset fifo for next frame */ + fifo8_reset(&s->tx_fifo); + fifo8_reset(&s->rx_fifo); } static inline uint8_t get_seq_index(PnvSpi *s) @@ -310,13 +295,11 @@ static void calculate_N1(PnvSpi *s, uint8_t opcode) * If Forced Implicit mode and count control doesn't * indicate transmit then reset the tx count to 0 */ - if (GETFIELD(SPI_CTR_CFG_N1_CTRL_B2, - s->regs[SPI_CTR_CFG_REG]) == 0) { + if (GETFIELD(SPI_CTR_CFG_N1_CTRL_B2, s->regs[SPI_CTR_CFG_REG]) == 0) { s->N1_tx = 0; } /* If rx count control for N1 is set, load the rx value */ - if (GETFIELD(SPI_CTR_CFG_N1_CTRL_B3, - s->regs[SPI_CTR_CFG_REG]) == 1) { + if (GETFIELD(SPI_CTR_CFG_N1_CTRL_B3, s->regs[SPI_CTR_CFG_REG]) == 1) { s->N1_rx = s->N1_bytes; } } @@ -328,8 +311,7 @@ static void calculate_N1(PnvSpi *s, uint8_t opcode) * cap the size at a max of 64 bits or 72 bits and set the sequencer FSM * error bit. */ - uint8_t ecc_control = GETFIELD(SPI_CLK_CFG_ECC_CTRL, - s->regs[SPI_CLK_CFG_REG]); + uint8_t ecc_control = GETFIELD(SPI_CLK_CFG_ECC_CTRL, s->regs[SPI_CLK_CFG_REG]); if (ecc_control == 0 || ecc_control == 2) { if (s->N1_bytes > (PNV_SPI_REG_SIZE + 1)) { qemu_log_mask(LOG_GUEST_ERROR, "Unsupported N1 shift size when " @@ -340,8 +322,7 @@ static void calculate_N1(PnvSpi *s, uint8_t opcode) } } else if (s->N1_bytes > PNV_SPI_REG_SIZE) { qemu_log_mask(LOG_GUEST_ERROR, "Unsupported N1 shift size, " - "bytes = 0x%x, bits = 0x%x\n", - s->N1_bytes, s->N1_bits); + "bytes = 0x%x, bits = 0x%x\n", s->N1_bytes, s->N1_bits); s->N1_bytes = PNV_SPI_REG_SIZE; s->N1_bits = s->N1_bytes * 8; } @@ -350,19 +331,10 @@ static void calculate_N1(PnvSpi *s, uint8_t opcode) /* * Shift_N1 operation handler method */ -static bool operation_shiftn1(PnvSpi *s, uint8_t opcode, - PnvXferBuffer **payload, bool send_n1_alone) +static bool operation_shiftn1(PnvSpi *s, uint8_t opcode, bool send_n1_alone) { uint8_t n1_count; bool stop = false; - - /* - * If there isn't a current payload left over from a stopped sequence - * create a new one. - */ - if (*payload == NULL) { - *payload = pnv_spi_xfer_buffer_new(); - } /* * Use a combination of N1 counters to build the N1 portion of the * transmit payload. @@ -413,9 +385,13 @@ static bool operation_shiftn1(PnvSpi *s, uint8_t opcode, */ uint8_t n1_byte = 0x00; n1_byte = get_from_offset(s, n1_count); - trace_pnv_spi_tx_append("n1_byte", n1_byte, n1_count); - *(pnv_spi_xfer_buffer_write_ptr(*payload, (*payload)->len, 1)) = - n1_byte; + if (!fifo8_is_full(&s->tx_fifo)) { + trace_pnv_spi_tx_append("n1_byte", n1_byte, n1_count); + fifo8_push(&s->tx_fifo, n1_byte); + } else { + qemu_log_mask(LOG_GUEST_ERROR, "pnv_spi: TX_FIFO is full\n"); + break; + } } else { /* * We hit a shift_n1 opcode TX but the TDR is empty, tell the @@ -436,16 +412,17 @@ static bool operation_shiftn1(PnvSpi *s, uint8_t opcode, * - we are receiving and the RDR is empty so we allow the operation * to proceed. */ - if ((s->N1_rx != 0) && (GETFIELD(SPI_STS_RDR_FULL, - s->status) == 1)) { + if ((s->N1_rx != 0) && (GETFIELD(SPI_STS_RDR_FULL, s->status) == 1)) { trace_pnv_spi_sequencer_stop_requested("shift N1" "set for receive but RDR is full"); stop = true; break; - } else { + } else if (!fifo8_is_full(&s->tx_fifo)) { trace_pnv_spi_tx_append_FF("n1_byte"); - *(pnv_spi_xfer_buffer_write_ptr(*payload, (*payload)->len, 1)) - = 0xff; + fifo8_push(&s->tx_fifo, 0xff); + } else { + qemu_log_mask(LOG_GUEST_ERROR, "pnv_spi: TX_FIFO is full\n"); + break; } } n1_count++; @@ -486,15 +463,13 @@ static bool operation_shiftn1(PnvSpi *s, uint8_t opcode, */ if (send_n1_alone && !stop) { /* We have a TX and a full TDR or an RX and an empty RDR */ - trace_pnv_spi_tx_request("Shifting N1 frame", (*payload)->len); - transfer(s, *payload); + trace_pnv_spi_tx_request("Shifting N1 frame", fifo8_num_used(&s->tx_fifo)); + transfer(s); /* The N1 frame shift is complete so reset the N1 counters */ s->N2_bits = 0; s->N2_bytes = 0; s->N2_tx = 0; s->N2_rx = 0; - pnv_spi_xfer_buffer_free(*payload); - *payload = NULL; } return stop; } /* end of operation_shiftn1() */ @@ -552,13 +527,11 @@ static void calculate_N2(PnvSpi *s, uint8_t opcode) * If Forced Implicit mode and count control doesn't * indicate a receive then reset the rx count to 0 */ - if (GETFIELD(SPI_CTR_CFG_N2_CTRL_B3, - s->regs[SPI_CTR_CFG_REG]) == 0) { + if (GETFIELD(SPI_CTR_CFG_N2_CTRL_B3, s->regs[SPI_CTR_CFG_REG]) == 0) { s->N2_rx = 0; } /* If tx count control for N2 is set, load the tx value */ - if (GETFIELD(SPI_CTR_CFG_N2_CTRL_B2, - s->regs[SPI_CTR_CFG_REG]) == 1) { + if (GETFIELD(SPI_CTR_CFG_N2_CTRL_B2, s->regs[SPI_CTR_CFG_REG]) == 1) { s->N2_tx = s->N2_bytes; } } @@ -571,8 +544,7 @@ static void calculate_N2(PnvSpi *s, uint8_t opcode) * cap the size at a max of 64 bits or 72 bits and set the sequencer FSM * error bit. */ - uint8_t ecc_control = GETFIELD(SPI_CLK_CFG_ECC_CTRL, - s->regs[SPI_CLK_CFG_REG]); + uint8_t ecc_control = GETFIELD(SPI_CLK_CFG_ECC_CTRL, s->regs[SPI_CLK_CFG_REG]); if (ecc_control == 0 || ecc_control == 2) { if (s->N2_bytes > (PNV_SPI_REG_SIZE + 1)) { /* Unsupported N2 shift size when ECC enabled */ @@ -590,19 +562,10 @@ static void calculate_N2(PnvSpi *s, uint8_t opcode) * Shift_N2 operation handler method */ -static bool operation_shiftn2(PnvSpi *s, uint8_t opcode, - PnvXferBuffer **payload) +static bool operation_shiftn2(PnvSpi *s, uint8_t opcode) { uint8_t n2_count; bool stop = false; - - /* - * If there isn't a current payload left over from a stopped sequence - * create a new one. - */ - if (*payload == NULL) { - *payload = pnv_spi_xfer_buffer_new(); - } /* * Use a combination of N2 counters to build the N2 portion of the * transmit payload. @@ -629,44 +592,47 @@ static bool operation_shiftn2(PnvSpi *s, uint8_t opcode, * code continue will end up building the payload twice in the same * buffer since RDR full causes a sequence stop and restart. */ - if ((s->N2_rx != 0) && - (GETFIELD(SPI_STS_RDR_FULL, s->status) == 1)) { + if ((s->N2_rx != 0) && (GETFIELD(SPI_STS_RDR_FULL, s->status) == 1)) { trace_pnv_spi_sequencer_stop_requested("shift N2 set" "for receive but RDR is full"); stop = true; break; } - if ((s->N2_tx != 0) && ((s->N1_tx + n2_count) < - PNV_SPI_REG_SIZE)) { + if ((s->N2_tx != 0) && ((s->N1_tx + n2_count) < PNV_SPI_REG_SIZE)) { /* Always append data for the N2 segment if it is set for TX */ uint8_t n2_byte = 0x00; n2_byte = get_from_offset(s, (s->N1_tx + n2_count)); - trace_pnv_spi_tx_append("n2_byte", n2_byte, (s->N1_tx + n2_count)); - *(pnv_spi_xfer_buffer_write_ptr(*payload, (*payload)->len, 1)) - = n2_byte; - } else { + if (!fifo8_is_full(&s->tx_fifo)) { + trace_pnv_spi_tx_append("n2_byte", n2_byte, (s->N1_tx + n2_count)); + fifo8_push(&s->tx_fifo, n2_byte); + } else { + qemu_log_mask(LOG_GUEST_ERROR, "pnv_spi: TX_FIFO is full\n"); + break; + } + } else if (!fifo8_is_full(&s->tx_fifo)) { /* * Regardless of whether or not N2 is set for TX or RX, we need * the number of bytes in the payload to match the overall length * of the operation. */ trace_pnv_spi_tx_append_FF("n2_byte"); - *(pnv_spi_xfer_buffer_write_ptr(*payload, (*payload)->len, 1)) - = 0xff; + fifo8_push(&s->tx_fifo, 0xff); + } else { + qemu_log_mask(LOG_GUEST_ERROR, "pnv_spi: TX_FIFO is full\n"); + break; } n2_count++; } /* end of while */ if (!stop) { /* We have a TX and a full TDR or an RX and an empty RDR */ - trace_pnv_spi_tx_request("Shifting N2 frame", (*payload)->len); - transfer(s, *payload); + trace_pnv_spi_tx_request("Shifting N2 frame", fifo8_num_used(&s->tx_fifo)); + transfer(s); /* * If we are doing an N2 TX and the TDR is full we need to clear the * TDR_full status. Do this here instead of up in the loop above so we * don't log the message in every loop iteration. */ - if ((s->N2_tx != 0) && - (GETFIELD(SPI_STS_TDR_FULL, s->status) == 1)) { + if ((s->N2_tx != 0) && (GETFIELD(SPI_STS_TDR_FULL, s->status) == 1)) { s->status = SETFIELD(SPI_STS_TDR_FULL, s->status, 0); } /* @@ -682,8 +648,6 @@ static bool operation_shiftn2(PnvSpi *s, uint8_t opcode, s->N1_bytes = 0; s->N1_tx = 0; s->N1_rx = 0; - pnv_spi_xfer_buffer_free(*payload); - *payload = NULL; } return stop; } /* end of operation_shiftn2()*/ @@ -701,19 +665,6 @@ static void operation_sequencer(PnvSpi *s) uint8_t opcode = 0; uint8_t masked_opcode = 0; - /* - * PnvXferBuffer for containing the payload of the SPI frame. - * This is a static because there are cases where a sequence has to stop - * and wait for the target application to unload the RDR. If this occurs - * during a sequence where N1 is not sent alone and instead combined with - * N2 since the N1 tx length + the N2 tx length is less than the size of - * the TDR. - */ - static PnvXferBuffer *payload; - - if (payload == NULL) { - payload = pnv_spi_xfer_buffer_new(); - } /* * Clear the sequencer FSM error bit - general_SPI_status[3] * before starting a sequence. @@ -775,10 +726,8 @@ static void operation_sequencer(PnvSpi *s) s->status = SETFIELD(SPI_STS_SHIFTER_FSM, s->status, FSM_DONE); } else if (s->responder_select != 1) { qemu_log_mask(LOG_GUEST_ERROR, "Slave selection other than 1 " - "not supported, select = 0x%x\n", - s->responder_select); - trace_pnv_spi_sequencer_stop_requested("invalid " - "responder select"); + "not supported, select = 0x%x\n", s->responder_select); + trace_pnv_spi_sequencer_stop_requested("invalid responder select"); s->status = SETFIELD(SPI_STS_SHIFTER_FSM, s->status, FSM_IDLE); stop = true; } else { @@ -840,9 +789,8 @@ static void operation_sequencer(PnvSpi *s) == SEQ_OP_SHIFT_N2) { send_n1_alone = false; } - s->status = SETFIELD(SPI_STS_SHIFTER_FSM, s->status, - FSM_SHIFT_N1); - stop = operation_shiftn1(s, opcode, &payload, send_n1_alone); + s->status = SETFIELD(SPI_STS_SHIFTER_FSM, s->status, FSM_SHIFT_N1); + stop = operation_shiftn1(s, opcode, send_n1_alone); if (stop) { /* * The operation code says to stop, this can occur if: @@ -858,7 +806,7 @@ static void operation_sequencer(PnvSpi *s) if (GETFIELD(SPI_STS_TDR_UNDERRUN, s->status)) { s->shift_n1_done = true; s->status = SETFIELD(SPI_STS_SHIFTER_FSM, s->status, - FSM_SHIFT_N2); + FSM_SHIFT_N2); s->status = SETFIELD(SPI_STS_SEQ_INDEX, s->status, (get_seq_index(s) + 1)); } else { @@ -866,8 +814,7 @@ static void operation_sequencer(PnvSpi *s) * This is case (1) or (2) so the sequencer needs to * wait and NOT go to the next sequence yet. */ - s->status = SETFIELD(SPI_STS_SHIFTER_FSM, s->status, - FSM_WAIT); + s->status = SETFIELD(SPI_STS_SHIFTER_FSM, s->status, FSM_WAIT); } } else { /* Ok to move on to the next index */ @@ -890,21 +837,18 @@ static void operation_sequencer(PnvSpi *s) * error bit 3 (general_SPI_status[3]) in status reg. */ s->status = SETFIELD(SPI_STS_GEN_STATUS_B3, s->status, 1); - trace_pnv_spi_sequencer_stop_requested("shift_n2 " - "w/no shift_n1 done"); + trace_pnv_spi_sequencer_stop_requested("shift_n2 w/no shift_n1 done"); stop = true; } else { /* Ok to do a Shift_N2 */ - s->status = SETFIELD(SPI_STS_SHIFTER_FSM, s->status, - FSM_SHIFT_N2); - stop = operation_shiftn2(s, opcode, &payload); + s->status = SETFIELD(SPI_STS_SHIFTER_FSM, s->status, FSM_SHIFT_N2); + stop = operation_shiftn2(s, opcode); /* * If the operation code says to stop set the shifter state to * wait and stop */ if (stop) { - s->status = SETFIELD(SPI_STS_SHIFTER_FSM, s->status, - FSM_WAIT); + s->status = SETFIELD(SPI_STS_SHIFTER_FSM, s->status, FSM_WAIT); } else { /* Ok to move on to the next index */ next_sequencer_fsm(s); @@ -988,8 +932,7 @@ static void operation_sequencer(PnvSpi *s) case SEQ_OP_BRANCH_IFNEQ_INC_2: s->status = SETFIELD(SPI_STS_SEQ_FSM, s->status, SEQ_STATE_EXECUTE); trace_pnv_spi_sequencer_op("BRANCH_IFNEQ_INC_2", get_seq_index(s)); - uint8_t condition2 = GETFIELD(SPI_CTR_CFG_CMP2, - s->regs[SPI_CTR_CFG_REG]); + uint8_t condition2 = GETFIELD(SPI_CTR_CFG_CMP2, s->regs[SPI_CTR_CFG_REG]); /* * The spec says the loop should execute count compare + 1 times. * However we learned from engineering that we really only loop @@ -1209,6 +1152,9 @@ static void pnv_spi_realize(DeviceState *dev, Error **errp) s->cs_line = g_new0(qemu_irq, 1); qdev_init_gpio_out_named(DEVICE(s), s->cs_line, "cs", 1); + fifo8_create(&s->tx_fifo, PNV_SPI_FIFO_SIZE); + fifo8_create(&s->rx_fifo, PNV_SPI_FIFO_SIZE); + /* spi scoms */ pnv_xscom_region_init(&s->xscom_spic_regs, OBJECT(s), &pnv_spi_xscom_ops, s, "xscom-spi", PNV10_XSCOM_PIB_SPIC_SIZE); diff --git a/include/hw/ssi/pnv_spi.h b/include/hw/ssi/pnv_spi.h index 8815f67d45..9878d9a25f 100644 --- a/include/hw/ssi/pnv_spi.h +++ b/include/hw/ssi/pnv_spi.h @@ -23,6 +23,7 @@ #include "hw/ssi/ssi.h" #include "hw/sysbus.h" +#include "qemu/fifo8.h" #define TYPE_PNV_SPI "pnv-spi" OBJECT_DECLARE_SIMPLE_TYPE(PnvSpi, PNV_SPI) @@ -37,6 +38,8 @@ typedef struct PnvSpi { SSIBus *ssi_bus; qemu_irq *cs_line; MemoryRegion xscom_spic_regs; + Fifo8 tx_fifo; + Fifo8 rx_fifo; /* SPI object number */ uint32_t spic_num; uint8_t transfer_len; From patchwork Tue Mar 11 12:57:32 2025 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Nicholas Piggin X-Patchwork-Id: 14011829 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.lore.kernel.org (Postfix) with ESMTPS id A44CBC28B2E for ; Tue, 11 Mar 2025 13:12:06 +0000 (UTC) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1trzIw-0003FU-8s; Tue, 11 Mar 2025 09:05:54 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1trzDl-0004tJ-OT; Tue, 11 Mar 2025 09:00:42 -0400 Received: from mail-pj1-x102a.google.com ([2607:f8b0:4864:20::102a]) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_128_GCM_SHA256:128) (Exim 4.90_1) (envelope-from ) id 1trzDf-0008SW-Oh; Tue, 11 Mar 2025 09:00:33 -0400 Received: by mail-pj1-x102a.google.com with SMTP id 98e67ed59e1d1-2ff04f36fd2so9014252a91.1; Tue, 11 Mar 2025 06:00:26 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20230601; t=1741698025; x=1742302825; darn=nongnu.org; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to; bh=ltiIpntD1e/ZvbcOYuUkJzWPVpcS1p6NcC9JSvLJgJs=; b=gh37F6v75VHtGQ30qUt8BY5QNVQSu+jF5GU2C4YlYgsDN/UyHTOTorKh8AaicBhq4V hwzJrfyqH2vT/Rxf+NYCh5p33RsvCXzkl18j+zI7u6kF/O/wp7TIr5I8sZlr+7Ahb5IZ DoMGWjCJDxAm36mR6LtzKQuzNs5yZFVolPwjBzduBa7caE6egW08O7wqqZxG60bvmN0R tR80hi2TxUFIQiNFxaVYHa1CyUVgIQ2du+T/FKDpqzFrfGS+jN9VhRL0+M3k7ykdvlDd eUGFJ0lnG0wcPpkOIaUQgF2kZkYj2p/7nlxkIOwmQJYZKEEYuEFDWQIZ4DBjdGlOicpO QwzA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1741698025; x=1742302825; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=ltiIpntD1e/ZvbcOYuUkJzWPVpcS1p6NcC9JSvLJgJs=; b=QCnwBwRm58r4O089lCOCkn1SpNFIqUFWvAtvfLszY6VjilkNgH1UjC9F60wy9T7e+s Ag/9GZdDMxUcn3flIja0bKa6JnMTmVV/J4PtDmmTWZrghqMPkVsT/fSEddohbgLBmH6u RuLKiuAfA5FRrSQyUPQEefpgbL1hUBhQnlyw2lgy5xyVWWfXRR4bIIxPgoaHjj07ChQO vMOJrGCKZZJTkeBE11SFuDXHhwkp9pPu4LwAcId6AUNvblMgh6GkZFLplfdzPRRFtIrE 4bIZw/BPrzIPfwuM62djg/IZ3qnmGa90Iiy5fc7pqg/Ug+MkyuVuaNcF9rRjDMsWD3R1 kw2Q== X-Forwarded-Encrypted: i=1; AJvYcCVMnqXcYEGufZYxmhqdN62corU3omZmSYgbokCAyHZ9+0aDpTosFYn5esq6XZEaW2HfzZWTZSUE2A==@nongnu.org X-Gm-Message-State: AOJu0Yxg2De6tSHI0TTL7xTV3GEMwbZHkbmzUVyOh516PYhIl7W+XymF ccefWAyR4LlqIe3YDpvNHf6NfY39VBShYbEPMjy9DeZ8bjwJkWNsScSAQw== X-Gm-Gg: ASbGncspVS4NBIffocKZ/bOTB8/nK9vvSu1LhFZc1jZ+9zHWn7FlbA7a6XMJRaS7+mB 5dPktMEt9k75ELmlKKhs3OQWJzhtuhfnaHx888s4KljZv0gWtSsaMrKlcaS4kqZRpkJk1+3DTT/ xL3jPFt9NhrLvpdpaZYuciMDAPn/epLMm5REIgJmQnPzicFzi3eha9KF8YIn502tdkXk8kj7q2H OYa3VY9ZrhNNLmpxtzEgNaM5aZNFmraG+aaYndpeyFGUe/o6Ph55OX8VROIMyffL/Gd/cR6pYlR lodYwfTyUbCSfHcWEljK0DH626ikDUwpynsWmpOqnEGEQz1Wfh0= X-Google-Smtp-Source: AGHT+IEUX7EQKfo4DCOgQUmp+PAEpVwTq+rX9BWmWCAia6eMLOHO9RLW5iwyQW9TghvOet5wGrhpFg== X-Received: by 2002:a17:90b:2e51:b0:2ff:7331:18bc with SMTP id 98e67ed59e1d1-2ff7ceee7ebmr22740098a91.26.1741698024574; Tue, 11 Mar 2025 06:00:24 -0700 (PDT) Received: from wheely.local0.net ([118.208.151.101]) by smtp.gmail.com with ESMTPSA id 98e67ed59e1d1-2ff4e773dddsm11822318a91.12.2025.03.11.06.00.22 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 11 Mar 2025 06:00:24 -0700 (PDT) From: Nicholas Piggin To: qemu-devel@nongnu.org Cc: Nicholas Piggin , qemu-ppc@nongnu.org, Chalapathi V Subject: [PULL 38/72] hw/ssi/pnv_spi: Use local var seq_index instead of get_seq_index(). Date: Tue, 11 Mar 2025 22:57:32 +1000 Message-ID: <20250311125815.903177-39-npiggin@gmail.com> X-Mailer: git-send-email 2.47.1 In-Reply-To: <20250311125815.903177-1-npiggin@gmail.com> References: <20250311125815.903177-1-npiggin@gmail.com> MIME-Version: 1.0 Received-SPF: pass client-ip=2607:f8b0:4864:20::102a; envelope-from=npiggin@gmail.com; helo=mail-pj1-x102a.google.com X-Spam_score_int: -20 X-Spam_score: -2.1 X-Spam_bar: -- X-Spam_report: (-2.1 / 5.0 requ) BAYES_00=-1.9, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_AU=-0.1, DKIM_VALID_EF=-0.1, FREEMAIL_FROM=0.001, RCVD_IN_DNSWL_NONE=-0.0001, SPF_HELO_NONE=0.001, T_SPF_TEMPERROR=0.01 autolearn=ham autolearn_force=no X-Spam_action: no action X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: qemu-devel-bounces+qemu-devel=archiver.kernel.org@nongnu.org Sender: qemu-devel-bounces+qemu-devel=archiver.kernel.org@nongnu.org From: Chalapathi V Use a local variable seq_index instead of repeatedly calling get_seq_index() method and open-code next_sequencer_fsm(). Signed-off-by: Chalapathi V Reviewed-by: Nicholas Piggin Message-ID: <20250303141328.23991-3-chalapathi.v@linux.ibm.com> Signed-off-by: Nicholas Piggin --- hw/ssi/pnv_spi.c | 97 ++++++++++++++++++++++++++---------------------- 1 file changed, 52 insertions(+), 45 deletions(-) diff --git a/hw/ssi/pnv_spi.c b/hw/ssi/pnv_spi.c index 388b425157..de33542c35 100644 --- a/hw/ssi/pnv_spi.c +++ b/hw/ssi/pnv_spi.c @@ -227,18 +227,6 @@ static void transfer(PnvSpi *s) fifo8_reset(&s->rx_fifo); } -static inline uint8_t get_seq_index(PnvSpi *s) -{ - return GETFIELD(SPI_STS_SEQ_INDEX, s->status); -} - -static inline void next_sequencer_fsm(PnvSpi *s) -{ - uint8_t seq_index = get_seq_index(s); - s->status = SETFIELD(SPI_STS_SEQ_INDEX, s->status, (seq_index + 1)); - s->status = SETFIELD(SPI_STS_SEQ_FSM, s->status, SEQ_STATE_INDEX_INCREMENT); -} - /* * Calculate the N1 counters based on passed in opcode and * internal register values. @@ -664,6 +652,7 @@ static void operation_sequencer(PnvSpi *s) bool stop = false; /* Flag to stop the sequencer */ uint8_t opcode = 0; uint8_t masked_opcode = 0; + uint8_t seq_index; /* * Clear the sequencer FSM error bit - general_SPI_status[3] @@ -677,12 +666,17 @@ static void operation_sequencer(PnvSpi *s) if (GETFIELD(SPI_STS_SEQ_FSM, s->status) == SEQ_STATE_IDLE) { s->status = SETFIELD(SPI_STS_SEQ_INDEX, s->status, 0); } + /* + * SPI_STS_SEQ_INDEX of status register is kept in seq_index variable and + * updated back to status register at the end of operation_sequencer(). + */ + seq_index = GETFIELD(SPI_STS_SEQ_INDEX, s->status); /* * There are only 8 possible operation IDs to iterate through though * some operations may cause more than one frame to be sequenced. */ - while (get_seq_index(s) < NUM_SEQ_OPS) { - opcode = s->seq_op[get_seq_index(s)]; + while (seq_index < NUM_SEQ_OPS) { + opcode = s->seq_op[seq_index]; /* Set sequencer state to decode */ s->status = SETFIELD(SPI_STS_SEQ_FSM, s->status, SEQ_STATE_DECODE); /* @@ -699,7 +693,7 @@ static void operation_sequencer(PnvSpi *s) case SEQ_OP_STOP: s->status = SETFIELD(SPI_STS_SEQ_FSM, s->status, SEQ_STATE_EXECUTE); /* A stop operation in any position stops the sequencer */ - trace_pnv_spi_sequencer_op("STOP", get_seq_index(s)); + trace_pnv_spi_sequencer_op("STOP", seq_index); stop = true; s->status = SETFIELD(SPI_STS_SHIFTER_FSM, s->status, FSM_IDLE); @@ -710,7 +704,7 @@ static void operation_sequencer(PnvSpi *s) case SEQ_OP_SELECT_SLAVE: s->status = SETFIELD(SPI_STS_SEQ_FSM, s->status, SEQ_STATE_EXECUTE); - trace_pnv_spi_sequencer_op("SELECT_SLAVE", get_seq_index(s)); + trace_pnv_spi_sequencer_op("SELECT_SLAVE", seq_index); /* * This device currently only supports a single responder * connection at position 0. De-selecting a responder is fine @@ -721,8 +715,7 @@ static void operation_sequencer(PnvSpi *s) if (s->responder_select == 0) { trace_pnv_spi_shifter_done(); qemu_set_irq(s->cs_line[0], 1); - s->status = SETFIELD(SPI_STS_SEQ_INDEX, s->status, - (get_seq_index(s) + 1)); + seq_index++; s->status = SETFIELD(SPI_STS_SHIFTER_FSM, s->status, FSM_DONE); } else if (s->responder_select != 1) { qemu_log_mask(LOG_GUEST_ERROR, "Slave selection other than 1 " @@ -747,13 +740,15 @@ static void operation_sequencer(PnvSpi *s) * applies once a valid responder select has occurred. */ s->shift_n1_done = false; - next_sequencer_fsm(s); + seq_index++; + s->status = SETFIELD(SPI_STS_SEQ_FSM, s->status, + SEQ_STATE_INDEX_INCREMENT); } break; case SEQ_OP_SHIFT_N1: s->status = SETFIELD(SPI_STS_SEQ_FSM, s->status, SEQ_STATE_EXECUTE); - trace_pnv_spi_sequencer_op("SHIFT_N1", get_seq_index(s)); + trace_pnv_spi_sequencer_op("SHIFT_N1", seq_index); /* * Only allow a shift_n1 when the state is not IDLE or DONE. * In either of those two cases the sequencer is not in a proper @@ -785,8 +780,9 @@ static void operation_sequencer(PnvSpi *s) * transmission to the responder without requiring a refill of * the TDR between the two operations. */ - if (PNV_SPI_MASKED_OPCODE(s->seq_op[get_seq_index(s) + 1]) - == SEQ_OP_SHIFT_N2) { + if ((seq_index != 7) && + PNV_SPI_MASKED_OPCODE(s->seq_op[(seq_index + 1)]) == + SEQ_OP_SHIFT_N2) { send_n1_alone = false; } s->status = SETFIELD(SPI_STS_SHIFTER_FSM, s->status, FSM_SHIFT_N1); @@ -806,9 +802,8 @@ static void operation_sequencer(PnvSpi *s) if (GETFIELD(SPI_STS_TDR_UNDERRUN, s->status)) { s->shift_n1_done = true; s->status = SETFIELD(SPI_STS_SHIFTER_FSM, s->status, - FSM_SHIFT_N2); - s->status = SETFIELD(SPI_STS_SEQ_INDEX, s->status, - (get_seq_index(s) + 1)); + FSM_SHIFT_N2); + seq_index++; } else { /* * This is case (1) or (2) so the sequencer needs to @@ -819,14 +814,16 @@ static void operation_sequencer(PnvSpi *s) } else { /* Ok to move on to the next index */ s->shift_n1_done = true; - next_sequencer_fsm(s); + seq_index++; + s->status = SETFIELD(SPI_STS_SEQ_FSM, s->status, + SEQ_STATE_INDEX_INCREMENT); } } break; case SEQ_OP_SHIFT_N2: s->status = SETFIELD(SPI_STS_SEQ_FSM, s->status, SEQ_STATE_EXECUTE); - trace_pnv_spi_sequencer_op("SHIFT_N2", get_seq_index(s)); + trace_pnv_spi_sequencer_op("SHIFT_N2", seq_index); if (!s->shift_n1_done) { qemu_log_mask(LOG_GUEST_ERROR, "Shift_N2 is not allowed if a " "Shift_N1 is not done, shifter state = 0x%llx", @@ -851,14 +848,16 @@ static void operation_sequencer(PnvSpi *s) s->status = SETFIELD(SPI_STS_SHIFTER_FSM, s->status, FSM_WAIT); } else { /* Ok to move on to the next index */ - next_sequencer_fsm(s); + seq_index++; + s->status = SETFIELD(SPI_STS_SEQ_FSM, s->status, + SEQ_STATE_INDEX_INCREMENT); } } break; case SEQ_OP_BRANCH_IFNEQ_RDR: s->status = SETFIELD(SPI_STS_SEQ_FSM, s->status, SEQ_STATE_EXECUTE); - trace_pnv_spi_sequencer_op("BRANCH_IFNEQ_RDR", get_seq_index(s)); + trace_pnv_spi_sequencer_op("BRANCH_IFNEQ_RDR", seq_index); /* * The memory mapping register RDR match value is compared against * the 16 rightmost bytes of the RDR (potentially with masking). @@ -874,15 +873,16 @@ static void operation_sequencer(PnvSpi *s) if (rdr_matched) { trace_pnv_spi_RDR_match("success"); /* A match occurred, increment the sequencer index. */ - next_sequencer_fsm(s); + seq_index++; + s->status = SETFIELD(SPI_STS_SEQ_FSM, s->status, + SEQ_STATE_INDEX_INCREMENT); } else { trace_pnv_spi_RDR_match("failed"); /* * Branch the sequencer to the index coded into the op * code. */ - s->status = SETFIELD(SPI_STS_SEQ_INDEX, s->status, - PNV_SPI_OPCODE_LO_NIBBLE(opcode)); + seq_index = PNV_SPI_OPCODE_LO_NIBBLE(opcode); } /* * Regardless of where the branch ended up we want the @@ -901,12 +901,13 @@ static void operation_sequencer(PnvSpi *s) case SEQ_OP_TRANSFER_TDR: s->status = SETFIELD(SPI_STS_SEQ_FSM, s->status, SEQ_STATE_EXECUTE); qemu_log_mask(LOG_GUEST_ERROR, "Transfer TDR is not supported\n"); - next_sequencer_fsm(s); + seq_index++; + s->status = SETFIELD(SPI_STS_SEQ_FSM, s->status, SEQ_STATE_INDEX_INCREMENT); break; case SEQ_OP_BRANCH_IFNEQ_INC_1: s->status = SETFIELD(SPI_STS_SEQ_FSM, s->status, SEQ_STATE_EXECUTE); - trace_pnv_spi_sequencer_op("BRANCH_IFNEQ_INC_1", get_seq_index(s)); + trace_pnv_spi_sequencer_op("BRANCH_IFNEQ_INC_1", seq_index); /* * The spec says the loop should execute count compare + 1 times. * However we learned from engineering that we really only loop @@ -920,19 +921,21 @@ static void operation_sequencer(PnvSpi *s) * mask off all but the first three bits so we don't try to * access beyond the sequencer_operation_reg boundary. */ - s->status = SETFIELD(SPI_STS_SEQ_INDEX, s->status, - PNV_SPI_OPCODE_LO_NIBBLE(opcode)); + seq_index = PNV_SPI_OPCODE_LO_NIBBLE(opcode); s->loop_counter_1++; } else { /* Continue to next index if loop counter is reached */ - next_sequencer_fsm(s); + seq_index++; + s->status = SETFIELD(SPI_STS_SEQ_FSM, s->status, + SEQ_STATE_INDEX_INCREMENT); } break; case SEQ_OP_BRANCH_IFNEQ_INC_2: s->status = SETFIELD(SPI_STS_SEQ_FSM, s->status, SEQ_STATE_EXECUTE); - trace_pnv_spi_sequencer_op("BRANCH_IFNEQ_INC_2", get_seq_index(s)); - uint8_t condition2 = GETFIELD(SPI_CTR_CFG_CMP2, s->regs[SPI_CTR_CFG_REG]); + trace_pnv_spi_sequencer_op("BRANCH_IFNEQ_INC_2", seq_index); + uint8_t condition2 = GETFIELD(SPI_CTR_CFG_CMP2, + s->regs[SPI_CTR_CFG_REG]); /* * The spec says the loop should execute count compare + 1 times. * However we learned from engineering that we really only loop @@ -945,19 +948,21 @@ static void operation_sequencer(PnvSpi *s) * mask off all but the first three bits so we don't try to * access beyond the sequencer_operation_reg boundary. */ - s->status = SETFIELD(SPI_STS_SEQ_INDEX, - s->status, PNV_SPI_OPCODE_LO_NIBBLE(opcode)); + seq_index = PNV_SPI_OPCODE_LO_NIBBLE(opcode); s->loop_counter_2++; } else { /* Continue to next index if loop counter is reached */ - next_sequencer_fsm(s); + seq_index++; + s->status = SETFIELD(SPI_STS_SEQ_FSM, s->status, + SEQ_STATE_INDEX_INCREMENT); } break; default: s->status = SETFIELD(SPI_STS_SEQ_FSM, s->status, SEQ_STATE_EXECUTE); /* Ignore unsupported operations. */ - next_sequencer_fsm(s); + seq_index++; + s->status = SETFIELD(SPI_STS_SEQ_FSM, s->status, SEQ_STATE_INDEX_INCREMENT); break; } /* end of switch */ /* @@ -965,10 +970,10 @@ static void operation_sequencer(PnvSpi *s) * we need to go ahead and end things as if there was a STOP at the * end. */ - if (get_seq_index(s) == NUM_SEQ_OPS) { + if (seq_index == NUM_SEQ_OPS) { /* All 8 opcodes completed, sequencer idling */ s->status = SETFIELD(SPI_STS_SHIFTER_FSM, s->status, FSM_IDLE); - s->status = SETFIELD(SPI_STS_SEQ_INDEX, s->status, 0); + seq_index = 0; s->loop_counter_1 = 0; s->loop_counter_2 = 0; s->status = SETFIELD(SPI_STS_SEQ_FSM, s->status, SEQ_STATE_IDLE); @@ -979,6 +984,8 @@ static void operation_sequencer(PnvSpi *s) break; } } /* end of while */ + /* Update sequencer index field in status.*/ + s->status = SETFIELD(SPI_STS_SEQ_INDEX, s->status, seq_index); return; } /* end of operation_sequencer() */ From patchwork Tue Mar 11 12:57:33 2025 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Nicholas Piggin X-Patchwork-Id: 14011818 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.lore.kernel.org (Postfix) with ESMTPS id 1C64BC282EC for ; Tue, 11 Mar 2025 13:07:54 +0000 (UTC) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1trzGR-000802-MB; Tue, 11 Mar 2025 09:03:20 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1trzDl-0004tI-6D; Tue, 11 Mar 2025 09:00:42 -0400 Received: from mail-pl1-x62b.google.com ([2607:f8b0:4864:20::62b]) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_128_GCM_SHA256:128) (Exim 4.90_1) (envelope-from ) id 1trzDi-0008Un-E5; Tue, 11 Mar 2025 09:00:32 -0400 Received: by mail-pl1-x62b.google.com with SMTP id d9443c01a7336-224100e9a5cso100846765ad.2; Tue, 11 Mar 2025 06:00:29 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20230601; t=1741698028; x=1742302828; darn=nongnu.org; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to; bh=q3BmDWJaQxO3ga2r+rH3p0NW/4tv9mRzlMcun1D9rBI=; b=Bb5Vh8Lg6CUG+QuEXCtK7740+jGENUxDPxEya1jOaUlOJ1LMXZcQP/642zz5O5YGGD yT/9jEiI5CvVaURBwbxtbRUnQSk9o1tglqvE4/BlnVkBYZy9NlJKQ1wp7/2RYLaRurJm K692Sx1/dD2KOUolC3nSC5qWxGK1g9RgZvucc4Ss5Mlt65ds1Ms5YHui5qfiXGARenWZ IGVM9I04zB+uOxLOs6g1Kg1mgI0pjjxy/JwgAeFgDVQVZZkwQ9en07/rsTlLV2Arr5BP l2Dxeene0wzmQPKUrE9Rw5RKU4jQ63pCu7uOCveqC6Dl+wD3kb823QYj6CjlRpHodx6j 87Tw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1741698028; x=1742302828; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=q3BmDWJaQxO3ga2r+rH3p0NW/4tv9mRzlMcun1D9rBI=; b=OaLIpyNN6PrO/UH170pxjxkWF2Kq5Ul3SKqop0FqXg2prs+qwALWFODEkcsexhyMDG 8oBROczBB8e2jJ7wo0chozToKp+mplDD2uMXER16TwM+PBuq2GKLEh6tqANxLNVmGI3p upmfjCLW7VibZ8PhJfShD+L9PeMi0iNqHQy5QK/ZSkyf7bK5etpoj+5feE3fcXC6ZhUa ztsUb+Y/7E+RDUlRey4SNuaqwuOYRoK4GuvsgQjtgJ3lTNBL96B0jVFjQdpd9UwSuq7a 6jT0Ot18k51rEn2tJzTgtWhQNseVkO3+9OtvrsEkRBUUkAU9aQqjbh+rJkqL7HUHMhMs FRjg== X-Forwarded-Encrypted: i=1; AJvYcCWusDzGsR1TW+JCm9bcUATuLJ7AYwJah5WjjzUwjWdc6+H2YA6TfXjKogDh5pO48BoXIta4paDx1g==@nongnu.org X-Gm-Message-State: AOJu0YxzO3/tecyboolXxS3xD2d+BCyHwc9KsvkfPzMOSx9saywVgvYb s7v4W+ticmHOCDzgZvUI8Xv3S96F2A5zErxSLk/e97b2+Jdw+wYSFxGTig== X-Gm-Gg: ASbGnctX3p52xKT45XGYYFmahtIvQp7+fZHUzSMdBbw1KdEbwaupwA/69EAxpdtobws N1EeDNHZ3oKW8v9m0aJS3P3skboKwT1IxqOAw9ktQfm/ANTyMmQK+W4v4rXRipsK+GD827mMzn5 JZCPzEeLxDVl/7qNBU5fmPVHHCw8gG3tUBIkPL1ilfUp/NSoGLiJkyexQcq4MjMmuSmzA8untFY d9T43JP52UASLM/+I67N+Lw5Eaj3jx+jmG2raDbyNUXX2w3VxhFUBjKz52E76XtiIVvvsSEI16T 3cvjP6+xT/XoljRErPU1JlsPWvcsKs9DQAowg4ooE0bWfgzZaGA= X-Google-Smtp-Source: AGHT+IHb56irBhoKneJKzVkcTWD2cD2JK+WC3OxKBGYfFbR7a0+WmGbvRRsobRKDte3B6loA6Ja/6Q== X-Received: by 2002:a17:903:298b:b0:21f:4649:fd49 with SMTP id d9443c01a7336-22428c221dbmr291023675ad.49.1741698027290; Tue, 11 Mar 2025 06:00:27 -0700 (PDT) Received: from wheely.local0.net ([118.208.151.101]) by smtp.gmail.com with ESMTPSA id 98e67ed59e1d1-2ff4e773dddsm11822318a91.12.2025.03.11.06.00.25 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 11 Mar 2025 06:00:26 -0700 (PDT) From: Nicholas Piggin To: qemu-devel@nongnu.org Cc: Nicholas Piggin , qemu-ppc@nongnu.org, Chalapathi V Subject: [PULL 39/72] hw/ssi/pnv_spi: Make bus names distinct for each controllers of a socket Date: Tue, 11 Mar 2025 22:57:33 +1000 Message-ID: <20250311125815.903177-40-npiggin@gmail.com> X-Mailer: git-send-email 2.47.1 In-Reply-To: <20250311125815.903177-1-npiggin@gmail.com> References: <20250311125815.903177-1-npiggin@gmail.com> MIME-Version: 1.0 Received-SPF: pass client-ip=2607:f8b0:4864:20::62b; envelope-from=npiggin@gmail.com; helo=mail-pl1-x62b.google.com X-Spam_score_int: -20 X-Spam_score: -2.1 X-Spam_bar: -- X-Spam_report: (-2.1 / 5.0 requ) BAYES_00=-1.9, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_AU=-0.1, DKIM_VALID_EF=-0.1, FREEMAIL_FROM=0.001, RCVD_IN_DNSWL_NONE=-0.0001, SPF_HELO_NONE=0.001, SPF_PASS=-0.001 autolearn=ham autolearn_force=no X-Spam_action: no action X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: qemu-devel-bounces+qemu-devel=archiver.kernel.org@nongnu.org Sender: qemu-devel-bounces+qemu-devel=archiver.kernel.org@nongnu.org From: Chalapathi V Create a spi buses with distinct names on each socket so that responders are attached to correct SPI controllers. Change the bus name to chipX.spi. where X = 0.. QOM tree on a 2 socket machine: (qemu) info qom-tree /machine (powernv10-machine) /chip[0] (power10_v2.0-pnv-chip) /pib_spic[0] (pnv-spi) /chip0.spi.0 (SSI) /xscom-spi[0] (memory-region) /chip[1] (power10_v2.0-pnv-chip) /pib_spic[0] (pnv-spi) /chip1.spi.0 (SSI) /xscom-spi[0] (memory-region) Signed-off-by: Chalapathi V Message-ID: <20250303141328.23991-4-chalapathi.v@linux.ibm.com> Signed-off-by: Nicholas Piggin --- hw/ppc/pnv.c | 2 ++ hw/ssi/pnv_spi.c | 5 +++-- include/hw/ssi/pnv_spi.h | 3 ++- tests/qtest/pnv-spi-seeprom-test.c | 2 +- 4 files changed, 8 insertions(+), 4 deletions(-) diff --git a/hw/ppc/pnv.c b/hw/ppc/pnv.c index d60574d601..59365370c3 100644 --- a/hw/ppc/pnv.c +++ b/hw/ppc/pnv.c @@ -2252,6 +2252,8 @@ static void pnv_chip_power10_realize(DeviceState *dev, Error **errp) /* pib_spic[2] connected to 25csm04 which implements 1 byte transfer */ object_property_set_int(OBJECT(&chip10->pib_spic[i]), "transfer_len", (i == 2) ? 1 : 4, &error_fatal); + object_property_set_int(OBJECT(&chip10->pib_spic[i]), "chip-id", + chip->chip_id, &error_fatal); if (!sysbus_realize(SYS_BUS_DEVICE(OBJECT (&chip10->pib_spic[i])), errp)) { return; diff --git a/hw/ssi/pnv_spi.c b/hw/ssi/pnv_spi.c index de33542c35..83221607c9 100644 --- a/hw/ssi/pnv_spi.c +++ b/hw/ssi/pnv_spi.c @@ -1147,14 +1147,15 @@ static const MemoryRegionOps pnv_spi_xscom_ops = { static const Property pnv_spi_properties[] = { DEFINE_PROP_UINT32("spic_num", PnvSpi, spic_num, 0), + DEFINE_PROP_UINT32("chip-id", PnvSpi, chip_id, 0), DEFINE_PROP_UINT8("transfer_len", PnvSpi, transfer_len, 4), }; static void pnv_spi_realize(DeviceState *dev, Error **errp) { PnvSpi *s = PNV_SPI(dev); - g_autofree char *name = g_strdup_printf(TYPE_PNV_SPI_BUS ".%d", - s->spic_num); + g_autofree char *name = g_strdup_printf("chip%d." TYPE_PNV_SPI_BUS ".%d", + s->chip_id, s->spic_num); s->ssi_bus = ssi_create_bus(dev, name); s->cs_line = g_new0(qemu_irq, 1); qdev_init_gpio_out_named(DEVICE(s), s->cs_line, "cs", 1); diff --git a/include/hw/ssi/pnv_spi.h b/include/hw/ssi/pnv_spi.h index 9878d9a25f..6adb72dbb2 100644 --- a/include/hw/ssi/pnv_spi.h +++ b/include/hw/ssi/pnv_spi.h @@ -31,7 +31,7 @@ OBJECT_DECLARE_SIMPLE_TYPE(PnvSpi, PNV_SPI) #define PNV_SPI_REG_SIZE 8 #define PNV_SPI_REGS 7 -#define TYPE_PNV_SPI_BUS "pnv-spi-bus" +#define TYPE_PNV_SPI_BUS "spi" typedef struct PnvSpi { SysBusDevice parent_obj; @@ -42,6 +42,7 @@ typedef struct PnvSpi { Fifo8 rx_fifo; /* SPI object number */ uint32_t spic_num; + uint32_t chip_id; uint8_t transfer_len; uint8_t responder_select; /* To verify if shift_n1 happens prior to shift_n2 */ diff --git a/tests/qtest/pnv-spi-seeprom-test.c b/tests/qtest/pnv-spi-seeprom-test.c index 57f20af76e..600493c425 100644 --- a/tests/qtest/pnv-spi-seeprom-test.c +++ b/tests/qtest/pnv-spi-seeprom-test.c @@ -92,7 +92,7 @@ static void test_spi_seeprom(const void *data) qts = qtest_initf("-machine powernv10 -smp 2,cores=2," "threads=1 -accel tcg,thread=single -nographic " "-blockdev node-name=pib_spic2,driver=file," - "filename=%s -device 25csm04,bus=pnv-spi-bus.2,cs=0," + "filename=%s -device 25csm04,bus=chip0.spi.2,cs=0," "drive=pib_spic2", tmp_path); spi_seeprom_transaction(qts, chip); qtest_quit(qts); From patchwork Tue Mar 11 12:57:34 2025 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Nicholas Piggin X-Patchwork-Id: 14011888 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.lore.kernel.org (Postfix) with ESMTPS id 0F577C28B30 for ; Tue, 11 Mar 2025 13:23:38 +0000 (UTC) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1trzIv-0003Cz-F6; Tue, 11 Mar 2025 09:05:53 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1trzDp-0004v6-Qh; Tue, 11 Mar 2025 09:00:42 -0400 Received: from mail-pj1-x1032.google.com ([2607:f8b0:4864:20::1032]) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_128_GCM_SHA256:128) (Exim 4.90_1) (envelope-from ) id 1trzDl-0008WV-Sd; Tue, 11 Mar 2025 09:00:35 -0400 Received: by mail-pj1-x1032.google.com with SMTP id 98e67ed59e1d1-2ff784dc055so7175187a91.1; Tue, 11 Mar 2025 06:00:32 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20230601; t=1741698030; x=1742302830; darn=nongnu.org; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to; bh=e+hvRNZhyfNMby5k48ebI9t7MyykDhncL1DN8gtvFQA=; b=eSywFVXrP4iijlCcvKDl+XqgBov45nb+yLSZgiY/DyUqwFwPPc+tSzdo/f7aNXs1iw AeXsPhNDgA5AmIGJGPS8BqMPt+U+MehoQJz/gFkTx874Isknio7ycfFiJPdKgEJ3lBq8 yyVva2D3QqFAA1aXF6REiogWSSD4mrkbbai34SjClcmbhRs7F7fwnbGqjxSlewQjSZCu KTqGaUKSPI6crCFNQ9SU5OdcbBEW9kyN/s2ZyBxDBobn80sJ4O1WSo6T8sOB9R8w0hnR 7QwX3eYxnuQn+1mC51fNxENvzYFEAuLN5m9ev/9oqw4hEYw6TaZGSxjxW1k4UtwJajUD SKBg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1741698030; x=1742302830; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=e+hvRNZhyfNMby5k48ebI9t7MyykDhncL1DN8gtvFQA=; b=DMbtECXifVt4/XitHQOktuQyAfdPLGm7wwukdACrKY1IQiBakOsydZcgk7lTYHscOv 7YMTBa6aK30b9nFappL1PW/Gf06Y9YIqCX8XMlW5Ifb3Bx+1/XyKfLWU0d5i3XySmwbP bfQvv0zKrc7l0rowQxFFR+tKje2rEPmNjcydy2gsVtvoJvi0pkj9073oEVhXPOB3I40g m8lJ0NhsunjvmjZQiPgdThxhbkYwKquPkFhkxXPtx6BPU4eGDjg4P/lnS7iw9606YLGi N5H3fXNTyfUKBw/ZTFEsyTiar/jpRMDFH8qsjIzaPzEdWa6IQkFB0OKKcZngrCqZgHhb qvbg== X-Forwarded-Encrypted: i=1; AJvYcCU9RfPREC1G/uoLEsSAMYyyEwbrSgLMDq2Sf92O7LIKRXTMCG++++YaWyVcG7+nSyZKop2HBInNuQ==@nongnu.org X-Gm-Message-State: AOJu0Yz5I05OjwhgJAxowh76v/Kupqt8cReS/G+Z8ep5pypyDREhq5Zh G6vo0c9WMwM6VHDKq58GCbO4OUfaJpztZBzcnvsbxZ1RJKlSPUlZsDLHvQ== X-Gm-Gg: ASbGncuSaMvKlg2hGuua4Btlo9+CgMt1mHG95zKGvJHt4uLqpwUHT274dkat66LMC2c 4zDPKY25fJHF9Gq/2jV2/Axit1hGRw4976zWY0Ju/N7cWjegAak9Mfi6aq1PVTF5hPpBeS+YwnA 9YatzKpz2RDRaxyZtApwghYaRWdN8s4NN9sbcG125wnQMyJ8r5M/r4Vato5z1jy+mqtSfCpQKGs cORxbgC0qjrjhm0QnRYMKWn5utUJ773ztZL3IXi7ji/KoZSwAQMpzaX7QjGw1QV1E+Ukry2xhNh Vj+TWKYbWpVZoV3oaNaORwP3pQL2x+IGSEf+9JWkP4oc6HyOCgW9pHxhSG9Nmg== X-Google-Smtp-Source: AGHT+IGu88eBRybEnsZgPcHrjAlxoFTCJ0W9NxLeLN700ULZI4NP7fp5wZAQOeuXJJgQfk5WJy4Ytw== X-Received: by 2002:a17:90b:528a:b0:2ff:6e72:b8e2 with SMTP id 98e67ed59e1d1-300ff37051bmr4324135a91.31.1741698030344; Tue, 11 Mar 2025 06:00:30 -0700 (PDT) Received: from wheely.local0.net ([118.208.151.101]) by smtp.gmail.com with ESMTPSA id 98e67ed59e1d1-2ff4e773dddsm11822318a91.12.2025.03.11.06.00.28 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 11 Mar 2025 06:00:29 -0700 (PDT) From: Nicholas Piggin To: qemu-devel@nongnu.org Cc: Nicholas Piggin , qemu-ppc@nongnu.org, Chalapathi V Subject: [PULL 40/72] hw/ssi/pnv_spi: Put a limit to RDR match failures Date: Tue, 11 Mar 2025 22:57:34 +1000 Message-ID: <20250311125815.903177-41-npiggin@gmail.com> X-Mailer: git-send-email 2.47.1 In-Reply-To: <20250311125815.903177-1-npiggin@gmail.com> References: <20250311125815.903177-1-npiggin@gmail.com> MIME-Version: 1.0 Received-SPF: pass client-ip=2607:f8b0:4864:20::1032; envelope-from=npiggin@gmail.com; helo=mail-pj1-x1032.google.com X-Spam_score_int: -20 X-Spam_score: -2.1 X-Spam_bar: -- X-Spam_report: (-2.1 / 5.0 requ) BAYES_00=-1.9, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_AU=-0.1, DKIM_VALID_EF=-0.1, FREEMAIL_FROM=0.001, RCVD_IN_DNSWL_NONE=-0.0001, SPF_HELO_NONE=0.001, SPF_PASS=-0.001 autolearn=ham autolearn_force=no X-Spam_action: no action X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: qemu-devel-bounces+qemu-devel=archiver.kernel.org@nongnu.org Sender: qemu-devel-bounces+qemu-devel=archiver.kernel.org@nongnu.org From: Chalapathi V There is a possibility that SPI controller can get into loop due to indefinite RDR match failures. Hence put a limit to failures and stop the sequencer. Signed-off-by: Chalapathi V Reviewed-by: Nicholas Piggin Message-ID: <20250303141328.23991-5-chalapathi.v@linux.ibm.com> Signed-off-by: Nicholas Piggin --- hw/ssi/pnv_spi.c | 10 ++++++++++ include/hw/ssi/pnv_spi.h | 1 + 2 files changed, 11 insertions(+) diff --git a/hw/ssi/pnv_spi.c b/hw/ssi/pnv_spi.c index 83221607c9..126070393e 100644 --- a/hw/ssi/pnv_spi.c +++ b/hw/ssi/pnv_spi.c @@ -20,6 +20,7 @@ #define PNV_SPI_OPCODE_LO_NIBBLE(x) (x & 0x0F) #define PNV_SPI_MASKED_OPCODE(x) (x & 0xF0) #define PNV_SPI_FIFO_SIZE 16 +#define RDR_MATCH_FAILURE_LIMIT 16 /* * Macro from include/hw/ppc/fdt.h @@ -872,18 +873,27 @@ static void operation_sequencer(PnvSpi *s) rdr_matched = does_rdr_match(s); if (rdr_matched) { trace_pnv_spi_RDR_match("success"); + s->fail_count = 0; /* A match occurred, increment the sequencer index. */ seq_index++; s->status = SETFIELD(SPI_STS_SEQ_FSM, s->status, SEQ_STATE_INDEX_INCREMENT); } else { trace_pnv_spi_RDR_match("failed"); + s->fail_count++; /* * Branch the sequencer to the index coded into the op * code. */ seq_index = PNV_SPI_OPCODE_LO_NIBBLE(opcode); } + if (s->fail_count >= RDR_MATCH_FAILURE_LIMIT) { + qemu_log_mask(LOG_GUEST_ERROR, "pnv_spi: RDR match failure" + " limit crossed %d times hence requesting " + "sequencer to stop.\n", + RDR_MATCH_FAILURE_LIMIT); + stop = true; + } /* * Regardless of where the branch ended up we want the * sequencer to continue shifting so we have to clear diff --git a/include/hw/ssi/pnv_spi.h b/include/hw/ssi/pnv_spi.h index 6adb72dbb2..c591a0663d 100644 --- a/include/hw/ssi/pnv_spi.h +++ b/include/hw/ssi/pnv_spi.h @@ -40,6 +40,7 @@ typedef struct PnvSpi { MemoryRegion xscom_spic_regs; Fifo8 tx_fifo; Fifo8 rx_fifo; + uint8_t fail_count; /* RDR Match failure counter */ /* SPI object number */ uint32_t spic_num; uint32_t chip_id; From patchwork Tue Mar 11 12:57:35 2025 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: Nicholas Piggin X-Patchwork-Id: 14011892 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.lore.kernel.org (Postfix) with ESMTPS id B04B4C282EC for ; Tue, 11 Mar 2025 13:24:56 +0000 (UTC) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1trzKt-00028d-2L; Tue, 11 Mar 2025 09:07:55 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1trzDx-0004zv-Vd; Tue, 11 Mar 2025 09:00:50 -0400 Received: from mail-pj1-x1030.google.com ([2607:f8b0:4864:20::1030]) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_128_GCM_SHA256:128) (Exim 4.90_1) (envelope-from ) id 1trzDq-00006S-1t; Tue, 11 Mar 2025 09:00:44 -0400 Received: by mail-pj1-x1030.google.com with SMTP id 98e67ed59e1d1-2fef5c978ccso8070371a91.1; Tue, 11 Mar 2025 06:00:35 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20230601; t=1741698033; x=1742302833; darn=nongnu.org; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to; bh=tZ8e0vShkNtIuKOZGNzWODhsrmyTMS8jpNRn157CjZU=; b=VoLqJz/Cm7CDbXqFUPLqUOd7Q23puRPRbYBgZS3bnhPnXGlu17okWYc6sHRpCxf370 fAL12m1kg19v3Qb/hiLAHp/UoUNWihxxqVAbDO1Q4c+Ly5zrOaOXX1y3on72g4b2REzF aeo/Zm6Ix6Il8Iu7M7Ml238vRq4UIFDKuWGUUbEUQLu16HV2FYaUiMuZnmf85gIhMina pP8tGYcuB1+0MBpeYiUN2vjr49XkNs/2f4QRmHiHfdYFR8QCdJUUh/paYJ0XeOlcoUeo 6RRHHkX5tcV8GszxeYUKNSo9dp1FkNa283+VGFwE8UQbDTYhd+S03IU0F+x+EuqqhKu9 gvlA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1741698033; x=1742302833; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=tZ8e0vShkNtIuKOZGNzWODhsrmyTMS8jpNRn157CjZU=; b=IGobXPt7zBWFIWjmjd/5Ppc2xWWeG35UoIiqqAPJCNQiplyCAmRyiIrr11rDavEG70 wI+DoPOOiFDJUnxz8BdcQe1hqQK5ioce4nB5qPUeZYh3nfwND9lFAiOW5lu/ULodUFgO fSeCzGqJwnsc7Q9lAwOOstAm9cQXdYoJx6Dpm7Cby/gbTJpj3vX38Lf7QUY5fxIgVtIB kDYnwyFj+Xw3g27rp4D+PogV3PK4M+WTlBh3FY3tdTDy+9Nlr/Axi2CHC9dp+eWL+ZrR h2ejGVr+mL4tpdiHjbSJt5996CZvrHxE+nVUzq0yyJlybBbnt/tA6hrQTdU2O6eYLPg+ 5Vpg== X-Forwarded-Encrypted: i=1; AJvYcCW2UyOnIbtQKHA3pIJ3CuWJXPmCwmqVFQRejh/eOvhz3K4VN73ffKDVZ/KP7lyavP/o6kKDu75+7g==@nongnu.org X-Gm-Message-State: AOJu0YwyZUmdJMzOS59G6Vnyiyi/bNj/Kv5OKwmNwo6A+Wfcv2Gywgp8 rgtIaefELMtdMHCNkc4TNtd4K0wRw6Hqq2+y+exLYLF8+n4+mE3/3f3ROw== X-Gm-Gg: ASbGncsl/9S2vqMu3mqcnmgr6VssuP0wYfuBtsyzd8QfWdfORq9IUERBLuOAsQ9nelv X3d2j6Y5h4nJs/7EzkKzLWi3TNLqyGKcBO1LMf/SJsL3p/LRF5vcEkggElh8iQ/Fm2ZhOLH3XPh +/GCUmx12fWHp/L5fbo0Gqv7CH1xmDggH55WhMyuQvJPoQOX20gmtw12aQxFNHxKOIailqeDfKd xE/xv0pU/PGTqv5RpZvSR07Mm2eRQYiBTRl1d9T7Siu1P6YGhlJiyehOA2aZ/sIKvhFgBlXlNv6 J+AmXMMgRdZl3ZrCJwi8pi8z547HbU+g2g6PKryg2JkVTW6+vwY= X-Google-Smtp-Source: AGHT+IEqcXWS1kF+UEBbIJscupE6OMlrGspwIhQqxXseanccg+qVgpTrd8f9LikehZQg7pqTgEV6/Q== X-Received: by 2002:a17:90a:e7c2:b0:2ff:693a:758d with SMTP id 98e67ed59e1d1-2ff7ceef0famr25700066a91.27.1741698033020; Tue, 11 Mar 2025 06:00:33 -0700 (PDT) Received: from wheely.local0.net ([118.208.151.101]) by smtp.gmail.com with ESMTPSA id 98e67ed59e1d1-2ff4e773dddsm11822318a91.12.2025.03.11.06.00.30 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 11 Mar 2025 06:00:32 -0700 (PDT) From: Nicholas Piggin To: qemu-devel@nongnu.org Cc: Nicholas Piggin , qemu-ppc@nongnu.org, =?utf-8?q?Phil?= =?utf-8?q?ippe_Mathieu-Daud=C3=A9?= Subject: [PULL 41/72] hw/ppc/spapr: Restrict CONFER hypercall to TCG Date: Tue, 11 Mar 2025 22:57:35 +1000 Message-ID: <20250311125815.903177-42-npiggin@gmail.com> X-Mailer: git-send-email 2.47.1 In-Reply-To: <20250311125815.903177-1-npiggin@gmail.com> References: <20250311125815.903177-1-npiggin@gmail.com> MIME-Version: 1.0 Received-SPF: pass client-ip=2607:f8b0:4864:20::1030; envelope-from=npiggin@gmail.com; helo=mail-pj1-x1030.google.com X-Spam_score_int: -20 X-Spam_score: -2.1 X-Spam_bar: -- X-Spam_report: (-2.1 / 5.0 requ) BAYES_00=-1.9, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_AU=-0.1, DKIM_VALID_EF=-0.1, FREEMAIL_FROM=0.001, RCVD_IN_DNSWL_NONE=-0.0001, SPF_HELO_NONE=0.001, SPF_PASS=-0.001 autolearn=ham autolearn_force=no X-Spam_action: no action X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: qemu-devel-bounces+qemu-devel=archiver.kernel.org@nongnu.org Sender: qemu-devel-bounces+qemu-devel=archiver.kernel.org@nongnu.org From: Philippe Mathieu-Daudé KVM handles H_CONFER and does not pass it along to QEMU, so only vhyp (as used by TCG spapr) needs to handle it. [npiggin: Add changelog] Signed-off-by: Philippe Mathieu-Daudé Message-ID: <20250127102620.39159-2-philmd@linaro.org> Signed-off-by: Nicholas Piggin --- hw/ppc/spapr_hcall.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/hw/ppc/spapr_hcall.c b/hw/ppc/spapr_hcall.c index f987ff323f..4f1933b8da 100644 --- a/hw/ppc/spapr_hcall.c +++ b/hw/ppc/spapr_hcall.c @@ -580,6 +580,8 @@ static target_ulong h_confer(PowerPCCPU *cpu, SpaprMachineState *spapr, CPUState *cs = CPU(cpu); SpaprCpuState *spapr_cpu; + assert(tcg_enabled()); /* KVM will have handled this */ + /* * -1 means confer to all other CPUs without dispatch counter check, * otherwise it's a targeted confer. From patchwork Tue Mar 11 12:57:36 2025 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Nicholas Piggin X-Patchwork-Id: 14011810 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.lore.kernel.org (Postfix) with ESMTPS id 0D440C282EC for ; Tue, 11 Mar 2025 13:06:41 +0000 (UTC) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1trzJ0-0003SI-4c; Tue, 11 Mar 2025 09:05:58 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1trzDw-0004zj-2t; Tue, 11 Mar 2025 09:00:49 -0400 Received: from mail-pl1-x633.google.com ([2607:f8b0:4864:20::633]) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_128_GCM_SHA256:128) (Exim 4.90_1) (envelope-from ) id 1trzDs-00006w-EF; Tue, 11 Mar 2025 09:00:43 -0400 Received: by mail-pl1-x633.google.com with SMTP id d9443c01a7336-223959039f4so107093655ad.3; Tue, 11 Mar 2025 06:00:37 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20230601; t=1741698036; x=1742302836; darn=nongnu.org; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to; bh=0SOjOhB33VcprDEO41KFUFk52SOqUV2z89oKt7zJj2k=; b=KMr1duMRe3iB4aMaisXIuLVJodxxkZWcf1mteaP9BR2aANi8AF84JXqAfCJ3gZYyta oLBHKZ8TarBOiS+ld9q75mhNGHj9xf/pEL6BACZHCYHbNMtz1FjDjehd+R7do38xtubG BqovjpnSvBZzz54jZytSAY69+PRYSZARsTZxEiVdI/KRzLomG02fLEGV29q/Jot2rBFf LsXc1lrdIPoTakZx+L1LObRHUuNCY9MiyU+so/UUgTtmI9LDNEJ4RpMgyfb92cskRcOC ii0zOtBHbAKXZoY7WFk3yI9YMpillTbnmTrNtL5aygycA1V30wHHP7FW+/4KQkShB5/o LSfg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1741698036; x=1742302836; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=0SOjOhB33VcprDEO41KFUFk52SOqUV2z89oKt7zJj2k=; b=WZkxyca8GRCJwRuSfqFfMGUT2B4YkCPrcjWgpIYBp3/odEcOlPRNsrpDkDjuXxCXJD zpNU3AB88OqGfgSnWFH8AnihYLW+ZWPRlWPevbnwXfR9b4//azzwKY9pIB1y2Kkt6YoA GpHnCNPNbdmoRrTl3Qe3GZVdrXCF9QLc4P2VfK8ynxx4Pcny0596MQfH7Vx/Wcgrd9kw AFg6HoM5OzYZ8g4BzIBx+yc+VWX2LIm9RHtRMvP1YrHK3M3avXO2PvUfPnnT/3GANRFe Uak16ty4Lh0vcGTtyPg2gT13azzjSdxuBlIJoQfQmIM043Uh7i6WsPR0P94R3zy1oBDv BDEw== X-Forwarded-Encrypted: i=1; AJvYcCWEruztmpkhvsiWJnToFsbixJ8MFve91/eazdav/2iqG4ZBkAfrrkoNIC6/2BuNAZF386xAIU2u9A==@nongnu.org X-Gm-Message-State: AOJu0YwM1J+KnEQa0oFoWvuX5J1M8FIJZ1NyAa9qHELrGit4FUpudQAO x8q0SKCWW+jW5zzf4Fx4S7uxsGT/n2BcED8XfaN9whGKLuvVGJHY9Zz10Q== X-Gm-Gg: ASbGnctxRGV5KRQ/bmT1W09sLecOlvQ0vMS9tBn9zzprWqGhe5Bv86Q+jMOEM9IeSdj kEOWeoaTVBKS5W/EBMiDVqdJXMhK0ujdAWZIHoJ/3HIy9lmTTEIWRbUUxKjWI8j5UPum7ZdFENQ W+O6dNjQX3Cm1M4myBvmUYMN4PVorJcpsZYw3Dl3uqRqPw+o3EjWy+vustbMBsvTmIDaCaIx54R VvHpwOvwmMIVqaXsB36gblQtzSlsKgTPGdhmiIG7QlHygzFl1JSdQD/VnJvgnu6vWac0v/kFTYx G9dGi3uxclcXX1qvCkCPM1fyeGmsfhzxWGui03pKuoHmWQ+v0Ts= X-Google-Smtp-Source: AGHT+IHEqSmL9HA6QPp39OII2HSFm1GvK8H36w04DYL7MNdIUNL8CqudgVl32QZt22hc/hIM1yxeNg== X-Received: by 2002:a17:902:fc47:b0:223:5a6e:b20 with SMTP id d9443c01a7336-2242887eb29mr245014615ad.7.1741698035735; Tue, 11 Mar 2025 06:00:35 -0700 (PDT) Received: from wheely.local0.net ([118.208.151.101]) by smtp.gmail.com with ESMTPSA id 98e67ed59e1d1-2ff4e773dddsm11822318a91.12.2025.03.11.06.00.33 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 11 Mar 2025 06:00:35 -0700 (PDT) From: Nicholas Piggin To: qemu-devel@nongnu.org Cc: Nicholas Piggin , qemu-ppc@nongnu.org, dan tan Subject: [PULL 42/72] ppc/pnv: Add new PowerPC Special Purpose Registers (RWMR) Date: Tue, 11 Mar 2025 22:57:36 +1000 Message-ID: <20250311125815.903177-43-npiggin@gmail.com> X-Mailer: git-send-email 2.47.1 In-Reply-To: <20250311125815.903177-1-npiggin@gmail.com> References: <20250311125815.903177-1-npiggin@gmail.com> MIME-Version: 1.0 Received-SPF: pass client-ip=2607:f8b0:4864:20::633; envelope-from=npiggin@gmail.com; helo=mail-pl1-x633.google.com X-Spam_score_int: -20 X-Spam_score: -2.1 X-Spam_bar: -- X-Spam_report: (-2.1 / 5.0 requ) BAYES_00=-1.9, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_AU=-0.1, DKIM_VALID_EF=-0.1, FREEMAIL_FROM=0.001, RCVD_IN_DNSWL_NONE=-0.0001, SPF_HELO_NONE=0.001, SPF_PASS=-0.001 autolearn=ham autolearn_force=no X-Spam_action: no action X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: qemu-devel-bounces+qemu-devel=archiver.kernel.org@nongnu.org Sender: qemu-devel-bounces+qemu-devel=archiver.kernel.org@nongnu.org From: dan tan Register RWMR - Region Weighted Mode Register for privileged access in Power9 and Power10 It controls what the SPURR register produces. Specs: - Power10: https://files.openpower.foundation/s/EgCy7C43p2NSRfR TCG does not model SMT priority, timing, resource controls and status so this register has no effect for now. [npiggin: adjust changelog] Signed-off-by: dan tan Message-ID: <20250116154226.13376-1-dantan@linux.vnet.ibm.com> Signed-off-by: Nicholas Piggin --- target/ppc/cpu.h | 1 + target/ppc/cpu_init.c | 5 +++++ 2 files changed, 6 insertions(+) diff --git a/target/ppc/cpu.h b/target/ppc/cpu.h index 682583d1d1..25b1e6d6b0 100644 --- a/target/ppc/cpu.h +++ b/target/ppc/cpu.h @@ -2102,6 +2102,7 @@ void ppc_compat_add_property(Object *obj, const char *name, #define SPR_PMCR (0x374) #define SPR_440_ITV0 (0x374) #define SPR_440_ITV1 (0x375) +#define SPR_RWMR (0x375) #define SPR_440_ITV2 (0x376) #define SPR_440_ITV3 (0x377) #define SPR_440_CCR1 (0x378) diff --git a/target/ppc/cpu_init.c b/target/ppc/cpu_init.c index 54035c7bbb..8d73e11540 100644 --- a/target/ppc/cpu_init.c +++ b/target/ppc/cpu_init.c @@ -5773,6 +5773,11 @@ static void register_power9_book4_sprs(CPUPPCState *env) SPR_NOACCESS, SPR_NOACCESS, &spr_read_generic, &spr_write_generic, KVM_REG_PPC_WORT, 0); + spr_register_hv(env, SPR_RWMR, "RWMR", + SPR_NOACCESS, SPR_NOACCESS, + &spr_read_generic, &spr_write_generic, + &spr_read_generic, &spr_write_generic, + 0x00000000); #endif } From patchwork Tue Mar 11 12:57:37 2025 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: Nicholas Piggin X-Patchwork-Id: 14011886 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.lore.kernel.org (Postfix) with ESMTPS id 21CEEC28B2E for ; Tue, 11 Mar 2025 13:23:36 +0000 (UTC) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1trzJK-00045t-Qf; Tue, 11 Mar 2025 09:06:19 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1trzDw-0004zk-O4; Tue, 11 Mar 2025 09:00:49 -0400 Received: from mail-pj1-x1035.google.com ([2607:f8b0:4864:20::1035]) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_128_GCM_SHA256:128) (Exim 4.90_1) (envelope-from ) id 1trzDt-00007a-Hp; Tue, 11 Mar 2025 09:00:44 -0400 Received: by mail-pj1-x1035.google.com with SMTP id 98e67ed59e1d1-2ff6e91cff5so7759815a91.2; Tue, 11 Mar 2025 06:00:40 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20230601; t=1741698039; x=1742302839; darn=nongnu.org; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to; bh=ef5JtUmQjY3eZoVQLsqqxOztpN+e+XJ12V25TE9Pgi8=; b=R5K31FYExGIIdHSgoQ1uFjhDjRnvBSsRdZWjyWL3RtyBIraPc8a8igtKfRyLo6vxkE R7KURS+/OjPnkYOkfowOuYUJ36gaXbBs0P2R0MDDXFhF807gv/Echi0vm3+dXWa8DXhL CWZ4L1K9OE5SAQ8fA4dHRVIRD2zu6sNWntWIqjWhyeXIA1BxwXGs7HQojM4alYN0sEj7 b2+rI/OskHBZ5xIhTz8EOyE1sjju5WWci78Vxm/S2RuSuRQzn3Zv2bY9ui/rB8Snifr3 hE5le4TIT/rXpVeROnIN7Zh286GRzuIrWiQv9/p5XyE0dVwkiD/zzNI6PBALjRqpV8nY dliQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1741698039; x=1742302839; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=ef5JtUmQjY3eZoVQLsqqxOztpN+e+XJ12V25TE9Pgi8=; b=snMy09y3gGb36B8cwi4YctyiZTs47mh24e8m/6MGFEsgG+oVmSrah8h0ueT8dBr2Jw TM8DvWo3UuB5uwSNFwBanj1f/D993ONmDoiYXbQL+t4hfLWsqvgOnsxw1lvz6lX2T419 boebcCi7OGHkAJme45NqVOzRjcC5QemCKkuLUYflafubD6VK/npdrtBYjqWuW+zwjtH2 9XwkBuHZ5ej+Eocsp2fSnbEEU7nRLYa+ft+1VlKUcS86Xl1sOh03tRmRDMNOfxJA/u/Q y9TXmeHiJaem2l884PQ9tJ1P7nItDqHVJwHqAJ9WlKfV9vBWeFgQjHj/6YmKxiMBb3hE Mi5w== X-Forwarded-Encrypted: i=1; AJvYcCURu+umiYqh3qsAl5OugzxgVmvoXRZOS73X55rvPTZadXKCvWwSfs2qDPPam43J79F5dPuQ4sJp9A==@nongnu.org X-Gm-Message-State: AOJu0Yw3MCPysFSy7i4CuGvWjkitcGO9XXXfbXZslOe4R+OAO2CALAr1 Zh257XgEVy9LrzK5Lu6XpHFSbfCGYp5SI2wpFdjPykVyW90Yzz1DzLRntQ== X-Gm-Gg: ASbGncu+TLF7Z1Kw7YJw1p6eNmyeCTe2rr9qDlXpDDM2uHG9n3MBH8bzrym3jZEVK8i OEbPHSv4Hc8qouDd6pUsP12OxCtl4mJJEaq9ywDT4312wWkpNy1KZ7JJV+/X4i51OEs0K1SxSC2 +a6DDIr/KjfzyTXjpSeGF+8TZoK0ITSfBreDEzERM2qFFtfKNU/mSK13efEGaQ8X+ajg1BruWru H9RCH0TILPPn8xseXhbenb+bBb5z1QY/xUgGBbbK+0fejUWOUBC+QnHG60ijxTy4S5PZIf5ZBxi RuibenwzPcwanB/DM2w3U3Vfl/BAitxdePuXxWcwk/lB6oe4wZQ= X-Google-Smtp-Source: AGHT+IH45hJAsbcuERTowHkzKWunADMl6tTLtwrJOii8wJU6Mh69BxSiogcqltCklb7uCL7iO4fkxw== X-Received: by 2002:a17:90a:ec87:b0:2fe:dd2c:f8e7 with SMTP id 98e67ed59e1d1-2ff7ce8fa48mr26297537a91.10.1741698038779; Tue, 11 Mar 2025 06:00:38 -0700 (PDT) Received: from wheely.local0.net ([118.208.151.101]) by smtp.gmail.com with ESMTPSA id 98e67ed59e1d1-2ff4e773dddsm11822318a91.12.2025.03.11.06.00.36 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 11 Mar 2025 06:00:38 -0700 (PDT) From: Nicholas Piggin To: qemu-devel@nongnu.org Cc: Nicholas Piggin , qemu-ppc@nongnu.org, =?utf-8?q?Phil?= =?utf-8?q?ippe_Mathieu-Daud=C3=A9?= , Harsh Prateek Bora Subject: [PULL 43/72] target/ppc: Make ppc_ldl_code() declaration public Date: Tue, 11 Mar 2025 22:57:37 +1000 Message-ID: <20250311125815.903177-44-npiggin@gmail.com> X-Mailer: git-send-email 2.47.1 In-Reply-To: <20250311125815.903177-1-npiggin@gmail.com> References: <20250311125815.903177-1-npiggin@gmail.com> MIME-Version: 1.0 Received-SPF: pass client-ip=2607:f8b0:4864:20::1035; envelope-from=npiggin@gmail.com; helo=mail-pj1-x1035.google.com X-Spam_score_int: -20 X-Spam_score: -2.1 X-Spam_bar: -- X-Spam_report: (-2.1 / 5.0 requ) BAYES_00=-1.9, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_AU=-0.1, DKIM_VALID_EF=-0.1, FREEMAIL_FROM=0.001, RCVD_IN_DNSWL_NONE=-0.0001, SPF_HELO_NONE=0.001, SPF_PASS=-0.001 autolearn=ham autolearn_force=no X-Spam_action: no action X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: qemu-devel-bounces+qemu-devel=archiver.kernel.org@nongnu.org Sender: qemu-devel-bounces+qemu-devel=archiver.kernel.org@nongnu.org From: Philippe Mathieu-Daudé We are going to move code calling ppc_ldl_code() out of excp_helper.c where it is defined. Expose its declaration for few commits, until eventually making it static again once everything is moved. Signed-off-by: Philippe Mathieu-Daudé Reviewed-by: Harsh Prateek Bora Message-ID: <20250127102620.39159-4-philmd@linaro.org> Signed-off-by: Nicholas Piggin --- target/ppc/excp_helper.c | 2 +- target/ppc/internal.h | 2 ++ 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/target/ppc/excp_helper.c b/target/ppc/excp_helper.c index fde9912230..7ed4bbec03 100644 --- a/target/ppc/excp_helper.c +++ b/target/ppc/excp_helper.c @@ -144,7 +144,7 @@ static inline bool insn_need_byteswap(CPUArchState *env) return !!(env->msr & ((target_ulong)1 << MSR_LE)); } -static uint32_t ppc_ldl_code(CPUArchState *env, target_ulong addr) +uint32_t ppc_ldl_code(CPUArchState *env, target_ulong addr) { uint32_t insn = cpu_ldl_code(env, addr); diff --git a/target/ppc/internal.h b/target/ppc/internal.h index 20fb2ec593..46db6adfcf 100644 --- a/target/ppc/internal.h +++ b/target/ppc/internal.h @@ -268,6 +268,8 @@ static inline void pte_invalidate(target_ulong *pte0) #define PTE_PTEM_MASK 0x7FFFFFBF #define PTE_CHECK_MASK (TARGET_PAGE_MASK | 0x7B) +uint32_t ppc_ldl_code(CPUArchState *env, target_ulong addr); + #ifdef CONFIG_USER_ONLY void ppc_cpu_record_sigsegv(CPUState *cs, vaddr addr, MMUAccessType access_type, From patchwork Tue Mar 11 12:57:38 2025 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: Nicholas Piggin X-Patchwork-Id: 14011891 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.lore.kernel.org (Postfix) with ESMTPS id 67138C282EC for ; Tue, 11 Mar 2025 13:24:51 +0000 (UTC) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1trzG2-0007lU-6r; Tue, 11 Mar 2025 09:02:58 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1trzE1-00051Z-OM; Tue, 11 Mar 2025 09:00:51 -0400 Received: from mail-pj1-x1036.google.com ([2607:f8b0:4864:20::1036]) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_128_GCM_SHA256:128) (Exim 4.90_1) (envelope-from ) id 1trzDw-00008I-CB; Tue, 11 Mar 2025 09:00:49 -0400 Received: by mail-pj1-x1036.google.com with SMTP id 98e67ed59e1d1-2fecba90cc3so10439391a91.2; Tue, 11 Mar 2025 06:00:43 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20230601; t=1741698042; x=1742302842; darn=nongnu.org; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to; bh=REbqXCfa8pgvPbVQj8PRaR6rcvUlPevWe8sa0CWfROg=; b=Rq4+J3WxtIk/Pxbh8GjHnUb0rotO7F5rQ/hRuDMRKfXDvwKgDid3bafvcx4EkuV37P rJUf58uNEYrmzWJrvSG0QPSxg9reSmuZH1n8BfHdvaGvYSDVx5iPOAMatnjFBG/H8ioK 0vIiFjcqhq49+4Ia6J8APi26x/x6caqw44Zh4lM8ID8NPcbmFUB01h/FoeoZDiDecnlF PVpA1geBsIh1QYWd7LbJHmdBtfTgeiQweXJduIfj5oK7zzGstxTlurjnQRsEAfCbpMCz xIlRHrE1ZD7+Emf6wVOzZiVIWkm2MNd8NdmFdSq3H2oatFOouKrGEHt0TE2/9SxAdF7a v6QQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1741698042; x=1742302842; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=REbqXCfa8pgvPbVQj8PRaR6rcvUlPevWe8sa0CWfROg=; b=f+ioq74YE8d0SJ9tinrQ9Vj/iwuppYO5GnG16jv/hELYTCZL/7PXqUmvgemiI1L28L heDQjvcm7OqhxG+d1Lz2VGQafXTafL57wTy8pGsluCnPBMndMuP55ckYvqQnb5ACvIRr UgiiOYSOrmV/oy3gokTyzH+eXZrp//XPyA0RMGdkaxYrIMOqhMMx3ZzpHm77G44wZL6f 9T3wF73V79KfaOg8u1gOV3annIs3bRr4xE8A21nufDMT752epf5e1OeC+Esd/90QhHWk dc1z35+aQuMdRzLK36WN5eYN1s4Z8UJzoKJz0iQP9QOLO6e1mkvDa9YZf/D2docTl41O IOrQ== X-Forwarded-Encrypted: i=1; AJvYcCXS8jckMR1M4XwfDmMZkT1fbSUShQavkca5BO1aq6l5Xlsczr+VJXxPmD6YAbuI1DkzPQX8XBYutQ==@nongnu.org X-Gm-Message-State: AOJu0YzZLcKbxgdKdJO1yFnALQiHadoiIFFCR8vsSYkDjl3riLa4JOPu 1CB//EukC+cBqksXQMDaldK5NcqGZ4zVXm8qOlbG/goP6NEt0i8oHgKqPQ== X-Gm-Gg: ASbGncuY0vpT1EUz1p1xO/ca9HGFXJ93F5iPr4nmFOWSWz5RBkvAyCb4ORsnQER7ZfH uFRVPKLkDLktYd6+MIsenrsUU8ZuTejUyxhMfAEPqIGSr0GFT1yJmSAHkazjJB4L5D0/urOwFhg Q2wOBTBvnk6KuXQR4XgViTXhO14neLWO5QCVFZMqGzZodrxdqBw6JP99vCWwYT1yaSIAnSxuOtf QFfhS2y5Rpw3EofPEvOTc0JJy75RGhV/hMtp0+j0sRjBKDQ2MW0Wwni2rv7EcpPf8eCPdESDlIj gjC8w7c0vruM4SC+dhy5jzcd+tBeOuFMzeIj+QXQecvta4jYR1g= X-Google-Smtp-Source: AGHT+IFe4gxagE/tvsGdhOBDbnrU7b1D6VEvAbxeb6U5V91Du+JBsNh86syAphhju8NEfWrAsmwL2A== X-Received: by 2002:a17:90b:3b52:b0:2f8:49ad:4079 with SMTP id 98e67ed59e1d1-2ff7ce451e3mr25660168a91.6.1741698041806; Tue, 11 Mar 2025 06:00:41 -0700 (PDT) Received: from wheely.local0.net ([118.208.151.101]) by smtp.gmail.com with ESMTPSA id 98e67ed59e1d1-2ff4e773dddsm11822318a91.12.2025.03.11.06.00.39 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 11 Mar 2025 06:00:41 -0700 (PDT) From: Nicholas Piggin To: qemu-devel@nongnu.org Cc: Nicholas Piggin , qemu-ppc@nongnu.org, =?utf-8?q?Phil?= =?utf-8?q?ippe_Mathieu-Daud=C3=A9?= , Harsh Prateek Bora Subject: [PULL 44/72] target/ppc: Move TCG specific exception handlers to tcg-excp_helper.c Date: Tue, 11 Mar 2025 22:57:38 +1000 Message-ID: <20250311125815.903177-45-npiggin@gmail.com> X-Mailer: git-send-email 2.47.1 In-Reply-To: <20250311125815.903177-1-npiggin@gmail.com> References: <20250311125815.903177-1-npiggin@gmail.com> MIME-Version: 1.0 Received-SPF: pass client-ip=2607:f8b0:4864:20::1036; envelope-from=npiggin@gmail.com; helo=mail-pj1-x1036.google.com X-Spam_score_int: -20 X-Spam_score: -2.1 X-Spam_bar: -- X-Spam_report: (-2.1 / 5.0 requ) BAYES_00=-1.9, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_AU=-0.1, DKIM_VALID_EF=-0.1, FREEMAIL_FROM=0.001, RCVD_IN_DNSWL_NONE=-0.0001, SPF_HELO_NONE=0.001, SPF_PASS=-0.001 autolearn=ham autolearn_force=no X-Spam_action: no action X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: qemu-devel-bounces+qemu-devel=archiver.kernel.org@nongnu.org Sender: qemu-devel-bounces+qemu-devel=archiver.kernel.org@nongnu.org From: Philippe Mathieu-Daudé Move the TCGCPUOps handlers to a new unit: tcg-excp_helper.c, only built when TCG is selected. See in target/ppc/cpu_init.c: #ifdef CONFIG_TCG static const TCGCPUOps ppc_tcg_ops = { ... .do_unaligned_access = ppc_cpu_do_unaligned_access, .do_transaction_failed = ppc_cpu_do_transaction_failed, .debug_excp_handler = ppc_cpu_debug_excp_handler, .debug_check_breakpoint = ppc_cpu_debug_check_breakpoint, .debug_check_watchpoint = ppc_cpu_debug_check_watchpoint, }; #endif /* CONFIG_TCG */ Signed-off-by: Philippe Mathieu-Daudé Reviewed-by: Harsh Prateek Bora Message-ID: <20250127102620.39159-5-philmd@linaro.org> Signed-off-by: Nicholas Piggin --- target/ppc/excp_helper.c | 173 ------------------------------ target/ppc/meson.build | 1 + target/ppc/tcg-excp_helper.c | 202 +++++++++++++++++++++++++++++++++++ 3 files changed, 203 insertions(+), 173 deletions(-) create mode 100644 target/ppc/tcg-excp_helper.c diff --git a/target/ppc/excp_helper.c b/target/ppc/excp_helper.c index 7ed4bbec03..b05eb7f5ae 100644 --- a/target/ppc/excp_helper.c +++ b/target/ppc/excp_helper.c @@ -3144,178 +3144,5 @@ void helper_book3s_trace(CPUPPCState *env, target_ulong prev_ip) raise_exception_err(env, POWERPC_EXCP_TRACE, error_code); } -void ppc_cpu_do_unaligned_access(CPUState *cs, vaddr vaddr, - MMUAccessType access_type, - int mmu_idx, uintptr_t retaddr) -{ - CPUPPCState *env = cpu_env(cs); - uint32_t insn; - - /* Restore state and reload the insn we executed, for filling in DSISR. */ - cpu_restore_state(cs, retaddr); - insn = ppc_ldl_code(env, env->nip); - - switch (env->mmu_model) { - case POWERPC_MMU_SOFT_4xx: - env->spr[SPR_40x_DEAR] = vaddr; - break; - case POWERPC_MMU_BOOKE: - case POWERPC_MMU_BOOKE206: - env->spr[SPR_BOOKE_DEAR] = vaddr; - break; - default: - env->spr[SPR_DAR] = vaddr; - break; - } - - cs->exception_index = POWERPC_EXCP_ALIGN; - env->error_code = insn & 0x03FF0000; - cpu_loop_exit(cs); -} - -void ppc_cpu_do_transaction_failed(CPUState *cs, hwaddr physaddr, - vaddr vaddr, unsigned size, - MMUAccessType access_type, - int mmu_idx, MemTxAttrs attrs, - MemTxResult response, uintptr_t retaddr) -{ - CPUPPCState *env = cpu_env(cs); - - switch (env->excp_model) { -#if defined(TARGET_PPC64) - case POWERPC_EXCP_POWER8: - case POWERPC_EXCP_POWER9: - case POWERPC_EXCP_POWER10: - case POWERPC_EXCP_POWER11: - /* - * Machine check codes can be found in processor User Manual or - * Linux or skiboot source. - */ - if (access_type == MMU_DATA_LOAD) { - env->spr[SPR_DAR] = vaddr; - env->spr[SPR_DSISR] = PPC_BIT(57); - env->error_code = PPC_BIT(42); - - } else if (access_type == MMU_DATA_STORE) { - /* - * MCE for stores in POWER is asynchronous so hardware does - * not set DAR, but QEMU can do better. - */ - env->spr[SPR_DAR] = vaddr; - env->error_code = PPC_BIT(36) | PPC_BIT(43) | PPC_BIT(45); - env->error_code |= PPC_BIT(42); - - } else { /* Fetch */ - /* - * is_prefix_insn_excp() tests !PPC_BIT(42) to avoid fetching - * the instruction, so that must always be clear for fetches. - */ - env->error_code = PPC_BIT(36) | PPC_BIT(44) | PPC_BIT(45); - } - break; -#endif - default: - /* - * TODO: Check behaviour for other CPUs, for now do nothing. - * Could add a basic MCE even if real hardware ignores. - */ - return; - } - - cs->exception_index = POWERPC_EXCP_MCHECK; - cpu_loop_exit_restore(cs, retaddr); -} - -void ppc_cpu_debug_excp_handler(CPUState *cs) -{ -#if defined(TARGET_PPC64) - CPUPPCState *env = cpu_env(cs); - - if (env->insns_flags2 & PPC2_ISA207S) { - if (cs->watchpoint_hit) { - if (cs->watchpoint_hit->flags & BP_CPU) { - env->spr[SPR_DAR] = cs->watchpoint_hit->hitaddr; - env->spr[SPR_DSISR] = PPC_BIT(41); - cs->watchpoint_hit = NULL; - raise_exception(env, POWERPC_EXCP_DSI); - } - cs->watchpoint_hit = NULL; - } else if (cpu_breakpoint_test(cs, env->nip, BP_CPU)) { - raise_exception_err(env, POWERPC_EXCP_TRACE, - PPC_BIT(33) | PPC_BIT(43)); - } - } -#endif -} - -bool ppc_cpu_debug_check_breakpoint(CPUState *cs) -{ -#if defined(TARGET_PPC64) - CPUPPCState *env = cpu_env(cs); - - if (env->insns_flags2 & PPC2_ISA207S) { - target_ulong priv; - - priv = env->spr[SPR_CIABR] & PPC_BITMASK(62, 63); - switch (priv) { - case 0x1: /* problem */ - return env->msr & ((target_ulong)1 << MSR_PR); - case 0x2: /* supervisor */ - return (!(env->msr & ((target_ulong)1 << MSR_PR)) && - !(env->msr & ((target_ulong)1 << MSR_HV))); - case 0x3: /* hypervisor */ - return (!(env->msr & ((target_ulong)1 << MSR_PR)) && - (env->msr & ((target_ulong)1 << MSR_HV))); - default: - g_assert_not_reached(); - } - } -#endif - - return false; -} - -bool ppc_cpu_debug_check_watchpoint(CPUState *cs, CPUWatchpoint *wp) -{ -#if defined(TARGET_PPC64) - CPUPPCState *env = cpu_env(cs); - - if (env->insns_flags2 & PPC2_ISA207S) { - if (wp == env->dawr0_watchpoint) { - uint32_t dawrx = env->spr[SPR_DAWRX0]; - bool wt = extract32(dawrx, PPC_BIT_NR(59), 1); - bool wti = extract32(dawrx, PPC_BIT_NR(60), 1); - bool hv = extract32(dawrx, PPC_BIT_NR(61), 1); - bool sv = extract32(dawrx, PPC_BIT_NR(62), 1); - bool pr = extract32(dawrx, PPC_BIT_NR(62), 1); - - if ((env->msr & ((target_ulong)1 << MSR_PR)) && !pr) { - return false; - } else if ((env->msr & ((target_ulong)1 << MSR_HV)) && !hv) { - return false; - } else if (!sv) { - return false; - } - - if (!wti) { - if (env->msr & ((target_ulong)1 << MSR_DR)) { - if (!wt) { - return false; - } - } else { - if (wt) { - return false; - } - } - } - - return true; - } - } -#endif - - return false; -} - #endif /* !CONFIG_USER_ONLY */ #endif /* CONFIG_TCG */ diff --git a/target/ppc/meson.build b/target/ppc/meson.build index db3b7a0c33..8eed1fa40c 100644 --- a/target/ppc/meson.build +++ b/target/ppc/meson.build @@ -14,6 +14,7 @@ ppc_ss.add(when: 'CONFIG_TCG', if_true: files( 'int_helper.c', 'mem_helper.c', 'misc_helper.c', + 'tcg-excp_helper.c', 'timebase_helper.c', 'translate.c', 'power8-pmu.c', diff --git a/target/ppc/tcg-excp_helper.c b/target/ppc/tcg-excp_helper.c new file mode 100644 index 0000000000..3402dbe05e --- /dev/null +++ b/target/ppc/tcg-excp_helper.c @@ -0,0 +1,202 @@ +/* + * PowerPC exception emulation helpers for QEMU (TCG specific) + * + * 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 "exec/cpu_ldst.h" + +#include "hw/ppc/ppc.h" +#include "internal.h" +#include "cpu.h" +#include "trace.h" + +#ifndef CONFIG_USER_ONLY + +void ppc_cpu_do_unaligned_access(CPUState *cs, vaddr vaddr, + MMUAccessType access_type, + int mmu_idx, uintptr_t retaddr) +{ + CPUPPCState *env = cpu_env(cs); + uint32_t insn; + + /* Restore state and reload the insn we executed, for filling in DSISR. */ + cpu_restore_state(cs, retaddr); + insn = ppc_ldl_code(env, env->nip); + + switch (env->mmu_model) { + case POWERPC_MMU_SOFT_4xx: + env->spr[SPR_40x_DEAR] = vaddr; + break; + case POWERPC_MMU_BOOKE: + case POWERPC_MMU_BOOKE206: + env->spr[SPR_BOOKE_DEAR] = vaddr; + break; + default: + env->spr[SPR_DAR] = vaddr; + break; + } + + cs->exception_index = POWERPC_EXCP_ALIGN; + env->error_code = insn & 0x03FF0000; + cpu_loop_exit(cs); +} + +void ppc_cpu_do_transaction_failed(CPUState *cs, hwaddr physaddr, + vaddr vaddr, unsigned size, + MMUAccessType access_type, + int mmu_idx, MemTxAttrs attrs, + MemTxResult response, uintptr_t retaddr) +{ + CPUPPCState *env = cpu_env(cs); + + switch (env->excp_model) { +#if defined(TARGET_PPC64) + case POWERPC_EXCP_POWER8: + case POWERPC_EXCP_POWER9: + case POWERPC_EXCP_POWER10: + case POWERPC_EXCP_POWER11: + /* + * Machine check codes can be found in processor User Manual or + * Linux or skiboot source. + */ + if (access_type == MMU_DATA_LOAD) { + env->spr[SPR_DAR] = vaddr; + env->spr[SPR_DSISR] = PPC_BIT(57); + env->error_code = PPC_BIT(42); + + } else if (access_type == MMU_DATA_STORE) { + /* + * MCE for stores in POWER is asynchronous so hardware does + * not set DAR, but QEMU can do better. + */ + env->spr[SPR_DAR] = vaddr; + env->error_code = PPC_BIT(36) | PPC_BIT(43) | PPC_BIT(45); + env->error_code |= PPC_BIT(42); + + } else { /* Fetch */ + /* + * is_prefix_insn_excp() tests !PPC_BIT(42) to avoid fetching + * the instruction, so that must always be clear for fetches. + */ + env->error_code = PPC_BIT(36) | PPC_BIT(44) | PPC_BIT(45); + } + break; +#endif + default: + /* + * TODO: Check behaviour for other CPUs, for now do nothing. + * Could add a basic MCE even if real hardware ignores. + */ + return; + } + + cs->exception_index = POWERPC_EXCP_MCHECK; + cpu_loop_exit_restore(cs, retaddr); +} + +void ppc_cpu_debug_excp_handler(CPUState *cs) +{ +#if defined(TARGET_PPC64) + CPUPPCState *env = cpu_env(cs); + + if (env->insns_flags2 & PPC2_ISA207S) { + if (cs->watchpoint_hit) { + if (cs->watchpoint_hit->flags & BP_CPU) { + env->spr[SPR_DAR] = cs->watchpoint_hit->hitaddr; + env->spr[SPR_DSISR] = PPC_BIT(41); + cs->watchpoint_hit = NULL; + raise_exception(env, POWERPC_EXCP_DSI); + } + cs->watchpoint_hit = NULL; + } else if (cpu_breakpoint_test(cs, env->nip, BP_CPU)) { + raise_exception_err(env, POWERPC_EXCP_TRACE, + PPC_BIT(33) | PPC_BIT(43)); + } + } +#endif +} + +bool ppc_cpu_debug_check_breakpoint(CPUState *cs) +{ +#if defined(TARGET_PPC64) + CPUPPCState *env = cpu_env(cs); + + if (env->insns_flags2 & PPC2_ISA207S) { + target_ulong priv; + + priv = env->spr[SPR_CIABR] & PPC_BITMASK(62, 63); + switch (priv) { + case 0x1: /* problem */ + return env->msr & ((target_ulong)1 << MSR_PR); + case 0x2: /* supervisor */ + return (!(env->msr & ((target_ulong)1 << MSR_PR)) && + !(env->msr & ((target_ulong)1 << MSR_HV))); + case 0x3: /* hypervisor */ + return (!(env->msr & ((target_ulong)1 << MSR_PR)) && + (env->msr & ((target_ulong)1 << MSR_HV))); + default: + g_assert_not_reached(); + } + } +#endif + + return false; +} + +bool ppc_cpu_debug_check_watchpoint(CPUState *cs, CPUWatchpoint *wp) +{ +#if defined(TARGET_PPC64) + CPUPPCState *env = cpu_env(cs); + + if (env->insns_flags2 & PPC2_ISA207S) { + if (wp == env->dawr0_watchpoint) { + uint32_t dawrx = env->spr[SPR_DAWRX0]; + bool wt = extract32(dawrx, PPC_BIT_NR(59), 1); + bool wti = extract32(dawrx, PPC_BIT_NR(60), 1); + bool hv = extract32(dawrx, PPC_BIT_NR(61), 1); + bool sv = extract32(dawrx, PPC_BIT_NR(62), 1); + bool pr = extract32(dawrx, PPC_BIT_NR(62), 1); + + if ((env->msr & ((target_ulong)1 << MSR_PR)) && !pr) { + return false; + } else if ((env->msr & ((target_ulong)1 << MSR_HV)) && !hv) { + return false; + } else if (!sv) { + return false; + } + + if (!wti) { + if (env->msr & ((target_ulong)1 << MSR_DR)) { + if (!wt) { + return false; + } + } else { + if (wt) { + return false; + } + } + } + + return true; + } + } +#endif + + return false; +} + +#endif /* !CONFIG_USER_ONLY */ From patchwork Tue Mar 11 12:57:39 2025 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: Nicholas Piggin X-Patchwork-Id: 14011894 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.lore.kernel.org (Postfix) with ESMTPS id 4AC1AC28B2E for ; Tue, 11 Mar 2025 13:26:04 +0000 (UTC) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1trzGa-00008x-P2; Tue, 11 Mar 2025 09:03:28 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1trzE3-000571-73; Tue, 11 Mar 2025 09:00:54 -0400 Received: from mail-pj1-x1035.google.com ([2607:f8b0:4864:20::1035]) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_128_GCM_SHA256:128) (Exim 4.90_1) (envelope-from ) id 1trzE1-00008m-7d; Tue, 11 Mar 2025 09:00:50 -0400 Received: by mail-pj1-x1035.google.com with SMTP id 98e67ed59e1d1-2feae794508so8085256a91.0; Tue, 11 Mar 2025 06:00:46 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20230601; t=1741698045; x=1742302845; darn=nongnu.org; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to; bh=6S9jU22byVS+8eEKHCDnlZgprjWuUh/KidjFhLfhjko=; b=g0JGOoSGfuoYUeXAaUG3BJg0XrY7UkTxVo0ysK9C/E1YDXltfl2bnN8D4H8FJiUWQ6 ZKD6PmPOnGnuW6QpDSMs0WiA8GPBv7pVOgVqiwbFhS0ZPt/LL3sh/+/BLYs26Ivd/i9/ 1MXJLdiP53QCEZc+2SECahtLaKfl31CW857/KMzaCp0WC2ASLGO9CFyfWLegFjpuZmIN aV29qdHFwXTxs9qIXde9DwzmPgaY6dI30anBOOt3JzDogbWYe8jBLk1s2kD6jVLPFJLX mPSNzx3+OIfMaItDfJcIDr+KaCGdGOcEOvFOQE/taWJkDuIdZldkN9TmrQtQkikuAJQw DQHA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1741698045; x=1742302845; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=6S9jU22byVS+8eEKHCDnlZgprjWuUh/KidjFhLfhjko=; b=kXYySotCYwaWc7JtmxIAMwmvRofNZvH7ksBzM3H+dEUDIAD/lGvvfkXIEs5WtWUY9s SUSdCG9QL9SkrQ3HPZi5h8NoM/E7g7MJl5j/x8zMCoreXdQ5NkWkg1mfBChPmwpL6h2R sai0tXkf+1Y/7RY+v7cmBrVbMxJB+kYy0133gfcYYMAlQUwmHpOVof7AUI4zaLiO9iiy RhBw8g7jMds3bEqtCecc8B9EBY6Mcoop0flL8QErRfZhLtj7gddxXr7jg38tTNe1dCuv g++tYazpXGPLBpb2zM+oz/5zrBK18yVV9TpdC7HaErNYqVame2kwRY6FXzLVPJYcN/iN F8uw== X-Forwarded-Encrypted: i=1; AJvYcCXGW23q1tU5RDkApiUfTAyHEheisuVpVYJ0aaN+3E/ooVEgdvu6Bhz6irVs12QfIzo+MHqe9TvlbQ==@nongnu.org X-Gm-Message-State: AOJu0Yxb1zgVbVE+BrJ0MY913Vge8Rg//s0iqceTFoK9BsNTfekVqZ0W AZaUiSddq1VsYYnk//eMQShW7o2ApUp5gcPAqwnaCjIQfDuq2vs7/XV8+w== X-Gm-Gg: ASbGncuYOhZaqSM2lOV2C+UaNYG2omp3b1gmMyGKIyofAz51bElH+unh07MeUsyPBQ+ xoBeTmIseoTLwg/FS1+Sr3NmyTKaAMqjuLvX5stdF7erJR/bwTnP6rKtdJC7RiWLr1ul5qBvjv1 /VLHLUFpAr7q0gkRdF49sIrKCRwqT07mE82uwn1QXRUtzPmo+4rUV1DQfhlos1PmA13WQL+4FgR e26/3x3rJ8ev2cZZb/RcE7N6mwFhTiqVcBqfMbypqnShWWO3rTAV4MoFk2M1hvDcRcP4xTPdvRy bYfId+RNKcoWMJjWOJ7K5FXe+Q94h3qIJqx1UQqRsaB/D6atHZGCxU6IM/GqBg== X-Google-Smtp-Source: AGHT+IEJNGqwgZToGOe1BXasTksgFUwuhGEsFPva1IxfrTL6K1igtZZvwGwUR4jjkaiHfpQAoTTBJQ== X-Received: by 2002:a17:90b:1c05:b0:2ee:a583:e616 with SMTP id 98e67ed59e1d1-2ff7ce6d543mr27900239a91.9.1741698044790; Tue, 11 Mar 2025 06:00:44 -0700 (PDT) Received: from wheely.local0.net ([118.208.151.101]) by smtp.gmail.com with ESMTPSA id 98e67ed59e1d1-2ff4e773dddsm11822318a91.12.2025.03.11.06.00.42 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 11 Mar 2025 06:00:44 -0700 (PDT) From: Nicholas Piggin To: qemu-devel@nongnu.org Cc: Nicholas Piggin , qemu-ppc@nongnu.org, =?utf-8?q?Phil?= =?utf-8?q?ippe_Mathieu-Daud=C3=A9?= , Harsh Prateek Bora Subject: [PULL 45/72] target/ppc: Move ppc_ldl_code() to tcg-excp_helper.c Date: Tue, 11 Mar 2025 22:57:39 +1000 Message-ID: <20250311125815.903177-46-npiggin@gmail.com> X-Mailer: git-send-email 2.47.1 In-Reply-To: <20250311125815.903177-1-npiggin@gmail.com> References: <20250311125815.903177-1-npiggin@gmail.com> MIME-Version: 1.0 Received-SPF: pass client-ip=2607:f8b0:4864:20::1035; envelope-from=npiggin@gmail.com; helo=mail-pj1-x1035.google.com X-Spam_score_int: -20 X-Spam_score: -2.1 X-Spam_bar: -- X-Spam_report: (-2.1 / 5.0 requ) BAYES_00=-1.9, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_AU=-0.1, DKIM_VALID_EF=-0.1, FREEMAIL_FROM=0.001, RCVD_IN_DNSWL_NONE=-0.0001, SPF_HELO_NONE=0.001, SPF_PASS=-0.001 autolearn=ham autolearn_force=no X-Spam_action: no action X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: qemu-devel-bounces+qemu-devel=archiver.kernel.org@nongnu.org Sender: qemu-devel-bounces+qemu-devel=archiver.kernel.org@nongnu.org From: Philippe Mathieu-Daudé Signed-off-by: Philippe Mathieu-Daudé Reviewed-by: Harsh Prateek Bora Message-ID: <20250127102620.39159-6-philmd@linaro.org> Signed-off-by: Nicholas Piggin --- target/ppc/excp_helper.c | 21 --------------------- target/ppc/tcg-excp_helper.c | 18 ++++++++++++++++++ 2 files changed, 18 insertions(+), 21 deletions(-) diff --git a/target/ppc/excp_helper.c b/target/ppc/excp_helper.c index b05eb7f5ae..8956466db1 100644 --- a/target/ppc/excp_helper.c +++ b/target/ppc/excp_helper.c @@ -136,27 +136,6 @@ static void dump_hcall(CPUPPCState *env) env->nip); } -#ifdef CONFIG_TCG -/* Return true iff byteswap is needed to load instruction */ -static inline bool insn_need_byteswap(CPUArchState *env) -{ - /* SYSTEM builds TARGET_BIG_ENDIAN. Need to swap when MSR[LE] is set */ - return !!(env->msr & ((target_ulong)1 << MSR_LE)); -} - -uint32_t ppc_ldl_code(CPUArchState *env, target_ulong addr) -{ - uint32_t insn = cpu_ldl_code(env, addr); - - if (insn_need_byteswap(env)) { - insn = bswap32(insn); - } - - return insn; -} - -#endif - static void ppc_excp_debug_sw_tlb(CPUPPCState *env, int excp) { const char *es; diff --git a/target/ppc/tcg-excp_helper.c b/target/ppc/tcg-excp_helper.c index 3402dbe05e..6950b78774 100644 --- a/target/ppc/tcg-excp_helper.c +++ b/target/ppc/tcg-excp_helper.c @@ -199,4 +199,22 @@ bool ppc_cpu_debug_check_watchpoint(CPUState *cs, CPUWatchpoint *wp) return false; } +/* Return true iff byteswap is needed to load instruction */ +static inline bool insn_need_byteswap(CPUArchState *env) +{ + /* SYSTEM builds TARGET_BIG_ENDIAN. Need to swap when MSR[LE] is set */ + return !!(env->msr & ((target_ulong)1 << MSR_LE)); +} + +uint32_t ppc_ldl_code(CPUArchState *env, target_ulong addr) +{ + uint32_t insn = cpu_ldl_code(env, addr); + + if (insn_need_byteswap(env)) { + insn = bswap32(insn); + } + + return insn; +} + #endif /* !CONFIG_USER_ONLY */ From patchwork Tue Mar 11 12:57:40 2025 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: Nicholas Piggin X-Patchwork-Id: 14011901 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.lore.kernel.org (Postfix) with ESMTPS id 68FB8C282EC for ; Tue, 11 Mar 2025 13:26:48 +0000 (UTC) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1trzFa-0006xO-Ty; Tue, 11 Mar 2025 09:02:26 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1trzE4-00057z-GP; Tue, 11 Mar 2025 09:00:54 -0400 Received: from mail-pj1-x102e.google.com ([2607:f8b0:4864:20::102e]) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_128_GCM_SHA256:128) (Exim 4.90_1) (envelope-from ) id 1trzE2-00009A-29; Tue, 11 Mar 2025 09:00:52 -0400 Received: by mail-pj1-x102e.google.com with SMTP id 98e67ed59e1d1-2ff187f027fso9046295a91.1; Tue, 11 Mar 2025 06:00:49 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20230601; t=1741698047; x=1742302847; darn=nongnu.org; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to; bh=9hQkVoYW8C4C1nZdyf/BtCP5nliX3X99Cb593+4du5g=; b=eDfIKjgbC3EK/TrN147pmQtrskKRtuJrbvpVJY7T4OJiVu5sXmoECtFWrxW6OS9o0K R5HeIHvuFgFc3e6jyiMH1nhvDRIIFrsCREBqwuf2t73uMJMp4/LWV86+K5KCfmErArkM RdTLnwVvmkdgHUCJhlwJrvRV7SP/4bySlC1wfe0ATLeN9nbB+zxEnpbXh0dGEgYyHqNv nL5s5bKwHysTXM4tYZwrWPmtpGi6N1tO5OUGAnm16UprscJGrevJ3V79DOORVz3yuabP s5GV4FqS0no4HCKJeb/s1Qi+dcIErZxt2lLCGhNGdOkhVbtyNs2Wph22CMbER4ru1HsC iBbg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1741698047; x=1742302847; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=9hQkVoYW8C4C1nZdyf/BtCP5nliX3X99Cb593+4du5g=; b=sdobTb9i3f/LW4SVUavfrjTCH+dXFH0MO0cuuGzu8XksHMNe29ZpAuVXry4WMqfvRK xnpD5DnykXu3Mdw5FCtAt7ziJ2Flo3oNEDR1C31ZL5HxVOB0n/QXpI5eTvGIL9xOtDzG xsnD7rvBWJ4NXQepQLcs3Mc4GAoiGS4lu8EswjVsXiBQn6sXa3FkSOdJWHdcvQ3dWO3v f31C7wITXsGjNvqyTibE/w4kcBz5vhzVicNW5srMcFT7GQPMQk0zUf+Fb3/vABXJ9gNy XqsEeJE/QRFHv6WMwHHLgAJgMeKopqLCSlE+73l/l63D4k+Pn5f8xrYk+wyaKY+dcjnJ kleQ== X-Forwarded-Encrypted: i=1; AJvYcCWhK2aCfRzv2756leJTmhuLM+8lI31RPsfEPwZa5hn4gtvgSHaywa/0uBFrf0nOw3SOH0jeuH5iDg==@nongnu.org X-Gm-Message-State: AOJu0Yydugn3LwOqLuO1QglvVzcpOy3K479v8CleckwB0eEn1+XWYKFG +MswCm9uQ7HPWVgRJBt8h7zg7mMbd4wVjnXqVKW3tC8om9qV60qTSKRxzA== X-Gm-Gg: ASbGnctuSpOmoWTpTIwttihpmRMF2rGR9JdQ7LdOuHU4V8lLxK9wT4TtHTSpAhAnBnP mVP3EKt0if0cpNw2Dmyb0yh86hfP2AZ74S92DXMGVJmIkDA9UtooGY9ZcOMwuUoBmqZlhdIxgzn S4Uat8WGnUWnqyRSgL0V9UjQoejRN2Pi0knceMMpScgdv8WonwGKvmEHIeRBIuifo2+Ij+KR4Xq caDmcRcZZMzS0DApW6rCgy4zgCDiNATV9jfEZxU/R6CQDdRnQukpwpv68VNjbcqzOG1SHYsVYjK oyi6qE/+BpwOABN3PO2SKTfFQlGm6MeUn1oqzDCOuXOgkvIxboo= X-Google-Smtp-Source: AGHT+IEQ5vWLyxKrkPdFANZhmP0hlFYINaCgpY7ahdt7nD9w+s45rEgz72q1SOQAueIKMEHSrqgTeQ== X-Received: by 2002:a17:90b:1f8c:b0:2fa:562c:c1cf with SMTP id 98e67ed59e1d1-301004f7fb3mr4645081a91.1.1741698047502; Tue, 11 Mar 2025 06:00:47 -0700 (PDT) Received: from wheely.local0.net ([118.208.151.101]) by smtp.gmail.com with ESMTPSA id 98e67ed59e1d1-2ff4e773dddsm11822318a91.12.2025.03.11.06.00.45 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 11 Mar 2025 06:00:47 -0700 (PDT) From: Nicholas Piggin To: qemu-devel@nongnu.org Cc: Nicholas Piggin , qemu-ppc@nongnu.org, =?utf-8?q?Phil?= =?utf-8?q?ippe_Mathieu-Daud=C3=A9?= Subject: [PULL 46/72] target/ppc: Ensure powerpc_mcheck_checkstop() is only called under TCG Date: Tue, 11 Mar 2025 22:57:40 +1000 Message-ID: <20250311125815.903177-47-npiggin@gmail.com> X-Mailer: git-send-email 2.47.1 In-Reply-To: <20250311125815.903177-1-npiggin@gmail.com> References: <20250311125815.903177-1-npiggin@gmail.com> MIME-Version: 1.0 Received-SPF: pass client-ip=2607:f8b0:4864:20::102e; envelope-from=npiggin@gmail.com; helo=mail-pj1-x102e.google.com X-Spam_score_int: -20 X-Spam_score: -2.1 X-Spam_bar: -- X-Spam_report: (-2.1 / 5.0 requ) BAYES_00=-1.9, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_AU=-0.1, DKIM_VALID_EF=-0.1, FREEMAIL_FROM=0.001, RCVD_IN_DNSWL_NONE=-0.0001, SPF_HELO_NONE=0.001, SPF_PASS=-0.001 autolearn=ham autolearn_force=no X-Spam_action: no action X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: qemu-devel-bounces+qemu-devel=archiver.kernel.org@nongnu.org Sender: qemu-devel-bounces+qemu-devel=archiver.kernel.org@nongnu.org From: Philippe Mathieu-Daudé Signed-off-by: Philippe Mathieu-Daudé Message-ID: <20250127102620.39159-7-philmd@linaro.org> Signed-off-by: Nicholas Piggin --- target/ppc/excp_helper.c | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/target/ppc/excp_helper.c b/target/ppc/excp_helper.c index 8956466db1..b08cd53688 100644 --- a/target/ppc/excp_helper.c +++ b/target/ppc/excp_helper.c @@ -19,6 +19,7 @@ #include "qemu/osdep.h" #include "qemu/main-loop.h" #include "qemu/log.h" +#include "system/tcg.h" #include "system/system.h" #include "system/runstate.h" #include "cpu.h" @@ -30,7 +31,6 @@ #include "trace.h" #ifdef CONFIG_TCG -#include "system/tcg.h" #include "exec/helper-proto.h" #include "exec/cpu_ldst.h" #endif @@ -443,13 +443,11 @@ void helper_attn(CPUPPCState *env) static void powerpc_mcheck_checkstop(CPUPPCState *env) { /* KVM guests always have MSR[ME] enabled */ -#ifdef CONFIG_TCG if (FIELD_EX64(env->msr, MSR, ME)) { return; } - + assert(tcg_enabled()); powerpc_checkstop(env, "machine check with MSR[ME]=0"); -#endif } static void powerpc_excp_40x(PowerPCCPU *cpu, int excp) From patchwork Tue Mar 11 12:57:41 2025 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: Nicholas Piggin X-Patchwork-Id: 14011837 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.lore.kernel.org (Postfix) with ESMTPS id 73E4AC28B2E for ; Tue, 11 Mar 2025 13:13:06 +0000 (UTC) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1trzJN-0004B4-Nv; Tue, 11 Mar 2025 09:06:22 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1trzEB-0005HS-O1; Tue, 11 Mar 2025 09:01:04 -0400 Received: from mail-pl1-x62b.google.com ([2607:f8b0:4864:20::62b]) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_128_GCM_SHA256:128) (Exim 4.90_1) (envelope-from ) id 1trzE4-0000AK-NB; Tue, 11 Mar 2025 09:00:58 -0400 Received: by mail-pl1-x62b.google.com with SMTP id d9443c01a7336-224341bbc1dso67994515ad.3; Tue, 11 Mar 2025 06:00:51 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20230601; t=1741698051; x=1742302851; darn=nongnu.org; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to; bh=VyPpxpR1LPgC7kHmIhSLHr8dyizfyqPn+5SkC4Qa1kM=; b=eb69PDmc6vgFL5ZGMpEkb/6i2Vb6ANHUT0/1zgouWOqdAJIZMQmqTrjh1BuBT6V+ua aSwtkdo7d7cm2cise4vFKrUK9eZgrvNYCuTS9SQ34kQHWt+LTAErsw+GdZyDC+1a7AYv jeGDJEgmU7mEaSGEzf89rLqgKLG4QkPJwQQ+ewqYfvQ6gEv6LoNltHtglWnZCnIqZ+Cj /vI3denqz7CA9Zl5wS5k23382xW+uImEslHyMAxfDti/i6lMh8/IItJtbiJoOPm7B6u1 BmhySgYv766x1l3XPSjgWwvGxR6ONRBzlWOfpD/XcvIuKUuXNLr7KNLGbzs16jU33FlU Rd6g== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1741698051; x=1742302851; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=VyPpxpR1LPgC7kHmIhSLHr8dyizfyqPn+5SkC4Qa1kM=; b=dBLpFqJxPXPy+2Kmi6Ky0ZjVAx/RpSKjVlZWPyQE26NFywZZMZtOscK9sYG9LuuBCp ott9VHRo6xBu7Xbwdx8Bi39i6ziIZE85RHSxs+tzZ3dM9qppTWLF15ic2L8PliNlapSz W9yeUpemkPZXPaLfmx2cRp6GDAdNid7yJLVoJKP+8Va8rXOlsN7rhbmUquh495r216T0 DNyH7HouvDwi/s2i3RlHcNSYco1+eqEkvZ8MRg4Pz+AMghXMP4bzdlQ7YsugRDYrmwAA 92nspWVqbaGj7Kmpl3q/bHK5WitawxBK9yR4+3hu3RYyw4Tbk40VrdSX3cRwAoDVi10H 4xwA== X-Forwarded-Encrypted: i=1; AJvYcCXohdBXpmIkIppv/mAraqR+QnWhjykf7WOHbxBDgmK4qJyZf1l/mMoRlqtW6jWGGVH0z7lL2m06gQ==@nongnu.org X-Gm-Message-State: AOJu0Yz4k3Y8ih8Uotb6UvBN1Gnp4/iPYxD8CrH9ewlRFxS+GxJ9QHrJ jzYgtTH0dEtZCvW2KF7pUkkwezi1/dXtvNAYwv1F3LbvPr5Y0FvNiPlwrA== X-Gm-Gg: ASbGncti2/TSZvvHusWKJGyPkg8dMIZDgt2utdFE/6MIV9NOVTkgc7/4JCXs412q4WL 4WDXBQKscmNi81SVIdPFfeo7PFiY3JvrED7LfbgNcVJ+OwmYYTt2JB67Ougsym2xxYEn+0lQ2jc y+AuakrGvwAenWjxK3LLwC9ogU4OObuyjj2EwYaJhFyripNlRSHLRYpBkQFVScmWO4VdZd1RL9T cug2PUMdZ26nsDyvmVQ69Ueyumm/9zDBZR2qQPyrO4JF1N8OKDPi3qPQER7TgE5jopV+FlDeu92 h+kHVQw3jSZvDcvCXHB81940gnhTJ5uVpEHIPhU1QGTlsCjgYXY= X-Google-Smtp-Source: AGHT+IG3/dJF0uCdNybHet8gcnCbHhEvUcYDAyybd/VVNwW6hC8T/djteCM/ofz2DtXmA4DQfaZzJQ== X-Received: by 2002:a17:902:c94d:b0:220:c066:94eb with SMTP id d9443c01a7336-22592e407damr48788845ad.25.1741698050538; Tue, 11 Mar 2025 06:00:50 -0700 (PDT) Received: from wheely.local0.net ([118.208.151.101]) by smtp.gmail.com with ESMTPSA id 98e67ed59e1d1-2ff4e773dddsm11822318a91.12.2025.03.11.06.00.47 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 11 Mar 2025 06:00:50 -0700 (PDT) From: Nicholas Piggin To: qemu-devel@nongnu.org Cc: Nicholas Piggin , qemu-ppc@nongnu.org, =?utf-8?q?Phil?= =?utf-8?q?ippe_Mathieu-Daud=C3=A9?= , Harsh Prateek Bora Subject: [PULL 47/72] target/ppc: Restrict powerpc_checkstop() to TCG Date: Tue, 11 Mar 2025 22:57:41 +1000 Message-ID: <20250311125815.903177-48-npiggin@gmail.com> X-Mailer: git-send-email 2.47.1 In-Reply-To: <20250311125815.903177-1-npiggin@gmail.com> References: <20250311125815.903177-1-npiggin@gmail.com> MIME-Version: 1.0 Received-SPF: pass client-ip=2607:f8b0:4864:20::62b; envelope-from=npiggin@gmail.com; helo=mail-pl1-x62b.google.com X-Spam_score_int: -20 X-Spam_score: -2.1 X-Spam_bar: -- X-Spam_report: (-2.1 / 5.0 requ) BAYES_00=-1.9, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_AU=-0.1, DKIM_VALID_EF=-0.1, FREEMAIL_FROM=0.001, RCVD_IN_DNSWL_NONE=-0.0001, SPF_PASS=-0.001, T_SPF_HELO_TEMPERROR=0.01 autolearn=ham autolearn_force=no X-Spam_action: no action X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: qemu-devel-bounces+qemu-devel=archiver.kernel.org@nongnu.org Sender: qemu-devel-bounces+qemu-devel=archiver.kernel.org@nongnu.org From: Philippe Mathieu-Daudé Expose powerpc_checkstop() prototype, and move it to tcg-excp_helper.c, only built when TCG is available. Signed-off-by: Philippe Mathieu-Daudé Reviewed-by: Harsh Prateek Bora Message-ID: <20250127102620.39159-8-philmd@linaro.org> Signed-off-by: Nicholas Piggin --- target/ppc/excp_helper.c | 26 -------------------------- target/ppc/internal.h | 4 +++- target/ppc/tcg-excp_helper.c | 28 ++++++++++++++++++++++++++++ 3 files changed, 31 insertions(+), 27 deletions(-) diff --git a/target/ppc/excp_helper.c b/target/ppc/excp_helper.c index b08cd53688..236e5078f5 100644 --- a/target/ppc/excp_helper.c +++ b/target/ppc/excp_helper.c @@ -400,32 +400,6 @@ static void powerpc_set_excp_state(PowerPCCPU *cpu, target_ulong vector, } #ifdef CONFIG_TCG -/* - * This stops the machine and logs CPU state without killing QEMU (like - * cpu_abort()) because it is often a guest error as opposed to a QEMU error, - * so the machine can still be debugged. - */ -static G_NORETURN void powerpc_checkstop(CPUPPCState *env, const char *reason) -{ - CPUState *cs = env_cpu(env); - FILE *f; - - f = qemu_log_trylock(); - if (f) { - fprintf(f, "Entering checkstop state: %s\n", reason); - cpu_dump_state(cs, f, CPU_DUMP_FPU | CPU_DUMP_CCOP); - qemu_log_unlock(f); - } - - /* - * This stops the machine and logs CPU state without killing QEMU - * (like cpu_abort()) so the machine can still be debugged (because - * it is often a guest error). - */ - qemu_system_guest_panicked(NULL); - cpu_loop_exit_noexc(cs); -} - #if defined(TARGET_PPC64) && !defined(CONFIG_USER_ONLY) void helper_attn(CPUPPCState *env) { diff --git a/target/ppc/internal.h b/target/ppc/internal.h index 46db6adfcf..62186bc1e6 100644 --- a/target/ppc/internal.h +++ b/target/ppc/internal.h @@ -289,7 +289,9 @@ void ppc_cpu_do_transaction_failed(CPUState *cs, hwaddr physaddr, void ppc_cpu_debug_excp_handler(CPUState *cs); bool ppc_cpu_debug_check_breakpoint(CPUState *cs); bool ppc_cpu_debug_check_watchpoint(CPUState *cs, CPUWatchpoint *wp); -#endif + +G_NORETURN void powerpc_checkstop(CPUPPCState *env, const char *reason); +#endif /* !CONFIG_USER_ONLY */ FIELD(GER_MSK, XMSK, 0, 4) FIELD(GER_MSK, YMSK, 4, 4) diff --git a/target/ppc/tcg-excp_helper.c b/target/ppc/tcg-excp_helper.c index 6950b78774..93c2d6b5a0 100644 --- a/target/ppc/tcg-excp_helper.c +++ b/target/ppc/tcg-excp_helper.c @@ -17,7 +17,9 @@ * License along with this library; if not, see . */ #include "qemu/osdep.h" +#include "qemu/log.h" #include "exec/cpu_ldst.h" +#include "system/runstate.h" #include "hw/ppc/ppc.h" #include "internal.h" @@ -199,6 +201,32 @@ bool ppc_cpu_debug_check_watchpoint(CPUState *cs, CPUWatchpoint *wp) return false; } +/* + * This stops the machine and logs CPU state without killing QEMU (like + * cpu_abort()) because it is often a guest error as opposed to a QEMU error, + * so the machine can still be debugged. + */ +G_NORETURN void powerpc_checkstop(CPUPPCState *env, const char *reason) +{ + CPUState *cs = env_cpu(env); + FILE *f; + + f = qemu_log_trylock(); + if (f) { + fprintf(f, "Entering checkstop state: %s\n", reason); + cpu_dump_state(cs, f, CPU_DUMP_FPU | CPU_DUMP_CCOP); + qemu_log_unlock(f); + } + + /* + * This stops the machine and logs CPU state without killing QEMU + * (like cpu_abort()) so the machine can still be debugged (because + * it is often a guest error). + */ + qemu_system_guest_panicked(NULL); + cpu_loop_exit_noexc(cs); +} + /* Return true iff byteswap is needed to load instruction */ static inline bool insn_need_byteswap(CPUArchState *env) { From patchwork Tue Mar 11 12:57:42 2025 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: Nicholas Piggin X-Patchwork-Id: 14011812 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.lore.kernel.org (Postfix) with ESMTPS id 031BAC28B30 for ; Tue, 11 Mar 2025 13:07:35 +0000 (UTC) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1trzHM-00015x-O9; Tue, 11 Mar 2025 09:04:28 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1trzED-0005Ng-Kz; Tue, 11 Mar 2025 09:01:06 -0400 Received: from mail-pj1-x102b.google.com ([2607:f8b0:4864:20::102b]) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_128_GCM_SHA256:128) (Exim 4.90_1) (envelope-from ) id 1trzE7-0000Aj-Ou; Tue, 11 Mar 2025 09:01:01 -0400 Received: by mail-pj1-x102b.google.com with SMTP id 98e67ed59e1d1-2ff615a114bso9412283a91.0; Tue, 11 Mar 2025 06:00:54 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20230601; t=1741698053; x=1742302853; darn=nongnu.org; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to; bh=JXbLVl+GmIzuW1zJgw//SH32S1N1RiaYQUubYyQlPG0=; b=Bh/r8up3aPDla4svFh8HanutVZTxATTXNNt3bC7Xbc05twUzQuIrWR4oJMua9uuvw3 sn67IRL0MbaeWBPCoYqL6YsM4w8nRNLFz6nERJ7KOiyrdnbfNRi5qe43IATvf/y8DOw7 owkYpoiBPMKrWUaYwNdtlHz6A6ahDNIkqYvxZYilthWz2KnEBhaKX2UOFae9yoLPIwp7 h+qCX/X4D/J8DDLzjbfkje5KuUISAsZeV0ykw5HBE8eq4/VYEl0M2CnkmU2q4w5Nt66L IhJ0kjh/Kn8voRpFhsHvGiLzVWS3NslFkRZtxqRsD5zBfPkFflYFGL9mM0U/q/QG1OFg 1yLA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1741698053; x=1742302853; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=JXbLVl+GmIzuW1zJgw//SH32S1N1RiaYQUubYyQlPG0=; b=Cc2vnNybVBggWjFFw8G6lXZdltllyHf9a1GRF8jII9A/L+lwmYBMyyJDlyyFKukkSe I6lgVod2DXvvY4aakT1zRb0SWqEOTJpkz1TMJF8x6NNe2YwoJVduMwH801x+NCs3uLV8 zhHlhIwcdLK8xTmal+Dh2VRUKnldl/Pzbw366jpgUqtWIXBsgVygb+Y3v8b0E1uLFGdz VtxExglvg3b3BzIG4L+YF1ig4COrZdLtWIJcdFP//YoL1zjtidvuTX5IhwHoABXzhbYg guVI/gcw/+53ejYKhOSZGqB4X9XRoAQpf903gkZfoXOXaI05IxI8tUpQGPkNjzbZp3BJ W2YQ== X-Forwarded-Encrypted: i=1; AJvYcCVz9xEFVrOrAYYC15wUf6rDh6dtqgXZ897imX/glH4vg/8l6pXUz6ZRRCPYV53EXk88rD7C91Y9Dw==@nongnu.org X-Gm-Message-State: AOJu0Yz/Y2i6fvNEyOps6rFDdke4VQvIGSWRlWbuteewvxIZvy0wopsB QzBz2jY4oS0A/RZ0/ZduZ/0msZlfZXgWh5Slo+wJXsREWRC01C6dVemW9A== X-Gm-Gg: ASbGnctvXzxkaYfQ2/4CweMyFAbto4I9W5YmyOAE83YzCt/iwkmzPipF1SjRBpKjzus C/suJbNBz1cIRzIRqwgHqLZcvti8LQKtZm7ecrROLwZaj6/tsuYWZh74fbeuZ/rWFHCmIGFz3S+ zZwpDjhGDryMatAKYwqyIBoBoMLtJ4AP2fXs20i6fQN1E6rNb1E2e5lJTzzjNrP+VgEDo88jjzT /AXI6gvtMuYI+tWfPOZSUAodfHK/XyjIga+jS5P0dWRESVXhR4447BjhTtCnPdlqakEY8wGcw5W plCroTl5+yzbr/kQ9/1rXEVo33pYPDSz+VQw41AAGT48BNX+pQY= X-Google-Smtp-Source: AGHT+IHnqpZUL1uuPGF2HHgzmnk1DrgtTaZH/qHHRmSOFnKUqmV8NiMImsPjDSvzrVxu//xlhETawg== X-Received: by 2002:a17:90b:50c7:b0:2fa:2268:1af4 with SMTP id 98e67ed59e1d1-3010051c043mr4492197a91.7.1741698053591; Tue, 11 Mar 2025 06:00:53 -0700 (PDT) Received: from wheely.local0.net ([118.208.151.101]) by smtp.gmail.com with ESMTPSA id 98e67ed59e1d1-2ff4e773dddsm11822318a91.12.2025.03.11.06.00.51 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 11 Mar 2025 06:00:53 -0700 (PDT) From: Nicholas Piggin To: qemu-devel@nongnu.org Cc: Nicholas Piggin , qemu-ppc@nongnu.org, =?utf-8?q?Phil?= =?utf-8?q?ippe_Mathieu-Daud=C3=A9?= , Harsh Prateek Bora Subject: [PULL 48/72] target/ppc: Remove raise_exception_ra() Date: Tue, 11 Mar 2025 22:57:42 +1000 Message-ID: <20250311125815.903177-49-npiggin@gmail.com> X-Mailer: git-send-email 2.47.1 In-Reply-To: <20250311125815.903177-1-npiggin@gmail.com> References: <20250311125815.903177-1-npiggin@gmail.com> MIME-Version: 1.0 Received-SPF: pass client-ip=2607:f8b0:4864:20::102b; envelope-from=npiggin@gmail.com; helo=mail-pj1-x102b.google.com X-Spam_score_int: -20 X-Spam_score: -2.1 X-Spam_bar: -- X-Spam_report: (-2.1 / 5.0 requ) BAYES_00=-1.9, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_AU=-0.1, DKIM_VALID_EF=-0.1, FREEMAIL_FROM=0.001, RCVD_IN_DNSWL_NONE=-0.0001, SPF_HELO_NONE=0.001, SPF_PASS=-0.001 autolearn=ham autolearn_force=no X-Spam_action: no action X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: qemu-devel-bounces+qemu-devel=archiver.kernel.org@nongnu.org Sender: qemu-devel-bounces+qemu-devel=archiver.kernel.org@nongnu.org From: Philippe Mathieu-Daudé Introduced in commit db789c6cd33 ("ppc: Provide basic raise_exception_* functions"), raise_exception_ra() has never been used. Remove as dead code. Signed-off-by: Philippe Mathieu-Daudé Reviewed-by: Harsh Prateek Bora Message-ID: <20250127102620.39159-9-philmd@linaro.org> Signed-off-by: Nicholas Piggin --- target/ppc/cpu.h | 2 -- target/ppc/excp_helper.c | 6 ------ 2 files changed, 8 deletions(-) diff --git a/target/ppc/cpu.h b/target/ppc/cpu.h index 25b1e6d6b0..505b589714 100644 --- a/target/ppc/cpu.h +++ b/target/ppc/cpu.h @@ -2756,8 +2756,6 @@ static inline void cpu_get_tb_cpu_state(CPUPPCState *env, vaddr *pc, #endif G_NORETURN void raise_exception(CPUPPCState *env, uint32_t exception); -G_NORETURN void raise_exception_ra(CPUPPCState *env, uint32_t exception, - uintptr_t raddr); G_NORETURN void raise_exception_err(CPUPPCState *env, uint32_t exception, uint32_t error_code); G_NORETURN void raise_exception_err_ra(CPUPPCState *env, uint32_t exception, diff --git a/target/ppc/excp_helper.c b/target/ppc/excp_helper.c index 236e5078f5..9e1a2ecc36 100644 --- a/target/ppc/excp_helper.c +++ b/target/ppc/excp_helper.c @@ -2528,12 +2528,6 @@ void raise_exception(CPUPPCState *env, uint32_t exception) raise_exception_err_ra(env, exception, 0, 0); } -void raise_exception_ra(CPUPPCState *env, uint32_t exception, - uintptr_t raddr) -{ - raise_exception_err_ra(env, exception, 0, raddr); -} - #ifdef CONFIG_TCG void helper_raise_exception_err(CPUPPCState *env, uint32_t exception, uint32_t error_code) From patchwork Tue Mar 11 12:57:43 2025 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: Nicholas Piggin X-Patchwork-Id: 14011882 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.lore.kernel.org (Postfix) with ESMTPS id C6940C28B2E for ; Tue, 11 Mar 2025 13:21:58 +0000 (UTC) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1trzJV-0004Zz-Ew; Tue, 11 Mar 2025 09:06:29 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1trzEE-0005No-U3; Tue, 11 Mar 2025 09:01:06 -0400 Received: from mail-pj1-x1029.google.com ([2607:f8b0:4864:20::1029]) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_128_GCM_SHA256:128) (Exim 4.90_1) (envelope-from ) id 1trzEA-0000B8-IC; Tue, 11 Mar 2025 09:01:01 -0400 Received: by mail-pj1-x1029.google.com with SMTP id 98e67ed59e1d1-2fa8ac56891so8062867a91.2; Tue, 11 Mar 2025 06:00:57 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20230601; t=1741698056; x=1742302856; darn=nongnu.org; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to; bh=6QcWNxidF+8F14IOmySk+2TS0qLc2Hl5I2PiCaOol8E=; b=eL5sZd0Jnn1SuZ1B9g0xrkRT4NCcdK08rkgHNLqdvTYCusg3AYFvYdxXknsQhuUtPt aF0UR2o/xHHt4rxesnUcBiBev0AiAPFaXkLi3RuSXV8Y8bShvTyZ5lKLAqtj9ugcDEY0 jsuFgqKfa/5Y+t1k+bDG1LGTff3+68NJo3/Ob2v1EE9I4kt/MDDflWO0weRoQ3iY6J6o DlCX+z9nTf4Ub+OCXaLzc9dcx7L0KeXOOHWEcvEqZjHOnwE/Mdt90uarTNWZS788nY5n VRmjfnzjWrEWjEPY1nA8EXij5qMsQEUESlZF76w+xx5I5zZqTlsEDNE8EUKoeCWOC3tA n4PA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1741698056; x=1742302856; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=6QcWNxidF+8F14IOmySk+2TS0qLc2Hl5I2PiCaOol8E=; b=FrUVxUemX+CGE0amQwJBx8Ot5jiWZ9AJOZ2gqPrLWSs/h7546B4hxRwg3yUbBFkqGO QZSaCyUXKdef5Jm1sUnWxwPYu6qR3TG0FbekgzvnPatPFzb7GKZswkeLojEfJ19lAODx TVqlMQMgW6m1P+s3ix1N76+a2jim1lLFGXabzrvqfhHS6AKq3XbNLMON3by64i1+osxW KsTm+2WBqqfjZLOnFwVgXExRcFU5BXbOIRBQG18C1KR2LIKuSu6NKj3RSfJBaoLDPSjI UrXqzi/jgbGLyb4/jxZPhaLsOCNCf08MPrBoKuynlsKjDwiwN+5FYm8ie5TXSqC4thi1 LFDQ== X-Forwarded-Encrypted: i=1; AJvYcCULCnGTy5mGZ+3n8+80znvvFk19n3GDRiXuUJY4iGkNwQC9i2q4XJlUGyec0P3UuV6FlgvgqXpeOw==@nongnu.org X-Gm-Message-State: AOJu0Yy+l+qLGvCJTuBJiZ7uniBbcYQdVjGMJ6cfEVLJ4JRGhAs6hdJw svo1AqezRV1KKkUBVnUYZffZXg8JotNvhGTBL0f+KzepErb5uSokQ7AlNg== X-Gm-Gg: ASbGncvozUsh/PaXmXVEumBNcc/OtCDxcwGWfd8YeWtWTmYc7wuJb8lwtpRUmlJrrkI /nN0D1F4mLr6LkpQKloTsxJJn1PfEoGydd2Vl/5wf3+bqQcfGHjermFwLsRupqmSYgudZVxRkIS /9m25MgHPm5jVa5I8M6b4DWdvJft9YALXx71hQLLGHNiBvbjOiDZNJLojsTK+Glp5LIiEuc5XNd KGAEIcic06MeypcFnrC33yuKWLfvDgO8WahcSwiyQ/Ve+Zu/HTfl4WsNkk8dVZkd+Mv/HdA6P05 B4ENXa3CABmUxQPVK4YbzXneJAHaJPQhS7uFTjMr03U4By+BKD4= X-Google-Smtp-Source: AGHT+IHCy4rvVri/vTa/rnjuzFdLf5mF5P6ijmWnVC0Tsoonsvdoe3C9wE8weJlK9fPlu2zNDGd++Q== X-Received: by 2002:a17:90b:278f:b0:2f7:4cce:ae37 with SMTP id 98e67ed59e1d1-2ff7ce8958fmr30255905a91.18.1741698056295; Tue, 11 Mar 2025 06:00:56 -0700 (PDT) Received: from wheely.local0.net ([118.208.151.101]) by smtp.gmail.com with ESMTPSA id 98e67ed59e1d1-2ff4e773dddsm11822318a91.12.2025.03.11.06.00.54 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 11 Mar 2025 06:00:55 -0700 (PDT) From: Nicholas Piggin To: qemu-devel@nongnu.org Cc: Nicholas Piggin , qemu-ppc@nongnu.org, =?utf-8?q?Phil?= =?utf-8?q?ippe_Mathieu-Daud=C3=A9?= Subject: [PULL 49/72] target/ppc: Restrict exception helpers to TCG Date: Tue, 11 Mar 2025 22:57:43 +1000 Message-ID: <20250311125815.903177-50-npiggin@gmail.com> X-Mailer: git-send-email 2.47.1 In-Reply-To: <20250311125815.903177-1-npiggin@gmail.com> References: <20250311125815.903177-1-npiggin@gmail.com> MIME-Version: 1.0 Received-SPF: pass client-ip=2607:f8b0:4864:20::1029; envelope-from=npiggin@gmail.com; helo=mail-pj1-x1029.google.com X-Spam_score_int: -20 X-Spam_score: -2.1 X-Spam_bar: -- X-Spam_report: (-2.1 / 5.0 requ) BAYES_00=-1.9, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_AU=-0.1, DKIM_VALID_EF=-0.1, FREEMAIL_FROM=0.001, RCVD_IN_DNSWL_NONE=-0.0001, SPF_HELO_NONE=0.001, SPF_PASS=-0.001 autolearn=ham autolearn_force=no X-Spam_action: no action X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: qemu-devel-bounces+qemu-devel=archiver.kernel.org@nongnu.org Sender: qemu-devel-bounces+qemu-devel=archiver.kernel.org@nongnu.org From: Philippe Mathieu-Daudé Move exception helpers to tcg-excp_helper.c so they are only built when TCG is selected. Preprocessor guards are added for some helpers unused when CONFIG_USER_ONLY. [npiggin: mention USER_ONLY change] Signed-off-by: Philippe Mathieu-Daudé Message-ID: <20250127102620.39159-10-philmd@linaro.org> Signed-off-by: Nicholas Piggin --- target/ppc/excp_helper.c | 34 -------------------------------- target/ppc/tcg-excp_helper.c | 38 ++++++++++++++++++++++++++++++++++++ 2 files changed, 38 insertions(+), 34 deletions(-) diff --git a/target/ppc/excp_helper.c b/target/ppc/excp_helper.c index 9e1a2ecc36..6a12402b23 100644 --- a/target/ppc/excp_helper.c +++ b/target/ppc/excp_helper.c @@ -2504,41 +2504,7 @@ bool ppc_cpu_exec_interrupt(CPUState *cs, int interrupt_request) #endif /* !CONFIG_USER_ONLY */ -/*****************************************************************************/ -/* Exceptions processing helpers */ - -void raise_exception_err_ra(CPUPPCState *env, uint32_t exception, - uint32_t error_code, uintptr_t raddr) -{ - CPUState *cs = env_cpu(env); - - cs->exception_index = exception; - env->error_code = error_code; - cpu_loop_exit_restore(cs, raddr); -} - -void raise_exception_err(CPUPPCState *env, uint32_t exception, - uint32_t error_code) -{ - raise_exception_err_ra(env, exception, error_code, 0); -} - -void raise_exception(CPUPPCState *env, uint32_t exception) -{ - raise_exception_err_ra(env, exception, 0, 0); -} - #ifdef CONFIG_TCG -void helper_raise_exception_err(CPUPPCState *env, uint32_t exception, - uint32_t error_code) -{ - raise_exception_err_ra(env, exception, error_code, 0); -} - -void helper_raise_exception(CPUPPCState *env, uint32_t exception) -{ - raise_exception_err_ra(env, exception, 0, 0); -} #ifndef CONFIG_USER_ONLY void helper_store_msr(CPUPPCState *env, target_ulong val) diff --git a/target/ppc/tcg-excp_helper.c b/target/ppc/tcg-excp_helper.c index 93c2d6b5a0..268a161459 100644 --- a/target/ppc/tcg-excp_helper.c +++ b/target/ppc/tcg-excp_helper.c @@ -19,15 +19,53 @@ #include "qemu/osdep.h" #include "qemu/log.h" #include "exec/cpu_ldst.h" +#include "exec/exec-all.h" +#include "exec/helper-proto.h" #include "system/runstate.h" +#include "helper_regs.h" #include "hw/ppc/ppc.h" #include "internal.h" #include "cpu.h" #include "trace.h" +/*****************************************************************************/ +/* Exceptions processing helpers */ + +void raise_exception_err_ra(CPUPPCState *env, uint32_t exception, + uint32_t error_code, uintptr_t raddr) +{ + CPUState *cs = env_cpu(env); + + cs->exception_index = exception; + env->error_code = error_code; + cpu_loop_exit_restore(cs, raddr); +} + +void helper_raise_exception_err(CPUPPCState *env, uint32_t exception, + uint32_t error_code) +{ + raise_exception_err_ra(env, exception, error_code, 0); +} + +void helper_raise_exception(CPUPPCState *env, uint32_t exception) +{ + raise_exception_err_ra(env, exception, 0, 0); +} + #ifndef CONFIG_USER_ONLY +void raise_exception_err(CPUPPCState *env, uint32_t exception, + uint32_t error_code) +{ + raise_exception_err_ra(env, exception, error_code, 0); +} + +void raise_exception(CPUPPCState *env, uint32_t exception) +{ + raise_exception_err_ra(env, exception, 0, 0); +} + void ppc_cpu_do_unaligned_access(CPUState *cs, vaddr vaddr, MMUAccessType access_type, int mmu_idx, uintptr_t retaddr) From patchwork Tue Mar 11 12:57:44 2025 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: Nicholas Piggin X-Patchwork-Id: 14011844 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.lore.kernel.org (Postfix) with ESMTPS id B889AC282EC for ; Tue, 11 Mar 2025 13:15:15 +0000 (UTC) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1trzI6-0001f3-31; Tue, 11 Mar 2025 09:05:03 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1trzEI-0005QP-Qa; Tue, 11 Mar 2025 09:01:10 -0400 Received: from mail-pl1-x62d.google.com ([2607:f8b0:4864:20::62d]) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_128_GCM_SHA256:128) (Exim 4.90_1) (envelope-from ) id 1trzED-0000CT-QB; Tue, 11 Mar 2025 09:01:04 -0400 Received: by mail-pl1-x62d.google.com with SMTP id d9443c01a7336-22355618fd9so99664825ad.3; Tue, 11 Mar 2025 06:01:01 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20230601; t=1741698059; x=1742302859; darn=nongnu.org; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to; bh=Biw+0LaKs2HJdMoWQD130jxziht29GfeWu2Z9l8GRBs=; b=jNgGFDfs+JE4sbk8FPEcPOiBf2oLd8vucgPWU6NrziL5kR2Lf/WfdVQqi5fod8WWFi Mt5PtO5KZvRTvV6Dg+xVcq4nypNLe3B4+9tDFrPXlSpaKhHVcmSq8NDqmJcGAjCL55Mw SAN4XqUqNQv/ZlpeRvXwxSH43ZG/5JAoncWx+r8iRQxqWJqhRRtePGG2QONWziotXj9W j+/i6a9Ug0PDEFAmQpY2uq84fLhnSc0X7bFRCZrGpBSiTovnMmxUzCl1T+grDPXsgBDo J+64yMUvrK+49RSH9y4LdovP/OeWkXuyrMzpQmATVOdVrWPK1uDGo0nomiZNSHSA6Eh2 6dBQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1741698059; x=1742302859; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=Biw+0LaKs2HJdMoWQD130jxziht29GfeWu2Z9l8GRBs=; b=fM4tjZzEa9l28/ytnGyPPHWQuwwOZ1LQYs0e897Cp0aWuEeulq2NIrSBrBlPzmoIjF xqXjAEt6RwrR5JqQd6YWyRMIb/1d8zk4IOqrA2XVysqBzp0nLn45U9fxktVdNmBGEZBf 7cZbpDGJrQ7wk0IqwgNatX2/KKvm/tyTLZclDCwNNIyJqMxSzt/KXbdgMTzOztAGDTB2 lwJZRbjUnRGUac4D3Ya91J/ArRHZMBBPq77aM8egtPcKQoJLlmdd/Lc26TmRbpxXo7F7 lHY5ePfSpmJNm0BonIb7Y9bXeaHghfXZdeiKVq+WKnj5/5daA7BEMGQDsabHDB/QM69R ZXSA== X-Forwarded-Encrypted: i=1; AJvYcCW9Ys8zXU+SLE73bhNCYMKI2mUqsZGsR5PhXFwTeUthNQ0E5x4dpHU5ByxufiDvft427O2VK/ubLQ==@nongnu.org X-Gm-Message-State: AOJu0YwYBiXH+ElDlBfW1UUXeCCdr+9a1cjCFuWnCKMX45tPWjT2wok/ gyK+JWp/GGDHYpEMxIkiwDIN90SgIPLhnpUxxMJY5sjSJ0YSxGOZQJC2Bw== X-Gm-Gg: ASbGncsU3BQWghfGrrS1mg/8d1DwLZ/HoegM4pYdqqSWr1DgO+JsYoV4HSHKWsVb2zq ju1MdYXot9Qll6b0083DbEbui7gnWZngl+Kk5iTdC9md8BsU3a6uFUrPhP29zbqZHBLiAC21qac iXlndXexSN2K4IrqiF8oAkGJ8EUVD/H5ooZkDkQ1V9eZdOB3UL0COdRv7T/AYTbd/TaZZwxQRqG mPgj9gvygHzIBWrp1zrtSs+Q98k6wkcYADQpQxYYwu2Jap6d/C8z1fkTeNURGMly0Bswmy9Jk7U jdHZqzf63I23qLfwkv2vFJF7rcvzwXMxmNXEBR5cnM5WeZvkRwY= X-Google-Smtp-Source: AGHT+IEN2raaLOqVO0ZPFX4PCEgIolIjqfTVMFmar8x3HrSJ/wAhF1QBtB3+lHf9sRyqOCUeLk3sHA== X-Received: by 2002:a17:902:d2cd:b0:224:255b:c934 with SMTP id d9443c01a7336-225931af86amr33975445ad.51.1741698059286; Tue, 11 Mar 2025 06:00:59 -0700 (PDT) Received: from wheely.local0.net ([118.208.151.101]) by smtp.gmail.com with ESMTPSA id 98e67ed59e1d1-2ff4e773dddsm11822318a91.12.2025.03.11.06.00.56 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 11 Mar 2025 06:00:58 -0700 (PDT) From: Nicholas Piggin To: qemu-devel@nongnu.org Cc: Nicholas Piggin , qemu-ppc@nongnu.org, =?utf-8?q?Phil?= =?utf-8?q?ippe_Mathieu-Daud=C3=A9?= , Harsh Prateek Bora Subject: [PULL 50/72] target/ppc: Restrict various common helpers to TCG Date: Tue, 11 Mar 2025 22:57:44 +1000 Message-ID: <20250311125815.903177-51-npiggin@gmail.com> X-Mailer: git-send-email 2.47.1 In-Reply-To: <20250311125815.903177-1-npiggin@gmail.com> References: <20250311125815.903177-1-npiggin@gmail.com> MIME-Version: 1.0 Received-SPF: pass client-ip=2607:f8b0:4864:20::62d; envelope-from=npiggin@gmail.com; helo=mail-pl1-x62d.google.com X-Spam_score_int: -20 X-Spam_score: -2.1 X-Spam_bar: -- X-Spam_report: (-2.1 / 5.0 requ) BAYES_00=-1.9, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_AU=-0.1, DKIM_VALID_EF=-0.1, FREEMAIL_FROM=0.001, RCVD_IN_DNSWL_NONE=-0.0001, SPF_HELO_NONE=0.001, SPF_PASS=-0.001 autolearn=ham autolearn_force=no X-Spam_action: no action X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: qemu-devel-bounces+qemu-devel=archiver.kernel.org@nongnu.org Sender: qemu-devel-bounces+qemu-devel=archiver.kernel.org@nongnu.org From: Philippe Mathieu-Daudé Move helpers common to system/user emulation to tcg-excp_helper.c. Signed-off-by: Philippe Mathieu-Daudé Reviewed-by: Harsh Prateek Bora Message-ID: <20250127102620.39159-12-philmd@linaro.org> Signed-off-by: Nicholas Piggin --- target/ppc/excp_helper.c | 141 ---------------------------------- target/ppc/tcg-excp_helper.c | 143 +++++++++++++++++++++++++++++++++++ 2 files changed, 143 insertions(+), 141 deletions(-) diff --git a/target/ppc/excp_helper.c b/target/ppc/excp_helper.c index 6a12402b23..511e27f726 100644 --- a/target/ppc/excp_helper.c +++ b/target/ppc/excp_helper.c @@ -2711,148 +2711,7 @@ void helper_rfmci(CPUPPCState *env) /* FIXME: choose CSRR1 or MCSRR1 based on cpu type */ do_rfi(env, env->spr[SPR_BOOKE_MCSRR0], env->spr[SPR_BOOKE_MCSRR1]); } -#endif /* !CONFIG_USER_ONLY */ - -void helper_TW(CPUPPCState *env, target_ulong arg1, target_ulong arg2, - uint32_t flags) -{ - if (!likely(!(((int32_t)arg1 < (int32_t)arg2 && (flags & 0x10)) || - ((int32_t)arg1 > (int32_t)arg2 && (flags & 0x08)) || - ((int32_t)arg1 == (int32_t)arg2 && (flags & 0x04)) || - ((uint32_t)arg1 < (uint32_t)arg2 && (flags & 0x02)) || - ((uint32_t)arg1 > (uint32_t)arg2 && (flags & 0x01))))) { - raise_exception_err_ra(env, POWERPC_EXCP_PROGRAM, - POWERPC_EXCP_TRAP, GETPC()); - } -} - -#ifdef TARGET_PPC64 -void helper_TD(CPUPPCState *env, target_ulong arg1, target_ulong arg2, - uint32_t flags) -{ - if (!likely(!(((int64_t)arg1 < (int64_t)arg2 && (flags & 0x10)) || - ((int64_t)arg1 > (int64_t)arg2 && (flags & 0x08)) || - ((int64_t)arg1 == (int64_t)arg2 && (flags & 0x04)) || - ((uint64_t)arg1 < (uint64_t)arg2 && (flags & 0x02)) || - ((uint64_t)arg1 > (uint64_t)arg2 && (flags & 0x01))))) { - raise_exception_err_ra(env, POWERPC_EXCP_PROGRAM, - POWERPC_EXCP_TRAP, GETPC()); - } -} -#endif /* TARGET_PPC64 */ - -static uint32_t helper_SIMON_LIKE_32_64(uint32_t x, uint64_t key, uint32_t lane) -{ - const uint16_t c = 0xfffc; - const uint64_t z0 = 0xfa2561cdf44ac398ULL; - uint16_t z = 0, temp; - uint16_t k[32], eff_k[32], xleft[33], xright[33], fxleft[32]; - - for (int i = 3; i >= 0; i--) { - k[i] = key & 0xffff; - key >>= 16; - } - xleft[0] = x & 0xffff; - xright[0] = (x >> 16) & 0xffff; - - for (int i = 0; i < 28; i++) { - z = (z0 >> (63 - i)) & 1; - temp = ror16(k[i + 3], 3) ^ k[i + 1]; - k[i + 4] = c ^ z ^ k[i] ^ temp ^ ror16(temp, 1); - } - - for (int i = 0; i < 8; i++) { - eff_k[4 * i + 0] = k[4 * i + ((0 + lane) % 4)]; - eff_k[4 * i + 1] = k[4 * i + ((1 + lane) % 4)]; - eff_k[4 * i + 2] = k[4 * i + ((2 + lane) % 4)]; - eff_k[4 * i + 3] = k[4 * i + ((3 + lane) % 4)]; - } - - for (int i = 0; i < 32; i++) { - fxleft[i] = (rol16(xleft[i], 1) & - rol16(xleft[i], 8)) ^ rol16(xleft[i], 2); - xleft[i + 1] = xright[i] ^ fxleft[i] ^ eff_k[i]; - xright[i + 1] = xleft[i]; - } - - return (((uint32_t)xright[32]) << 16) | xleft[32]; -} -static uint64_t hash_digest(uint64_t ra, uint64_t rb, uint64_t key) -{ - uint64_t stage0_h = 0ULL, stage0_l = 0ULL; - uint64_t stage1_h, stage1_l; - - for (int i = 0; i < 4; i++) { - stage0_h |= ror64(rb & 0xff, 8 * (2 * i + 1)); - stage0_h |= ((ra >> 32) & 0xff) << (8 * 2 * i); - stage0_l |= ror64((rb >> 32) & 0xff, 8 * (2 * i + 1)); - stage0_l |= (ra & 0xff) << (8 * 2 * i); - rb >>= 8; - ra >>= 8; - } - - stage1_h = (uint64_t)helper_SIMON_LIKE_32_64(stage0_h >> 32, key, 0) << 32; - stage1_h |= helper_SIMON_LIKE_32_64(stage0_h, key, 1); - stage1_l = (uint64_t)helper_SIMON_LIKE_32_64(stage0_l >> 32, key, 2) << 32; - stage1_l |= helper_SIMON_LIKE_32_64(stage0_l, key, 3); - - return stage1_h ^ stage1_l; -} - -static void do_hash(CPUPPCState *env, target_ulong ea, target_ulong ra, - target_ulong rb, uint64_t key, bool store) -{ - uint64_t calculated_hash = hash_digest(ra, rb, key), loaded_hash; - - if (store) { - cpu_stq_data_ra(env, ea, calculated_hash, GETPC()); - } else { - loaded_hash = cpu_ldq_data_ra(env, ea, GETPC()); - if (loaded_hash != calculated_hash) { - raise_exception_err_ra(env, POWERPC_EXCP_PROGRAM, - POWERPC_EXCP_TRAP, GETPC()); - } - } -} - -#include "qemu/guest-random.h" - -#ifdef TARGET_PPC64 -#define HELPER_HASH(op, key, store, dexcr_aspect) \ -void helper_##op(CPUPPCState *env, target_ulong ea, target_ulong ra, \ - target_ulong rb) \ -{ \ - if (env->msr & R_MSR_PR_MASK) { \ - if (!(env->spr[SPR_DEXCR] & R_DEXCR_PRO_##dexcr_aspect##_MASK || \ - env->spr[SPR_HDEXCR] & R_HDEXCR_ENF_##dexcr_aspect##_MASK)) \ - return; \ - } else if (!(env->msr & R_MSR_HV_MASK)) { \ - if (!(env->spr[SPR_DEXCR] & R_DEXCR_PNH_##dexcr_aspect##_MASK || \ - env->spr[SPR_HDEXCR] & R_HDEXCR_ENF_##dexcr_aspect##_MASK)) \ - return; \ - } else if (!(env->msr & R_MSR_S_MASK)) { \ - if (!(env->spr[SPR_HDEXCR] & R_HDEXCR_HNU_##dexcr_aspect##_MASK)) \ - return; \ - } \ - \ - do_hash(env, ea, ra, rb, key, store); \ -} -#else -#define HELPER_HASH(op, key, store, dexcr_aspect) \ -void helper_##op(CPUPPCState *env, target_ulong ea, target_ulong ra, \ - target_ulong rb) \ -{ \ - do_hash(env, ea, ra, rb, key, store); \ -} -#endif /* TARGET_PPC64 */ - -HELPER_HASH(HASHST, env->spr[SPR_HASHKEYR], true, NPHIE) -HELPER_HASH(HASHCHK, env->spr[SPR_HASHKEYR], false, NPHIE) -HELPER_HASH(HASHSTP, env->spr[SPR_HASHPKEYR], true, PHIE) -HELPER_HASH(HASHCHKP, env->spr[SPR_HASHPKEYR], false, PHIE) - -#ifndef CONFIG_USER_ONLY /* Embedded.Processor Control */ static int dbell2irq(target_ulong rb) { diff --git a/target/ppc/tcg-excp_helper.c b/target/ppc/tcg-excp_helper.c index 268a161459..2459d2d095 100644 --- a/target/ppc/tcg-excp_helper.c +++ b/target/ppc/tcg-excp_helper.c @@ -66,6 +66,149 @@ void raise_exception(CPUPPCState *env, uint32_t exception) raise_exception_err_ra(env, exception, 0, 0); } +#endif /* !CONFIG_USER_ONLY */ + +void helper_TW(CPUPPCState *env, target_ulong arg1, target_ulong arg2, + uint32_t flags) +{ + if (!likely(!(((int32_t)arg1 < (int32_t)arg2 && (flags & 0x10)) || + ((int32_t)arg1 > (int32_t)arg2 && (flags & 0x08)) || + ((int32_t)arg1 == (int32_t)arg2 && (flags & 0x04)) || + ((uint32_t)arg1 < (uint32_t)arg2 && (flags & 0x02)) || + ((uint32_t)arg1 > (uint32_t)arg2 && (flags & 0x01))))) { + raise_exception_err_ra(env, POWERPC_EXCP_PROGRAM, + POWERPC_EXCP_TRAP, GETPC()); + } +} + +#ifdef TARGET_PPC64 +void helper_TD(CPUPPCState *env, target_ulong arg1, target_ulong arg2, + uint32_t flags) +{ + if (!likely(!(((int64_t)arg1 < (int64_t)arg2 && (flags & 0x10)) || + ((int64_t)arg1 > (int64_t)arg2 && (flags & 0x08)) || + ((int64_t)arg1 == (int64_t)arg2 && (flags & 0x04)) || + ((uint64_t)arg1 < (uint64_t)arg2 && (flags & 0x02)) || + ((uint64_t)arg1 > (uint64_t)arg2 && (flags & 0x01))))) { + raise_exception_err_ra(env, POWERPC_EXCP_PROGRAM, + POWERPC_EXCP_TRAP, GETPC()); + } +} +#endif /* TARGET_PPC64 */ + +static uint32_t helper_SIMON_LIKE_32_64(uint32_t x, uint64_t key, uint32_t lane) +{ + const uint16_t c = 0xfffc; + const uint64_t z0 = 0xfa2561cdf44ac398ULL; + uint16_t z = 0, temp; + uint16_t k[32], eff_k[32], xleft[33], xright[33], fxleft[32]; + + for (int i = 3; i >= 0; i--) { + k[i] = key & 0xffff; + key >>= 16; + } + xleft[0] = x & 0xffff; + xright[0] = (x >> 16) & 0xffff; + + for (int i = 0; i < 28; i++) { + z = (z0 >> (63 - i)) & 1; + temp = ror16(k[i + 3], 3) ^ k[i + 1]; + k[i + 4] = c ^ z ^ k[i] ^ temp ^ ror16(temp, 1); + } + + for (int i = 0; i < 8; i++) { + eff_k[4 * i + 0] = k[4 * i + ((0 + lane) % 4)]; + eff_k[4 * i + 1] = k[4 * i + ((1 + lane) % 4)]; + eff_k[4 * i + 2] = k[4 * i + ((2 + lane) % 4)]; + eff_k[4 * i + 3] = k[4 * i + ((3 + lane) % 4)]; + } + + for (int i = 0; i < 32; i++) { + fxleft[i] = (rol16(xleft[i], 1) & + rol16(xleft[i], 8)) ^ rol16(xleft[i], 2); + xleft[i + 1] = xright[i] ^ fxleft[i] ^ eff_k[i]; + xright[i + 1] = xleft[i]; + } + + return (((uint32_t)xright[32]) << 16) | xleft[32]; +} + +static uint64_t hash_digest(uint64_t ra, uint64_t rb, uint64_t key) +{ + uint64_t stage0_h = 0ULL, stage0_l = 0ULL; + uint64_t stage1_h, stage1_l; + + for (int i = 0; i < 4; i++) { + stage0_h |= ror64(rb & 0xff, 8 * (2 * i + 1)); + stage0_h |= ((ra >> 32) & 0xff) << (8 * 2 * i); + stage0_l |= ror64((rb >> 32) & 0xff, 8 * (2 * i + 1)); + stage0_l |= (ra & 0xff) << (8 * 2 * i); + rb >>= 8; + ra >>= 8; + } + + stage1_h = (uint64_t)helper_SIMON_LIKE_32_64(stage0_h >> 32, key, 0) << 32; + stage1_h |= helper_SIMON_LIKE_32_64(stage0_h, key, 1); + stage1_l = (uint64_t)helper_SIMON_LIKE_32_64(stage0_l >> 32, key, 2) << 32; + stage1_l |= helper_SIMON_LIKE_32_64(stage0_l, key, 3); + + return stage1_h ^ stage1_l; +} + +static void do_hash(CPUPPCState *env, target_ulong ea, target_ulong ra, + target_ulong rb, uint64_t key, bool store) +{ + uint64_t calculated_hash = hash_digest(ra, rb, key), loaded_hash; + + if (store) { + cpu_stq_data_ra(env, ea, calculated_hash, GETPC()); + } else { + loaded_hash = cpu_ldq_data_ra(env, ea, GETPC()); + if (loaded_hash != calculated_hash) { + raise_exception_err_ra(env, POWERPC_EXCP_PROGRAM, + POWERPC_EXCP_TRAP, GETPC()); + } + } +} + +#include "qemu/guest-random.h" + +#ifdef TARGET_PPC64 +#define HELPER_HASH(op, key, store, dexcr_aspect) \ +void helper_##op(CPUPPCState *env, target_ulong ea, target_ulong ra, \ + target_ulong rb) \ +{ \ + if (env->msr & R_MSR_PR_MASK) { \ + if (!(env->spr[SPR_DEXCR] & R_DEXCR_PRO_##dexcr_aspect##_MASK || \ + env->spr[SPR_HDEXCR] & R_HDEXCR_ENF_##dexcr_aspect##_MASK)) \ + return; \ + } else if (!(env->msr & R_MSR_HV_MASK)) { \ + if (!(env->spr[SPR_DEXCR] & R_DEXCR_PNH_##dexcr_aspect##_MASK || \ + env->spr[SPR_HDEXCR] & R_HDEXCR_ENF_##dexcr_aspect##_MASK)) \ + return; \ + } else if (!(env->msr & R_MSR_S_MASK)) { \ + if (!(env->spr[SPR_HDEXCR] & R_HDEXCR_HNU_##dexcr_aspect##_MASK)) \ + return; \ + } \ + \ + do_hash(env, ea, ra, rb, key, store); \ +} +#else +#define HELPER_HASH(op, key, store, dexcr_aspect) \ +void helper_##op(CPUPPCState *env, target_ulong ea, target_ulong ra, \ + target_ulong rb) \ +{ \ + do_hash(env, ea, ra, rb, key, store); \ +} +#endif /* TARGET_PPC64 */ + +HELPER_HASH(HASHST, env->spr[SPR_HASHKEYR], true, NPHIE) +HELPER_HASH(HASHCHK, env->spr[SPR_HASHKEYR], false, NPHIE) +HELPER_HASH(HASHSTP, env->spr[SPR_HASHPKEYR], true, PHIE) +HELPER_HASH(HASHCHKP, env->spr[SPR_HASHPKEYR], false, PHIE) + +#ifndef CONFIG_USER_ONLY + void ppc_cpu_do_unaligned_access(CPUState *cs, vaddr vaddr, MMUAccessType access_type, int mmu_idx, uintptr_t retaddr) From patchwork Tue Mar 11 12:57:45 2025 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: Nicholas Piggin X-Patchwork-Id: 14011821 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.lore.kernel.org (Postfix) with ESMTPS id B78ADC282EC for ; Tue, 11 Mar 2025 13:09:58 +0000 (UTC) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1trzID-0001wZ-Vi; Tue, 11 Mar 2025 09:05:12 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1trzEN-0005TL-Ui; Tue, 11 Mar 2025 09:01:21 -0400 Received: from mail-pj1-x102c.google.com ([2607:f8b0:4864:20::102c]) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_128_GCM_SHA256:128) (Exim 4.90_1) (envelope-from ) id 1trzEJ-0000DH-2M; Tue, 11 Mar 2025 09:01:11 -0400 Received: by mail-pj1-x102c.google.com with SMTP id 98e67ed59e1d1-2ff80290debso7724277a91.3; Tue, 11 Mar 2025 06:01:03 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20230601; t=1741698062; x=1742302862; darn=nongnu.org; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to; bh=VAXQPpG8yd5CXPgOFWtFPIwtpv24G2eRO8aH++zGVxo=; b=G0Zm74GA1pzpklSPTPSacE1hJP4V0G36ex4nKhOHlf26g7Bz6y57HAHo6fMWSZa6Wj 2JbAUA2MIeDl3787lVzG0Odho+8xYVTB+2PSdosWF1qzcAxBNWSSsTVzfxVG/pvIKmcU g/1c8oIEBoo+kTjVAoQBhoZ/UQ8aW7TckLhBPjBSbzbJLiNjpb/+Tk7fXb2gG0sZqLc4 DpG5bkiO3Rp0NXTl31igvUQ3SZhotNTYHgTBNwX/lHi5zyq6O0BQimOTxgCRHe0dWkBU g1l1kuFkFjsz3sSyv6A8wb9oFl4EzjQ20X+ZOa6bsXGmGdyysliK5a8aL7+U59alBZf/ IwVA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1741698062; x=1742302862; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=VAXQPpG8yd5CXPgOFWtFPIwtpv24G2eRO8aH++zGVxo=; b=bpxMZJPRi5TbWsCe1b6WbLxlua052m4RSnxjY9raZrEIdrbabUbloF6ubOvkMs3Y/t S0pRaxF8zGwXNMlyOHt192WcfBkQJD7xa5qlJmiRDZoKoMh9eg3xFLZl+x/idCOCTIKq vBOo4Ykxw87DYTmICgzkU+HxoJ/wnxYfwkh8dLRaEBmSlN01V9Y+xEBBGHOC2zqhl/8V jjVXnge4okPIxTrB+fmo6itOwHS6KpjZoPctamh2igwESZZDOruR0YHy+Sr0mXAqt/T0 CLo9IGwQYmRdTuhxoDWKpMZuGNGNduth8HcBIuHNphKldAx360cPObpnybNiAp1nSjkz eziw== X-Forwarded-Encrypted: i=1; AJvYcCVRKEjNiDuoN7UBiJQy5WIA5B4WZsak93ZAm5IDZI++KNve+1rELh7BAIV0Sds+p6TM6TQf1erndA==@nongnu.org X-Gm-Message-State: AOJu0YweEl9/qmsLDBiQgnRMttuTFOGP1jCS11oCgh6xktUiw6BY+i4L u28BeLYckAiRSY25KNYqATxC49bQcHmJ5ERYDH78MkX43JkH7tXtj8g+DA== X-Gm-Gg: ASbGnctnIOpq6Gx5V++I+XFeVH2FjgvrPYd9bwzTBtMl1TTAvbPxkkKynmWqr0flW9m LnVrlszoFRUvoarcasy1vSiTa0nSdGT8yJUWIKeUY6ayCqscdxBpkTvNGkwMPFlKXX6GiWjEfjw hjtaUjL3pTaSYcM8KS4Ibp8HL487a4b70zB08JF62RdcBFY0xHzkghynJtc2SJ5vOFucOG6PsnQ EytqbR92Hm9RTZWXF86lBL5/TGhaNTE6m/IdIrm75kQRTRuBqv/vfC9jixzQf2WVmDHcVR/MNPm RavAVgK0nJA+BXlQM4scIMK4uKw9c8RstILpCICnykd7dtm2wiU= X-Google-Smtp-Source: AGHT+IEJvJex1riie9VM+bWx3XlnhXhRmXd5P61c4kiVRPjzQmZVW6m/KZ7BsyvbNOgHzGmhMPAdtg== X-Received: by 2002:a17:90b:390c:b0:2f9:cf97:56a6 with SMTP id 98e67ed59e1d1-2ff7ce63ffbmr29281898a91.14.1741698062313; Tue, 11 Mar 2025 06:01:02 -0700 (PDT) Received: from wheely.local0.net ([118.208.151.101]) by smtp.gmail.com with ESMTPSA id 98e67ed59e1d1-2ff4e773dddsm11822318a91.12.2025.03.11.06.00.59 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 11 Mar 2025 06:01:01 -0700 (PDT) From: Nicholas Piggin To: qemu-devel@nongnu.org Cc: Nicholas Piggin , qemu-ppc@nongnu.org, =?utf-8?q?Phil?= =?utf-8?q?ippe_Mathieu-Daud=C3=A9?= , Harsh Prateek Bora Subject: [PULL 51/72] target/ppc: Fix style in excp_helper.c Date: Tue, 11 Mar 2025 22:57:45 +1000 Message-ID: <20250311125815.903177-52-npiggin@gmail.com> X-Mailer: git-send-email 2.47.1 In-Reply-To: <20250311125815.903177-1-npiggin@gmail.com> References: <20250311125815.903177-1-npiggin@gmail.com> MIME-Version: 1.0 Received-SPF: pass client-ip=2607:f8b0:4864:20::102c; envelope-from=npiggin@gmail.com; helo=mail-pj1-x102c.google.com X-Spam_score_int: -16 X-Spam_score: -1.7 X-Spam_bar: - X-Spam_report: (-1.7 / 5.0 requ) BAYES_00=-1.9, DKIM_INVALID=0.1, DKIM_SIGNED=0.1, FREEMAIL_FROM=0.001, RCVD_IN_DNSWL_NONE=-0.0001, SPF_HELO_NONE=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.29 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: qemu-devel-bounces+qemu-devel=archiver.kernel.org@nongnu.org Sender: qemu-devel-bounces+qemu-devel=archiver.kernel.org@nongnu.org From: Philippe Mathieu-Daudé Fix style in do_rfi() before moving the code around. Signed-off-by: Philippe Mathieu-Daudé Reviewed-by: Harsh Prateek Bora Message-ID: <20250127102620.39159-13-philmd@linaro.org> Signed-off-by: Nicholas Piggin --- target/ppc/excp_helper.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/target/ppc/excp_helper.c b/target/ppc/excp_helper.c index 511e27f726..659852543f 100644 --- a/target/ppc/excp_helper.c +++ b/target/ppc/excp_helper.c @@ -2558,8 +2558,9 @@ static void do_rfi(CPUPPCState *env, target_ulong nip, target_ulong msr) msr &= ~(1ULL << MSR_POW); /* MSR:TGPR cannot be set by any form of rfi */ - if (env->flags & POWERPC_FLAG_TGPR) + if (env->flags & POWERPC_FLAG_TGPR) { msr &= ~(1ULL << MSR_TGPR); + } #ifdef TARGET_PPC64 /* Switching to 32-bit ? Crop the nip */ From patchwork Tue Mar 11 12:57:46 2025 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: Nicholas Piggin X-Patchwork-Id: 14011823 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.lore.kernel.org (Postfix) with ESMTPS id 19441C28B30 for ; Tue, 11 Mar 2025 13:11:08 +0000 (UTC) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1trzKx-0002TN-Cf; Tue, 11 Mar 2025 09:07:59 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1trzEN-0005TK-Sp; Tue, 11 Mar 2025 09:01:21 -0400 Received: from mail-pj1-x1036.google.com ([2607:f8b0:4864:20::1036]) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_128_GCM_SHA256:128) (Exim 4.90_1) (envelope-from ) id 1trzEK-0000Db-IS; Tue, 11 Mar 2025 09:01:10 -0400 Received: by mail-pj1-x1036.google.com with SMTP id 98e67ed59e1d1-2feae794508so8085970a91.0; Tue, 11 Mar 2025 06:01:06 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20230601; t=1741698065; x=1742302865; darn=nongnu.org; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to; bh=5Qg32i2ZNEVpFinMGEejCFLsCi4jerRMng5QMzQ5ljg=; b=jPOZJ1W6a7aU1DT7kM0gJiUtabIfAzBQb4KKuH26N0KVhsiWN8YCeVLipCpN7B/zC+ y2DYd8Xb/Yph0IdPxGmUTKz0GiqWoSd0Zc1nIofNqDh6uq17ooVECq357hRBRAw1gMqE 4y6MPGXX4It96/6JjjmFOq6b7w1kkd1bE0OcOBqtP1Wj52GiyCQtHr4CUJ4PVCYP6TU1 L8GJwNXd5VM5ocge0sXvJYUUNh5FXpfK8ks4aGV5ubii17gB8BOuD4Y1KX0GRcSLaEEp LWLYOmmXVJfu2PSzeHm7ad5I/0cebsZlfd5I2CyMgvggkOerjps2CcY21l9iBu9tNj64 L7Qw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1741698065; x=1742302865; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=5Qg32i2ZNEVpFinMGEejCFLsCi4jerRMng5QMzQ5ljg=; b=IdqH/hlw4he3UCoVoeyEAB8EpozjnY/dhVCpEkZLlrJB9a0+9dQUMmHlcrDhUtB4ZV YGC5n3ToYhnpk8SMLygpOQQ+E3Sa4rBqjGAJKs/Sdmka27rdu6IfcJIAe6Cl0P0LFDqO P9wGhJDEDozFUACbSrPgKENjBwZ6xHTCW5++iykDzmHXTd5wkVK+sKL1DojkFyjh5CZs SxjQL5ueodq5jZgtew0P8eHFnQQzSiAK8ziXLnDeSnBldkfG/QZDd5Q/+/Zz8lThjdCc H9nwzanTEIp/bLDVwEgSTf0EF1EJfqcTCohp3hATZrweckCqSwfQp0EK58rdrlZwpgGX f62A== X-Forwarded-Encrypted: i=1; AJvYcCVeSkxcgUlu7YwIP65J3tMk8i17+OdlUgQI3UYeHGdsw1CbtH+CeMo6Pm+10LDiDjp6K3xOQneKWQ==@nongnu.org X-Gm-Message-State: AOJu0YyIlBmgbFYmqzuzbHnqfSOht+W7rD3oGnQmDSMKaVa6zUD5tIrD uTwDbGae/v3Yrc7PSDC6leHU1l40q5BnEBHYSe5TEtLpF9ZD8L9orWPtjw== X-Gm-Gg: ASbGncsD74c4hbiuy+05dcEIcw79DfWJ0FxwOrA/+U+j7DEW/cdXkw++OXXFtT81j96 6k9CyEzPLjSNJ32DeCfjP43O8maPEVFXFVoUtm99dg78hWFQ1N83SOVimIcA1+P0adUb1i4HijD ATv3oYr9RiYPJ0QBgAZtFxmXUEucCJMLGTkvJ3aWUwMwniCY9frycS9aB3BjwCfLqk1rZsndQz7 HlmFaadjM/J7/Z/aaqcEcOOgpFX64PfDtP1oBbdxMZJgFktihnQptoGpcAEGo8ZuDQTgmnc9ja2 gixdNTXYE1JW4xgXrZFiFdPnMDaNVGBUQ36mLvE0w9OJMJgVlk8= X-Google-Smtp-Source: AGHT+IEwarqDwS1tOb+Lcio8qbjL4V185hjh6m8ZxICy60WOf2aj6Auap8YBaJFrK7xSUUIxW68g1Q== X-Received: by 2002:a17:90b:1c05:b0:2ee:a583:e616 with SMTP id 98e67ed59e1d1-2ff7ce6d543mr27902162a91.9.1741698065313; Tue, 11 Mar 2025 06:01:05 -0700 (PDT) Received: from wheely.local0.net ([118.208.151.101]) by smtp.gmail.com with ESMTPSA id 98e67ed59e1d1-2ff4e773dddsm11822318a91.12.2025.03.11.06.01.02 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 11 Mar 2025 06:01:04 -0700 (PDT) From: Nicholas Piggin To: qemu-devel@nongnu.org Cc: Nicholas Piggin , qemu-ppc@nongnu.org, =?utf-8?q?Phil?= =?utf-8?q?ippe_Mathieu-Daud=C3=A9?= , Harsh Prateek Bora Subject: [PULL 52/72] target/ppc: Make powerpc_excp() prototype public Date: Tue, 11 Mar 2025 22:57:46 +1000 Message-ID: <20250311125815.903177-53-npiggin@gmail.com> X-Mailer: git-send-email 2.47.1 In-Reply-To: <20250311125815.903177-1-npiggin@gmail.com> References: <20250311125815.903177-1-npiggin@gmail.com> MIME-Version: 1.0 Received-SPF: pass client-ip=2607:f8b0:4864:20::1036; envelope-from=npiggin@gmail.com; helo=mail-pj1-x1036.google.com X-Spam_score_int: -20 X-Spam_score: -2.1 X-Spam_bar: -- X-Spam_report: (-2.1 / 5.0 requ) BAYES_00=-1.9, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_AU=-0.1, DKIM_VALID_EF=-0.1, FREEMAIL_FROM=0.001, RCVD_IN_DNSWL_NONE=-0.0001, SPF_HELO_NONE=0.001, SPF_PASS=-0.001 autolearn=ham autolearn_force=no X-Spam_action: no action X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: qemu-devel-bounces+qemu-devel=archiver.kernel.org@nongnu.org Sender: qemu-devel-bounces+qemu-devel=archiver.kernel.org@nongnu.org From: Philippe Mathieu-Daudé In order to move TCG specific code dependent on powerpc_excp() in the next commit, expose its prototype in "internal.h". Signed-off-by: Philippe Mathieu-Daudé Reviewed-by: Harsh Prateek Bora Message-ID: <20250127102620.39159-14-philmd@linaro.org> Signed-off-by: Nicholas Piggin --- target/ppc/excp_helper.c | 2 +- target/ppc/internal.h | 2 ++ 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/target/ppc/excp_helper.c b/target/ppc/excp_helper.c index 659852543f..9ba5335698 100644 --- a/target/ppc/excp_helper.c +++ b/target/ppc/excp_helper.c @@ -1571,7 +1571,7 @@ static inline void powerpc_excp_books(PowerPCCPU *cpu, int excp) } #endif /* TARGET_PPC64 */ -static void powerpc_excp(PowerPCCPU *cpu, int excp) +void powerpc_excp(PowerPCCPU *cpu, int excp) { CPUPPCState *env = &cpu->env; diff --git a/target/ppc/internal.h b/target/ppc/internal.h index 62186bc1e6..9012d3809c 100644 --- a/target/ppc/internal.h +++ b/target/ppc/internal.h @@ -291,6 +291,8 @@ bool ppc_cpu_debug_check_breakpoint(CPUState *cs); bool ppc_cpu_debug_check_watchpoint(CPUState *cs, CPUWatchpoint *wp); G_NORETURN void powerpc_checkstop(CPUPPCState *env, const char *reason); +void powerpc_excp(PowerPCCPU *cpu, int excp); + #endif /* !CONFIG_USER_ONLY */ FIELD(GER_MSK, XMSK, 0, 4) From patchwork Tue Mar 11 12:57:47 2025 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: Nicholas Piggin X-Patchwork-Id: 14011811 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.lore.kernel.org (Postfix) with ESMTPS id 8D8C1C28B2E for ; Tue, 11 Mar 2025 13:07:07 +0000 (UTC) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1trzIp-0002YC-P6; Tue, 11 Mar 2025 09:05:47 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1trzET-0005Uw-Bb; Tue, 11 Mar 2025 09:01:24 -0400 Received: from mail-pl1-x633.google.com ([2607:f8b0:4864:20::633]) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_128_GCM_SHA256:128) (Exim 4.90_1) (envelope-from ) id 1trzEP-0000EK-1N; Tue, 11 Mar 2025 09:01:17 -0400 Received: by mail-pl1-x633.google.com with SMTP id d9443c01a7336-2255003f4c6so49940685ad.0; Tue, 11 Mar 2025 06:01:10 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20230601; t=1741698069; x=1742302869; darn=nongnu.org; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to; bh=gOr0Iv0DC4pt8besb91uNgjRLEvbLePKXK2ZL6VXyUs=; b=SbeYQddCnmDPak1ipsZ9ONRB3vBMjdmuFbUPl10wxeIJjzx4n1b/2g5ivCybwi+cfK rnxt/GlutS9jvpWdi4p9mW6joDPbCz2cbAbsAyM3fKBkKQtb0PaOm6YJHNfXwFXMLanz DXYFslu/cnWZlcYi/2NOEhbgjJi6zwZ1ZcF43ZopN2kldINmXIRD62hFIm6aEqVEpPsX oUkYCTm0mfCyH1erSd1egetgszgmw5n+IqLHdcCVM4NEtZQNx1ZNa7lNTnsDW77fxDqk i+01oOpl34oD0/NtMMKpjhdfPFQxMcrBeVYrYxVTdVpeO7ZNPvJ/fpAGabXEUXbik03I 8YCA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1741698069; x=1742302869; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=gOr0Iv0DC4pt8besb91uNgjRLEvbLePKXK2ZL6VXyUs=; b=RD3z0IqU6Iz4Rxa9wjj20RRLNZBy4WoRSC/0lQK72oySr7V+DrE5/liGDJSdNUBpcd i5DLppGRf+b3JLEiYhPdT6A5IjQVe5IjEXcStgKkomWCwVoDjNTokhkHfR72qC3GJyKO YftoNmBiNur8buU03RVhXnKa4vkckKiUG5aRPgw8nxVDqZuwbdu1U7m5p4j+ovwpajku XqunGfT0TNEeltioiJnESpX4PgalCCDA/MnrGyLXnlmSL4c9uLsGX4M8s0vF2GcDihP4 SiUppATm5NCon9Q8wDASuZU4kmaIDSuLmL73F6nNEcyGZi1UH94jI80S0N3CJYncEdd2 70ng== X-Forwarded-Encrypted: i=1; AJvYcCXj97HoCXMK7Q2a9Q1t7FLcdKuLe17ZpiHjxuOgsoc09gazEX/OFI74lvoZVxE5jOpwYwN7QudjlQ==@nongnu.org X-Gm-Message-State: AOJu0Yxpc9cIRKasGIOccWWn9io6MmxYqOkYRxOhJ8ncIM43/nN9dkPn tfTOmGDIHaNlefYLb446R2Bow8Z3JfuxSUWYBoC7liuEDGnViOksh06VMA== X-Gm-Gg: ASbGnctxFx90mMJTbuxhr4kHJDlYqJ/Ymyn47ijRlyWKtTf5rLOX2uUbyF2g1PEOBx4 DM0mchPacXs63WDBmv1Z2vns7pq928X9gTrzBQ7nPOrJHRZl5SfhQHhuzX5lk39H1flccS/Y3O2 8Hfxn+b3fyWZuCbDAFdGCMwVTVgPUYHKM28czGPJX4TW7FyfDY8CVokagjXe8hLpubH2CfLvaMW HYe5P1a0rTCGTb8mvZdE0FbZr7uFSlglGWlu47pHHAh2Zv96Nwe2/fc/CLV+kn1S4lcxGtHmPcD vWp2Jpkb6cA/wk1ggWJEHERKC73MDVuIfvTWyQi7SQ2l/vnWwws= X-Google-Smtp-Source: AGHT+IExUlv0Jo62kwnGnHDajJY1AZaA8nuTSvQU84mIJwOieUTYENuxymwv7a/4IDwoozsO0bkrXw== X-Received: by 2002:a17:90b:2e8f:b0:2fe:b907:3b05 with SMTP id 98e67ed59e1d1-300ff3661a9mr4807699a91.29.1741698068472; Tue, 11 Mar 2025 06:01:08 -0700 (PDT) Received: from wheely.local0.net ([118.208.151.101]) by smtp.gmail.com with ESMTPSA id 98e67ed59e1d1-2ff4e773dddsm11822318a91.12.2025.03.11.06.01.05 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 11 Mar 2025 06:01:08 -0700 (PDT) From: Nicholas Piggin To: qemu-devel@nongnu.org Cc: Nicholas Piggin , qemu-ppc@nongnu.org, =?utf-8?q?Phil?= =?utf-8?q?ippe_Mathieu-Daud=C3=A9?= , Harsh Prateek Bora Subject: [PULL 53/72] target/ppc: Restrict ATTN / SCV / PMINSN helpers to TCG Date: Tue, 11 Mar 2025 22:57:47 +1000 Message-ID: <20250311125815.903177-54-npiggin@gmail.com> X-Mailer: git-send-email 2.47.1 In-Reply-To: <20250311125815.903177-1-npiggin@gmail.com> References: <20250311125815.903177-1-npiggin@gmail.com> MIME-Version: 1.0 Received-SPF: pass client-ip=2607:f8b0:4864:20::633; envelope-from=npiggin@gmail.com; helo=mail-pl1-x633.google.com X-Spam_score_int: -20 X-Spam_score: -2.1 X-Spam_bar: -- X-Spam_report: (-2.1 / 5.0 requ) BAYES_00=-1.9, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_AU=-0.1, DKIM_VALID_EF=-0.1, FREEMAIL_FROM=0.001, RCVD_IN_DNSWL_NONE=-0.0001, SPF_HELO_NONE=0.001, SPF_PASS=-0.001 autolearn=ham autolearn_force=no X-Spam_action: no action X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: qemu-devel-bounces+qemu-devel=archiver.kernel.org@nongnu.org Sender: qemu-devel-bounces+qemu-devel=archiver.kernel.org@nongnu.org From: Philippe Mathieu-Daudé Move helper_attn(), helper_scv() and helper_pminsn() to tcg-excp_helper.c. Signed-off-by: Philippe Mathieu-Daudé Reviewed-by: Harsh Prateek Bora Message-ID: <20250127102620.39159-15-philmd@linaro.org> Signed-off-by: Nicholas Piggin --- target/ppc/cpu.h | 3 - target/ppc/excp_helper.c | 434 ----------------------------------- target/ppc/tcg-excp_helper.c | 423 +++++++++++++++++++++++++++++++++- 3 files changed, 421 insertions(+), 439 deletions(-) diff --git a/target/ppc/cpu.h b/target/ppc/cpu.h index 505b589714..8d43983fe1 100644 --- a/target/ppc/cpu.h +++ b/target/ppc/cpu.h @@ -2755,9 +2755,6 @@ static inline void cpu_get_tb_cpu_state(CPUPPCState *env, vaddr *pc, } #endif -G_NORETURN void raise_exception(CPUPPCState *env, uint32_t exception); -G_NORETURN void raise_exception_err(CPUPPCState *env, uint32_t exception, - uint32_t error_code); G_NORETURN void raise_exception_err_ra(CPUPPCState *env, uint32_t exception, uint32_t error_code, uintptr_t raddr); diff --git a/target/ppc/excp_helper.c b/target/ppc/excp_helper.c index 9ba5335698..44e19aacd8 100644 --- a/target/ppc/excp_helper.c +++ b/target/ppc/excp_helper.c @@ -30,11 +30,6 @@ #include "trace.h" -#ifdef CONFIG_TCG -#include "exec/helper-proto.h" -#include "exec/cpu_ldst.h" -#endif - /*****************************************************************************/ /* Exception processing */ #ifndef CONFIG_USER_ONLY @@ -399,21 +394,6 @@ static void powerpc_set_excp_state(PowerPCCPU *cpu, target_ulong vector, env->reserve_addr = -1; } -#ifdef CONFIG_TCG -#if defined(TARGET_PPC64) && !defined(CONFIG_USER_ONLY) -void helper_attn(CPUPPCState *env) -{ - /* POWER attn is unprivileged when enabled by HID, otherwise illegal */ - if ((*env->check_attn)(env)) { - powerpc_checkstop(env, "host executed attn"); - } else { - raise_exception_err(env, POWERPC_EXCP_HV_EMU, - POWERPC_EXCP_INVAL | POWERPC_EXCP_INVAL_INVAL); - } -} -#endif -#endif /* CONFIG_TCG */ - static void powerpc_mcheck_checkstop(CPUPPCState *env) { /* KVM guests always have MSR[ME] enabled */ @@ -2503,417 +2483,3 @@ bool ppc_cpu_exec_interrupt(CPUState *cs, int interrupt_request) } #endif /* !CONFIG_USER_ONLY */ - -#ifdef CONFIG_TCG - -#ifndef CONFIG_USER_ONLY -void helper_store_msr(CPUPPCState *env, target_ulong val) -{ - uint32_t excp = hreg_store_msr(env, val, 0); - - if (excp != 0) { - cpu_interrupt_exittb(env_cpu(env)); - raise_exception(env, excp); - } -} - -void helper_ppc_maybe_interrupt(CPUPPCState *env) -{ - ppc_maybe_interrupt(env); -} - -#ifdef 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, uint32_t insn) -{ - CPUState *cs = env_cpu(env); - - cs->halted = 1; - - /* Condition for waking up at 0x100 */ - env->resume_as_sreset = (insn != PPC_PM_STOP) || - (env->spr[SPR_PSSCR] & PSSCR_EC); - - /* HDECR is not to wake from PM state, it may have already fired */ - if (env->resume_as_sreset) { - PowerPCCPU *cpu = env_archcpu(env); - ppc_set_irq(cpu, PPC_INTERRUPT_HDECR, 0); - } - - ppc_maybe_interrupt(env); -} -#endif /* TARGET_PPC64 */ - -static void do_rfi(CPUPPCState *env, target_ulong nip, target_ulong msr) -{ - /* MSR:POW cannot be set by any form of rfi */ - msr &= ~(1ULL << MSR_POW); - - /* MSR:TGPR cannot be set by any form of rfi */ - if (env->flags & POWERPC_FLAG_TGPR) { - msr &= ~(1ULL << MSR_TGPR); - } - -#ifdef TARGET_PPC64 - /* Switching to 32-bit ? Crop the nip */ - if (!msr_is_64bit(env, msr)) { - nip = (uint32_t)nip; - } -#else - nip = (uint32_t)nip; -#endif - /* XXX: beware: this is false if VLE is supported */ - env->nip = nip & ~((target_ulong)0x00000003); - hreg_store_msr(env, msr, 1); - trace_ppc_excp_rfi(env->nip, env->msr); - /* - * No need to raise an exception here, as rfi is always the last - * insn of a TB - */ - cpu_interrupt_exittb(env_cpu(env)); - /* Reset the reservation */ - env->reserve_addr = -1; - - /* Context synchronizing: check if TCG TLB needs flush */ - check_tlb_flush(env, false); -} - -void helper_rfi(CPUPPCState *env) -{ - do_rfi(env, env->spr[SPR_SRR0], env->spr[SPR_SRR1] & 0xfffffffful); -} - -#ifdef TARGET_PPC64 -void helper_rfid(CPUPPCState *env) -{ - /* - * The architecture defines a number of rules for which bits can - * change but in practice, we handle this in hreg_store_msr() - * which will be called by do_rfi(), so there is no need to filter - * here - */ - do_rfi(env, env->spr[SPR_SRR0], env->spr[SPR_SRR1]); -} - -void helper_rfscv(CPUPPCState *env) -{ - do_rfi(env, env->lr, env->ctr); -} - -void helper_hrfid(CPUPPCState *env) -{ - do_rfi(env, env->spr[SPR_HSRR0], env->spr[SPR_HSRR1]); -} - -void helper_rfebb(CPUPPCState *env, target_ulong s) -{ - target_ulong msr = env->msr; - - /* - * Handling of BESCR bits 32:33 according to PowerISA v3.1: - * - * "If BESCR 32:33 != 0b00 the instruction is treated as if - * the instruction form were invalid." - */ - if (env->spr[SPR_BESCR] & BESCR_INVALID) { - raise_exception_err(env, POWERPC_EXCP_PROGRAM, - POWERPC_EXCP_INVAL | POWERPC_EXCP_INVAL_INVAL); - } - - env->nip = env->spr[SPR_EBBRR]; - - /* Switching to 32-bit ? Crop the nip */ - if (!msr_is_64bit(env, msr)) { - env->nip = (uint32_t)env->spr[SPR_EBBRR]; - } - - if (s) { - env->spr[SPR_BESCR] |= BESCR_GE; - } else { - env->spr[SPR_BESCR] &= ~BESCR_GE; - } -} - -/* - * Triggers or queues an 'ebb_excp' EBB exception. All checks - * but FSCR, HFSCR and msr_pr must be done beforehand. - * - * PowerISA v3.1 isn't clear about whether an EBB should be - * postponed or cancelled if the EBB facility is unavailable. - * Our assumption here is that the EBB is cancelled if both - * FSCR and HFSCR EBB facilities aren't available. - */ -static void do_ebb(CPUPPCState *env, int ebb_excp) -{ - PowerPCCPU *cpu = env_archcpu(env); - - /* - * FSCR_EBB and FSCR_IC_EBB are the same bits used with - * HFSCR. - */ - helper_fscr_facility_check(env, FSCR_EBB, 0, FSCR_IC_EBB); - helper_hfscr_facility_check(env, FSCR_EBB, "EBB", FSCR_IC_EBB); - - if (ebb_excp == POWERPC_EXCP_PERFM_EBB) { - env->spr[SPR_BESCR] |= BESCR_PMEO; - } else if (ebb_excp == POWERPC_EXCP_EXTERNAL_EBB) { - env->spr[SPR_BESCR] |= BESCR_EEO; - } - - if (FIELD_EX64(env->msr, MSR, PR)) { - powerpc_excp(cpu, ebb_excp); - } else { - ppc_set_irq(cpu, PPC_INTERRUPT_EBB, 1); - } -} - -void raise_ebb_perfm_exception(CPUPPCState *env) -{ - bool perfm_ebb_enabled = env->spr[SPR_POWER_MMCR0] & MMCR0_EBE && - env->spr[SPR_BESCR] & BESCR_PME && - env->spr[SPR_BESCR] & BESCR_GE; - - if (!perfm_ebb_enabled) { - return; - } - - do_ebb(env, POWERPC_EXCP_PERFM_EBB); -} -#endif /* TARGET_PPC64 */ - -/*****************************************************************************/ -/* Embedded PowerPC specific helpers */ -void helper_40x_rfci(CPUPPCState *env) -{ - do_rfi(env, env->spr[SPR_40x_SRR2], env->spr[SPR_40x_SRR3]); -} - -void helper_rfci(CPUPPCState *env) -{ - do_rfi(env, env->spr[SPR_BOOKE_CSRR0], env->spr[SPR_BOOKE_CSRR1]); -} - -void helper_rfdi(CPUPPCState *env) -{ - /* FIXME: choose CSRR1 or DSRR1 based on cpu type */ - do_rfi(env, env->spr[SPR_BOOKE_DSRR0], env->spr[SPR_BOOKE_DSRR1]); -} - -void helper_rfmci(CPUPPCState *env) -{ - /* FIXME: choose CSRR1 or MCSRR1 based on cpu type */ - do_rfi(env, env->spr[SPR_BOOKE_MCSRR0], env->spr[SPR_BOOKE_MCSRR1]); -} - -/* Embedded.Processor Control */ -static int dbell2irq(target_ulong rb) -{ - int msg = rb & DBELL_TYPE_MASK; - int irq = -1; - - switch (msg) { - case DBELL_TYPE_DBELL: - irq = PPC_INTERRUPT_DOORBELL; - break; - case DBELL_TYPE_DBELL_CRIT: - irq = PPC_INTERRUPT_CDOORBELL; - break; - case DBELL_TYPE_G_DBELL: - case DBELL_TYPE_G_DBELL_CRIT: - case DBELL_TYPE_G_DBELL_MC: - /* XXX implement */ - default: - break; - } - - return irq; -} - -void helper_msgclr(CPUPPCState *env, target_ulong rb) -{ - int irq = dbell2irq(rb); - - if (irq < 0) { - return; - } - - ppc_set_irq(env_archcpu(env), irq, 0); -} - -void helper_msgsnd(target_ulong rb) -{ - int irq = dbell2irq(rb); - int pir = rb & DBELL_PIRTAG_MASK; - CPUState *cs; - - if (irq < 0) { - return; - } - - bql_lock(); - CPU_FOREACH(cs) { - PowerPCCPU *cpu = POWERPC_CPU(cs); - CPUPPCState *cenv = &cpu->env; - - if ((rb & DBELL_BRDCAST_MASK) || (cenv->spr[SPR_BOOKE_PIR] == pir)) { - ppc_set_irq(cpu, irq, 1); - } - } - bql_unlock(); -} - -/* Server Processor Control */ - -static bool dbell_type_server(target_ulong rb) -{ - /* - * A Directed Hypervisor Doorbell message is sent only if the - * message type is 5. All other types are reserved and the - * instruction is a no-op - */ - return (rb & DBELL_TYPE_MASK) == DBELL_TYPE_DBELL_SERVER; -} - -static inline bool dbell_bcast_core(target_ulong rb) -{ - return (rb & DBELL_BRDCAST_MASK) == DBELL_BRDCAST_CORE; -} - -static inline bool dbell_bcast_subproc(target_ulong rb) -{ - return (rb & DBELL_BRDCAST_MASK) == DBELL_BRDCAST_SUBPROC; -} - -/* - * Send an interrupt to a thread in the same core as env). - */ -static void msgsnd_core_tir(CPUPPCState *env, uint32_t target_tir, int irq) -{ - PowerPCCPU *cpu = env_archcpu(env); - CPUState *cs = env_cpu(env); - - if (ppc_cpu_lpar_single_threaded(cs)) { - if (target_tir == 0) { - ppc_set_irq(cpu, irq, 1); - } - } else { - CPUState *ccs; - - /* Does iothread need to be locked for walking CPU list? */ - bql_lock(); - THREAD_SIBLING_FOREACH(cs, ccs) { - PowerPCCPU *ccpu = POWERPC_CPU(ccs); - if (target_tir == ppc_cpu_tir(ccpu)) { - ppc_set_irq(ccpu, irq, 1); - break; - } - } - bql_unlock(); - } -} - -void helper_book3s_msgclr(CPUPPCState *env, target_ulong rb) -{ - if (!dbell_type_server(rb)) { - return; - } - - ppc_set_irq(env_archcpu(env), PPC_INTERRUPT_HDOORBELL, 0); -} - -void helper_book3s_msgsnd(CPUPPCState *env, target_ulong rb) -{ - int pir = rb & DBELL_PROCIDTAG_MASK; - bool brdcast = false; - CPUState *cs, *ccs; - PowerPCCPU *cpu; - - if (!dbell_type_server(rb)) { - return; - } - - /* POWER8 msgsnd is like msgsndp (targets a thread within core) */ - if (!(env->insns_flags2 & PPC2_ISA300)) { - msgsnd_core_tir(env, rb & PPC_BITMASK(57, 63), PPC_INTERRUPT_HDOORBELL); - return; - } - - /* POWER9 and later msgsnd is a global (targets any thread) */ - cpu = ppc_get_vcpu_by_pir(pir); - if (!cpu) { - return; - } - cs = CPU(cpu); - - if (dbell_bcast_core(rb) || (dbell_bcast_subproc(rb) && - (env->flags & POWERPC_FLAG_SMT_1LPAR))) { - brdcast = true; - } - - if (ppc_cpu_core_single_threaded(cs) || !brdcast) { - ppc_set_irq(cpu, PPC_INTERRUPT_HDOORBELL, 1); - return; - } - - /* - * Why is bql needed for walking CPU list? Answer seems to be because ppc - * irq handling needs it, but ppc_set_irq takes the lock itself if needed, - * so could this be removed? - */ - bql_lock(); - THREAD_SIBLING_FOREACH(cs, ccs) { - ppc_set_irq(POWERPC_CPU(ccs), PPC_INTERRUPT_HDOORBELL, 1); - } - bql_unlock(); -} - -#ifdef TARGET_PPC64 -void helper_book3s_msgclrp(CPUPPCState *env, target_ulong rb) -{ - helper_hfscr_facility_check(env, HFSCR_MSGP, "msgclrp", HFSCR_IC_MSGP); - - if (!dbell_type_server(rb)) { - return; - } - - ppc_set_irq(env_archcpu(env), PPC_INTERRUPT_DOORBELL, 0); -} - -/* - * sends a message to another thread on the same - * multi-threaded processor - */ -void helper_book3s_msgsndp(CPUPPCState *env, target_ulong rb) -{ - helper_hfscr_facility_check(env, HFSCR_MSGP, "msgsndp", HFSCR_IC_MSGP); - - if (!dbell_type_server(rb)) { - return; - } - - msgsnd_core_tir(env, rb & PPC_BITMASK(57, 63), PPC_INTERRUPT_DOORBELL); -} -#endif /* TARGET_PPC64 */ - -/* Single-step tracing */ -void helper_book3s_trace(CPUPPCState *env, target_ulong prev_ip) -{ - uint32_t error_code = 0; - if (env->insns_flags2 & PPC2_ISA207S) { - /* Load/store reporting, SRR1[35, 36] and SDAR, are not implemented. */ - env->spr[SPR_POWER_SIAR] = prev_ip; - error_code = PPC_BIT(33); - } - raise_exception_err(env, POWERPC_EXCP_TRACE, error_code); -} - -#endif /* !CONFIG_USER_ONLY */ -#endif /* CONFIG_TCG */ diff --git a/target/ppc/tcg-excp_helper.c b/target/ppc/tcg-excp_helper.c index 2459d2d095..4b859a8ffa 100644 --- a/target/ppc/tcg-excp_helper.c +++ b/target/ppc/tcg-excp_helper.c @@ -17,6 +17,7 @@ * License along with this library; if not, see . */ #include "qemu/osdep.h" +#include "qemu/main-loop.h" #include "qemu/log.h" #include "exec/cpu_ldst.h" #include "exec/exec-all.h" @@ -55,13 +56,13 @@ void helper_raise_exception(CPUPPCState *env, uint32_t exception) #ifndef CONFIG_USER_ONLY -void raise_exception_err(CPUPPCState *env, uint32_t exception, +static G_NORETURN void raise_exception_err(CPUPPCState *env, uint32_t exception, uint32_t error_code) { raise_exception_err_ra(env, exception, error_code, 0); } -void raise_exception(CPUPPCState *env, uint32_t exception) +static G_NORETURN void raise_exception(CPUPPCState *env, uint32_t exception) { raise_exception_err_ra(env, exception, 0, 0); } @@ -426,4 +427,422 @@ uint32_t ppc_ldl_code(CPUArchState *env, target_ulong addr) return insn; } +#if defined(TARGET_PPC64) +void helper_attn(CPUPPCState *env) +{ + /* POWER attn is unprivileged when enabled by HID, otherwise illegal */ + if ((*env->check_attn)(env)) { + powerpc_checkstop(env, "host executed attn"); + } else { + raise_exception_err(env, POWERPC_EXCP_HV_EMU, + POWERPC_EXCP_INVAL | POWERPC_EXCP_INVAL_INVAL); + } +} + +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, uint32_t insn) +{ + CPUState *cs = env_cpu(env); + + cs->halted = 1; + + /* Condition for waking up at 0x100 */ + env->resume_as_sreset = (insn != PPC_PM_STOP) || + (env->spr[SPR_PSSCR] & PSSCR_EC); + + /* HDECR is not to wake from PM state, it may have already fired */ + if (env->resume_as_sreset) { + PowerPCCPU *cpu = env_archcpu(env); + ppc_set_irq(cpu, PPC_INTERRUPT_HDECR, 0); + } + + ppc_maybe_interrupt(env); +} + +#endif /* TARGET_PPC64 */ +void helper_store_msr(CPUPPCState *env, target_ulong val) +{ + uint32_t excp = hreg_store_msr(env, val, 0); + + if (excp != 0) { + cpu_interrupt_exittb(env_cpu(env)); + raise_exception(env, excp); + } +} + +void helper_ppc_maybe_interrupt(CPUPPCState *env) +{ + ppc_maybe_interrupt(env); +} + +static void do_rfi(CPUPPCState *env, target_ulong nip, target_ulong msr) +{ + /* MSR:POW cannot be set by any form of rfi */ + msr &= ~(1ULL << MSR_POW); + + /* MSR:TGPR cannot be set by any form of rfi */ + if (env->flags & POWERPC_FLAG_TGPR) { + msr &= ~(1ULL << MSR_TGPR); + } + +#ifdef TARGET_PPC64 + /* Switching to 32-bit ? Crop the nip */ + if (!msr_is_64bit(env, msr)) { + nip = (uint32_t)nip; + } +#else + nip = (uint32_t)nip; +#endif + /* XXX: beware: this is false if VLE is supported */ + env->nip = nip & ~((target_ulong)0x00000003); + hreg_store_msr(env, msr, 1); + trace_ppc_excp_rfi(env->nip, env->msr); + /* + * No need to raise an exception here, as rfi is always the last + * insn of a TB + */ + cpu_interrupt_exittb(env_cpu(env)); + /* Reset the reservation */ + env->reserve_addr = -1; + + /* Context synchronizing: check if TCG TLB needs flush */ + check_tlb_flush(env, false); +} + +void helper_rfi(CPUPPCState *env) +{ + do_rfi(env, env->spr[SPR_SRR0], env->spr[SPR_SRR1] & 0xfffffffful); +} + +#ifdef TARGET_PPC64 +void helper_rfid(CPUPPCState *env) +{ + /* + * The architecture defines a number of rules for which bits can + * change but in practice, we handle this in hreg_store_msr() + * which will be called by do_rfi(), so there is no need to filter + * here + */ + do_rfi(env, env->spr[SPR_SRR0], env->spr[SPR_SRR1]); +} + +void helper_rfscv(CPUPPCState *env) +{ + do_rfi(env, env->lr, env->ctr); +} + +void helper_hrfid(CPUPPCState *env) +{ + do_rfi(env, env->spr[SPR_HSRR0], env->spr[SPR_HSRR1]); +} + +void helper_rfebb(CPUPPCState *env, target_ulong s) +{ + target_ulong msr = env->msr; + + /* + * Handling of BESCR bits 32:33 according to PowerISA v3.1: + * + * "If BESCR 32:33 != 0b00 the instruction is treated as if + * the instruction form were invalid." + */ + if (env->spr[SPR_BESCR] & BESCR_INVALID) { + raise_exception_err(env, POWERPC_EXCP_PROGRAM, + POWERPC_EXCP_INVAL | POWERPC_EXCP_INVAL_INVAL); + } + + env->nip = env->spr[SPR_EBBRR]; + + /* Switching to 32-bit ? Crop the nip */ + if (!msr_is_64bit(env, msr)) { + env->nip = (uint32_t)env->spr[SPR_EBBRR]; + } + + if (s) { + env->spr[SPR_BESCR] |= BESCR_GE; + } else { + env->spr[SPR_BESCR] &= ~BESCR_GE; + } +} + +/* + * Triggers or queues an 'ebb_excp' EBB exception. All checks + * but FSCR, HFSCR and msr_pr must be done beforehand. + * + * PowerISA v3.1 isn't clear about whether an EBB should be + * postponed or cancelled if the EBB facility is unavailable. + * Our assumption here is that the EBB is cancelled if both + * FSCR and HFSCR EBB facilities aren't available. + */ +static void do_ebb(CPUPPCState *env, int ebb_excp) +{ + PowerPCCPU *cpu = env_archcpu(env); + + /* + * FSCR_EBB and FSCR_IC_EBB are the same bits used with + * HFSCR. + */ + helper_fscr_facility_check(env, FSCR_EBB, 0, FSCR_IC_EBB); + helper_hfscr_facility_check(env, FSCR_EBB, "EBB", FSCR_IC_EBB); + + if (ebb_excp == POWERPC_EXCP_PERFM_EBB) { + env->spr[SPR_BESCR] |= BESCR_PMEO; + } else if (ebb_excp == POWERPC_EXCP_EXTERNAL_EBB) { + env->spr[SPR_BESCR] |= BESCR_EEO; + } + + if (FIELD_EX64(env->msr, MSR, PR)) { + powerpc_excp(cpu, ebb_excp); + } else { + ppc_set_irq(cpu, PPC_INTERRUPT_EBB, 1); + } +} + +void raise_ebb_perfm_exception(CPUPPCState *env) +{ + bool perfm_ebb_enabled = env->spr[SPR_POWER_MMCR0] & MMCR0_EBE && + env->spr[SPR_BESCR] & BESCR_PME && + env->spr[SPR_BESCR] & BESCR_GE; + + if (!perfm_ebb_enabled) { + return; + } + + do_ebb(env, POWERPC_EXCP_PERFM_EBB); +} +#endif /* TARGET_PPC64 */ + +/*****************************************************************************/ +/* Embedded PowerPC specific helpers */ +void helper_40x_rfci(CPUPPCState *env) +{ + do_rfi(env, env->spr[SPR_40x_SRR2], env->spr[SPR_40x_SRR3]); +} + +void helper_rfci(CPUPPCState *env) +{ + do_rfi(env, env->spr[SPR_BOOKE_CSRR0], env->spr[SPR_BOOKE_CSRR1]); +} + +void helper_rfdi(CPUPPCState *env) +{ + /* FIXME: choose CSRR1 or DSRR1 based on cpu type */ + do_rfi(env, env->spr[SPR_BOOKE_DSRR0], env->spr[SPR_BOOKE_DSRR1]); +} + +void helper_rfmci(CPUPPCState *env) +{ + /* FIXME: choose CSRR1 or MCSRR1 based on cpu type */ + do_rfi(env, env->spr[SPR_BOOKE_MCSRR0], env->spr[SPR_BOOKE_MCSRR1]); +} + +/* Embedded.Processor Control */ +static int dbell2irq(target_ulong rb) +{ + int msg = rb & DBELL_TYPE_MASK; + int irq = -1; + + switch (msg) { + case DBELL_TYPE_DBELL: + irq = PPC_INTERRUPT_DOORBELL; + break; + case DBELL_TYPE_DBELL_CRIT: + irq = PPC_INTERRUPT_CDOORBELL; + break; + case DBELL_TYPE_G_DBELL: + case DBELL_TYPE_G_DBELL_CRIT: + case DBELL_TYPE_G_DBELL_MC: + /* XXX implement */ + default: + break; + } + + return irq; +} + +void helper_msgclr(CPUPPCState *env, target_ulong rb) +{ + int irq = dbell2irq(rb); + + if (irq < 0) { + return; + } + + ppc_set_irq(env_archcpu(env), irq, 0); +} + +void helper_msgsnd(target_ulong rb) +{ + int irq = dbell2irq(rb); + int pir = rb & DBELL_PIRTAG_MASK; + CPUState *cs; + + if (irq < 0) { + return; + } + + bql_lock(); + CPU_FOREACH(cs) { + PowerPCCPU *cpu = POWERPC_CPU(cs); + CPUPPCState *cenv = &cpu->env; + + if ((rb & DBELL_BRDCAST_MASK) || (cenv->spr[SPR_BOOKE_PIR] == pir)) { + ppc_set_irq(cpu, irq, 1); + } + } + bql_unlock(); +} + +/* Server Processor Control */ + +static bool dbell_type_server(target_ulong rb) +{ + /* + * A Directed Hypervisor Doorbell message is sent only if the + * message type is 5. All other types are reserved and the + * instruction is a no-op + */ + return (rb & DBELL_TYPE_MASK) == DBELL_TYPE_DBELL_SERVER; +} + +static inline bool dbell_bcast_core(target_ulong rb) +{ + return (rb & DBELL_BRDCAST_MASK) == DBELL_BRDCAST_CORE; +} + +static inline bool dbell_bcast_subproc(target_ulong rb) +{ + return (rb & DBELL_BRDCAST_MASK) == DBELL_BRDCAST_SUBPROC; +} + +/* + * Send an interrupt to a thread in the same core as env). + */ +static void msgsnd_core_tir(CPUPPCState *env, uint32_t target_tir, int irq) +{ + PowerPCCPU *cpu = env_archcpu(env); + CPUState *cs = env_cpu(env); + + if (ppc_cpu_lpar_single_threaded(cs)) { + if (target_tir == 0) { + ppc_set_irq(cpu, irq, 1); + } + } else { + CPUState *ccs; + + /* Does iothread need to be locked for walking CPU list? */ + bql_lock(); + THREAD_SIBLING_FOREACH(cs, ccs) { + PowerPCCPU *ccpu = POWERPC_CPU(ccs); + if (target_tir == ppc_cpu_tir(ccpu)) { + ppc_set_irq(ccpu, irq, 1); + break; + } + } + bql_unlock(); + } +} + +void helper_book3s_msgclr(CPUPPCState *env, target_ulong rb) +{ + if (!dbell_type_server(rb)) { + return; + } + + ppc_set_irq(env_archcpu(env), PPC_INTERRUPT_HDOORBELL, 0); +} + +void helper_book3s_msgsnd(CPUPPCState *env, target_ulong rb) +{ + int pir = rb & DBELL_PROCIDTAG_MASK; + bool brdcast = false; + CPUState *cs, *ccs; + PowerPCCPU *cpu; + + if (!dbell_type_server(rb)) { + return; + } + + /* POWER8 msgsnd is like msgsndp (targets a thread within core) */ + if (!(env->insns_flags2 & PPC2_ISA300)) { + msgsnd_core_tir(env, rb & PPC_BITMASK(57, 63), PPC_INTERRUPT_HDOORBELL); + return; + } + + /* POWER9 and later msgsnd is a global (targets any thread) */ + cpu = ppc_get_vcpu_by_pir(pir); + if (!cpu) { + return; + } + cs = CPU(cpu); + + if (dbell_bcast_core(rb) || (dbell_bcast_subproc(rb) && + (env->flags & POWERPC_FLAG_SMT_1LPAR))) { + brdcast = true; + } + + if (ppc_cpu_core_single_threaded(cs) || !brdcast) { + ppc_set_irq(cpu, PPC_INTERRUPT_HDOORBELL, 1); + return; + } + + /* + * Why is bql needed for walking CPU list? Answer seems to be because ppc + * irq handling needs it, but ppc_set_irq takes the lock itself if needed, + * so could this be removed? + */ + bql_lock(); + THREAD_SIBLING_FOREACH(cs, ccs) { + ppc_set_irq(POWERPC_CPU(ccs), PPC_INTERRUPT_HDOORBELL, 1); + } + bql_unlock(); +} + +#ifdef TARGET_PPC64 +void helper_book3s_msgclrp(CPUPPCState *env, target_ulong rb) +{ + helper_hfscr_facility_check(env, HFSCR_MSGP, "msgclrp", HFSCR_IC_MSGP); + + if (!dbell_type_server(rb)) { + return; + } + + ppc_set_irq(env_archcpu(env), PPC_INTERRUPT_DOORBELL, 0); +} + +/* + * sends a message to another thread on the same + * multi-threaded processor + */ +void helper_book3s_msgsndp(CPUPPCState *env, target_ulong rb) +{ + helper_hfscr_facility_check(env, HFSCR_MSGP, "msgsndp", HFSCR_IC_MSGP); + + if (!dbell_type_server(rb)) { + return; + } + + msgsnd_core_tir(env, rb & PPC_BITMASK(57, 63), PPC_INTERRUPT_DOORBELL); +} +#endif /* TARGET_PPC64 */ + +/* Single-step tracing */ +void helper_book3s_trace(CPUPPCState *env, target_ulong prev_ip) +{ + uint32_t error_code = 0; + if (env->insns_flags2 & PPC2_ISA207S) { + /* Load/store reporting, SRR1[35, 36] and SDAR, are not implemented. */ + env->spr[SPR_POWER_SIAR] = prev_ip; + error_code = PPC_BIT(33); + } + raise_exception_err(env, POWERPC_EXCP_TRACE, error_code); +} #endif /* !CONFIG_USER_ONLY */ From patchwork Tue Mar 11 12:57:48 2025 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: Nicholas Piggin X-Patchwork-Id: 14011827 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.lore.kernel.org (Postfix) with ESMTPS id B7A47C282EC for ; Tue, 11 Mar 2025 13:11:52 +0000 (UTC) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1trzIX-0002FP-OI; Tue, 11 Mar 2025 09:05:37 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1trzET-0005Uv-19; Tue, 11 Mar 2025 09:01:24 -0400 Received: from mail-pj1-x1033.google.com ([2607:f8b0:4864:20::1033]) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_128_GCM_SHA256:128) (Exim 4.90_1) (envelope-from ) id 1trzEP-0000F2-Mi; Tue, 11 Mar 2025 09:01:16 -0400 Received: by mail-pj1-x1033.google.com with SMTP id 98e67ed59e1d1-2ff69365e1dso7929377a91.3; Tue, 11 Mar 2025 06:01:12 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20230601; t=1741698071; x=1742302871; darn=nongnu.org; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to; bh=A6q6Au2PYMTFLE8G5QWMGA2jsF0I3uVxpvs/IiCO/uk=; b=lXeppP1+vghLkG/pDv/OlwJbFFgAs7rIO6pNb+/q7jZcBPCxs2bM9jGUlyspT9g/OM Epsll3+5lS3F6HpJxyx3SJm/QqpCOvX104Xo8AR3YiCKTtm9lHepZsWG2C9350PyB/Vy 3bMtxmKUdeEFA2WM1XXMeg9FxQpt0+C02OtnOpG0BqHUe35wJjZxYx09VIUulAtRgYdk T2wi5lye2W012gjKonfy+MWTt2LMZaqz5HVws3AgibX15DD39XxFO3I/6tfGk+xBb20s tLV+CyAjnhA0kIkUUHfqnPKOLtAaxujDsKtJAwIPpB3zmJmlf3dm9Mo5r5X22ypS8xei rv8Q== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1741698071; x=1742302871; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=A6q6Au2PYMTFLE8G5QWMGA2jsF0I3uVxpvs/IiCO/uk=; b=SS66HIl1CwTUCdZB9GI//u9unMC03YHFgBhqReQ1EemaYzwZenbVwcwrpXLxr5fRw2 muWoLpitvQuj+8RjQp0Msdw+LtUsR3s7Zxc8o29t9Jzso9S4/kIziO1h7yjAdyxSUYdj 68R1k1c5KGK1MoEsfrlfBIbSSaWIds9SuvIgVNiIEsX+99P8E7fKq81HLCo8rB0HXT23 autd5+CsuoyX7IhvLqk8nup4T7ALr0pnJqcahMKPEM5JtW8DZv5uar1VW3r4uaTkgAOY uBCbMD/Q+yclr1dx69b+tkYH1whGYRvukO3AwiQB4gk65owXOJySaK9DOG19Nz76mcLj HlHQ== X-Forwarded-Encrypted: i=1; AJvYcCUe/hVnYp84r2CARbXen1QdLpzqKjBn4lo/FUxPKLgsJEyHIVY6MPR/TljPFyK12sE239NPznyF8A==@nongnu.org X-Gm-Message-State: AOJu0YwNnn/AOa+EaSN1VsGq8Yl2K22yJ/a1twneThsORlM0lTEdcRfs 11ZQM7ZvG9yzbfQENUNcc91RvpwFsQmqUKmz1jqhLe+ez+0zeq7c0sPHgw== X-Gm-Gg: ASbGncuVMFy+xjNULygJtMgnUhSpJ1hFc7Ir86GLcvaM4Ga+xHwZGFFHkUtzNb/8cZI kvoGQITIOCEOu984niZIVvTwT0kcej+o/sukXI5k+6QawwhtDBPXRhClqFIOQ12HeKHz3kAFmjK 20s6hOVzNsXsip8VqUwDCs421MAlmAeBktONYhnMr+zjpd8GMlcnNk1e6XUEEzQPoZx7JFyxP6S iRIQNQAdCWaDiSQ+dt+J3BPwieszPeOWMIa343bUeDEL80Sknb/8vAQNUxiODHS1jibh1CWHldi sKLu23ftjnSQkgxBwEwyC71Xf+0IV75/iA1FrIzuSLXP4J5KPME= X-Google-Smtp-Source: AGHT+IFHxsySwNaiuFmOaF0flXJIqS8ZmcbDMIyGEaCgNHxjC15RdQwaFlxhKTL6OL5W4I5lt7gdgw== X-Received: by 2002:a17:90a:e7ce:b0:2ff:58a4:9db3 with SMTP id 98e67ed59e1d1-2ff7cf25652mr26488690a91.35.1741698071504; Tue, 11 Mar 2025 06:01:11 -0700 (PDT) Received: from wheely.local0.net ([118.208.151.101]) by smtp.gmail.com with ESMTPSA id 98e67ed59e1d1-2ff4e773dddsm11822318a91.12.2025.03.11.06.01.08 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 11 Mar 2025 06:01:11 -0700 (PDT) From: Nicholas Piggin To: qemu-devel@nongnu.org Cc: Nicholas Piggin , qemu-ppc@nongnu.org, =?utf-8?q?Phil?= =?utf-8?q?ippe_Mathieu-Daud=C3=A9?= , Harsh Prateek Bora Subject: [PULL 54/72] hw/ppc/spapr: Convert HPTE() macro as hpte_get_ptr() method Date: Tue, 11 Mar 2025 22:57:48 +1000 Message-ID: <20250311125815.903177-55-npiggin@gmail.com> X-Mailer: git-send-email 2.47.1 In-Reply-To: <20250311125815.903177-1-npiggin@gmail.com> References: <20250311125815.903177-1-npiggin@gmail.com> MIME-Version: 1.0 Received-SPF: pass client-ip=2607:f8b0:4864:20::1033; envelope-from=npiggin@gmail.com; helo=mail-pj1-x1033.google.com X-Spam_score_int: -20 X-Spam_score: -2.1 X-Spam_bar: -- X-Spam_report: (-2.1 / 5.0 requ) BAYES_00=-1.9, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_AU=-0.1, DKIM_VALID_EF=-0.1, FREEMAIL_FROM=0.001, RCVD_IN_DNSWL_NONE=-0.0001, SPF_HELO_NONE=0.001, SPF_PASS=-0.001 autolearn=ham autolearn_force=no X-Spam_action: no action X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: qemu-devel-bounces+qemu-devel=archiver.kernel.org@nongnu.org Sender: qemu-devel-bounces+qemu-devel=archiver.kernel.org@nongnu.org From: Philippe Mathieu-Daudé Convert HPTE() macro as hpte_get_ptr() method. Reviewed-by: Nicholas Piggin Signed-off-by: Philippe Mathieu-Daudé Reviewed-by: Harsh Prateek Bora Message-ID: <20241220213103.6314-2-philmd@linaro.org> Signed-off-by: Nicholas Piggin --- hw/ppc/spapr.c | 38 ++++++++++++++++++++++---------------- 1 file changed, 22 insertions(+), 16 deletions(-) diff --git a/hw/ppc/spapr.c b/hw/ppc/spapr.c index c7cf04e063..0cae4853db 100644 --- a/hw/ppc/spapr.c +++ b/hw/ppc/spapr.c @@ -1402,7 +1402,13 @@ static bool spapr_get_pate(PPCVirtualHypervisor *vhyp, PowerPCCPU *cpu, } } -#define HPTE(_table, _i) (void *)(((uint64_t *)(_table)) + ((_i) * 2)) +static uint64_t *hpte_get_ptr(SpaprMachineState *s, unsigned index) +{ + uint64_t *table = s->htab; + + return &table[2 * index]; +} + #define HPTE_VALID(_hpte) (tswap64(*((uint64_t *)(_hpte))) & HPTE64_V_VALID) #define HPTE_DIRTY(_hpte) (tswap64(*((uint64_t *)(_hpte))) & HPTE64_V_HPTE_DIRTY) #define CLEAN_HPTE(_hpte) ((*(uint64_t *)(_hpte)) &= tswap64(~HPTE64_V_HPTE_DIRTY)) @@ -1617,7 +1623,7 @@ int spapr_reallocate_hpt(SpaprMachineState *spapr, int shift, Error **errp) spapr->htab_shift = shift; for (i = 0; i < size / HASH_PTE_SIZE_64; i++) { - DIRTY_HPTE(HPTE(spapr->htab, i)); + DIRTY_HPTE(hpte_get_ptr(spapr, i)); } } /* We're setting up a hash table, so that means we're not radix */ @@ -2174,7 +2180,7 @@ static void htab_save_chunk(QEMUFile *f, SpaprMachineState *spapr, qemu_put_be32(f, chunkstart); qemu_put_be16(f, n_valid); qemu_put_be16(f, n_invalid); - qemu_put_buffer(f, HPTE(spapr->htab, chunkstart), + qemu_put_buffer(f, (void *)hpte_get_ptr(spapr, chunkstart), HASH_PTE_SIZE_64 * n_valid); } @@ -2200,16 +2206,16 @@ static void htab_save_first_pass(QEMUFile *f, SpaprMachineState *spapr, /* Consume invalid HPTEs */ while ((index < htabslots) - && !HPTE_VALID(HPTE(spapr->htab, index))) { - CLEAN_HPTE(HPTE(spapr->htab, index)); + && !HPTE_VALID(hpte_get_ptr(spapr, index))) { + CLEAN_HPTE(hpte_get_ptr(spapr, index)); index++; } /* Consume valid HPTEs */ chunkstart = index; while ((index < htabslots) && (index - chunkstart < USHRT_MAX) - && HPTE_VALID(HPTE(spapr->htab, index))) { - CLEAN_HPTE(HPTE(spapr->htab, index)); + && HPTE_VALID(hpte_get_ptr(spapr, index))) { + CLEAN_HPTE(hpte_get_ptr(spapr, index)); index++; } @@ -2249,7 +2255,7 @@ static int htab_save_later_pass(QEMUFile *f, SpaprMachineState *spapr, /* Consume non-dirty HPTEs */ while ((index < htabslots) - && !HPTE_DIRTY(HPTE(spapr->htab, index))) { + && !HPTE_DIRTY(hpte_get_ptr(spapr, index))) { index++; examined++; } @@ -2257,9 +2263,9 @@ static int htab_save_later_pass(QEMUFile *f, SpaprMachineState *spapr, chunkstart = index; /* Consume valid dirty HPTEs */ while ((index < htabslots) && (index - chunkstart < USHRT_MAX) - && HPTE_DIRTY(HPTE(spapr->htab, index)) - && HPTE_VALID(HPTE(spapr->htab, index))) { - CLEAN_HPTE(HPTE(spapr->htab, index)); + && HPTE_DIRTY(hpte_get_ptr(spapr, index)) + && HPTE_VALID(hpte_get_ptr(spapr, index))) { + CLEAN_HPTE(hpte_get_ptr(spapr, index)); index++; examined++; } @@ -2267,9 +2273,9 @@ static int htab_save_later_pass(QEMUFile *f, SpaprMachineState *spapr, invalidstart = index; /* Consume invalid dirty HPTEs */ while ((index < htabslots) && (index - invalidstart < USHRT_MAX) - && HPTE_DIRTY(HPTE(spapr->htab, index)) - && !HPTE_VALID(HPTE(spapr->htab, index))) { - CLEAN_HPTE(HPTE(spapr->htab, index)); + && HPTE_DIRTY(hpte_get_ptr(spapr, index)) + && !HPTE_VALID(hpte_get_ptr(spapr, index))) { + CLEAN_HPTE(hpte_get_ptr(spapr, index)); index++; examined++; } @@ -2451,11 +2457,11 @@ static int htab_load(QEMUFile *f, void *opaque, int version_id) if (spapr->htab) { if (n_valid) { - qemu_get_buffer(f, HPTE(spapr->htab, index), + qemu_get_buffer(f, (void *)hpte_get_ptr(spapr, index), HASH_PTE_SIZE_64 * n_valid); } if (n_invalid) { - memset(HPTE(spapr->htab, index + n_valid), 0, + memset(hpte_get_ptr(spapr, index + n_valid), 0, HASH_PTE_SIZE_64 * n_invalid); } } else { From patchwork Tue Mar 11 12:57:49 2025 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: Nicholas Piggin X-Patchwork-Id: 14011900 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.lore.kernel.org (Postfix) with ESMTPS id 16252C35FF1 for ; Tue, 11 Mar 2025 13:26:41 +0000 (UTC) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1trzIr-0002oH-AC; Tue, 11 Mar 2025 09:05:49 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1trzEX-0005Vj-7I; Tue, 11 Mar 2025 09:01:27 -0400 Received: from mail-pj1-x1036.google.com ([2607:f8b0:4864:20::1036]) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_128_GCM_SHA256:128) (Exim 4.90_1) (envelope-from ) id 1trzET-0000FP-7t; Tue, 11 Mar 2025 09:01:19 -0400 Received: by mail-pj1-x1036.google.com with SMTP id 98e67ed59e1d1-2ff797f8f1bso7290510a91.3; Tue, 11 Mar 2025 06:01:15 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20230601; t=1741698074; x=1742302874; darn=nongnu.org; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to; bh=kNfAFKwb/h/Q47CuyyAbJR4Xbbiqi59X5UF2kJZMU+s=; b=kxuU6wQQwNaZ4em4NG4E6Q0MFA3DZJ85S04AoxUi7JnFufgZoZhtkwGfIDeuhw+6pK NouYzoddDctuadi4UL7/il4Rkof4m5BJAUVo4fhE+af44/SnqtEhB5JEBJ/jZqFvfPgp cqimOvAP5CbNQacpHGFDnOfsnHmbSkO5A+aTJbvFOoG3zXSB6R06MFhovsoLygaFwri0 eHOT3In42NwyutpLmsgQaEUjs6xoCJDxkoNUNdNRykUGQg3UuTJQj13vjEvq5fRNazfg gP/xJJ+j8Ai2s3wEJkoFKxsNpANhE7B9UkTdHadC/0Q+U4lwREjGt1HyF3ByN7VXYIFy C1gw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1741698074; x=1742302874; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=kNfAFKwb/h/Q47CuyyAbJR4Xbbiqi59X5UF2kJZMU+s=; b=ltr/HqNkrFcKauHaTi/qbXnf1Whr5KRT4QIaJXkSDLSLDgm42UDOG3WohAAXCx8hgf MHuKb3Fsp2qJmuKwd+4SpP4qQsunM4cAMJkQeYMTZZvdTWKngcdy/0OoacfdvRSEKSgq TX3v3N1h9G5YeqdXB1PXtEnEexmJ5AlLE6CBADA2JLo4UiY68JhPqp/047NvYlZj6L2u zElTps19q46kD1AVH1wvFZ/n4bcDaj44bj+9TGu4BSeDZP9d8J6g2EbmfdVQZgZShaNJ xNYWbCJhigc1qsh9WGxr0qfEitqhDKt+2LpcHr9L7ytMcReCs4PQVjNTUm+O+Urf/guq IPYQ== X-Forwarded-Encrypted: i=1; AJvYcCX/LoaRH22fENwWTcy2vdTdH+YlsFVWkm0T+CS/pSNO31qSpkLi4HH9dbSGRFAItZ8boLf16fyvbg==@nongnu.org X-Gm-Message-State: AOJu0YzHVvQLnBAW2ErImN2DZacFp18gRswQL2oEYCf8R+NLPt871B5O m509l/O6e2R4soXyG/hvV97gPNrO47261+2CFwKaaa0CGiOMvi4QzzQZoQ== X-Gm-Gg: ASbGnctbmIEm6E+I3aLkq+8v7pPwPDCS8kkpoK9EyBtvqis29X7F+YZYQUHi98vqJV1 VbrrYlhWJwxGtkmuw51y5x5L/BNiDObx4kpZ3AfGjJLWFoeAw5/jhp1AIpt4jZgHdT6aMdkY4A2 0aSl8BFZxID09aAwaDQWXLqaWFLSCSoUY0l0np0weqodiFKgHx7asKelmc9xpUe5lPEf+smIoGP fqBLuJeT9Df0yl6GsVAy7B3jwt3+X2D/i4gp5DlJ2yTs7qWSwKOHkJ7xq8pTwtgDQK/qo6KDiyz H6Px5ydoB4reOZJR2QbUTkHGBnKRRCqKlaFJzIjOCrzsfEwq1NtqcGqjbu2z6Q== X-Google-Smtp-Source: AGHT+IEUxDsnBxxE5nNu4SKGqQyGuvwFXnfJLIyrLcaDFm/15CUqwxnjvMAlvSg/FQ7RNNwBFBQGpw== X-Received: by 2002:a17:90b:2648:b0:2fe:e9c6:689e with SMTP id 98e67ed59e1d1-300ff0c9bacmr4859052a91.8.1741698074488; Tue, 11 Mar 2025 06:01:14 -0700 (PDT) Received: from wheely.local0.net ([118.208.151.101]) by smtp.gmail.com with ESMTPSA id 98e67ed59e1d1-2ff4e773dddsm11822318a91.12.2025.03.11.06.01.11 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 11 Mar 2025 06:01:14 -0700 (PDT) From: Nicholas Piggin To: qemu-devel@nongnu.org Cc: Nicholas Piggin , qemu-ppc@nongnu.org, =?utf-8?q?Phil?= =?utf-8?q?ippe_Mathieu-Daud=C3=A9?= , Harsh Prateek Bora Subject: [PULL 55/72] hw/ppc/spapr: Convert HPTE_VALID() macro as hpte_is_valid() method Date: Tue, 11 Mar 2025 22:57:49 +1000 Message-ID: <20250311125815.903177-56-npiggin@gmail.com> X-Mailer: git-send-email 2.47.1 In-Reply-To: <20250311125815.903177-1-npiggin@gmail.com> References: <20250311125815.903177-1-npiggin@gmail.com> MIME-Version: 1.0 Received-SPF: pass client-ip=2607:f8b0:4864:20::1036; envelope-from=npiggin@gmail.com; helo=mail-pj1-x1036.google.com X-Spam_score_int: -20 X-Spam_score: -2.1 X-Spam_bar: -- X-Spam_report: (-2.1 / 5.0 requ) BAYES_00=-1.9, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_AU=-0.1, DKIM_VALID_EF=-0.1, FREEMAIL_FROM=0.001, RCVD_IN_DNSWL_NONE=-0.0001, SPF_HELO_NONE=0.001, SPF_PASS=-0.001 autolearn=ham autolearn_force=no X-Spam_action: no action X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: qemu-devel-bounces+qemu-devel=archiver.kernel.org@nongnu.org Sender: qemu-devel-bounces+qemu-devel=archiver.kernel.org@nongnu.org From: Philippe Mathieu-Daudé Convert HPTE_VALID() macro as hpte_is_valid() method. sPAPR data structures including the hash page table are big-endian regardless of current CPU endian mode, so use the big-endian LD/ST API to access the hash PTEs. Signed-off-by: Philippe Mathieu-Daudé Reviewed-by: Nicholas Piggin Reviewed-by: Harsh Prateek Bora Message-ID: <20241220213103.6314-3-philmd@linaro.org> Signed-off-by: Nicholas Piggin --- hw/ppc/spapr.c | 14 +++++++++----- 1 file changed, 9 insertions(+), 5 deletions(-) diff --git a/hw/ppc/spapr.c b/hw/ppc/spapr.c index 0cae4853db..daf997cea1 100644 --- a/hw/ppc/spapr.c +++ b/hw/ppc/spapr.c @@ -1409,7 +1409,11 @@ static uint64_t *hpte_get_ptr(SpaprMachineState *s, unsigned index) return &table[2 * index]; } -#define HPTE_VALID(_hpte) (tswap64(*((uint64_t *)(_hpte))) & HPTE64_V_VALID) +static bool hpte_is_valid(SpaprMachineState *s, unsigned index) +{ + return ldq_be_p(hpte_get_ptr(s, index)) & HPTE64_V_VALID; +} + #define HPTE_DIRTY(_hpte) (tswap64(*((uint64_t *)(_hpte))) & HPTE64_V_HPTE_DIRTY) #define CLEAN_HPTE(_hpte) ((*(uint64_t *)(_hpte)) &= tswap64(~HPTE64_V_HPTE_DIRTY)) #define DIRTY_HPTE(_hpte) ((*(uint64_t *)(_hpte)) |= tswap64(HPTE64_V_HPTE_DIRTY)) @@ -2206,7 +2210,7 @@ static void htab_save_first_pass(QEMUFile *f, SpaprMachineState *spapr, /* Consume invalid HPTEs */ while ((index < htabslots) - && !HPTE_VALID(hpte_get_ptr(spapr, index))) { + && !hpte_is_valid(spapr, index)) { CLEAN_HPTE(hpte_get_ptr(spapr, index)); index++; } @@ -2214,7 +2218,7 @@ static void htab_save_first_pass(QEMUFile *f, SpaprMachineState *spapr, /* Consume valid HPTEs */ chunkstart = index; while ((index < htabslots) && (index - chunkstart < USHRT_MAX) - && HPTE_VALID(hpte_get_ptr(spapr, index))) { + && hpte_is_valid(spapr, index)) { CLEAN_HPTE(hpte_get_ptr(spapr, index)); index++; } @@ -2264,7 +2268,7 @@ static int htab_save_later_pass(QEMUFile *f, SpaprMachineState *spapr, /* Consume valid dirty HPTEs */ while ((index < htabslots) && (index - chunkstart < USHRT_MAX) && HPTE_DIRTY(hpte_get_ptr(spapr, index)) - && HPTE_VALID(hpte_get_ptr(spapr, index))) { + && hpte_is_valid(spapr, index)) { CLEAN_HPTE(hpte_get_ptr(spapr, index)); index++; examined++; @@ -2274,7 +2278,7 @@ static int htab_save_later_pass(QEMUFile *f, SpaprMachineState *spapr, /* Consume invalid dirty HPTEs */ while ((index < htabslots) && (index - invalidstart < USHRT_MAX) && HPTE_DIRTY(hpte_get_ptr(spapr, index)) - && !HPTE_VALID(hpte_get_ptr(spapr, index))) { + && !hpte_is_valid(spapr, index)) { CLEAN_HPTE(hpte_get_ptr(spapr, index)); index++; examined++; From patchwork Tue Mar 11 12:57:50 2025 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: Nicholas Piggin X-Patchwork-Id: 14011908 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.lore.kernel.org (Postfix) with ESMTPS id B9C5DC282EC for ; Tue, 11 Mar 2025 13:28:56 +0000 (UTC) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1trzJP-0004Hz-4m; Tue, 11 Mar 2025 09:06:23 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1trzEZ-0005Vr-Qf; Tue, 11 Mar 2025 09:01:27 -0400 Received: from mail-pj1-x1030.google.com ([2607:f8b0:4864:20::1030]) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_128_GCM_SHA256:128) (Exim 4.90_1) (envelope-from ) id 1trzEV-0000G9-Uv; Tue, 11 Mar 2025 09:01:22 -0400 Received: by mail-pj1-x1030.google.com with SMTP id 98e67ed59e1d1-2feb91a25bdso8350772a91.1; Tue, 11 Mar 2025 06:01:19 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20230601; t=1741698078; x=1742302878; darn=nongnu.org; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to; bh=wiqaFq1CDDEcKauctJ0QrZkvhAfYnv9s43KRAQPzSbk=; b=jhN5LRDOEOV3/BwiWc7xG9BytRBVTP0ZlL/jGLUaSF+VH+NjQ2IGBj+MNMIYfJ1eKF eMfajtBXpDfTz7oKMFjQDkqw5H1pbDr51u6+A+xkQtGahxcpklq0rokdj4n4MmSFoIRc ch33CWZGwLkun6aT+S0EDiMedGFe6KdJRSI7woGBYFG+307+TXrm4FfU9cMAAERobeKs L9vZYJL0ZfAquAXSK1lng1WgApIOPCKrFoGX82G1vy5FMz2FYDjlbI0bWApQfFfouwSR Y4QEK5Wj8sG1C6zC19u6qhAZNX4eVDD6qtwIQnaDS/FzZm5OvvkxXzX96VtFHHJe60PW lHUg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1741698078; x=1742302878; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=wiqaFq1CDDEcKauctJ0QrZkvhAfYnv9s43KRAQPzSbk=; b=Io7S9OMD1Mvf/Rq3JhlQQRxH9RxwbQM+StJ3GeIn10rfJ8jLR8zmST8CoSKDpV7jNG p8mzjxM3LbFUVteuSf3TbOICxHci46UeaxOS4RESpafzlr0GVzxre4lI/hypT1V1Ku2I y2YGHrkaE72SuS7zI2pZJ1XWSRNOSYBCFPRdln1u5anLyhhMSvF3mGKDuMWZrRpW7g/L pFIAu+vOThTJfQbxgTwMSJuOJ8E9Axtokk7fQPFdHyyH6balnnQ+taPvhqDLEyALfOSF qoJA7qGBaPDdC2J7A4QujqHCSnM/UN9k6dbfb6O7adXpV3rc840CY2LX8vatmHfFQEqS 24Lg== X-Forwarded-Encrypted: i=1; AJvYcCXirWT0qS4NmR21+Ai/yLFBwAIpsQg/SK0rPnihKN3wJrT2xIIm9LrbCkpT/95Mkva9yugfpeJqqg==@nongnu.org X-Gm-Message-State: AOJu0YypYlDRJ575Th20UdME2b65WtMVAyE/IVVJCy4OMnl4hyeE//YQ Xlev6bf8IZ7PB1RnZnGAQQr5k+WWUOAx7khgTj88ygkk2x9Lu7ME8Bhe2A== X-Gm-Gg: ASbGncvvMQn3bwt6Il2wUdrPKYwYbjG0VVF/uCEG/8nW4yBJXjJGLV+jGWQ1pi1b3hl 94dOsRjr5eOxqBXODsNxn32iCOAlvM2kKoBZstHGLna1twtA+tECJnWj6zGFfz7rZIeYi/U0xOg MAWAt/mPHizPeXUppKbSCln0MSH9mZcg7mWpKy/YdBmhhLDJWMi19H5gmc0D77CLOF3N/Om7O4j 15AAZHH7QNwhYrXlLRaZrNffgbjspUkHE+WN1R7vyl9D6Fg0a60hBvurVS9sTbARenNfMEUb7iH uvP+x8TeNaOP5tGtCAOrzPDd38mF4Fe7QTYXwopnDttMlx131Ck= X-Google-Smtp-Source: AGHT+IFZ4rCUZEjZpe1mFQo3aIobhNdwaD5QnMN0PnEvFwTHHvx+66sIohxoNQUv+G35Fntl0zu/OA== X-Received: by 2002:a17:90b:2742:b0:2fe:a8b1:7d8 with SMTP id 98e67ed59e1d1-300ff34d643mr4832273a91.25.1741698077824; Tue, 11 Mar 2025 06:01:17 -0700 (PDT) Received: from wheely.local0.net ([118.208.151.101]) by smtp.gmail.com with ESMTPSA id 98e67ed59e1d1-2ff4e773dddsm11822318a91.12.2025.03.11.06.01.14 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 11 Mar 2025 06:01:17 -0700 (PDT) From: Nicholas Piggin To: qemu-devel@nongnu.org Cc: Nicholas Piggin , qemu-ppc@nongnu.org, =?utf-8?q?Phil?= =?utf-8?q?ippe_Mathieu-Daud=C3=A9?= , Harsh Prateek Bora Subject: [PULL 56/72] hw/ppc/spapr: Convert HPTE_DIRTY() macro as hpte_is_dirty() method Date: Tue, 11 Mar 2025 22:57:50 +1000 Message-ID: <20250311125815.903177-57-npiggin@gmail.com> X-Mailer: git-send-email 2.47.1 In-Reply-To: <20250311125815.903177-1-npiggin@gmail.com> References: <20250311125815.903177-1-npiggin@gmail.com> MIME-Version: 1.0 Received-SPF: pass client-ip=2607:f8b0:4864:20::1030; envelope-from=npiggin@gmail.com; helo=mail-pj1-x1030.google.com X-Spam_score_int: -20 X-Spam_score: -2.1 X-Spam_bar: -- X-Spam_report: (-2.1 / 5.0 requ) BAYES_00=-1.9, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_AU=-0.1, DKIM_VALID_EF=-0.1, FREEMAIL_FROM=0.001, RCVD_IN_DNSWL_NONE=-0.0001, SPF_HELO_NONE=0.001, SPF_PASS=-0.001 autolearn=ham autolearn_force=no X-Spam_action: no action X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: qemu-devel-bounces+qemu-devel=archiver.kernel.org@nongnu.org Sender: qemu-devel-bounces+qemu-devel=archiver.kernel.org@nongnu.org From: Philippe Mathieu-Daudé Convert HPTE_DIRTY() macro as hpte_is_dirty() method. sPAPR data structures including the hash page table are big-endian regardless of current CPU endian mode, so use the big-endian LD/ST API to access the hash PTEs. Reviewed-by: Nicholas Piggin Signed-off-by: Philippe Mathieu-Daudé Reviewed-by: Harsh Prateek Bora Message-ID: <20241220213103.6314-4-philmd@linaro.org> Signed-off-by: Nicholas Piggin --- hw/ppc/spapr.c | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/hw/ppc/spapr.c b/hw/ppc/spapr.c index daf997cea1..dd81398445 100644 --- a/hw/ppc/spapr.c +++ b/hw/ppc/spapr.c @@ -1414,7 +1414,11 @@ static bool hpte_is_valid(SpaprMachineState *s, unsigned index) return ldq_be_p(hpte_get_ptr(s, index)) & HPTE64_V_VALID; } -#define HPTE_DIRTY(_hpte) (tswap64(*((uint64_t *)(_hpte))) & HPTE64_V_HPTE_DIRTY) +static bool hpte_is_dirty(SpaprMachineState *s, unsigned index) +{ + return ldq_be_p(hpte_get_ptr(s, index)) & HPTE64_V_HPTE_DIRTY; +} + #define CLEAN_HPTE(_hpte) ((*(uint64_t *)(_hpte)) &= tswap64(~HPTE64_V_HPTE_DIRTY)) #define DIRTY_HPTE(_hpte) ((*(uint64_t *)(_hpte)) |= tswap64(HPTE64_V_HPTE_DIRTY)) @@ -2259,7 +2263,7 @@ static int htab_save_later_pass(QEMUFile *f, SpaprMachineState *spapr, /* Consume non-dirty HPTEs */ while ((index < htabslots) - && !HPTE_DIRTY(hpte_get_ptr(spapr, index))) { + && !hpte_is_dirty(spapr, index)) { index++; examined++; } @@ -2267,7 +2271,7 @@ static int htab_save_later_pass(QEMUFile *f, SpaprMachineState *spapr, chunkstart = index; /* Consume valid dirty HPTEs */ while ((index < htabslots) && (index - chunkstart < USHRT_MAX) - && HPTE_DIRTY(hpte_get_ptr(spapr, index)) + && hpte_is_dirty(spapr, index) && hpte_is_valid(spapr, index)) { CLEAN_HPTE(hpte_get_ptr(spapr, index)); index++; @@ -2277,7 +2281,7 @@ static int htab_save_later_pass(QEMUFile *f, SpaprMachineState *spapr, invalidstart = index; /* Consume invalid dirty HPTEs */ while ((index < htabslots) && (index - invalidstart < USHRT_MAX) - && HPTE_DIRTY(hpte_get_ptr(spapr, index)) + && hpte_is_dirty(spapr, index) && !hpte_is_valid(spapr, index)) { CLEAN_HPTE(hpte_get_ptr(spapr, index)); index++; From patchwork Tue Mar 11 12:57:51 2025 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: Nicholas Piggin X-Patchwork-Id: 14011836 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.lore.kernel.org (Postfix) with ESMTPS id B1F4BC28B2E for ; Tue, 11 Mar 2025 13:12:58 +0000 (UTC) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1trzIu-00034F-29; Tue, 11 Mar 2025 09:05:52 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1trzEe-0005XO-A0; Tue, 11 Mar 2025 09:01:30 -0400 Received: from mail-pj1-x1029.google.com ([2607:f8b0:4864:20::1029]) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_128_GCM_SHA256:128) (Exim 4.90_1) (envelope-from ) id 1trzEa-0000Gv-LY; Tue, 11 Mar 2025 09:01:27 -0400 Received: by mail-pj1-x1029.google.com with SMTP id 98e67ed59e1d1-2f9d3d0f55dso8228505a91.1; Tue, 11 Mar 2025 06:01:23 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20230601; t=1741698082; x=1742302882; darn=nongnu.org; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to; bh=vyXD5UzpUW0YaKhAXXjbHUshaxnE47RC+WIYwrc3gYk=; b=XNEiM5gAK3OsrCtpEp9VMs0G3iu5Tq/2ANyAqtl3CYwKX6ZgfYok9UUxHbl7chuT92 uM0bBm8wkPe9KyIfvZKN/21/iSVmB5rJHRlkFd0vA4Ppyhz4Kw4Nn47BRF6YzTkofqbi NVo0zEYLSC/W0f3YkbKD7b7Tfbw25diI71DVQgWbGzFUjHB4p5njY5Ytnohxvc/8GkUU 2dzOTTRLXw0+X0TEq8XcVhYmc8d3Q5yvnPCogkV7AYdroN+4G+b/B9cXBSHnyuLauSPk Y9n11kYeNkaehkLp86eXaQHxYtjer2zy/wj+vu70RXJVKWEMfVNolPW0iPkq8PqVkXy0 YpQw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1741698082; x=1742302882; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=vyXD5UzpUW0YaKhAXXjbHUshaxnE47RC+WIYwrc3gYk=; b=I+fcPISZ4fcYobtykJZY9vkq2qOjluiPbhSvuCbtLohl9DjaeTIkG0ypfy1TnvFMXK 5hv7O+7sflQd92OYEvOX6elIry7d0+5mxeQn9M9oiiMz7kBONf0E/FT+iJY9+onVfAKB Sp/swthvplZYuMSCHJEQXuPZ0i6tjMlUJ5dR3l//51I+FxCJflPzyLngNxtGwB6P5c0p 7frU0mjMdcI+FQEtTjHQZI+oZXYOCen7HBsxLo2CRWDXA9/DTdd/XI/cNUjURXV1wEPl t42UXLGpv7qV/+8kTXanR3ALsGAxvhOywS4OzHCU5ib566SFN5g7M09qDg4R8FznqdHH dIDg== X-Forwarded-Encrypted: i=1; AJvYcCUVV+7Nee8sdnDcyLt5o6eFppOv1YXdl0xtNq5WnVe0GIQm8d3y9YBByKCFT/d9XOzF0CjLjKRDcw==@nongnu.org X-Gm-Message-State: AOJu0YwsMqaK3K1WkK5s75n/z6TZCXp/TOcnUbmr9Ei2C00H+CCXkLne 6/YLwJgIQXsc6+0kYFI2PGfnVpuUFTghG/DBTexiR7aBCP9/AWG6/4q8Vg== X-Gm-Gg: ASbGncs4W9QeT58sB1W+K6e0ed7kzeYi+dac0/a2Zwdkd7OAVhle873Z5JkRKkzx9lh qio0oenhN2JETzxytcvy4z8bw5Y0NUVZqets6G49QmOFh1+ox0yejO5C9xLAzahd+ni1LXyaPbW ViW34OzKmQ3U7hVr2yD779EMZw4D27PprW3ThX0gRocraJEFwxsxXYGVQ3MGGI9jJur0JPm/uT1 hSu6L3oM8etI7zH1i5xaUz5WT7O7JDJTn2WHg6g8Zq+vMzxG6Y3g/8Czu0AZdza65l+0R4tcdYR tqCMQ1lSzp2/fSTmTXLU911t2uhYpd7ipsK5O3iruCNHCvsLakWF9RESTwSv6A== X-Google-Smtp-Source: AGHT+IEMJZBUgVnye9Cur+e6qLx66fIs3LKKWKwiYdXdizHq23zqK1Kp7v7WjIVSvGuGTSNK+VlNvw== X-Received: by 2002:a17:90b:38cd:b0:2ee:741c:e9f4 with SMTP id 98e67ed59e1d1-2ff7ce8e5dfmr26796090a91.11.1741698080776; Tue, 11 Mar 2025 06:01:20 -0700 (PDT) Received: from wheely.local0.net ([118.208.151.101]) by smtp.gmail.com with ESMTPSA id 98e67ed59e1d1-2ff4e773dddsm11822318a91.12.2025.03.11.06.01.18 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 11 Mar 2025 06:01:20 -0700 (PDT) From: Nicholas Piggin To: qemu-devel@nongnu.org Cc: Nicholas Piggin , qemu-ppc@nongnu.org, =?utf-8?q?Phil?= =?utf-8?q?ippe_Mathieu-Daud=C3=A9?= , Harsh Prateek Bora Subject: [PULL 57/72] hw/ppc/spapr: Convert CLEAN_HPTE() macro as hpte_set_clean() method Date: Tue, 11 Mar 2025 22:57:51 +1000 Message-ID: <20250311125815.903177-58-npiggin@gmail.com> X-Mailer: git-send-email 2.47.1 In-Reply-To: <20250311125815.903177-1-npiggin@gmail.com> References: <20250311125815.903177-1-npiggin@gmail.com> MIME-Version: 1.0 Received-SPF: pass client-ip=2607:f8b0:4864:20::1029; envelope-from=npiggin@gmail.com; helo=mail-pj1-x1029.google.com X-Spam_score_int: -20 X-Spam_score: -2.1 X-Spam_bar: -- X-Spam_report: (-2.1 / 5.0 requ) BAYES_00=-1.9, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_AU=-0.1, DKIM_VALID_EF=-0.1, FREEMAIL_FROM=0.001, RCVD_IN_DNSWL_NONE=-0.0001, SPF_HELO_NONE=0.001, SPF_PASS=-0.001 autolearn=ham autolearn_force=no X-Spam_action: no action X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: qemu-devel-bounces+qemu-devel=archiver.kernel.org@nongnu.org Sender: qemu-devel-bounces+qemu-devel=archiver.kernel.org@nongnu.org From: Philippe Mathieu-Daudé Convert CLEAN_HPTE() macro as hpte_set_clean() method. sPAPR data structures including the hash page table are big-endian regardless of current CPU endian mode, so use the big-endian LD/ST API to access the hash PTEs. Reviewed-by: Nicholas Piggin Signed-off-by: Philippe Mathieu-Daudé Reviewed-by: Harsh Prateek Bora Message-ID: <20241220213103.6314-5-philmd@linaro.org> Signed-off-by: Nicholas Piggin --- hw/ppc/spapr.c | 15 ++++++++++----- 1 file changed, 10 insertions(+), 5 deletions(-) diff --git a/hw/ppc/spapr.c b/hw/ppc/spapr.c index dd81398445..3568a97045 100644 --- a/hw/ppc/spapr.c +++ b/hw/ppc/spapr.c @@ -1419,7 +1419,12 @@ static bool hpte_is_dirty(SpaprMachineState *s, unsigned index) return ldq_be_p(hpte_get_ptr(s, index)) & HPTE64_V_HPTE_DIRTY; } -#define CLEAN_HPTE(_hpte) ((*(uint64_t *)(_hpte)) &= tswap64(~HPTE64_V_HPTE_DIRTY)) +static void hpte_set_clean(SpaprMachineState *s, unsigned index) +{ + stq_be_p(hpte_get_ptr(s, index), + ldq_be_p(hpte_get_ptr(s, index)) & ~HPTE64_V_HPTE_DIRTY); +} + #define DIRTY_HPTE(_hpte) ((*(uint64_t *)(_hpte)) |= tswap64(HPTE64_V_HPTE_DIRTY)) /* @@ -2215,7 +2220,7 @@ static void htab_save_first_pass(QEMUFile *f, SpaprMachineState *spapr, /* Consume invalid HPTEs */ while ((index < htabslots) && !hpte_is_valid(spapr, index)) { - CLEAN_HPTE(hpte_get_ptr(spapr, index)); + hpte_set_clean(spapr, index); index++; } @@ -2223,7 +2228,7 @@ static void htab_save_first_pass(QEMUFile *f, SpaprMachineState *spapr, chunkstart = index; while ((index < htabslots) && (index - chunkstart < USHRT_MAX) && hpte_is_valid(spapr, index)) { - CLEAN_HPTE(hpte_get_ptr(spapr, index)); + hpte_set_clean(spapr, index); index++; } @@ -2273,7 +2278,7 @@ static int htab_save_later_pass(QEMUFile *f, SpaprMachineState *spapr, while ((index < htabslots) && (index - chunkstart < USHRT_MAX) && hpte_is_dirty(spapr, index) && hpte_is_valid(spapr, index)) { - CLEAN_HPTE(hpte_get_ptr(spapr, index)); + hpte_set_clean(spapr, index); index++; examined++; } @@ -2283,7 +2288,7 @@ static int htab_save_later_pass(QEMUFile *f, SpaprMachineState *spapr, while ((index < htabslots) && (index - invalidstart < USHRT_MAX) && hpte_is_dirty(spapr, index) && !hpte_is_valid(spapr, index)) { - CLEAN_HPTE(hpte_get_ptr(spapr, index)); + hpte_set_clean(spapr, index); index++; examined++; } From patchwork Tue Mar 11 12:57:52 2025 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: Nicholas Piggin X-Patchwork-Id: 14011814 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.lore.kernel.org (Postfix) with ESMTPS id 8EC66C28B30 for ; Tue, 11 Mar 2025 13:07:38 +0000 (UTC) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1trzJU-0004ZV-Vi; Tue, 11 Mar 2025 09:06:29 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1trzEg-0005Xy-7J; Tue, 11 Mar 2025 09:01:34 -0400 Received: from mail-pj1-x1036.google.com ([2607:f8b0:4864:20::1036]) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_128_GCM_SHA256:128) (Exim 4.90_1) (envelope-from ) id 1trzEe-0000HU-Du; Tue, 11 Mar 2025 09:01:29 -0400 Received: by mail-pj1-x1036.google.com with SMTP id 98e67ed59e1d1-2ff6e91cff5so7761463a91.2; Tue, 11 Mar 2025 06:01:27 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20230601; t=1741698086; x=1742302886; darn=nongnu.org; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to; bh=ejM9HRB5/VzpqAv8bUdwCGywl1lKQVo0Ro8YQEozmw8=; b=FvN5cAYD1l7yoSUIdn26m3LNP0cBeVB0jUtQ22kZYN1uE5WSdbbH8+1Y/OMlQO5xU5 pnAQF0Z+mCEfFrRBzSODJh7OQ0wMJCMmTJ3cehQQPSMru3Wffh2dNL0kuUflXwBwcaf5 +ZqC/lqPZ/FXBfV/9mJiNrcZ6wnaMpKQPTwnB8uf8b95EyEgbCaIoOB/nbPCS3ZGTg9k JFY9dRRqatDV8QW9l2wvKiZuy8Xb5Y5F7YUiPEJ8aUuS94ksTnKadiY2SFT6rYhP/4zg B+coMUubNuIb4KKfScIsTPyh5YlN6b/bVml9Yf7PBC4YhizRP1UHaPsCBHD6Jd+aax9l jLyg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1741698086; x=1742302886; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=ejM9HRB5/VzpqAv8bUdwCGywl1lKQVo0Ro8YQEozmw8=; b=rI9yFR/FqpngZSGWDLzShBaExJmGhEXJudADGXgYg9tHHWPIlM/Lbnr428IYjEaFSB mAemjm5/rZkwiqKl36wPYwKqb/nIbjh9NW08yw+G1AlSzrZSgEmfVdVH32Zd3+DKwRUI aXivfaSVUqgSrmiotfsZP8ZgrRhcWnCjEoUUZYzDMGEYmNsvl7fAz7eKxwCKvugs1zl9 +LeuqiPXULpY3Ha9vRabOQUcSK+EUnZhtkdqmJhXrQEGW9TBrspoYMgnYah4ghCChq3/ gOr2QPkvbazTv338DWDAIECvnivbPD5QfDOMLeSvKI2aP9bCGE0ilV+FcD2cYyd5SFMQ CCpQ== X-Forwarded-Encrypted: i=1; AJvYcCUVw+alfklO1WjA/frZiR4rdXn/VrP9PBuuntPGluQ3H9UGTimBXndY509XRVlSImapOVCAtZEcsQ==@nongnu.org X-Gm-Message-State: AOJu0YzYVFxgzlRIv/wz4VDgWv7eIYlbP2w8UkuJmNAFin7d2Xm2jNo/ PZPvxNZdT6I4xX4iIkyMXivUwTivx1euJ/XC4UC9LyH/afJvj9qeJ8VqjQ== X-Gm-Gg: ASbGncvX/h4h8JVrriFnz24n38soxLxJbXIE/zRD54syYh2qF1563Zuj206LcIG6gUH nUI3HSiOGbG9oX1S2GFXl9nmNtmR9vs/eknVyCrQHNPWti7hXgmgFFT6aP+t65nDoEX2XUOgx9c eIM9GBYYQWpqZA43S7hSJTClhyXE6RsZgrIFQTV1PO45YTxXXxWTuC43N+O6feFkzl8l8acSO2E mbxlDyEJ9f/3RkwrROg8US5zvFHMBQvMaGX8upp6UtbaRS/XXtynDGym91Ju0k+1G4uIxchTXEq V3BAhmVv4eJnJwaWyXoWLMWhQ1AvOsISRTG6jNe7IuAsHYadaRA= X-Google-Smtp-Source: AGHT+IHs6oo++CKnNNKejh7ur7cPc0n4ZdhawTJB62wb1wpJAIC4e4u8rAG9ggbqG+vPbdLBj9Y1yw== X-Received: by 2002:a17:90b:1d04:b0:2ef:67c2:4030 with SMTP id 98e67ed59e1d1-2ff7cf0a667mr25504343a91.27.1741698084126; Tue, 11 Mar 2025 06:01:24 -0700 (PDT) Received: from wheely.local0.net ([118.208.151.101]) by smtp.gmail.com with ESMTPSA id 98e67ed59e1d1-2ff4e773dddsm11822318a91.12.2025.03.11.06.01.21 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 11 Mar 2025 06:01:23 -0700 (PDT) From: Nicholas Piggin To: qemu-devel@nongnu.org Cc: Nicholas Piggin , qemu-ppc@nongnu.org, =?utf-8?q?Phil?= =?utf-8?q?ippe_Mathieu-Daud=C3=A9?= , Harsh Prateek Bora Subject: [PULL 58/72] hw/ppc/spapr: Convert DIRTY_HPTE() macro as hpte_set_dirty() method Date: Tue, 11 Mar 2025 22:57:52 +1000 Message-ID: <20250311125815.903177-59-npiggin@gmail.com> X-Mailer: git-send-email 2.47.1 In-Reply-To: <20250311125815.903177-1-npiggin@gmail.com> References: <20250311125815.903177-1-npiggin@gmail.com> MIME-Version: 1.0 Received-SPF: pass client-ip=2607:f8b0:4864:20::1036; envelope-from=npiggin@gmail.com; helo=mail-pj1-x1036.google.com X-Spam_score_int: -20 X-Spam_score: -2.1 X-Spam_bar: -- X-Spam_report: (-2.1 / 5.0 requ) BAYES_00=-1.9, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_AU=-0.1, DKIM_VALID_EF=-0.1, FREEMAIL_FROM=0.001, RCVD_IN_DNSWL_NONE=-0.0001, SPF_HELO_NONE=0.001, SPF_PASS=-0.001 autolearn=ham autolearn_force=no X-Spam_action: no action X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: qemu-devel-bounces+qemu-devel=archiver.kernel.org@nongnu.org Sender: qemu-devel-bounces+qemu-devel=archiver.kernel.org@nongnu.org From: Philippe Mathieu-Daudé Convert DIRTY_HPTE() macro as hpte_set_dirty() method. sPAPR data structures including the hash page table are big-endian regardless of current CPU endian mode, so use the big-endian LD/ST API to access the hash PTEs. Reviewed-by: Nicholas Piggin Signed-off-by: Philippe Mathieu-Daudé Reviewed-by: Harsh Prateek Bora Message-ID: <20241220213103.6314-6-philmd@linaro.org> Signed-off-by: Nicholas Piggin --- hw/ppc/spapr.c | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/hw/ppc/spapr.c b/hw/ppc/spapr.c index 3568a97045..0acf3c53dc 100644 --- a/hw/ppc/spapr.c +++ b/hw/ppc/spapr.c @@ -1425,7 +1425,11 @@ static void hpte_set_clean(SpaprMachineState *s, unsigned index) ldq_be_p(hpte_get_ptr(s, index)) & ~HPTE64_V_HPTE_DIRTY); } -#define DIRTY_HPTE(_hpte) ((*(uint64_t *)(_hpte)) |= tswap64(HPTE64_V_HPTE_DIRTY)) +static void hpte_set_dirty(SpaprMachineState *s, unsigned index) +{ + stq_be_p(hpte_get_ptr(s, index), + ldq_be_p(hpte_get_ptr(s, index)) | HPTE64_V_HPTE_DIRTY); +} /* * Get the fd to access the kernel htab, re-opening it if necessary @@ -1636,7 +1640,7 @@ int spapr_reallocate_hpt(SpaprMachineState *spapr, int shift, Error **errp) spapr->htab_shift = shift; for (i = 0; i < size / HASH_PTE_SIZE_64; i++) { - DIRTY_HPTE(hpte_get_ptr(spapr, i)); + hpte_set_dirty(spapr, i); } } /* We're setting up a hash table, so that means we're not radix */ From patchwork Tue Mar 11 12:57:53 2025 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: Nicholas Piggin X-Patchwork-Id: 14011889 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.lore.kernel.org (Postfix) with ESMTPS id 38D16C28B2E for ; Tue, 11 Mar 2025 13:23:43 +0000 (UTC) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1trzJb-000534-Dr; Tue, 11 Mar 2025 09:06:35 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1trzEk-0005bA-3u; Tue, 11 Mar 2025 09:01:36 -0400 Received: from mail-pj1-x102a.google.com ([2607:f8b0:4864:20::102a]) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_128_GCM_SHA256:128) (Exim 4.90_1) (envelope-from ) id 1trzEg-0000Hn-9D; Tue, 11 Mar 2025 09:01:32 -0400 Received: by mail-pj1-x102a.google.com with SMTP id 98e67ed59e1d1-2ff69365e1dso7929979a91.3; Tue, 11 Mar 2025 06:01:28 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20230601; t=1741698087; x=1742302887; darn=nongnu.org; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to; bh=Q98gbAuec0TkReIAHsIjEI1jfEiskw6MwZvR40Hgs1w=; b=fTebRs/YekZTR3N+F00+3NCDbdmNVn1Rhdqx+BAPMVBakvoTTofs/oiMz9Jqzcdztq fk56ZeBIdPUnyHrcBrbckoKr2yzGM6//DpVqtUCAPEWP1Zn+DkWCuUXM636LAnox0VOJ +wxrvJXCD4YxCfmRk0Ya1IHwMeCp0VWggQI+fmFyWO7FbbZDizHVzAGtS4QMFJg3m5ol x+MPlR/coKjz/vRZRQ/ze4NDTYFrQGWcb0DfO7c33ikI/qcZBmz3bOYMjZ0qIZdF3sUX 1PQ3cPsb6vZa5hqy0Ebh1COqb36WuqNIN0F89CXIfdZl8mVTvsxKcQ8c3scoTxmqK3Lk x4VA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1741698087; x=1742302887; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=Q98gbAuec0TkReIAHsIjEI1jfEiskw6MwZvR40Hgs1w=; b=JGH/AkKs1S/wW3zhNIGEi3IoehXSUAzD9EqBElP4Qx9roZnG2PjLVp6f3LxwVv8voj 3uF7o7cYb24fIZ6zOuXOkipvQ6HJcWGQq6Zftgs6CTLAtquQN6jeZrV03RkzyvBiL+IK XLEuu5CFveJshxiJI4s1+AzkIAnAgDIhFw5Y7fvSPkmUssBI+uhF8+WxbWJCRLj1hpGj dkgCGjc8acaaNtTCy6QwR95W55f6sTTM/kYhKftnnYkkuGfoRxyKUKFJBVc326Nn0KO0 HDwC0gwR0SNBc87/v8hKgZ777Mm24K2ze951TuNbeycDfkXZYrDYm7gJlt4AB7MkQAIS Q/1g== X-Forwarded-Encrypted: i=1; AJvYcCV+z3sM5RAVxHhtO1LuX2rO545UdKJ51j5lS+dBPKluUQuaTmU0Wxfe6m0GYqrtRLrjir3m7EfRVg==@nongnu.org X-Gm-Message-State: AOJu0Yzf0hLUMHIkGYBl8l+P2LIRFeKJ2q1GL8cu81l8OqHl7sg54R5S qN/IicNMYLem60iC0zDw8wjprI+yfjfuzkolvGkg1Wrp1Nj9RqhEZ7lypw== X-Gm-Gg: ASbGncuTQZwQvdlQvrdzU2dZDQPAd/0Ij0r1OZCz8Yv6RevvBDACFLFAs7MPFEPHgqv 7Xrh05KQjNU6CtfjoYSYCG5WKUtIURqSXUE/Jn1gbksD4Ham2GIWRVLVkgHH2zNTn6Y/OkBlKI2 XvbRqoFJtWZmOFcuNyOTD9evObA0XH7ZpRKfawTO+5FOf1oNyOwLAKBDDDCaVnsg29r4KY7xecP RRJbiMzRPGwrHCcVEssMHxqz2x2nb4XSQwBJeGiU739GLO5vRWCflB1iTV6DxCo1n5TSmvzLn3n n1OOlF1VvLCTrTLF+9C0uMRp10MpR53NtVsAJFJ1LdMbsx4827s= X-Google-Smtp-Source: AGHT+IHxDv3LZ4LBZ1myb8OjwuffMy6ub21FaKhxEpo5n74ntVMs1uiuc7nCmlD4qbtnf/q+6ar6ZQ== X-Received: by 2002:a17:90b:38ca:b0:2f9:9ddd:689b with SMTP id 98e67ed59e1d1-2ff7ceee83amr22267581a91.22.1741698087437; Tue, 11 Mar 2025 06:01:27 -0700 (PDT) Received: from wheely.local0.net ([118.208.151.101]) by smtp.gmail.com with ESMTPSA id 98e67ed59e1d1-2ff4e773dddsm11822318a91.12.2025.03.11.06.01.24 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 11 Mar 2025 06:01:27 -0700 (PDT) From: Nicholas Piggin To: qemu-devel@nongnu.org Cc: Nicholas Piggin , qemu-ppc@nongnu.org, =?utf-8?q?Phil?= =?utf-8?q?ippe_Mathieu-Daud=C3=A9?= , BALATON Zoltan , Harsh Prateek Bora Subject: [PULL 59/72] hw/ppc/epapr: Do not swap ePAPR magic value Date: Tue, 11 Mar 2025 22:57:53 +1000 Message-ID: <20250311125815.903177-60-npiggin@gmail.com> X-Mailer: git-send-email 2.47.1 In-Reply-To: <20250311125815.903177-1-npiggin@gmail.com> References: <20250311125815.903177-1-npiggin@gmail.com> MIME-Version: 1.0 Received-SPF: pass client-ip=2607:f8b0:4864:20::102a; envelope-from=npiggin@gmail.com; helo=mail-pj1-x102a.google.com X-Spam_score_int: -20 X-Spam_score: -2.1 X-Spam_bar: -- X-Spam_report: (-2.1 / 5.0 requ) BAYES_00=-1.9, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_AU=-0.1, DKIM_VALID_EF=-0.1, FREEMAIL_FROM=0.001, RCVD_IN_DNSWL_NONE=-0.0001, SPF_HELO_NONE=0.001, SPF_PASS=-0.001 autolearn=ham autolearn_force=no X-Spam_action: no action X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: qemu-devel-bounces+qemu-devel=archiver.kernel.org@nongnu.org Sender: qemu-devel-bounces+qemu-devel=archiver.kernel.org@nongnu.org From: Philippe Mathieu-Daudé The ePAPR magic value in $r6 doesn't need to be byte swapped. See ePAPR-v1.1.pdf chapter 5.4.1 "Boot CPU Initial Register State" and the following mailing-list threads: https://lore.kernel.org/qemu-devel/CAFEAcA_NR4XW5DNL4nq7vnH4XRH5UWbhQCxuLyKqYk6_FCBrAA@mail.gmail.com/ https://lore.kernel.org/qemu-devel/D6F93NM6OW2L.2FDO88L38PABR@gmail.com/ Signed-off-by: Philippe Mathieu-Daudé Reviewed-by: Nicholas Piggin Tested-by: BALATON Zoltan Reviewed-by: Harsh Prateek Bora Message-ID: <20241220213103.6314-7-philmd@linaro.org> Signed-off-by: Nicholas Piggin --- hw/ppc/sam460ex.c | 2 +- hw/ppc/virtex_ml507.c | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/hw/ppc/sam460ex.c b/hw/ppc/sam460ex.c index 3ecae6a950..7dc3b309c8 100644 --- a/hw/ppc/sam460ex.c +++ b/hw/ppc/sam460ex.c @@ -234,7 +234,7 @@ static void main_cpu_reset(void *opaque) /* Create a mapping for the kernel. */ booke_set_tlb(&env->tlb.tlbe[0], 0, 0, 1 << 31); - env->gpr[6] = tswap32(EPAPR_MAGIC); + env->gpr[6] = EPAPR_MAGIC; env->gpr[7] = (16 * MiB) - 8; /* bi->ima_size; */ } else { diff --git a/hw/ppc/virtex_ml507.c b/hw/ppc/virtex_ml507.c index a01354d991..17115be74d 100644 --- a/hw/ppc/virtex_ml507.c +++ b/hw/ppc/virtex_ml507.c @@ -119,7 +119,7 @@ static void main_cpu_reset(void *opaque) /* Create a mapping spanning the 32bit addr space. */ booke_set_tlb(&env->tlb.tlbe[0], 0, 0, 1U << 31); booke_set_tlb(&env->tlb.tlbe[1], 0x80000000, 0x80000000, 1U << 31); - env->gpr[6] = tswap32(EPAPR_MAGIC); + env->gpr[6] = EPAPR_MAGIC; env->gpr[7] = bi->ima_size; } From patchwork Tue Mar 11 12:57:54 2025 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Nicholas Piggin X-Patchwork-Id: 14011839 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.lore.kernel.org (Postfix) with ESMTPS id 42602C282EC for ; Tue, 11 Mar 2025 13:13:27 +0000 (UTC) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1trzIz-0003QF-Ep; Tue, 11 Mar 2025 09:05:57 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1trzEn-0005c4-1n; Tue, 11 Mar 2025 09:01:37 -0400 Received: from mail-pj1-x102a.google.com ([2607:f8b0:4864:20::102a]) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_128_GCM_SHA256:128) (Exim 4.90_1) (envelope-from ) id 1trzEk-0000If-81; Tue, 11 Mar 2025 09:01:36 -0400 Received: by mail-pj1-x102a.google.com with SMTP id 98e67ed59e1d1-300f92661fcso2351212a91.3; Tue, 11 Mar 2025 06:01:33 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20230601; t=1741698092; x=1742302892; darn=nongnu.org; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to; bh=3JRInH28kT8NQFjaUfcoifBn4ExD1TRUGhB92fe2nGc=; b=HpAb6kZQCNJzCN4jJ/rcAIs3rZlOR2qm3G0RUvOcA3xrqhcV4ufKKBpdulqbV0jtYN YTd76e2k3rK2Qbpjr5ttwzG8CJhZlZQi86uHSfYZmn1RF1m58+N3rZ2QzSa4lgpBfZhK vFayUvM/ZogNQsl1Ku1u5TzbjtWJWhcoVvYoI2YOs7w0OYx63LXNBk6AKMjteC1tbUWV yDqN4g9cQdvIDspBTbMSzIo41pYYujxagUkzbegYnCZVDoLdzw1dWHtjV/o++tzO559F F6khPgQ3GoOIge3tALkCrH2I1qp6inWoI93TrzXPH/wm49Fd5Wwz/K+GgAUhBahhOBLr S6Yw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1741698092; x=1742302892; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=3JRInH28kT8NQFjaUfcoifBn4ExD1TRUGhB92fe2nGc=; b=dNfGiuTuXnod5aqzNmjC+JG8cQqjDbniCOWnFraQg3XLYlJuWRiI0PHzlS37Wp+38p 4ZfBUEd208YSJE3EeU/9u3OQqL/HbvgBJr0HhfTt3qrngtild5awj8EyOYSkncNawLy+ OehxG/OTOH9AFYXtpMK48hLzkSo0zi56GvDq0Tu9iTyIlTRUgSKO5Oipyptt0s8jv/ZJ vtdw3ivgbNB6B8koEUAe4c5w3CXUbltVroA4ROa4Xg0A3iIF2T9TC9uRQhQBHA0r/l4B 8qmGHG0mY/elNEnuHd6YWHl7vDaATA+TvKSvBmlAMYMQn9hJyuRpegdUVfg7kVeynQVv fHHw== X-Forwarded-Encrypted: i=1; AJvYcCVxK3WuK8C58ZAtrKnghWohlf/Z8GqYBvLT6QV4VcdJDo/kDLM7yZYbCB88FuenRoIiCvngTHiLCg==@nongnu.org X-Gm-Message-State: AOJu0YyHrsVj2/gY7qD/Z31Ck6JdgDrZRxmfRa3yBgDZZl6eHQWsBrTn nXpHyuXx2TaqoBqyetNOzuzscrg9NxOlGsDf3e3GVbolB7ZxuxBOTDWgdw== X-Gm-Gg: ASbGncvdZ4P+wMAqb0UWnjbl87ZajBZWu01MEbg0qRZ+c1CV6qmcJvRbk4rRTrSvPcJ OBoIywQlqODOA2BExIgaluPZHGp3urK1S0zjQ9FOZcO5XoaEj4Vxz5aDosgtakE2prgXzxFgibs vWM7mb2FFhTqT70FjR9k70qf3OQr1mui9cl99XlXk2CSajuhzTGxcvr2CkmMJ1xyGrW2j4Ag5A7 uXW05BzuOlKTZlb0aFbYkxmY4Q/CMiX0R00NnuqDCcrOEGyJLqrCGBzl+VGsoXjqCk1u+dWKTWh OPRFzHOtGDQZKDZS1yyM0KZuCXXsouPspjQQ68pf72SU0y6lqNQ= X-Google-Smtp-Source: AGHT+IF6rtusrJ9DZlMX+zGfMn0HFO0XtTsFU4OPR/740n799Hj9OtxiKDjfWWfmOec/CCvtKM8BCA== X-Received: by 2002:a17:90b:3e4f:b0:2ff:7b15:813b with SMTP id 98e67ed59e1d1-2ff7ce93a00mr30063132a91.17.1741698090463; Tue, 11 Mar 2025 06:01:30 -0700 (PDT) Received: from wheely.local0.net ([118.208.151.101]) by smtp.gmail.com with ESMTPSA id 98e67ed59e1d1-2ff4e773dddsm11822318a91.12.2025.03.11.06.01.27 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 11 Mar 2025 06:01:30 -0700 (PDT) From: Nicholas Piggin To: qemu-devel@nongnu.org Cc: Nicholas Piggin , qemu-ppc@nongnu.org, Shivaprasad G Bhat , Harsh Prateek Bora Subject: [PULL 60/72] ppc: Enable 2nd DAWR support on Power10 PowerNV machine Date: Tue, 11 Mar 2025 22:57:54 +1000 Message-ID: <20250311125815.903177-61-npiggin@gmail.com> X-Mailer: git-send-email 2.47.1 In-Reply-To: <20250311125815.903177-1-npiggin@gmail.com> References: <20250311125815.903177-1-npiggin@gmail.com> MIME-Version: 1.0 Received-SPF: pass client-ip=2607:f8b0:4864:20::102a; envelope-from=npiggin@gmail.com; helo=mail-pj1-x102a.google.com X-Spam_score_int: -20 X-Spam_score: -2.1 X-Spam_bar: -- X-Spam_report: (-2.1 / 5.0 requ) BAYES_00=-1.9, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_AU=-0.1, DKIM_VALID_EF=-0.1, FREEMAIL_FROM=0.001, RCVD_IN_DNSWL_NONE=-0.0001, SPF_HELO_NONE=0.001, SPF_PASS=-0.001 autolearn=ham autolearn_force=no X-Spam_action: no action X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: qemu-devel-bounces+qemu-devel=archiver.kernel.org@nongnu.org Sender: qemu-devel-bounces+qemu-devel=archiver.kernel.org@nongnu.org From: Shivaprasad G Bhat Extend the existing watchpoint facility from TCG DAWR0 emulation to DAWR1 on POWER10. Reviewed-by: Nicholas Piggin Reviewed-by: Harsh Prateek Bora Signed-off-by: Shivaprasad G Bhat Message-ID: <173708680684.1678.13237334676438770057.stgit@linux.ibm.com> Signed-off-by: Nicholas Piggin --- target/ppc/cpu.c | 45 +++++++++++++++++++-------- target/ppc/cpu.h | 6 ++-- target/ppc/cpu_init.c | 15 +++++++++ target/ppc/helper.h | 2 ++ target/ppc/machine.c | 3 +- target/ppc/misc_helper.c | 10 ++++++ target/ppc/spr_common.h | 2 ++ target/ppc/tcg-excp_helper.c | 59 +++++++++++++++++++----------------- target/ppc/translate.c | 12 ++++++++ 9 files changed, 110 insertions(+), 44 deletions(-) diff --git a/target/ppc/cpu.c b/target/ppc/cpu.c index d148cd76b4..bfcc695de7 100644 --- a/target/ppc/cpu.c +++ b/target/ppc/cpu.c @@ -130,11 +130,13 @@ void ppc_store_ciabr(CPUPPCState *env, target_ulong val) ppc_update_ciabr(env); } -void ppc_update_daw0(CPUPPCState *env) +void ppc_update_daw(CPUPPCState *env, int rid) { CPUState *cs = env_cpu(env); - target_ulong deaw = env->spr[SPR_DAWR0] & PPC_BITMASK(0, 60); - uint32_t dawrx = env->spr[SPR_DAWRX0]; + int spr_dawr = rid ? SPR_DAWR1 : SPR_DAWR0; + int spr_dawrx = rid ? SPR_DAWRX1 : SPR_DAWRX0; + target_ulong deaw = env->spr[spr_dawr] & PPC_BITMASK(0, 60); + uint32_t dawrx = env->spr[spr_dawrx]; int mrd = extract32(dawrx, PPC_BIT_NR(48), 54 - 48); bool dw = extract32(dawrx, PPC_BIT_NR(57), 1); bool dr = extract32(dawrx, PPC_BIT_NR(58), 1); @@ -144,9 +146,9 @@ void ppc_update_daw0(CPUPPCState *env) vaddr len; int flags; - if (env->dawr0_watchpoint) { - cpu_watchpoint_remove_by_ref(cs, env->dawr0_watchpoint); - env->dawr0_watchpoint = NULL; + if (env->dawr_watchpoint[rid]) { + cpu_watchpoint_remove_by_ref(cs, env->dawr_watchpoint[rid]); + env->dawr_watchpoint[rid] = NULL; } if (!dr && !dw) { @@ -166,28 +168,45 @@ void ppc_update_daw0(CPUPPCState *env) flags |= BP_MEM_WRITE; } - cpu_watchpoint_insert(cs, deaw, len, flags, &env->dawr0_watchpoint); + cpu_watchpoint_insert(cs, deaw, len, flags, &env->dawr_watchpoint[rid]); } void ppc_store_dawr0(CPUPPCState *env, target_ulong val) { env->spr[SPR_DAWR0] = val; - ppc_update_daw0(env); + ppc_update_daw(env, 0); } -void ppc_store_dawrx0(CPUPPCState *env, uint32_t val) +static void ppc_store_dawrx(CPUPPCState *env, uint32_t val, int rid) { int hrammc = extract32(val, PPC_BIT_NR(56), 1); if (hrammc) { /* This might be done with a second watchpoint at the xor of DEAW[0] */ - qemu_log_mask(LOG_UNIMP, "%s: DAWRX0[HRAMMC] is unimplemented\n", - __func__); + qemu_log_mask(LOG_UNIMP, "%s: DAWRX%d[HRAMMC] is unimplemented\n", + __func__, rid); } - env->spr[SPR_DAWRX0] = val; - ppc_update_daw0(env); + env->spr[rid ? SPR_DAWRX1 : SPR_DAWRX0] = val; + ppc_update_daw(env, rid); +} + +void ppc_store_dawrx0(CPUPPCState *env, uint32_t val) +{ + ppc_store_dawrx(env, val, 0); +} + +void ppc_store_dawr1(CPUPPCState *env, target_ulong val) +{ + env->spr[SPR_DAWR1] = val; + ppc_update_daw(env, 1); +} + +void ppc_store_dawrx1(CPUPPCState *env, uint32_t val) +{ + ppc_store_dawrx(env, val, 1); } + #endif #endif diff --git a/target/ppc/cpu.h b/target/ppc/cpu.h index 8d43983fe1..efab54a068 100644 --- a/target/ppc/cpu.h +++ b/target/ppc/cpu.h @@ -1260,7 +1260,7 @@ struct CPUArchState { #if defined(TARGET_PPC64) ppc_slb_t slb[MAX_SLB_ENTRIES]; /* PowerPC 64 SLB area */ struct CPUBreakpoint *ciabr_breakpoint; - struct CPUWatchpoint *dawr0_watchpoint; + struct CPUWatchpoint *dawr_watchpoint[2]; #endif target_ulong sr[32]; /* segment registers */ uint32_t nb_BATs; /* number of BATs */ @@ -1589,9 +1589,11 @@ void ppc_store_sdr1(CPUPPCState *env, target_ulong value); void ppc_store_lpcr(PowerPCCPU *cpu, target_ulong val); void ppc_update_ciabr(CPUPPCState *env); void ppc_store_ciabr(CPUPPCState *env, target_ulong value); -void ppc_update_daw0(CPUPPCState *env); +void ppc_update_daw(CPUPPCState *env, int rid); void ppc_store_dawr0(CPUPPCState *env, target_ulong value); void ppc_store_dawrx0(CPUPPCState *env, uint32_t value); +void ppc_store_dawr1(CPUPPCState *env, target_ulong value); +void ppc_store_dawrx1(CPUPPCState *env, uint32_t value); #endif /* !defined(CONFIG_USER_ONLY) */ void ppc_store_msr(CPUPPCState *env, target_ulong value); diff --git a/target/ppc/cpu_init.c b/target/ppc/cpu_init.c index 8d73e11540..9dc5ace828 100644 --- a/target/ppc/cpu_init.c +++ b/target/ppc/cpu_init.c @@ -5172,6 +5172,20 @@ static void register_book3s_207_dbg_sprs(CPUPPCState *env) KVM_REG_PPC_CIABR, 0x00000000); } +static void register_book3s_310_dbg_sprs(CPUPPCState *env) +{ + spr_register_kvm_hv(env, SPR_DAWR1, "DAWR1", + SPR_NOACCESS, SPR_NOACCESS, + SPR_NOACCESS, SPR_NOACCESS, + &spr_read_generic, &spr_write_dawr1, + KVM_REG_PPC_DAWR1, 0x00000000); + spr_register_kvm_hv(env, SPR_DAWRX1, "DAWRX1", + SPR_NOACCESS, SPR_NOACCESS, + SPR_NOACCESS, SPR_NOACCESS, + &spr_read_generic, &spr_write_dawrx1, + KVM_REG_PPC_DAWRX1, 0x00000000); +} + static void register_970_dbg_sprs(CPUPPCState *env) { /* Breakpoints */ @@ -6584,6 +6598,7 @@ static void init_proc_POWER10(CPUPPCState *env) { register_power9_common_sprs(env); register_HEIR64_spr(env); + register_book3s_310_dbg_sprs(env); register_power10_hash_sprs(env); register_power10_dexcr_sprs(env); register_power10_pmu_sup_sprs(env); diff --git a/target/ppc/helper.h b/target/ppc/helper.h index 11b914e640..ca414f2f43 100644 --- a/target/ppc/helper.h +++ b/target/ppc/helper.h @@ -28,6 +28,8 @@ DEF_HELPER_2(store_pcr, void, env, tl) DEF_HELPER_2(store_ciabr, void, env, tl) DEF_HELPER_2(store_dawr0, void, env, tl) DEF_HELPER_2(store_dawrx0, void, env, tl) +DEF_HELPER_2(store_dawr1, void, env, tl) +DEF_HELPER_2(store_dawrx1, void, env, tl) DEF_HELPER_2(store_mmcr0, void, env, tl) DEF_HELPER_2(store_mmcr1, void, env, tl) DEF_HELPER_2(store_mmcrA, void, env, tl) diff --git a/target/ppc/machine.c b/target/ppc/machine.c index 0bd7ae6c0c..98df5b4a3a 100644 --- a/target/ppc/machine.c +++ b/target/ppc/machine.c @@ -264,7 +264,8 @@ static int cpu_post_load(void *opaque, int version_id) /* Re-set breaks based on regs */ #if defined(TARGET_PPC64) ppc_update_ciabr(env); - ppc_update_daw0(env); + ppc_update_daw(env, 0); + ppc_update_daw(env, 1); #endif /* * TCG needs to re-start the decrementer timer and/or raise the diff --git a/target/ppc/misc_helper.c b/target/ppc/misc_helper.c index 190e9091fc..2d9512c116 100644 --- a/target/ppc/misc_helper.c +++ b/target/ppc/misc_helper.c @@ -234,6 +234,16 @@ void helper_store_dawrx0(CPUPPCState *env, target_ulong value) ppc_store_dawrx0(env, value); } +void helper_store_dawr1(CPUPPCState *env, target_ulong value) +{ + ppc_store_dawr1(env, value); +} + +void helper_store_dawrx1(CPUPPCState *env, target_ulong value) +{ + ppc_store_dawrx1(env, value); +} + /* * DPDES register is shared. Each bit reflects the state of the * doorbell interrupt of a thread of the same core. diff --git a/target/ppc/spr_common.h b/target/ppc/spr_common.h index 8e3117b463..84c910c440 100644 --- a/target/ppc/spr_common.h +++ b/target/ppc/spr_common.h @@ -165,6 +165,8 @@ void spr_write_cfar(DisasContext *ctx, int sprn, int gprn); void spr_write_ciabr(DisasContext *ctx, int sprn, int gprn); void spr_write_dawr0(DisasContext *ctx, int sprn, int gprn); void spr_write_dawrx0(DisasContext *ctx, int sprn, int gprn); +void spr_write_dawr1(DisasContext *ctx, int sprn, int gprn); +void spr_write_dawrx1(DisasContext *ctx, int sprn, int gprn); void spr_write_ureg(DisasContext *ctx, int sprn, int gprn); void spr_read_purr(DisasContext *ctx, int gprn, int sprn); void spr_write_purr(DisasContext *ctx, int sprn, int gprn); diff --git a/target/ppc/tcg-excp_helper.c b/target/ppc/tcg-excp_helper.c index 4b859a8ffa..5a189dc3d7 100644 --- a/target/ppc/tcg-excp_helper.c +++ b/target/ppc/tcg-excp_helper.c @@ -345,39 +345,42 @@ bool ppc_cpu_debug_check_watchpoint(CPUState *cs, CPUWatchpoint *wp) { #if defined(TARGET_PPC64) CPUPPCState *env = cpu_env(cs); + bool wt, wti, hv, sv, pr; + uint32_t dawrx; + + if ((env->insns_flags2 & PPC2_ISA207S) && + (wp == env->dawr_watchpoint[0])) { + dawrx = env->spr[SPR_DAWRX0]; + } else if ((env->insns_flags2 & PPC2_ISA310) && + (wp == env->dawr_watchpoint[1])) { + dawrx = env->spr[SPR_DAWRX1]; + } else { + return false; + } - if (env->insns_flags2 & PPC2_ISA207S) { - if (wp == env->dawr0_watchpoint) { - uint32_t dawrx = env->spr[SPR_DAWRX0]; - bool wt = extract32(dawrx, PPC_BIT_NR(59), 1); - bool wti = extract32(dawrx, PPC_BIT_NR(60), 1); - bool hv = extract32(dawrx, PPC_BIT_NR(61), 1); - bool sv = extract32(dawrx, PPC_BIT_NR(62), 1); - bool pr = extract32(dawrx, PPC_BIT_NR(62), 1); - - if ((env->msr & ((target_ulong)1 << MSR_PR)) && !pr) { - return false; - } else if ((env->msr & ((target_ulong)1 << MSR_HV)) && !hv) { - return false; - } else if (!sv) { - return false; - } + wt = extract32(dawrx, PPC_BIT_NR(59), 1); + wti = extract32(dawrx, PPC_BIT_NR(60), 1); + hv = extract32(dawrx, PPC_BIT_NR(61), 1); + sv = extract32(dawrx, PPC_BIT_NR(62), 1); + pr = extract32(dawrx, PPC_BIT_NR(62), 1); - if (!wti) { - if (env->msr & ((target_ulong)1 << MSR_DR)) { - if (!wt) { - return false; - } - } else { - if (wt) { - return false; - } - } - } + if ((env->msr & ((target_ulong)1 << MSR_PR)) && !pr) { + return false; + } else if ((env->msr & ((target_ulong)1 << MSR_HV)) && !hv) { + return false; + } else if (!sv) { + return false; + } - return true; + if (!wti) { + if (env->msr & ((target_ulong)1 << MSR_DR)) { + return wt; + } else { + return !wt; } } + + return true; #endif return false; diff --git a/target/ppc/translate.c b/target/ppc/translate.c index b0cc8bf283..a52cbc869a 100644 --- a/target/ppc/translate.c +++ b/target/ppc/translate.c @@ -637,6 +637,18 @@ void spr_write_dawrx0(DisasContext *ctx, int sprn, int gprn) translator_io_start(&ctx->base); gen_helper_store_dawrx0(tcg_env, cpu_gpr[gprn]); } + +void spr_write_dawr1(DisasContext *ctx, int sprn, int gprn) +{ + translator_io_start(&ctx->base); + gen_helper_store_dawr1(tcg_env, cpu_gpr[gprn]); +} + +void spr_write_dawrx1(DisasContext *ctx, int sprn, int gprn) +{ + translator_io_start(&ctx->base); + gen_helper_store_dawrx1(tcg_env, cpu_gpr[gprn]); +} #endif /* defined(TARGET_PPC64) && !defined(CONFIG_USER_ONLY) */ /* CTR */ From patchwork Tue Mar 11 12:57:55 2025 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Nicholas Piggin X-Patchwork-Id: 14011899 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.lore.kernel.org (Postfix) with ESMTPS id 1E296C282EC for ; Tue, 11 Mar 2025 13:26:40 +0000 (UTC) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1trzJr-00062S-CP; Tue, 11 Mar 2025 09:06:52 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1trzEp-0005km-Up; Tue, 11 Mar 2025 09:01:42 -0400 Received: from mail-pj1-x1035.google.com ([2607:f8b0:4864:20::1035]) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_128_GCM_SHA256:128) (Exim 4.90_1) (envelope-from ) id 1trzEn-0000JK-JF; Tue, 11 Mar 2025 09:01:39 -0400 Received: by mail-pj1-x1035.google.com with SMTP id 98e67ed59e1d1-2ff784dc055so7177610a91.1; Tue, 11 Mar 2025 06:01:35 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20230601; t=1741698094; x=1742302894; darn=nongnu.org; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to; bh=vHowS6P5BYg/rSJVbmvQ3akSwNj1ZtWnh45h27uLxQY=; b=DJlEHgGy+IAt8cQ90xUY0eIbcMW/wqlTV1fxtDucSmHEH0G99LpjiBjJyaDszrxutZ eNiZJ8pvEEqZZCRS3jOdh3ShuWOAiWI1PxbK5TsG9KegtcXDjJZIEy+Uv+Gg2Bl8+IHo jUn4t2GApMD2SIeqky6hRzwBvpbK3yM8p0MPi9YoioiZhhwoHqS3q55N8X7lGvqpybSk NraKvyVUaOw2yYe2tmFuUpuc4QMWdjQfuE++8jhRBenzBY/OV55BG0iCiNVNB6Ufnu6S k8Wo/ncGbubpWzxaLJGNlBXnWxGlz6nSIezHRcFcj/uVtL87Vv+eRkxVdkIcra35o1xW 0FhA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1741698094; x=1742302894; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=vHowS6P5BYg/rSJVbmvQ3akSwNj1ZtWnh45h27uLxQY=; b=nILcny2kp2WrKjRu0tUBm4XHTvv3q3+cjVooxT3Gd9hDm8+eH04rJ5+ImCkRflQcvT tQ8B3dvFxFw7WTwW17ccCRGkjMlwS4l4NtIlIF8BfDUzGpzA7nbkpF1t6/hbjnFzPPaw ns1T8t4YqN1H/TD28mxoCRml9pJBbV0O0PyLNyCP3J+OSNR+nCGa43eP2Bhk8rXnYdWQ P5XE0On2RjalXr4j2dxkSVm3YC5WFrlaC8Q2Pd/N5mlCw76vwyF+37lsW9nQ9VNKTok9 v7r+n8C4qW+oyvxL2pzBgnTU2EeSbvRpyv2ffm1NOPOWc/DN5DdVuT9KPsWNRwU/YtVb 6oLw== X-Forwarded-Encrypted: i=1; AJvYcCV7onlPN5mntk1em+WeCaKZhzaCOdDRAJHv4WKAStKtWaY8MEuG+YDGF8ym1lagMjFN5bBbamnxyw==@nongnu.org X-Gm-Message-State: AOJu0YzZOEFf7z/1N2a1w/DTCcafM97GRiZiyS1zbwzHmyWQl6boO0/J OA57TXQUGT+FuaAmpycEGcSTnLp/GP59Dnl6w0Cf+JAoZkwk7/tAkHcJvg== X-Gm-Gg: ASbGncvfwZsy3CTwqNEMO+TsxOVckna/TEk5SInSkZOSYpNltmK+Kt5aDD4M1mPOM+o BgRYMLE31qn6B+2AzxVPAhwVngExw1/y6xFqyVVyzEXLBaE8/VQRqa3XZiMZn6pqyzAfkM4TS37 7Ckw5Xv1i9lrC/72lULrSQpJ9+DBv18+YIOGOumzt6mwtlEW09J1/zM4qo0xawo7tfhzkWzDMKF 6Hrf03TRRdn48/6F4/6zyHdP8gc+RNnjo3eRDBXUl8T3/V1Its5G1/MnLL3DTdm0h4hbfLJD2Nx /OVJaRhzwWdquGrtLFnr733OvGX3mJQaSOHwDXW1+t1WOvg15wI= X-Google-Smtp-Source: AGHT+IEjE+5Z6cbs5WrPYTixKQE7tCPH4wzNRS834rYetiR6W7zxy28+Jn33fTdnxmTDagXM7abGuA== X-Received: by 2002:a17:90a:e70e:b0:2ee:f076:20fb with SMTP id 98e67ed59e1d1-300ff10c978mr5414489a91.17.1741698093784; Tue, 11 Mar 2025 06:01:33 -0700 (PDT) Received: from wheely.local0.net ([118.208.151.101]) by smtp.gmail.com with ESMTPSA id 98e67ed59e1d1-2ff4e773dddsm11822318a91.12.2025.03.11.06.01.30 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 11 Mar 2025 06:01:33 -0700 (PDT) From: Nicholas Piggin To: qemu-devel@nongnu.org Cc: Nicholas Piggin , qemu-ppc@nongnu.org, Shivaprasad G Bhat , Harsh Prateek Bora , Ravi Bangoria Subject: [PULL 61/72] ppc: spapr: Enable 2nd DAWR on Power10 pSeries machine Date: Tue, 11 Mar 2025 22:57:55 +1000 Message-ID: <20250311125815.903177-62-npiggin@gmail.com> X-Mailer: git-send-email 2.47.1 In-Reply-To: <20250311125815.903177-1-npiggin@gmail.com> References: <20250311125815.903177-1-npiggin@gmail.com> MIME-Version: 1.0 Received-SPF: pass client-ip=2607:f8b0:4864:20::1035; envelope-from=npiggin@gmail.com; helo=mail-pj1-x1035.google.com X-Spam_score_int: -20 X-Spam_score: -2.1 X-Spam_bar: -- X-Spam_report: (-2.1 / 5.0 requ) BAYES_00=-1.9, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_AU=-0.1, DKIM_VALID_EF=-0.1, FREEMAIL_FROM=0.001, RCVD_IN_DNSWL_NONE=-0.0001, SPF_HELO_NONE=0.001, SPF_PASS=-0.001 autolearn=ham autolearn_force=no X-Spam_action: no action X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: qemu-devel-bounces+qemu-devel=archiver.kernel.org@nongnu.org Sender: qemu-devel-bounces+qemu-devel=archiver.kernel.org@nongnu.org From: Shivaprasad G Bhat As per the PAPR, bit 0 of byte 64 in pa-features property indicates availability of 2nd DAWR registers. i.e. If this bit is set, 2nd DAWR is present, otherwise not. Use KVM_CAP_PPC_DAWR1 capability to find whether kvm supports 2nd DAWR or not. If it's supported, allow user to set the pa-feature bit in guest DT using cap-dawr1 machine capability. Reviewed-by: Nicholas Piggin Reviewed-by: Harsh Prateek Bora Signed-off-by: Ravi Bangoria Signed-off-by: Shivaprasad G Bhat Message-ID: <173708681866.1678.11128625982438367069.stgit@linux.ibm.com> Signed-off-by: Nicholas Piggin --- hw/ppc/spapr.c | 7 ++++++- hw/ppc/spapr_caps.c | 43 ++++++++++++++++++++++++++++++++++++++++++ hw/ppc/spapr_hcall.c | 27 +++++++++++++++++--------- include/hw/ppc/spapr.h | 6 +++++- target/ppc/kvm.c | 12 ++++++++++++ target/ppc/kvm_ppc.h | 12 ++++++++++++ 6 files changed, 96 insertions(+), 11 deletions(-) diff --git a/hw/ppc/spapr.c b/hw/ppc/spapr.c index 0acf3c53dc..fcd2ca515c 100644 --- a/hw/ppc/spapr.c +++ b/hw/ppc/spapr.c @@ -246,7 +246,7 @@ static void spapr_dt_pa_features(SpaprMachineState *spapr, 0x80, 0x00, 0x80, 0x00, 0x80, 0x00, /* 48 - 53 */ /* 54: DecFP, 56: DecI, 58: SHA */ 0x80, 0x00, 0x80, 0x00, 0x80, 0x00, /* 54 - 59 */ - /* 60: NM atomic, 62: RNG */ + /* 60: NM atomic, 62: RNG, 64: DAWR1 (ISA 3.1) */ 0x80, 0x00, 0x80, 0x00, 0x00, 0x00, /* 60 - 65 */ /* 68: DEXCR[SBHE|IBRTPDUS|SRAPD|NPHIE|PHIE] */ 0x00, 0x00, 0xce, 0x00, 0x00, 0x00, /* 66 - 71 */ @@ -295,6 +295,9 @@ static void spapr_dt_pa_features(SpaprMachineState *spapr, * in pa-features. So hide it from them. */ pa_features[40 + 2] &= ~0x80; /* Radix MMU */ } + if (spapr_get_cap(spapr, SPAPR_CAP_DAWR1)) { + pa_features[66] |= 0x80; + } _FDT((fdt_setprop(fdt, offset, "ibm,pa-features", pa_features, pa_size))); } @@ -2163,6 +2166,7 @@ static const VMStateDescription vmstate_spapr = { &vmstate_spapr_cap_rpt_invalidate, &vmstate_spapr_cap_ail_mode_3, &vmstate_spapr_cap_nested_papr, + &vmstate_spapr_cap_dawr1, NULL } }; @@ -4680,6 +4684,7 @@ static void spapr_machine_class_init(ObjectClass *oc, void *data) smc->default_caps.caps[SPAPR_CAP_CCF_ASSIST] = SPAPR_CAP_ON; smc->default_caps.caps[SPAPR_CAP_FWNMI] = SPAPR_CAP_ON; smc->default_caps.caps[SPAPR_CAP_RPT_INVALIDATE] = SPAPR_CAP_OFF; + smc->default_caps.caps[SPAPR_CAP_DAWR1] = SPAPR_CAP_ON; /* * This cap specifies whether the AIL 3 mode for diff --git a/hw/ppc/spapr_caps.c b/hw/ppc/spapr_caps.c index 904bff87ce..9f4fd0cb5e 100644 --- a/hw/ppc/spapr_caps.c +++ b/hw/ppc/spapr_caps.c @@ -696,6 +696,34 @@ static void cap_ail_mode_3_apply(SpaprMachineState *spapr, } } +static void cap_dawr1_apply(SpaprMachineState *spapr, uint8_t val, + Error **errp) +{ + ERRP_GUARD(); + + if (!val) { + return; /* Disable by default */ + } + + if (!ppc_type_check_compat(MACHINE(spapr)->cpu_type, + CPU_POWERPC_LOGICAL_3_10, 0, + spapr->max_compat_pvr)) { + error_setg(errp, "DAWR1 supported only on POWER10 and later CPUs"); + error_append_hint(errp, "Try appending -machine cap-dawr1=off\n"); + return; + } + + if (kvm_enabled()) { + if (!kvmppc_has_cap_dawr1()) { + error_setg(errp, "DAWR1 not supported by KVM."); + error_append_hint(errp, "Try appending -machine cap-dawr1=off"); + } else if (kvmppc_set_cap_dawr1(val) < 0) { + error_setg(errp, "Error enabling cap-dawr1 with KVM."); + error_append_hint(errp, "Try appending -machine cap-dawr1=off"); + } + } +} + SpaprCapabilityInfo capability_table[SPAPR_CAP_NUM] = { [SPAPR_CAP_HTM] = { .name = "htm", @@ -831,6 +859,15 @@ SpaprCapabilityInfo capability_table[SPAPR_CAP_NUM] = { .type = "bool", .apply = cap_ail_mode_3_apply, }, + [SPAPR_CAP_DAWR1] = { + .name = "dawr1", + .description = "Allow 2nd Data Address Watchpoint Register (DAWR1)", + .index = SPAPR_CAP_DAWR1, + .get = spapr_cap_get_bool, + .set = spapr_cap_set_bool, + .type = "bool", + .apply = cap_dawr1_apply, + }, }; static SpaprCapabilities default_caps_with_cpu(SpaprMachineState *spapr, @@ -841,6 +878,11 @@ static SpaprCapabilities default_caps_with_cpu(SpaprMachineState *spapr, caps = smc->default_caps; + if (!ppc_type_check_compat(cputype, CPU_POWERPC_LOGICAL_3_10, + 0, spapr->max_compat_pvr)) { + caps.caps[SPAPR_CAP_DAWR1] = SPAPR_CAP_OFF; + } + if (!ppc_type_check_compat(cputype, CPU_POWERPC_LOGICAL_3_00, 0, spapr->max_compat_pvr)) { caps.caps[SPAPR_CAP_LARGE_DECREMENTER] = SPAPR_CAP_OFF; @@ -975,6 +1017,7 @@ SPAPR_CAP_MIG_STATE(ccf_assist, SPAPR_CAP_CCF_ASSIST); SPAPR_CAP_MIG_STATE(fwnmi, SPAPR_CAP_FWNMI); SPAPR_CAP_MIG_STATE(rpt_invalidate, SPAPR_CAP_RPT_INVALIDATE); SPAPR_CAP_MIG_STATE(ail_mode_3, SPAPR_CAP_AIL_MODE_3); +SPAPR_CAP_MIG_STATE(dawr1, SPAPR_CAP_DAWR1); void spapr_caps_init(SpaprMachineState *spapr) { diff --git a/hw/ppc/spapr_hcall.c b/hw/ppc/spapr_hcall.c index 4f1933b8da..406aea4ecb 100644 --- a/hw/ppc/spapr_hcall.c +++ b/hw/ppc/spapr_hcall.c @@ -822,11 +822,12 @@ static target_ulong h_set_mode_resource_set_ciabr(PowerPCCPU *cpu, return H_SUCCESS; } -static target_ulong h_set_mode_resource_set_dawr0(PowerPCCPU *cpu, - SpaprMachineState *spapr, - target_ulong mflags, - target_ulong value1, - target_ulong value2) +static target_ulong h_set_mode_resource_set_dawr(PowerPCCPU *cpu, + SpaprMachineState *spapr, + target_ulong mflags, + target_ulong resource, + target_ulong value1, + target_ulong value2) { CPUPPCState *env = &cpu->env; @@ -839,8 +840,15 @@ static target_ulong h_set_mode_resource_set_dawr0(PowerPCCPU *cpu, return H_P4; } - ppc_store_dawr0(env, value1); - ppc_store_dawrx0(env, value2); + if (resource == H_SET_MODE_RESOURCE_SET_DAWR0) { + ppc_store_dawr0(env, value1); + ppc_store_dawrx0(env, value2); + } else if (resource == H_SET_MODE_RESOURCE_SET_DAWR1) { + ppc_store_dawr1(env, value1); + ppc_store_dawrx1(env, value2); + } else { + g_assert_not_reached(); + } return H_SUCCESS; } @@ -919,8 +927,9 @@ static target_ulong h_set_mode(PowerPCCPU *cpu, SpaprMachineState *spapr, args[3]); break; case H_SET_MODE_RESOURCE_SET_DAWR0: - ret = h_set_mode_resource_set_dawr0(cpu, spapr, args[0], args[2], - args[3]); + case H_SET_MODE_RESOURCE_SET_DAWR1: + ret = h_set_mode_resource_set_dawr(cpu, spapr, args[0], args[1], + args[2], args[3]); break; case H_SET_MODE_RESOURCE_LE: ret = h_set_mode_resource_le(cpu, spapr, args[0], args[2], args[3]); diff --git a/include/hw/ppc/spapr.h b/include/hw/ppc/spapr.h index a6c0547e31..d227f0b94b 100644 --- a/include/hw/ppc/spapr.h +++ b/include/hw/ppc/spapr.h @@ -83,8 +83,10 @@ typedef enum { #define SPAPR_CAP_AIL_MODE_3 0x0C /* Nested PAPR */ #define SPAPR_CAP_NESTED_PAPR 0x0D +/* DAWR1 */ +#define SPAPR_CAP_DAWR1 0x0E /* Num Caps */ -#define SPAPR_CAP_NUM (SPAPR_CAP_NESTED_PAPR + 1) +#define SPAPR_CAP_NUM (SPAPR_CAP_DAWR1 + 1) /* * Capability Values @@ -406,6 +408,7 @@ struct SpaprMachineState { #define H_SET_MODE_RESOURCE_SET_DAWR0 2 #define H_SET_MODE_RESOURCE_ADDR_TRANS_MODE 3 #define H_SET_MODE_RESOURCE_LE 4 +#define H_SET_MODE_RESOURCE_SET_DAWR1 5 /* Flags for H_SET_MODE_RESOURCE_LE */ #define H_SET_MODE_ENDIAN_BIG 0 @@ -1003,6 +1006,7 @@ extern const VMStateDescription vmstate_spapr_cap_fwnmi; extern const VMStateDescription vmstate_spapr_cap_rpt_invalidate; extern const VMStateDescription vmstate_spapr_cap_ail_mode_3; extern const VMStateDescription vmstate_spapr_wdt; +extern const VMStateDescription vmstate_spapr_cap_dawr1; static inline uint8_t spapr_get_cap(SpaprMachineState *spapr, int cap) { diff --git a/target/ppc/kvm.c b/target/ppc/kvm.c index 216638dee4..992356cb75 100644 --- a/target/ppc/kvm.c +++ b/target/ppc/kvm.c @@ -92,6 +92,7 @@ static int cap_large_decr; static int cap_fwnmi; static int cap_rpt_invalidate; static int cap_ail_mode_3; +static int cap_dawr1; #ifdef CONFIG_PSERIES static int cap_papr; @@ -152,6 +153,7 @@ int kvm_arch_init(MachineState *ms, KVMState *s) cap_ppc_nested_kvm_hv = kvm_vm_check_extension(s, KVM_CAP_PPC_NESTED_HV); cap_large_decr = kvmppc_get_dec_bits(); cap_fwnmi = kvm_vm_check_extension(s, KVM_CAP_PPC_FWNMI); + cap_dawr1 = kvm_vm_check_extension(s, KVM_CAP_PPC_DAWR1); /* * Note: setting it to false because there is not such capability * in KVM at this moment. @@ -2114,6 +2116,16 @@ int kvmppc_set_fwnmi(PowerPCCPU *cpu) return kvm_vcpu_enable_cap(cs, KVM_CAP_PPC_FWNMI, 0); } +bool kvmppc_has_cap_dawr1(void) +{ + return !!cap_dawr1; +} + +int kvmppc_set_cap_dawr1(int enable) +{ + return kvm_vm_enable_cap(kvm_state, KVM_CAP_PPC_DAWR1, 0, enable); +} + int kvmppc_smt_threads(void) { return cap_ppc_smt ? cap_ppc_smt : 1; diff --git a/target/ppc/kvm_ppc.h b/target/ppc/kvm_ppc.h index 1d8cb76a6b..a8768c1dfd 100644 --- a/target/ppc/kvm_ppc.h +++ b/target/ppc/kvm_ppc.h @@ -68,6 +68,8 @@ bool kvmppc_has_cap_htm(void); bool kvmppc_has_cap_mmu_radix(void); bool kvmppc_has_cap_mmu_hash_v3(void); bool kvmppc_has_cap_xive(void); +bool kvmppc_has_cap_dawr1(void); +int kvmppc_set_cap_dawr1(int enable); int kvmppc_get_cap_safe_cache(void); int kvmppc_get_cap_safe_bounds_check(void); int kvmppc_get_cap_safe_indirect_branch(void); @@ -377,6 +379,16 @@ static inline bool kvmppc_has_cap_xive(void) return false; } +static inline bool kvmppc_has_cap_dawr1(void) +{ + return false; +} + +static inline int kvmppc_set_cap_dawr1(int enable) +{ + abort(); +} + static inline int kvmppc_get_cap_safe_cache(void) { return 0; From patchwork Tue Mar 11 12:57:56 2025 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Nicholas Piggin X-Patchwork-Id: 14011841 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.lore.kernel.org (Postfix) with ESMTPS id 81B13C28B2E for ; Tue, 11 Mar 2025 13:13:57 +0000 (UTC) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1trzL6-0002qd-Dk; Tue, 11 Mar 2025 09:08:09 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1trzEu-0005sq-Gv; Tue, 11 Mar 2025 09:01:45 -0400 Received: from mail-pj1-x1031.google.com ([2607:f8b0:4864:20::1031]) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_128_GCM_SHA256:128) (Exim 4.90_1) (envelope-from ) id 1trzEp-0000Jv-Bk; Tue, 11 Mar 2025 09:01:44 -0400 Received: by mail-pj1-x1031.google.com with SMTP id 98e67ed59e1d1-2feae794508so8087231a91.0; Tue, 11 Mar 2025 06:01:38 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20230601; t=1741698097; x=1742302897; darn=nongnu.org; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to; bh=MvevJgZuo4bkG1Sd+5i0dJdPdtOcYaorR/nWe5rVjjE=; b=McXVTU7qOv4feBARpMHt7pyMy1FlVVrBkcA335/q+2nw36DmAKrv4gWz5mHTHWTBsu NruP6/cxhgCGmEmcBllkfRzgguz33bS24hvLXqu6e3vIWXx36iJD8zWMHVtUK3IgNqcs +zFqweuujZw+uv5vU/80w/zJ/OWWwCUYJaO0uSz4+Gx5AdtoeRcM0jqqCcbaI440YfpN oLJQK5gV7Zn5iEU67DjLM+G11POv6+b+ScARDgqfud2jjZh0z12KhNqnIyB6a2QpXGjT sc3Ag32a4DAZZdcQnypDQ5mTOxlFLK1fIA5rH5HJDCe7N1zpfZIUtigPCDwWXEjwFuoT r0dQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1741698097; x=1742302897; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=MvevJgZuo4bkG1Sd+5i0dJdPdtOcYaorR/nWe5rVjjE=; b=MJjDgYHRoiwPpH0DMH+oFmu6gfZ9VtIqaTeygxQQ+z62KWNTL/ahBGvOzqCTQsed5M dQiEcpUQSeRHTsv9iM3VfUr6Qt9t4RafqfoFtQUIxNGJoSCXFMQrElib1MYBtay/XSzx rgPwW1pkqpcYlgk2WW/t5hjf/wMdAYnBVcDayINybwM6TD6yYtJLnuXYmOjCgmb0tAYH Ol3KyxQlgUk+fDX2WLZWP1TD56CvBdwVpUrX+Clzh2nc7LjQDzV/t8xpo/bxecCmBUS7 KXdhXTFSqPnGRNYn/wjhVMdj8z/cwmvUYwHXRNVtwwKtmJ4CDEMH8hcd0RG5Wkl07TW2 TCug== X-Forwarded-Encrypted: i=1; AJvYcCVTEuplVE/+8vumGzWn4Lbq8zKtNRFjzObX2K3hu0R3RjnYYEyNpcbI+NvjFCwAE6k96zzmPBpt2A==@nongnu.org X-Gm-Message-State: AOJu0YxjNkkxwLVLb6YVfobzoSqBWP+PpR1Sts+4oG+Y2GSfSQyhacj7 WcRsOFC01/VOBS3t5EQiiuZDv5nLN7PDnK3Hd4pb9hIDPLiKYedI0zc8gQ== X-Gm-Gg: ASbGncsiKZP1yFRW+1K13cXRcDTxDBPzir5PwT9c21JwdOIkiOufPZct7YMYYDnYhfk mQ/6i0hyoomRt4vicAnqC92gvpC+5RujnWnu9JANB4E21W1tqYw0ON1vJawQn8Apki+rNTDHWe/ Z5H1uE8L8LBBsvM92dJgBbmc1mFIEKSYjG1YzOD6PHnuykXZ2SD1AhPCpLI2wnHkefvCej962lx gz9QrYlmrWhpjvYvNl4+/LMEI8zck+kaVavFZzl+b91L5zglxev6x+vtP9XJ1QmaqdHAPd5MO8g xqeM0fwhReFqlAYRtABM2OZephDJ738rSClG29XCfzW9BkOd30E= X-Google-Smtp-Source: AGHT+IHGaq0nnS5TDBnbJU9Jr5a7d+IsbyF4+HVbzZAWZR8sNw+QHvH1/Pr5wdo/VLI5qABjqLzgdQ== X-Received: by 2002:a17:90a:e7c2:b0:2ff:693a:758d with SMTP id 98e67ed59e1d1-2ff7ceef0famr25706466a91.27.1741698097019; Tue, 11 Mar 2025 06:01:37 -0700 (PDT) Received: from wheely.local0.net ([118.208.151.101]) by smtp.gmail.com with ESMTPSA id 98e67ed59e1d1-2ff4e773dddsm11822318a91.12.2025.03.11.06.01.34 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 11 Mar 2025 06:01:36 -0700 (PDT) From: Nicholas Piggin To: qemu-devel@nongnu.org Cc: Nicholas Piggin , qemu-ppc@nongnu.org, Vaibhav Jain , Harsh Prateek Bora Subject: [PULL 62/72] spapr: nested: Add support for reporting Hostwide state counter Date: Tue, 11 Mar 2025 22:57:56 +1000 Message-ID: <20250311125815.903177-63-npiggin@gmail.com> X-Mailer: git-send-email 2.47.1 In-Reply-To: <20250311125815.903177-1-npiggin@gmail.com> References: <20250311125815.903177-1-npiggin@gmail.com> MIME-Version: 1.0 Received-SPF: pass client-ip=2607:f8b0:4864:20::1031; envelope-from=npiggin@gmail.com; helo=mail-pj1-x1031.google.com X-Spam_score_int: -20 X-Spam_score: -2.1 X-Spam_bar: -- X-Spam_report: (-2.1 / 5.0 requ) BAYES_00=-1.9, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_AU=-0.1, DKIM_VALID_EF=-0.1, FREEMAIL_FROM=0.001, RCVD_IN_DNSWL_NONE=-0.0001, SPF_HELO_NONE=0.001, SPF_PASS=-0.001 autolearn=ham autolearn_force=no X-Spam_action: no action X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: qemu-devel-bounces+qemu-devel=archiver.kernel.org@nongnu.org Sender: qemu-devel-bounces+qemu-devel=archiver.kernel.org@nongnu.org From: Vaibhav Jain Add support for reporting Hostwide state counters for nested KVM pseries guests running with 'cap-nested-papr' on Qemu-TCG acting as L0-hypervisor. The Hostwide state counters are statistics about state that L0-hypervisor maintains for the L2-guests and represent the state of all L2-guests, not just a specific one. These stats counters are exposed to L1-Hypervisor by the L0-Hypervisor via a new bit-flag named 'getHostWideState' for the H_GUEST_GET_STATE hcall which is documented at [1]. Once this flag is set the hcall should populate the Guest-State-Elements in the requested GSB with the stat counter values. Currently following five counters are supported: * l0_guest_heap_size_inuse * l0_guest_heap_size_max * l0_guest_pagetable_size_inuse * l0_guest_pagetable_size_max * l0_guest_pagetable_reclaimed At the moment '0' is being reported for all these counters as these counters doesn't align with how L0-Qemu manages Guest memory. The patch implements support for these counters by adding new members to the 'struct SpaprMachineStateNested'. These new members are then plugged into the existing 'guest_state_element_types[]' with the help of a new macro 'GSBE_NESTED_MACHINE_DW' together with a new helper 'get_machine_ptr()'. guest_state_request_check() is updated to ensure correctness of the requested GSB and finally h_guest_getset_state() is updated to handle the newly introduced flag 'GUEST_STATE_REQUEST_HOST_WIDE'. This patch is tested with the proposed linux-kernel implementation to expose these stat-counter as perf-events at [2]. [1] https://lore.kernel.org/all/20241222140247.174998-2-vaibhav@linux.ibm.com [2] https://lore.kernel.org/all/20241222140247.174998-1-vaibhav@linux.ibm.com Signed-off-by: Vaibhav Jain Reviewed-by: Harsh Prateek Bora Message-ID: <20250221155449.530645-1-vaibhav@linux.ibm.com> Signed-off-by: Nicholas Piggin --- hw/ppc/spapr_nested.c | 119 ++++++++++++++++++++++++---------- include/hw/ppc/spapr_nested.h | 67 +++++++++++++++++-- 2 files changed, 147 insertions(+), 39 deletions(-) diff --git a/hw/ppc/spapr_nested.c b/hw/ppc/spapr_nested.c index 23958c6383..201f629203 100644 --- a/hw/ppc/spapr_nested.c +++ b/hw/ppc/spapr_nested.c @@ -65,10 +65,9 @@ static SpaprMachineStateNestedGuest *spapr_get_nested_guest(SpaprMachineState *spapr, target_ulong guestid) { - SpaprMachineStateNestedGuest *guest; - - guest = g_hash_table_lookup(spapr->nested.guests, GINT_TO_POINTER(guestid)); - return guest; + return spapr->nested.guests ? + g_hash_table_lookup(spapr->nested.guests, + GINT_TO_POINTER(guestid)) : NULL; } bool spapr_get_pate_nested_papr(SpaprMachineState *spapr, PowerPCCPU *cpu, @@ -594,26 +593,37 @@ static bool spapr_nested_vcpu_check(SpaprMachineStateNestedGuest *guest, return false; } -static void *get_vcpu_state_ptr(SpaprMachineStateNestedGuest *guest, - target_ulong vcpuid) +static void *get_vcpu_state_ptr(SpaprMachineState *spapr, + SpaprMachineStateNestedGuest *guest, + target_ulong vcpuid) { assert(spapr_nested_vcpu_check(guest, vcpuid, false)); return &guest->vcpus[vcpuid].state; } -static void *get_vcpu_ptr(SpaprMachineStateNestedGuest *guest, - target_ulong vcpuid) +static void *get_vcpu_ptr(SpaprMachineState *spapr, + SpaprMachineStateNestedGuest *guest, + target_ulong vcpuid) { assert(spapr_nested_vcpu_check(guest, vcpuid, false)); return &guest->vcpus[vcpuid]; } -static void *get_guest_ptr(SpaprMachineStateNestedGuest *guest, +static void *get_guest_ptr(SpaprMachineState *spapr, + SpaprMachineStateNestedGuest *guest, target_ulong vcpuid) { return guest; /* for GSBE_NESTED */ } +static void *get_machine_ptr(SpaprMachineState *spapr, + SpaprMachineStateNestedGuest *guest, + target_ulong vcpuid) +{ + /* ignore guest and vcpuid for this */ + return &spapr->nested; +} + /* * set=1 means the L1 is trying to set some state * set=0 means the L1 is trying to get some state @@ -1013,7 +1023,15 @@ struct guest_state_element_type guest_state_element_types[] = { GSBE_NESTED_VCPU(GSB_VCPU_OUT_BUFFER, 0x10, runbufout, copy_state_runbuf), GSBE_NESTED_VCPU(GSB_VCPU_OUT_BUF_MIN_SZ, 0x8, runbufout, out_buf_min_size), GSBE_NESTED_VCPU(GSB_VCPU_HDEC_EXPIRY_TB, 0x8, hdecr_expiry_tb, - copy_state_hdecr) + copy_state_hdecr), + GSBE_NESTED_MACHINE_DW(GSB_L0_GUEST_HEAP_INUSE, l0_guest_heap_inuse), + GSBE_NESTED_MACHINE_DW(GSB_L0_GUEST_HEAP_MAX, l0_guest_heap_max), + GSBE_NESTED_MACHINE_DW(GSB_L0_GUEST_PGTABLE_SIZE_INUSE, + l0_guest_pgtable_size_inuse), + GSBE_NESTED_MACHINE_DW(GSB_L0_GUEST_PGTABLE_SIZE_MAX, + l0_guest_pgtable_size_max), + GSBE_NESTED_MACHINE_DW(GSB_L0_GUEST_PGTABLE_RECLAIMED, + l0_guest_pgtable_reclaimed), }; void spapr_nested_gsb_init(void) @@ -1031,8 +1049,13 @@ void spapr_nested_gsb_init(void) else if (type->id >= GSB_VCPU_IN_BUFFER) /* 0x0c00 - 0xf000 Thread + RW */ type->flags = 0; + else if (type->id >= GSB_L0_GUEST_HEAP_INUSE) + + /*0x0800 - 0x0804 Hostwide Counters + RO */ + type->flags = GUEST_STATE_ELEMENT_TYPE_FLAG_HOST_WIDE | + GUEST_STATE_ELEMENT_TYPE_FLAG_READ_ONLY; else if (type->id >= GSB_VCPU_LPVR) - /* 0x0003 - 0x0bff Guest + RW */ + /* 0x0003 - 0x07ff Guest + RW */ type->flags = GUEST_STATE_ELEMENT_TYPE_FLAG_GUEST_WIDE; else if (type->id >= GSB_HV_VCPU_STATE_SIZE) /* 0x0001 - 0x0002 Guest + RO */ @@ -1139,18 +1162,26 @@ static bool guest_state_request_check(struct guest_state_request *gsr) return false; } - if (type->flags & GUEST_STATE_ELEMENT_TYPE_FLAG_GUEST_WIDE) { + if (type->flags & GUEST_STATE_ELEMENT_TYPE_FLAG_HOST_WIDE) { + /* Hostwide elements cant be clubbed with other types */ + if (!(gsr->flags & GUEST_STATE_REQUEST_HOST_WIDE)) { + qemu_log_mask(LOG_GUEST_ERROR, "trying to get/set a host wide " + "Element ID:%04x.\n", id); + return false; + } + } else if (type->flags & GUEST_STATE_ELEMENT_TYPE_FLAG_GUEST_WIDE) { /* guest wide element type */ if (!(gsr->flags & GUEST_STATE_REQUEST_GUEST_WIDE)) { - qemu_log_mask(LOG_GUEST_ERROR, "trying to set a guest wide " + qemu_log_mask(LOG_GUEST_ERROR, "trying to get/set a guest wide " "Element ID:%04x.\n", id); return false; } } else { /* thread wide element type */ - if (gsr->flags & GUEST_STATE_REQUEST_GUEST_WIDE) { - qemu_log_mask(LOG_GUEST_ERROR, "trying to set a thread wide " - "Element ID:%04x.\n", id); + if (gsr->flags & (GUEST_STATE_REQUEST_GUEST_WIDE | + GUEST_STATE_REQUEST_HOST_WIDE)) { + qemu_log_mask(LOG_GUEST_ERROR, "trying to get/set a thread wide" + " Element ID:%04x.\n", id); return false; } } @@ -1419,7 +1450,8 @@ static target_ulong h_guest_create_vcpu(PowerPCCPU *cpu, return H_SUCCESS; } -static target_ulong getset_state(SpaprMachineStateNestedGuest *guest, +static target_ulong getset_state(SpaprMachineState *spapr, + SpaprMachineStateNestedGuest *guest, uint64_t vcpuid, struct guest_state_request *gsr) { @@ -1452,7 +1484,7 @@ static target_ulong getset_state(SpaprMachineStateNestedGuest *guest, /* Get pointer to guest data to get/set */ if (type->location && type->copy) { - ptr = type->location(guest, vcpuid); + ptr = type->location(spapr, guest, vcpuid); assert(ptr); if (!~(type->mask) && is_gsr_invalid(gsr, element, type)) { return H_INVALID_ELEMENT_VALUE; @@ -1469,6 +1501,7 @@ next_element: } static target_ulong map_and_getset_state(PowerPCCPU *cpu, + SpaprMachineState *spapr, SpaprMachineStateNestedGuest *guest, uint64_t vcpuid, struct guest_state_request *gsr) @@ -1492,7 +1525,7 @@ static target_ulong map_and_getset_state(PowerPCCPU *cpu, goto out1; } - rc = getset_state(guest, vcpuid, gsr); + rc = getset_state(spapr, guest, vcpuid, gsr); out1: address_space_unmap(CPU(cpu)->as, gsr->gsb, len, is_write, len); @@ -1510,27 +1543,46 @@ static target_ulong h_guest_getset_state(PowerPCCPU *cpu, target_ulong buf = args[3]; target_ulong buflen = args[4]; struct guest_state_request gsr; - SpaprMachineStateNestedGuest *guest; + SpaprMachineStateNestedGuest *guest = NULL; - guest = spapr_get_nested_guest(spapr, lpid); - if (!guest) { - return H_P2; - } gsr.buf = buf; assert(buflen <= GSB_MAX_BUF_SIZE); gsr.len = buflen; gsr.flags = 0; - if (flags & H_GUEST_GETSET_STATE_FLAG_GUEST_WIDE) { + + /* Works for both get/set state */ + if ((flags & H_GUEST_GET_STATE_FLAGS_GUEST_WIDE) || + (flags & H_GUEST_SET_STATE_FLAGS_GUEST_WIDE)) { gsr.flags |= GUEST_STATE_REQUEST_GUEST_WIDE; } - if (flags & ~H_GUEST_GETSET_STATE_FLAG_GUEST_WIDE) { - return H_PARAMETER; /* flag not supported yet */ - } if (set) { + if (flags & ~H_GUEST_SET_STATE_FLAGS_MASK) { + return H_PARAMETER; + } gsr.flags |= GUEST_STATE_REQUEST_SET; + } else { + /* + * No reserved fields to be set in flags nor both + * GUEST/HOST wide bits + */ + if ((flags & ~H_GUEST_GET_STATE_FLAGS_MASK) || + (flags == H_GUEST_GET_STATE_FLAGS_MASK)) { + return H_PARAMETER; + } + + if (flags & H_GUEST_GET_STATE_FLAGS_HOST_WIDE) { + gsr.flags |= GUEST_STATE_REQUEST_HOST_WIDE; + } + } + + if (!(gsr.flags & GUEST_STATE_REQUEST_HOST_WIDE)) { + guest = spapr_get_nested_guest(spapr, lpid); + if (!guest) { + return H_P2; + } } - return map_and_getset_state(cpu, guest, vcpuid, &gsr); + return map_and_getset_state(cpu, spapr, guest, vcpuid, &gsr); } static target_ulong h_guest_set_state(PowerPCCPU *cpu, @@ -1641,7 +1693,8 @@ static int get_exit_ids(uint64_t srr0, uint16_t ids[16]) return nr; } -static void exit_process_output_buffer(PowerPCCPU *cpu, +static void exit_process_output_buffer(SpaprMachineState *spapr, + PowerPCCPU *cpu, SpaprMachineStateNestedGuest *guest, target_ulong vcpuid, target_ulong *r3) @@ -1679,7 +1732,7 @@ static void exit_process_output_buffer(PowerPCCPU *cpu, gsr.gsb = gsb; gsr.len = VCPU_OUT_BUF_MIN_SZ; gsr.flags = 0; /* get + never guest wide */ - getset_state(guest, vcpuid, &gsr); + getset_state(spapr, guest, vcpuid, &gsr); address_space_unmap(CPU(cpu)->as, gsb, len, true, len); return; @@ -1705,7 +1758,7 @@ void spapr_exit_nested_papr(SpaprMachineState *spapr, PowerPCCPU *cpu, int excp) exit_nested_store_l2(cpu, excp, vcpu); /* do the output buffer for run_vcpu*/ - exit_process_output_buffer(cpu, guest, vcpuid, &r3_return); + exit_process_output_buffer(spapr, cpu, guest, vcpuid, &r3_return); assert(env->spr[SPR_LPIDR] != 0); nested_load_state(cpu, spapr_cpu->nested_host_state); @@ -1820,7 +1873,7 @@ static target_ulong h_guest_run_vcpu(PowerPCCPU *cpu, gsr.buf = vcpu->runbufin.addr; gsr.len = vcpu->runbufin.size; gsr.flags = GUEST_STATE_REQUEST_SET; /* Thread wide + writing */ - rc = map_and_getset_state(cpu, guest, vcpuid, &gsr); + rc = map_and_getset_state(cpu, spapr, guest, vcpuid, &gsr); if (rc == H_SUCCESS) { nested_papr_run_vcpu(cpu, lpid, vcpu); } else { diff --git a/include/hw/ppc/spapr_nested.h b/include/hw/ppc/spapr_nested.h index e420220484..f7be0d5a95 100644 --- a/include/hw/ppc/spapr_nested.h +++ b/include/hw/ppc/spapr_nested.h @@ -11,7 +11,13 @@ #define GSB_TB_OFFSET 0x0004 /* Timebase Offset */ #define GSB_PART_SCOPED_PAGETBL 0x0005 /* Partition Scoped Page Table */ #define GSB_PROCESS_TBL 0x0006 /* Process Table */ - /* RESERVED 0x0007 - 0x0BFF */ + /* RESERVED 0x0007 - 0x07FF */ +#define GSB_L0_GUEST_HEAP_INUSE 0x0800 /* Guest Management Heap Size */ +#define GSB_L0_GUEST_HEAP_MAX 0x0801 /* Guest Management Heap Max Size */ +#define GSB_L0_GUEST_PGTABLE_SIZE_INUSE 0x0802 /* Guest Pagetable Size */ +#define GSB_L0_GUEST_PGTABLE_SIZE_MAX 0x0803 /* Guest Pagetable Max Size */ +#define GSB_L0_GUEST_PGTABLE_RECLAIMED 0x0804 /* Pagetable Reclaim in bytes */ + /* RESERVED 0x0805 - 0xBFF */ #define GSB_VCPU_IN_BUFFER 0x0C00 /* Run VCPU Input Buffer */ #define GSB_VCPU_OUT_BUFFER 0x0C01 /* Run VCPU Out Buffer */ #define GSB_VCPU_VPA 0x0C02 /* HRA to Guest VCPU VPA */ @@ -196,6 +202,38 @@ typedef struct SpaprMachineStateNested { #define NESTED_API_PAPR 2 bool capabilities_set; uint32_t pvr_base; + + /** + * l0_guest_heap_inuse: The currently used bytes in the Hypervisor's Guest + * Management Space associated with the Host Partition. + **/ + uint64_t l0_guest_heap_inuse; + + /** + * host_heap_max: The maximum bytes available in the Hypervisor's Guest + * Management Space associated with the Host Partition. + **/ + uint64_t l0_guest_heap_max; + + /** + * host_pagetable: The currently used bytes in the Hypervisor's Guest + * Page Table Management Space associated with the Host Partition. + **/ + uint64_t l0_guest_pgtable_size_inuse; + + /** + * host_pagetable_max: The maximum bytes available in the Hypervisor's Guest + * Page Table Management Space associated with the Host Partition. + **/ + uint64_t l0_guest_pgtable_size_max; + + /** + * host_pagetable_reclaim: The amount of space in bytes that has been + * reclaimed due to overcommit in the Hypervisor's Guest Page Table + * Management Space associated with the Host Partition. + **/ + uint64_t l0_guest_pgtable_reclaimed; + GHashTable *guests; } SpaprMachineStateNested; @@ -229,9 +267,15 @@ typedef struct SpaprMachineStateNestedGuest { #define HVMASK_HDEXCR 0x00000000FFFFFFFF #define HVMASK_TB_OFFSET 0x000000FFFFFFFFFF #define GSB_MAX_BUF_SIZE (1024 * 1024) -#define H_GUEST_GETSET_STATE_FLAG_GUEST_WIDE 0x8000000000000000 -#define GUEST_STATE_REQUEST_GUEST_WIDE 0x1 -#define GUEST_STATE_REQUEST_SET 0x2 +#define H_GUEST_GET_STATE_FLAGS_MASK 0xC000000000000000ULL +#define H_GUEST_SET_STATE_FLAGS_MASK 0x8000000000000000ULL +#define H_GUEST_SET_STATE_FLAGS_GUEST_WIDE 0x8000000000000000ULL +#define H_GUEST_GET_STATE_FLAGS_GUEST_WIDE 0x8000000000000000ULL +#define H_GUEST_GET_STATE_FLAGS_HOST_WIDE 0x4000000000000000ULL + +#define GUEST_STATE_REQUEST_GUEST_WIDE 0x1 +#define GUEST_STATE_REQUEST_HOST_WIDE 0x2 +#define GUEST_STATE_REQUEST_SET 0x4 /* * As per ISA v3.1B, following bits are reserved: @@ -251,6 +295,15 @@ typedef struct SpaprMachineStateNestedGuest { .copy = (c) \ } +#define GSBE_NESTED_MACHINE_DW(i, f) { \ + .id = (i), \ + .size = 8, \ + .location = get_machine_ptr, \ + .offset = offsetof(struct SpaprMachineStateNested, f), \ + .copy = copy_state_8to8, \ + .mask = HVMASK_DEFAULT \ +} + #define GSBE_NESTED(i, sz, f, c) { \ .id = (i), \ .size = (sz), \ @@ -509,9 +562,11 @@ struct guest_state_element_type { uint16_t id; int size; #define GUEST_STATE_ELEMENT_TYPE_FLAG_GUEST_WIDE 0x1 -#define GUEST_STATE_ELEMENT_TYPE_FLAG_READ_ONLY 0x2 +#define GUEST_STATE_ELEMENT_TYPE_FLAG_HOST_WIDE 0x2 +#define GUEST_STATE_ELEMENT_TYPE_FLAG_READ_ONLY 0x4 uint16_t flags; - void *(*location)(SpaprMachineStateNestedGuest *, target_ulong); + void *(*location)(struct SpaprMachineState *, SpaprMachineStateNestedGuest *, + target_ulong); size_t offset; void (*copy)(void *, void *, bool); uint64_t mask; From patchwork Tue Mar 11 12:57:57 2025 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Nicholas Piggin X-Patchwork-Id: 14011897 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.lore.kernel.org (Postfix) with ESMTPS id CC5E7C282EC for ; Tue, 11 Mar 2025 13:26:35 +0000 (UTC) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1trzJm-0005nP-8S; Tue, 11 Mar 2025 09:06:48 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1trzEv-0005tv-4P; Tue, 11 Mar 2025 09:01:46 -0400 Received: from mail-pj1-x1035.google.com ([2607:f8b0:4864:20::1035]) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_128_GCM_SHA256:128) (Exim 4.90_1) (envelope-from ) id 1trzEs-0000KV-H5; Tue, 11 Mar 2025 09:01:44 -0400 Received: by mail-pj1-x1035.google.com with SMTP id 98e67ed59e1d1-2f42992f608so9032932a91.0; Tue, 11 Mar 2025 06:01:40 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20230601; t=1741698099; x=1742302899; darn=nongnu.org; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to; bh=JY67tjfgQ34CRjW0ZGaljhvuHtNs5IgoqrFyn/RHWZc=; b=AWL+hf0yRuk1bQE/e1HZgJuK21sORynea7DAsLFvOxMum93xxWSccoFQcorcxSHAUy 92Rm2BFG+3UBnLIsHWa9S09HPS/4mU1YQE1DqcV9+BhWk25UQOu3rAl5Kkrmldvwx3bL p+rRZmrhCXN/yGiggW2yZKsoyiQzse3Cvytx6a/nFJp9TWNatWTPOxbfV/WvKuucwTcf //oquu5VKTVRDt4yQkhuln5EInEruxefGaAog8wQeIrQG0pACXI6gBdEwGRmgmHLyLlw rA8MwWJI5ToXus6y9sb+dfz3n/y3yt8TrTpnFKb+qwrtXwF4CHpcIjBQDoUhqRrHoyUl MBzg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1741698099; x=1742302899; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=JY67tjfgQ34CRjW0ZGaljhvuHtNs5IgoqrFyn/RHWZc=; b=Hqx273MCUVVNLkd0cVw8Ec088Md4Lh+Xy1ecXAu+IMzI+C1XbyLTjHr1pAFHHSxxDm IY13Gou7ByLdNJ4Q0JnZTOQ3N52WCV0elYtucc10lresX/r7Fm35zNEn/hrj0pTALkko pkj/Je0XhpRZDdUPl/zom5ftWTyrGr7e/IZ5S+UAAwUQ+4qwFF3bJTsFy8bgW2pL+LbX DR6uzU9pHEGi2zCmVNZyLKTxv/KJqQW8Ytc2Gco1swLFPKGZUMVEFEu/zidrUOwYtwsE kQmbh4uT0I8K5qwjgrnm0/v33XvAjQpIjME0676nzGi5PWv5eYIZBa+YmjQGw6vnJqlN Z+JQ== X-Forwarded-Encrypted: i=1; AJvYcCXyizlIIbA07NwE9lRmQxGdTtbCKe4fdDkiuuEGZJlPlKKHa+9OjqF9kwhp9KZYtoDkjxytK0oIpA==@nongnu.org X-Gm-Message-State: AOJu0Yyv7Zmic4VTYM8rnn2T7JAaa+SkMPd71UHKLERT3MnuU29ikjtQ 6oJ8jDN/DB2ICO8e19p9Y4ybHMCsiripcUqmBp36uOiGVmNm7n3giOeuHw== X-Gm-Gg: ASbGncskEJYZwShg+Huym507yXEWfzug9AiEyW2kurBJkD1UFDpXQzUJfqg0i9JexbE nMV99DuT9keTelgHBrriDHybhPfZ0Ab7Ww1DaR1iYDcbcFMthvwyLJ/447WnoMhUttML0VK+3An BeAeyuC9mPbxirYTPekM90+TEROGPHWM4Z5EHDmCGWBEg6DA9hu9D9YkqW7x6qDJluWMrVJ1yZw +QzR+FygQW40IaH4tUBWjxy2izWUGTxRKTWurRUKAdT2ljipnqg/rFEKPydN4t93Eear0NGzd5K HWsg3I1MXAiAFn15AU+iWyvQPFOl792ny/waocEsqYykOWSJwyX6Qh7JvmnPyQ== X-Google-Smtp-Source: AGHT+IHfbWkjiyhk8kgV3NYQHOuEDsaSJvC+Ced3BjtR/V255+jwgWGx78b0P9eE9vFtHLdputyg9g== X-Received: by 2002:a17:90b:1a86:b0:2ee:9b09:7d3d with SMTP id 98e67ed59e1d1-2ff7ce8b60amr24976057a91.19.1741698099460; Tue, 11 Mar 2025 06:01:39 -0700 (PDT) Received: from wheely.local0.net ([118.208.151.101]) by smtp.gmail.com with ESMTPSA id 98e67ed59e1d1-2ff4e773dddsm11822318a91.12.2025.03.11.06.01.37 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 11 Mar 2025 06:01:39 -0700 (PDT) From: Nicholas Piggin To: qemu-devel@nongnu.org Cc: Nicholas Piggin , qemu-ppc@nongnu.org Subject: [PULL 63/72] target/ppc: fix timebase register reset state Date: Tue, 11 Mar 2025 22:57:57 +1000 Message-ID: <20250311125815.903177-64-npiggin@gmail.com> X-Mailer: git-send-email 2.47.1 In-Reply-To: <20250311125815.903177-1-npiggin@gmail.com> References: <20250311125815.903177-1-npiggin@gmail.com> MIME-Version: 1.0 Received-SPF: pass client-ip=2607:f8b0:4864:20::1035; envelope-from=npiggin@gmail.com; helo=mail-pj1-x1035.google.com X-Spam_score_int: -20 X-Spam_score: -2.1 X-Spam_bar: -- X-Spam_report: (-2.1 / 5.0 requ) BAYES_00=-1.9, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_AU=-0.1, DKIM_VALID_EF=-0.1, FREEMAIL_FROM=0.001, RCVD_IN_DNSWL_NONE=-0.0001, SPF_HELO_NONE=0.001, SPF_PASS=-0.001 autolearn=ham autolearn_force=no X-Spam_action: no action X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: qemu-devel-bounces+qemu-devel=archiver.kernel.org@nongnu.org Sender: qemu-devel-bounces+qemu-devel=archiver.kernel.org@nongnu.org (H)DEC and PURR get reset before icount does, which causes them to be skewed and not match the init state. This can cause replay to not match the recorded trace exactly. For DEC and HDEC this is usually not noticable since they tend to get programmed before affecting the target machine. PURR has been observed to cause replay bugs when running Linux. Fix this by resetting using a time of 0. Message-ID: <20241219034035.1826173-2-npiggin@gmail.com> Signed-off-by: Nicholas Piggin --- hw/ppc/ppc.c | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/hw/ppc/ppc.c b/hw/ppc/ppc.c index 90e3db5cfe..3a80931538 100644 --- a/hw/ppc/ppc.c +++ b/hw/ppc/ppc.c @@ -1123,16 +1123,21 @@ void cpu_ppc_tb_reset(CPUPPCState *env) timer_del(tb_env->hdecr_timer); ppc_set_irq(cpu, PPC_INTERRUPT_HDECR, 0); tb_env->hdecr_next = 0; + _cpu_ppc_store_hdecr(cpu, 0, 0, 0, 64); } /* * There is a bug in Linux 2.4 kernels: * if a decrementer exception is pending when it enables msr_ee at startup, * it's not ready to handle it... + * + * On machine reset, this is called before icount is reset, so for + * icount-mode, setting TB registers using now == qemu_clock_get_ns() + * results in them being garbage after icount is reset. Use an + * explicit now == 0 to get a consistent reset state. */ - cpu_ppc_store_decr(env, -1); - cpu_ppc_store_hdecr(env, -1); - cpu_ppc_store_purr(env, 0x0000000000000000ULL); + _cpu_ppc_store_decr(cpu, 0, 0, -1, 64); + _cpu_ppc_store_purr(env, 0, 0); } void cpu_ppc_tb_free(CPUPPCState *env) From patchwork Tue Mar 11 12:57:58 2025 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Nicholas Piggin X-Patchwork-Id: 14011838 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.lore.kernel.org (Postfix) with ESMTPS id 67F2BC28B30 for ; Tue, 11 Mar 2025 13:13:07 +0000 (UTC) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1trzJz-00068y-DA; Tue, 11 Mar 2025 09:06:59 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1trzEv-0005v6-TO; Tue, 11 Mar 2025 09:01:47 -0400 Received: from mail-pj1-x1031.google.com ([2607:f8b0:4864:20::1031]) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_128_GCM_SHA256:128) (Exim 4.90_1) (envelope-from ) id 1trzEu-0000L5-63; Tue, 11 Mar 2025 09:01:45 -0400 Received: by mail-pj1-x1031.google.com with SMTP id 98e67ed59e1d1-2fe9759e5c1so8054887a91.0; Tue, 11 Mar 2025 06:01:43 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20230601; t=1741698102; x=1742302902; darn=nongnu.org; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to; bh=lV0y6ykMDBCM1ul3LncOR8t4MUHPncGhWb9AC9RcVko=; b=fnNjkko7V8djKvJXXLgjgrRE8/pdBbT4eDrQiXd9CbCsnT7FPhlllRMXIFPcNaR1/P 6XteelwdKMTdsKtePyJqH0R6jZabemK5KAzTTI8wIitERtU6J0RmHKc3qH9tPHdDqYIs LiXhIXE2CxJpuK4NeyJiIkwyS3DoigOvxaYQvGTvLnpNkoD5CyeT4OMWOaVQDFlSHchZ FEnBWWMNyG+jvoLVLsZqGtMDN5vYcOSDUqzgkEVhZiYetuQa6+Opp7OQsR/OeR211sGw u2EKNyd+48wNDl3s7wPLOX/qZnxRFQPqb4B+fpDKggeeMh6HP1yVdFqI29fyqUgQmney XLGA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1741698102; x=1742302902; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=lV0y6ykMDBCM1ul3LncOR8t4MUHPncGhWb9AC9RcVko=; b=HWVEEfBQ7Et+vMDTIpnGiXCa7O2fdgFxxZM17BTreuZHHqntYaozYPvfXzowTkhzff 6FZ/EMJ8Kn82SL44Z2sx5XfTxMYRt4NOFl+EnYaMiBBMddD6IU7mI2kjAx9HT/8Y8p9c IDXD/3jJSaop6zNQmKR/xNwougdnF/FSnjaOKUWY9Ka24cIwZnSgtyVGfb1hlkiWJzpy V9LhsJccW1avsD2ijz9gpKYkTy+N9jFh4HWGEGtDWE0e58WKJLa4cX3Y1aBM0OXWDV7R SoDUh+b/QJimPesPp0jtE/gppU52TdD/8m7a3zaJNRLgfEtfDqn95mCvXhQMK3btufDj 6MIQ== X-Forwarded-Encrypted: i=1; AJvYcCVIqn30pXoGwyVeLCP+XR4HOJyez/Rc8HKAikdNlHw271xvXc5z1m8cNj/VUHLvI5vVhJb5jmoJxA==@nongnu.org X-Gm-Message-State: AOJu0YxkrRz1oY1HBTC3ZJkEqpqhfYrUpW+91xBmLkIfirHFqbL+NR/O methTdK/I62N0OoXXs0XZJ8T0dKCyfiHVED+2oJ5q5tSKasdX5tqB2lxhQ== X-Gm-Gg: ASbGncskZbdojavG7J0FzybO8svhaWXFx5vXD9hSgbboV7Eo86g1imE+KcmbO2r/z7u Afod9WPTZtqnsUstRIZjYs0i/2S6UuDkrWJGS7K937NrwdhI53LGKGvf+QtshdOEEDuX427t2js nOCym8r9HBdbVvdmBFANVFlMMqUBIzTmcAC+7cM2bqp9a9AKYZC3XGr+bTsvKCqTeEU8oDS0PW1 umwoA1fSXS29mIU+p6RHKyI6aUGn73NQW8WJEhOyTVCw4RRWc86dONtUjM0+PCvWWixTiIcAej2 1+vQAN0CnxO1zxOGYVlgZHFbmWZ+slvdvyxrhvLDEyWcDFDxKXY= X-Google-Smtp-Source: AGHT+IFdo6Q7W2VRMrdNXkKgtKJ7N7iDZIPAYVg198lj4C5MNEmZNVQa3zcn4h4O/NeQxEU1I74E4w== X-Received: by 2002:a17:90a:d00f:b0:2ee:d433:7c50 with SMTP id 98e67ed59e1d1-300ff351ae3mr4025558a91.23.1741698101874; Tue, 11 Mar 2025 06:01:41 -0700 (PDT) Received: from wheely.local0.net ([118.208.151.101]) by smtp.gmail.com with ESMTPSA id 98e67ed59e1d1-2ff4e773dddsm11822318a91.12.2025.03.11.06.01.39 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 11 Mar 2025 06:01:41 -0700 (PDT) From: Nicholas Piggin To: qemu-devel@nongnu.org Cc: Nicholas Piggin , qemu-ppc@nongnu.org Subject: [PULL 64/72] target/ppc: Wire up BookE ATB registers for e500 family Date: Tue, 11 Mar 2025 22:57:58 +1000 Message-ID: <20250311125815.903177-65-npiggin@gmail.com> X-Mailer: git-send-email 2.47.1 In-Reply-To: <20250311125815.903177-1-npiggin@gmail.com> References: <20250311125815.903177-1-npiggin@gmail.com> MIME-Version: 1.0 Received-SPF: pass client-ip=2607:f8b0:4864:20::1031; envelope-from=npiggin@gmail.com; helo=mail-pj1-x1031.google.com X-Spam_score_int: -20 X-Spam_score: -2.1 X-Spam_bar: -- X-Spam_report: (-2.1 / 5.0 requ) BAYES_00=-1.9, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_AU=-0.1, DKIM_VALID_EF=-0.1, FREEMAIL_FROM=0.001, RCVD_IN_DNSWL_NONE=-0.0001, SPF_HELO_NONE=0.001, SPF_PASS=-0.001 autolearn=ham autolearn_force=no X-Spam_action: no action X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: qemu-devel-bounces+qemu-devel=archiver.kernel.org@nongnu.org Sender: qemu-devel-bounces+qemu-devel=archiver.kernel.org@nongnu.org From the Freescale PowerPC Architecture Primer: Alternate time base APU. This APU, implemented on the e500v2, defines a 64-bit time base counter that differs from the PowerPC defined time base in that it is not writable and counts at a different, and typically much higher, frequency. The alternate time base always counts up, wrapping when the 64-bit count overflows. This implementation of ATB uses the same frequency as the TB. The existing spr_read_atbu/l functions are unused without this patch to wire them into the SPR. RTEMS uses this SPR on the e6500, though this hasn't been tested. Message-ID: <20241219034035.1826173-6-npiggin@gmail.com> Signed-off-by: Nicholas Piggin --- target/ppc/cpu_init.c | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/target/ppc/cpu_init.c b/target/ppc/cpu_init.c index 9dc5ace828..8b590e7f17 100644 --- a/target/ppc/cpu_init.c +++ b/target/ppc/cpu_init.c @@ -922,6 +922,18 @@ static void register_BookE206_sprs(CPUPPCState *env, uint32_t mas_mask, #endif } +static void register_atb_sprs(CPUPPCState *env) +{ + spr_register(env, SPR_ATBL, "ATBL", + &spr_read_atbl, SPR_NOACCESS, + &spr_read_atbl, SPR_NOACCESS, + 0x00000000); + spr_register(env, SPR_ATBU, "ATBU", + &spr_read_atbu, SPR_NOACCESS, + &spr_read_atbu, SPR_NOACCESS, + 0x00000000); +} + /* SPR specific to PowerPC 440 implementation */ static void register_440_sprs(CPUPPCState *env) { @@ -2911,6 +2923,11 @@ static void init_proc_e500(CPUPPCState *env, int version) register_BookE206_sprs(env, 0x000000DF, tlbncfg, mmucfg); register_usprgh_sprs(env); + if (version != fsl_e500v1) { + /* e500v1 has no support for alternate timebase */ + register_atb_sprs(env); + } + spr_register(env, SPR_HID0, "HID0", SPR_NOACCESS, SPR_NOACCESS, &spr_read_generic, &spr_write_generic, From patchwork Tue Mar 11 12:57:59 2025 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Nicholas Piggin X-Patchwork-Id: 14011828 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.lore.kernel.org (Postfix) with ESMTPS id 79039C28B2E for ; Tue, 11 Mar 2025 13:11:58 +0000 (UTC) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1trzJz-0006A6-PO; Tue, 11 Mar 2025 09:06:59 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1trzEx-0005yo-TL; Tue, 11 Mar 2025 09:01:48 -0400 Received: from mail-pj1-x102d.google.com ([2607:f8b0:4864:20::102d]) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_128_GCM_SHA256:128) (Exim 4.90_1) (envelope-from ) id 1trzEw-0000LW-6c; Tue, 11 Mar 2025 09:01:47 -0400 Received: by mail-pj1-x102d.google.com with SMTP id 98e67ed59e1d1-2feb96064e4so10452685a91.1; Tue, 11 Mar 2025 06:01:45 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20230601; t=1741698104; x=1742302904; darn=nongnu.org; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to; bh=Ilno9T+zEsi8ai9jccA8FciMmreT00QeJlMccgO6CII=; b=eC1sNM8M2L7mnzvbf7oFH8kDhaP8kFy61ubLRZqrUTfyKZxAHJjbO/F5KDWTfWZl/n wuqli2wMNm20qXUJi5twIhYUVQqIz9GamMMTFEkwylRkvfUfrN0bnUyOzWhv1E7LSQTb BYlkGTb0L0uuvxS63HSDMO5vdxDeKdFhhDa9RPmnAH3OyEHc7HLySvjdiCbfKo3ZyxvD ffCokiVsV7N5fQHlYIVsAgJ36YacwpBjjFccKVaauVygpV8KwwoNpkS29ROBQyXVRKod tI4q5klWWK3m4rvtzsZ/wpnUHmmNU8CFlcULYrBQlW8HrpUTbDn/2ViXzJhXMXDQVJ3b ZCaw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1741698104; x=1742302904; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=Ilno9T+zEsi8ai9jccA8FciMmreT00QeJlMccgO6CII=; b=WdQCkac2XWbaEcloklwZAttmRBTvJ1eC6JB6tXHCHbctRxligDSHAt8OayDh377NE9 bdaEJuEIp8Q14L9Gu/ubeua9leJuwqRpWGqJuccXLwQFvKfPL2FYOP6s2ZmiTosq3jSH GgfGz5E6kDYE6SVxe3FLQEvv371BO7QCkN5/g2ilVQwiAU3cSG6vlVIN6I3UjV1uQuh4 Fd80X2WL6cwknAwwNpV47viNtuhv4liAYpbrO5NRDvKPmwEqteuOIWYiSm5IvYqEub2I i4DR0CAxjCiotnjZ3xEREmfGNBEHDvs2FaO/JpVU28nRLkYipe3hgjT06jIMIvtNj38J fBPw== X-Forwarded-Encrypted: i=1; AJvYcCWr0Z75IlGlOOIQRdJfSCGS6oiQOAbcYzOQ0GsGdFfVJ3cjPajvFukRGFYAHE0YPlwL89TfB/O3Ig==@nongnu.org X-Gm-Message-State: AOJu0YxbeOIvMPWdMwUa9svc3RUDnTiJGpxf57wPlrNWuWdMdQ+4yhHV a7h35CI6KLwbSIRFEoiZSABu06sz8Z3heMYcgpKIgfgHPFu8rBV1/Y5S1w== X-Gm-Gg: ASbGncuRq8R83hTEZaOXR1nJYKvsWNrc1xXZC961dPWzs2tknTjJtLbprhU4sb2DHvT qT4EnpEFvnKb6mQkQbH2YDBHBAXwlP/rXYDBb8yLqk8vqDKsIc0HkRD+BNshviXbl1mLk75bn9l Y6KfSCRAmBOJ8DBpPrstqzFkL4j6JtDuV5s6Ai/JaHh0AYc5u7DzpP9ClUg1iIEK+RTFG4cgDiH b7FZcNPY0tFKF7n7lRTwTGTjS+bTC0f4SioV5a3WG+6PKA9M29ROSKbfnBY3rK2mx1PrGGGwADP r6aNOvlBmt+cGE884pW922VNgIqDXB9g9WvJzfEP2HUbXqkU5owaRcYtVQBjOA== X-Google-Smtp-Source: AGHT+IHMU9Ha3HMA9N1E6G3VfYwY0OTrH/wycKuKcP6q00DRV4soyT0f4SifW/kAixS1ZMl6KA+VAQ== X-Received: by 2002:a17:90b:1d0a:b0:2ea:83a0:47a5 with SMTP id 98e67ed59e1d1-2ff7ce457acmr25997767a91.4.1741698104252; Tue, 11 Mar 2025 06:01:44 -0700 (PDT) Received: from wheely.local0.net ([118.208.151.101]) by smtp.gmail.com with ESMTPSA id 98e67ed59e1d1-2ff4e773dddsm11822318a91.12.2025.03.11.06.01.42 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 11 Mar 2025 06:01:43 -0700 (PDT) From: Nicholas Piggin To: qemu-devel@nongnu.org Cc: Nicholas Piggin , qemu-ppc@nongnu.org Subject: [PULL 65/72] target/ppc: Avoid warning message for zero process table entries Date: Tue, 11 Mar 2025 22:57:59 +1000 Message-ID: <20250311125815.903177-66-npiggin@gmail.com> X-Mailer: git-send-email 2.47.1 In-Reply-To: <20250311125815.903177-1-npiggin@gmail.com> References: <20250311125815.903177-1-npiggin@gmail.com> MIME-Version: 1.0 Received-SPF: pass client-ip=2607:f8b0:4864:20::102d; envelope-from=npiggin@gmail.com; helo=mail-pj1-x102d.google.com X-Spam_score_int: -20 X-Spam_score: -2.1 X-Spam_bar: -- X-Spam_report: (-2.1 / 5.0 requ) BAYES_00=-1.9, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_AU=-0.1, DKIM_VALID_EF=-0.1, FREEMAIL_FROM=0.001, RCVD_IN_DNSWL_NONE=-0.0001, SPF_HELO_NONE=0.001, SPF_PASS=-0.001 autolearn=ham autolearn_force=no X-Spam_action: no action X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: qemu-devel-bounces+qemu-devel=archiver.kernel.org@nongnu.org Sender: qemu-devel-bounces+qemu-devel=archiver.kernel.org@nongnu.org A translation that encounters a process table entry that is zero is something that Linux does to cause certain kernel NULL pointer dereferences to fault. It is not itself a programming error, so avoid the guest error log. Message-ID: <20241219034035.1826173-5-npiggin@gmail.com> Signed-off-by: Nicholas Piggin --- target/ppc/mmu-radix64.c | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/target/ppc/mmu-radix64.c b/target/ppc/mmu-radix64.c index 1d3d9e1be7..461eda4a3d 100644 --- a/target/ppc/mmu-radix64.c +++ b/target/ppc/mmu-radix64.c @@ -571,6 +571,20 @@ static int ppc_radix64_process_scoped_xlate(PowerPCCPU *cpu, prtbe0 = ldq_phys(cs->as, h_raddr); } + /* + * Some Linux uses a zero process table entry in PID!=0 for kernel context + * without userspace in order to fault on NULL dereference, because using + * PIDR=0 for the kernel causes the Q0 page table to be used to translate + * Q3 as well. Check for that case here to avoid the invalid configuration + * message. + */ + if (unlikely(!prtbe0)) { + if (guest_visible) { + ppc_radix64_raise_si(cpu, access_type, eaddr, DSISR_R_BADCONFIG); + } + return 1; + } + /* Walk Radix Tree from Process Table Entry to Convert EA to RA */ *g_page_size = PRTBE_R_GET_RTS(prtbe0); base_addr = prtbe0 & PRTBE_R_RPDB; From patchwork Tue Mar 11 12:58:00 2025 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: Nicholas Piggin X-Patchwork-Id: 14011845 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.lore.kernel.org (Postfix) with ESMTPS id B6247C28B30 for ; Tue, 11 Mar 2025 13:15:24 +0000 (UTC) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1trzK6-0006ZP-TI; Tue, 11 Mar 2025 09:07:08 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1trzF1-00062l-6z; Tue, 11 Mar 2025 09:01:53 -0400 Received: from mail-pj1-x102c.google.com ([2607:f8b0:4864:20::102c]) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_128_GCM_SHA256:128) (Exim 4.90_1) (envelope-from ) id 1trzEz-0000MD-HX; Tue, 11 Mar 2025 09:01:50 -0400 Received: by mail-pj1-x102c.google.com with SMTP id 98e67ed59e1d1-2feb91a25bdso8351929a91.1; Tue, 11 Mar 2025 06:01:48 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20230601; t=1741698107; x=1742302907; darn=nongnu.org; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to; bh=TQn7KOWUQFcqU1w4jtYKqmuC8Pu69FDqNY7Y/CrCA40=; b=EPoUpjeiPKGvD2rSrb/7jfGlD2ezASk+OL+EFviNCTw4p2mJSY/pRPkESWDAxmhAHr 2KEFRKVAusFZfHtKTzezHPf0zFsEEGA88dt8K7ENZbpHUs5l95PH4pdCpYMCDIe2gcK7 SU8eFKrW/ELWj/gyXNq4bFL3679nNP0f5FE9rwssHV4kOrymuBVAdsgJ4KJOhEwimZoM p/VpOnA6DuVJbr9yS2pVD/Ymyu9itNbzL/y/l/v9SG2skULiwvSdMkEQi/eGzGJs8fxv JhKQwK3ONVbF06DvlE3lW/fSgQc06SEUZdm7N1azlv/Bo4iWYlag8/QwICWczOH7WZxB 0Uxw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1741698107; x=1742302907; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=TQn7KOWUQFcqU1w4jtYKqmuC8Pu69FDqNY7Y/CrCA40=; b=qVMeetIcAJufjtf8Ec+2/xdPOZWx2pVRGcKdOVK2U4xf8KUkncaOtvuK4gtDxoK0df jbaWI/G5wJ/Aj4PEXuFz16dENJkEladrip5gLvT/afwZ0hNxygeW8U/vR8FQD/L198H4 jWID0BoTMUcbQeQrKhDdmJShamOpxXevtPCN7IgJ9SshDr5r0dcpTbtcZIodjIp/Xapc +AsWmkacwP/EBp3XxTDDt+GnbqyaqsMWiBCMJPwtcOx2gVUjXSR38++rEA0lR+2gBQNV 397Ux++9GVFcmv8ZoYLpwY41NlKLh3TS4bYgmudpAV4APmEsUsO+VqFPVpLl52tg39xw 5xRQ== X-Forwarded-Encrypted: i=1; AJvYcCUNjBlRKvRUFKpTo8SYofTBu+cXSkComN2ji3eOyZ+q3dEVqA5qXZqJ084SUY1y6kZQqGvC+H8mNw==@nongnu.org X-Gm-Message-State: AOJu0YxzCdZTUqmZfT3V/CGJUJqDzLTci0sVjMq1xbaNbpRUokachoe3 j2kwuhKLfagPPZClrCtLbMWKcg+GwxzFPz2p176shLjgsoK/qqQI+pZ8NQ== X-Gm-Gg: ASbGncugDu2bPeQ7n/rlnHBxUpQfh4DC4r611nsiEUbYzkU6QujqIGNAeaBZ8UO5yxa +0hYqFf+KAz7TYh3ZK5pW2dkCOZMYPPF2sw6PwI4no2C01YTF45dHIfZHrNmnTCCcJ0NKhAM1Tr 5+cKDNUvDLPl2p9OMIW5sxh6OkKYfu9S0Z5v+8th84GnY0YOG1GwFx/zghU9eNEWp2zq4rrE45f WYxkva/DG9rwZjf+QDFe96YUI7/4rR9ZqjNtBiXwJXYhUSL7PHTNufIWhNc6HyGNtGDvHn3r87h tTov+T/5SaNHTHvQu9+FFXJK2RidPNk1p6YLw0lh+wIBXFxZ/c4= X-Google-Smtp-Source: AGHT+IHivNbFtL7rTgJkaCQzrNnXxu0MUV9IllhCiFP4VhSb7Cv5sQSyZnueukBT4lrE3TaIIqOloA== X-Received: by 2002:a17:90b:2648:b0:2fe:e9c6:689e with SMTP id 98e67ed59e1d1-300ff0c9bacmr4862348a91.8.1741698107206; Tue, 11 Mar 2025 06:01:47 -0700 (PDT) Received: from wheely.local0.net ([118.208.151.101]) by smtp.gmail.com with ESMTPSA id 98e67ed59e1d1-2ff4e773dddsm11822318a91.12.2025.03.11.06.01.44 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 11 Mar 2025 06:01:46 -0700 (PDT) From: Nicholas Piggin To: qemu-devel@nongnu.org Cc: Nicholas Piggin , qemu-ppc@nongnu.org, Harsh Prateek Bora , =?utf-8?q?Philippe_Mathieu-Daud?= =?utf-8?q?=C3=A9?= Subject: [PULL 66/72] spapr: Generate random HASHPKEYR for spapr machines Date: Tue, 11 Mar 2025 22:58:00 +1000 Message-ID: <20250311125815.903177-67-npiggin@gmail.com> X-Mailer: git-send-email 2.47.1 In-Reply-To: <20250311125815.903177-1-npiggin@gmail.com> References: <20250311125815.903177-1-npiggin@gmail.com> MIME-Version: 1.0 Received-SPF: pass client-ip=2607:f8b0:4864:20::102c; envelope-from=npiggin@gmail.com; helo=mail-pj1-x102c.google.com X-Spam_score_int: -20 X-Spam_score: -2.1 X-Spam_bar: -- X-Spam_report: (-2.1 / 5.0 requ) BAYES_00=-1.9, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_AU=-0.1, DKIM_VALID_EF=-0.1, FREEMAIL_FROM=0.001, RCVD_IN_DNSWL_NONE=-0.0001, SPF_HELO_NONE=0.001, SPF_PASS=-0.001 autolearn=ham autolearn_force=no X-Spam_action: no action X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: qemu-devel-bounces+qemu-devel=archiver.kernel.org@nongnu.org Sender: qemu-devel-bounces+qemu-devel=archiver.kernel.org@nongnu.org The hypervisor is expected to create a value for the HASHPKEY SPR for each partition. Currently it uses zero for all partitions, use a random number instead, which in theory might make kernel ROP protection more secure. Signed-of-by: Nicholas Piggin Reviewed-by: Harsh Prateek Bora Reviewed-by: Philippe Mathieu-Daudé Message-ID: <20241219034035.1826173-4-npiggin@gmail.com> Signed-off-by: Nicholas Piggin --- hw/ppc/spapr.c | 3 +++ hw/ppc/spapr_cpu_core.c | 2 ++ include/hw/ppc/spapr.h | 1 + 3 files changed, 6 insertions(+) diff --git a/hw/ppc/spapr.c b/hw/ppc/spapr.c index fcd2ca515c..a415e51d07 100644 --- a/hw/ppc/spapr.c +++ b/hw/ppc/spapr.c @@ -2917,6 +2917,9 @@ static void spapr_machine_init(MachineState *machine) spapr_ovec_set(spapr->ov5, OV5_XIVE_EXPLOIT); } + qemu_guest_getrandom_nofail(&spapr->hashpkey_val, + sizeof(spapr->hashpkey_val)); + /* init CPUs */ spapr_init_cpus(spapr); diff --git a/hw/ppc/spapr_cpu_core.c b/hw/ppc/spapr_cpu_core.c index 9e0e0648a7..0671d9e44b 100644 --- a/hw/ppc/spapr_cpu_core.c +++ b/hw/ppc/spapr_cpu_core.c @@ -273,6 +273,8 @@ static bool spapr_realize_vcpu(PowerPCCPU *cpu, SpaprMachineState *spapr, env->spr_cb[SPR_PIR].default_value = cs->cpu_index; env->spr_cb[SPR_TIR].default_value = thread_index; + env->spr_cb[SPR_HASHPKEYR].default_value = spapr->hashpkey_val; + cpu_ppc_set_1lpar(cpu); /* Set time-base frequency to 512 MHz. vhyp must be set first. */ diff --git a/include/hw/ppc/spapr.h b/include/hw/ppc/spapr.h index d227f0b94b..39bd5bd5ed 100644 --- a/include/hw/ppc/spapr.h +++ b/include/hw/ppc/spapr.h @@ -203,6 +203,7 @@ struct SpaprMachineState { uint32_t fdt_initial_size; void *fdt_blob; uint8_t fdt_rng_seed[32]; + uint64_t hashpkey_val; long kernel_size; bool kernel_le; uint64_t kernel_addr; From patchwork Tue Mar 11 12:58:01 2025 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Nicholas Piggin X-Patchwork-Id: 14011881 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.lore.kernel.org (Postfix) with ESMTPS id 0B3B9C282EC for ; Tue, 11 Mar 2025 13:21:53 +0000 (UTC) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1trzKi-0000yJ-Le; Tue, 11 Mar 2025 09:07:44 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1trzFC-0006Gp-Cq; Tue, 11 Mar 2025 09:02:08 -0400 Received: from mail-pj1-x102d.google.com ([2607:f8b0:4864:20::102d]) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_128_GCM_SHA256:128) (Exim 4.90_1) (envelope-from ) id 1trzF3-0000Mh-H5; Tue, 11 Mar 2025 09:02:00 -0400 Received: by mail-pj1-x102d.google.com with SMTP id 98e67ed59e1d1-2feae794508so8087751a91.0; Tue, 11 Mar 2025 06:01:52 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20230601; t=1741698110; x=1742302910; darn=nongnu.org; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to; bh=Kxho44oluW8FOSM2HZbfWLIKk4fba+N89CNPXqjPZug=; b=h0yZUFWMoACsS+KnfRChFOlDIlKuKy4+gwe/LBTZbNal55kHDUUxHe55ZbQMFFsZ+o M0mxFpx0idByjce6KDUV59slq1wql3vO7vHsI4LxLZ63hD6vZw/3k7TB8XJzHrz45Dyu a7nhadZaxuFbPEh/MLQLn4vrrb4X1rZRaknJztMdXa/RIS7W9OBZlxdl5wxW+Q++lb4n 9FM956W5RGih43U1YxVawPWF1RUF15e23CQ1pngMYSDeLFesD52NBF4A+Hw2egvv4EIV H5NNxnRUxwEKuwYH36/dln3jOa0VTxeMuoLbPQAE9fX66EZIxQaJ6KyJ4RPP4rSM9ePf 1AsA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1741698110; x=1742302910; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=Kxho44oluW8FOSM2HZbfWLIKk4fba+N89CNPXqjPZug=; b=wNI13SH382S3menucWOkSwI4TCeEPpHoEyAimz39m1V2tzFScD2NduDCEnKPsrnZg5 Y9ASTLu45LKmk1rltH+gca+qo50aMqAsbJV568NUfbn/fqCppmHtox5ynCo5MpLCXVuN 3VUkttWxnLVFyok94BvJMLk7PXmSNoKkLQnVPGupg/fxqwDC/xDd89Dh2/rwlrFx07do nh+iGsr1wQl6EvYmAaRoMGej9RSgSaSQ3I8xZ/vOE3OOjU7GUNmMkaaLST6DGmfLDF6j io+1TZhTXVX3y1BlzYnE7xGiPmJ+OCama8lBlOtSn/Ey13tn6cmq1wIWEP1M1WRmG6XH Cv/A== X-Forwarded-Encrypted: i=1; AJvYcCXqjp1nNoMzWiwKpmNhpywi9NxwdSoexCxZt1r+177Mr26lcjySIzRHjo3b2SCpoztdnSOGPlOTYw==@nongnu.org X-Gm-Message-State: AOJu0YwsQxy+oLyhTD7HiA1yD8rE0Z3ftHoXuRHit4eDd8Mc8RLXuvzU uLq4maEfKzqLLWDKLLN6G8dZRNw1ZQfZXgPW1Gdc12i35GEuknrAQnJDgA== X-Gm-Gg: ASbGncsLRYeDhEKp+99iqG9WsKGxsA7kncxXybErXaCfGC+a152SdR4biJ8MEYSWGO/ 8DBsPYFRvjjwwmzrTXrblNpKL5awkXeA0C6gbacQq2ZgRuKFLKLNU/23ERDXecOxe7e0myYKCKP ESZHsCUorXPnTLrnD4tTO3QxYv3xMaVKHPUm0yCR52s36gYr17t1nJdsC7EJfxyfmDacgxx9BCY w5Qt4/Un4Ox0HEAO+hzlCDjBwAHFup5MUv4t4Kgh5gIx6ZCg6y7rF6gzeOsTgrouQG9OCw5zmWH hPiycqbSGSKLz1XCC6nUkfsfhGqKYjQzul4rMkWrAI7nTUUoh/E= X-Google-Smtp-Source: AGHT+IEUtO7mbUqOQOnuiCu3c0l7NIXHWY4nXKZgBD+EBY6vpZWxOZ12LNzENerDYxx6zHjK+gg6IQ== X-Received: by 2002:a17:90b:3c8d:b0:2ee:d63f:d73 with SMTP id 98e67ed59e1d1-2ff7ce6c9b5mr27223648a91.11.1741698109935; Tue, 11 Mar 2025 06:01:49 -0700 (PDT) Received: from wheely.local0.net ([118.208.151.101]) by smtp.gmail.com with ESMTPSA id 98e67ed59e1d1-2ff4e773dddsm11822318a91.12.2025.03.11.06.01.47 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 11 Mar 2025 06:01:49 -0700 (PDT) From: Nicholas Piggin To: qemu-devel@nongnu.org Cc: Nicholas Piggin , qemu-ppc@nongnu.org, BALATON Zoltan Subject: [PULL 67/72] ppc/amigaone: Simplify replacement dummy_fw Date: Tue, 11 Mar 2025 22:58:01 +1000 Message-ID: <20250311125815.903177-68-npiggin@gmail.com> X-Mailer: git-send-email 2.47.1 In-Reply-To: <20250311125815.903177-1-npiggin@gmail.com> References: <20250311125815.903177-1-npiggin@gmail.com> MIME-Version: 1.0 Received-SPF: pass client-ip=2607:f8b0:4864:20::102d; envelope-from=npiggin@gmail.com; helo=mail-pj1-x102d.google.com X-Spam_score_int: -20 X-Spam_score: -2.1 X-Spam_bar: -- X-Spam_report: (-2.1 / 5.0 requ) BAYES_00=-1.9, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_AU=-0.1, DKIM_VALID_EF=-0.1, FREEMAIL_FROM=0.001, RCVD_IN_DNSWL_NONE=-0.0001, SPF_HELO_NONE=0.001, SPF_PASS=-0.001 autolearn=ham autolearn_force=no X-Spam_action: no action X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: qemu-devel-bounces+qemu-devel=archiver.kernel.org@nongnu.org Sender: qemu-devel-bounces+qemu-devel=archiver.kernel.org@nongnu.org From: BALATON Zoltan There's no need to do shift in a loop, doing it in one instruction works just as well, only the result is used. Signed-off-by: BALATON Zoltan Reviewed-by: Nicholas Piggin Message-ID: <446bf740cbb99422be2cc5a31e51a1034eddded7.1740673173.git.balaton@eik.bme.hu> Signed-off-by: Nicholas Piggin --- hw/ppc/amigaone.c | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/hw/ppc/amigaone.c b/hw/ppc/amigaone.c index b02792221c..4290d58613 100644 --- a/hw/ppc/amigaone.c +++ b/hw/ppc/amigaone.c @@ -41,10 +41,7 @@ /* AmigaOS calls this routine from ROM, use this if no firmware loaded */ static const char dummy_fw[] = { - 0x38, 0x00, 0x00, 0x08, /* li r0,8 */ - 0x7c, 0x09, 0x03, 0xa6, /* mtctr r0 */ - 0x54, 0x63, 0xf8, 0x7e, /* srwi r3,r3,1 */ - 0x42, 0x00, 0xff, 0xfc, /* bdnz 0x8 */ + 0x54, 0x63, 0xc2, 0x3e, /* srwi r3,r3,8 */ 0x7c, 0x63, 0x18, 0xf8, /* not r3,r3 */ 0x4e, 0x80, 0x00, 0x20, /* blr */ }; From patchwork Tue Mar 11 12:58:02 2025 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Nicholas Piggin X-Patchwork-Id: 14011825 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.lore.kernel.org (Postfix) with ESMTPS id 8229EC28B2E for ; Tue, 11 Mar 2025 13:11:14 +0000 (UTC) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1trzK8-0006nm-UK; Tue, 11 Mar 2025 09:07:10 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1trzFD-0006Gy-NP; Tue, 11 Mar 2025 09:02:08 -0400 Received: from mail-pj1-x1030.google.com ([2607:f8b0:4864:20::1030]) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_128_GCM_SHA256:128) (Exim 4.90_1) (envelope-from ) id 1trzF8-0000N4-4n; Tue, 11 Mar 2025 09:02:03 -0400 Received: by mail-pj1-x1030.google.com with SMTP id 98e67ed59e1d1-2ff80290e44so8662566a91.0; Tue, 11 Mar 2025 06:01:55 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20230601; t=1741698113; x=1742302913; darn=nongnu.org; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to; bh=Ag/IQcoVCKBwm3hoxb2LywEaHZGgEXDr7bl00iOZl08=; b=eOdkHY4BYQI4L1Defs19wLjxkEydc/X49RZsYiUSeUp8AoWN6gXiy+8YUwUIwCdR2w bYlflupRIDriAcerPBLzWmVBtHcpMnT+PSd9cDKiuWXuMJhamluUNG4AHr4BKrSP68WX iBppjdkmoHiI8RIgslXapl5/Y1Stpvo1hDpWfiCT5kdDzLCxPI2nGQcit4J/WjUwKQUQ Gbhrhx41EgGYMHxWYKvkFyUY4LQrxbthj6CILcuv1pH6bOZMwi8sqIk8JE5UIHjmQgEm INZsFOX1JymnN3CAkni7H4wpWzm/kiBvfMxF/jQ20Vj61ZJavnJoTxOE8cV69lzr7t8H /JTQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1741698113; x=1742302913; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=Ag/IQcoVCKBwm3hoxb2LywEaHZGgEXDr7bl00iOZl08=; b=V4YSvJRvXVaev+yK9zIkcX0pZ+B8JTeQnbUYsPy5ZvAG7kqFMFHJm1Ezv/MibAEWxz cxjq+pU55LytlaLCmHoH0d41OROdE+a6+YX99dIGkUxQjE67Tv9gpCEWt3y+qoftJgOT 3lX5nUITlYvC2abVZw4cor513iEd641ppFFwidrPysiVq+hfbAy117o6vbCp8N7XfNZ+ Sn2lKdH52o9Pf0Ehzszy3agNuVJZasdWArEJh/xIHqQV9NMO4JdfBkLOaQp3CSsLHB31 6EADahqIuR0vToY6qR8Rc6mEsGfIo+usAvf7PAspdYvG6LpYCh1JZpb3YfQBPZpVuCsw iN0w== X-Forwarded-Encrypted: i=1; AJvYcCWa4eU1T2hJs+nM8BzGyQs93UgoxRsFW36ZXQN9tPYe6GNRos6sz/w1bhdG8o6y3GW0kxdvLYIgfg==@nongnu.org X-Gm-Message-State: AOJu0Yzr2wovBbKy5bupC2/NvodXWeWKIfQQLlIB5M2FouZilRd+81ev jAG5YV4/VEANvLAfdBwZhl5CxbVRXQwf126ypwU0YNzGdODyZ3c2Ds+SZQ== X-Gm-Gg: ASbGncswSE0s//1IQFzL3/C7oPCOq9Wv2PWEOiew8Kn2TIPaUdqfmdGm068mFG75B3q soiOzJ5jS2ECLg1CkCHlP3+EBKp59K+iqb8Tm3uvAs+CN/95lJqBT05ZkS0Mk7iCP8QB8QJDgLL TVONdk6GTzOE+gy5fwwzXe1jc0lv/GSOSMCMiE7+CL/9ggD5Q177BffwVnRUg4ES1YuCwzyfcpt uoIG2zWvUhh81nxy50WYySpMvHzVTKwZ42rMFSnuKoFIpBAOJlnlt//bO225TsxWpB8CnVbXAXq 7+dbuTuFNiaVM/MApXcLl+Dz4H1LAQnQE1ck51c9l1eju1o0+ns= X-Google-Smtp-Source: AGHT+IHGHi0YCKuzUX2ZW2gAJ1JVM7T7aSD2GJjt+xBz2msrBMmquFvOwCCHIZJ3MejaLnEfiScxNQ== X-Received: by 2002:a17:90b:1b0b:b0:2fc:c262:ef4b with SMTP id 98e67ed59e1d1-2ff7cea9a99mr30670044a91.18.1741698112616; Tue, 11 Mar 2025 06:01:52 -0700 (PDT) Received: from wheely.local0.net ([118.208.151.101]) by smtp.gmail.com with ESMTPSA id 98e67ed59e1d1-2ff4e773dddsm11822318a91.12.2025.03.11.06.01.50 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 11 Mar 2025 06:01:52 -0700 (PDT) From: Nicholas Piggin To: qemu-devel@nongnu.org Cc: Nicholas Piggin , qemu-ppc@nongnu.org, BALATON Zoltan Subject: [PULL 68/72] ppc/amigaone: Implement NVRAM emulation Date: Tue, 11 Mar 2025 22:58:02 +1000 Message-ID: <20250311125815.903177-69-npiggin@gmail.com> X-Mailer: git-send-email 2.47.1 In-Reply-To: <20250311125815.903177-1-npiggin@gmail.com> References: <20250311125815.903177-1-npiggin@gmail.com> MIME-Version: 1.0 Received-SPF: pass client-ip=2607:f8b0:4864:20::1030; envelope-from=npiggin@gmail.com; helo=mail-pj1-x1030.google.com X-Spam_score_int: -20 X-Spam_score: -2.1 X-Spam_bar: -- X-Spam_report: (-2.1 / 5.0 requ) BAYES_00=-1.9, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_AU=-0.1, DKIM_VALID_EF=-0.1, FREEMAIL_FROM=0.001, RCVD_IN_DNSWL_NONE=-0.0001, SPF_PASS=-0.001, T_SPF_HELO_TEMPERROR=0.01 autolearn=ham autolearn_force=no X-Spam_action: no action X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: qemu-devel-bounces+qemu-devel=archiver.kernel.org@nongnu.org Sender: qemu-devel-bounces+qemu-devel=archiver.kernel.org@nongnu.org From: BALATON Zoltan The board has a battery backed NVRAM where U-Boot environment is stored which is also accessed by AmigaOS and e.g. C:NVGetVar command crashes without it having at least a valid checksum. [npiggin: 32-bit compile fix] Signed-off-by: BALATON Zoltan Reviewed-by: Nicholas Piggin Message-ID: <7e4c0107ef6bdc2b20fb1e780a188275c7dc1e49.1740673173.git.balaton@eik.bme.hu> Signed-off-by: Nicholas Piggin --- hw/ppc/amigaone.c | 113 ++++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 110 insertions(+), 3 deletions(-) diff --git a/hw/ppc/amigaone.c b/hw/ppc/amigaone.c index 4290d58613..feb2cf452c 100644 --- a/hw/ppc/amigaone.c +++ b/hw/ppc/amigaone.c @@ -21,10 +21,13 @@ #include "hw/ide/pci.h" #include "hw/i2c/smbus_eeprom.h" #include "hw/ppc/ppc.h" +#include "system/block-backend.h" #include "system/qtest.h" #include "system/reset.h" #include "kvm_ppc.h" +#include /* for crc32 */ + #define BUS_FREQ_HZ 100000000 /* @@ -46,6 +49,100 @@ static const char dummy_fw[] = { 0x4e, 0x80, 0x00, 0x20, /* blr */ }; +#define NVRAM_ADDR 0xfd0e0000 +#define NVRAM_SIZE (4 * KiB) + +#define TYPE_A1_NVRAM "a1-nvram" +OBJECT_DECLARE_SIMPLE_TYPE(A1NVRAMState, A1_NVRAM) + +struct A1NVRAMState { + SysBusDevice parent_obj; + + MemoryRegion mr; + BlockBackend *blk; +}; + +static uint64_t nvram_read(void *opaque, hwaddr addr, unsigned int size) +{ + /* read callback not used because of romd mode */ + g_assert_not_reached(); +} + +static void nvram_write(void *opaque, hwaddr addr, uint64_t val, + unsigned int size) +{ + A1NVRAMState *s = opaque; + uint8_t *p = memory_region_get_ram_ptr(&s->mr); + + p[addr] = val; + if (s->blk) { + blk_pwrite(s->blk, addr, 1, &val, 0); + } +} + +static const MemoryRegionOps nvram_ops = { + .read = nvram_read, + .write = nvram_write, + .endianness = DEVICE_BIG_ENDIAN, + .impl = { + .min_access_size = 1, + .max_access_size = 1, + }, +}; + +static void nvram_realize(DeviceState *dev, Error **errp) +{ + A1NVRAMState *s = A1_NVRAM(dev); + void *p; + uint32_t *c; + + memory_region_init_rom_device(&s->mr, NULL, &nvram_ops, s, "nvram", + NVRAM_SIZE, &error_fatal); + sysbus_init_mmio(SYS_BUS_DEVICE(dev), &s->mr); + c = p = memory_region_get_ram_ptr(&s->mr); + if (s->blk) { + if (blk_getlength(s->blk) != NVRAM_SIZE) { + error_setg(errp, "NVRAM backing file size must be %" PRId64 "bytes", + NVRAM_SIZE); + return; + } + blk_set_perm(s->blk, BLK_PERM_CONSISTENT_READ | BLK_PERM_WRITE, + BLK_PERM_ALL, &error_fatal); + if (blk_pread(s->blk, 0, NVRAM_SIZE, p, 0) < 0) { + error_setg(errp, "Cannot read NVRAM contents from backing file"); + return; + } + } + if (*c == 0) { + *c = cpu_to_be32(crc32(0, p + 4, NVRAM_SIZE - 4)); + if (s->blk) { + blk_pwrite(s->blk, 0, 4, p, 0); + } + } +} + +static const Property nvram_properties[] = { + DEFINE_PROP_DRIVE("drive", A1NVRAMState, blk), +}; + +static void nvram_class_init(ObjectClass *oc, void *data) +{ + DeviceClass *dc = DEVICE_CLASS(oc); + + dc->realize = nvram_realize; + device_class_set_props(dc, nvram_properties); +} + +static const TypeInfo nvram_types[] = { + { + .name = TYPE_A1_NVRAM, + .parent = TYPE_SYS_BUS_DEVICE, + .instance_size = sizeof(A1NVRAMState), + .class_init = nvram_class_init, + }, +}; +DEFINE_TYPES(nvram_types) + static void amigaone_cpu_reset(void *opaque) { PowerPCCPU *cpu = opaque; @@ -72,7 +169,7 @@ static void amigaone_init(MachineState *machine) DeviceState *dev; I2CBus *i2c_bus; uint8_t *spd_data; - int i; + DriveInfo *di; /* init CPU */ cpu = POWERPC_CPU(cpu_create(machine->cpu_type)); @@ -97,6 +194,16 @@ static void amigaone_init(MachineState *machine) memory_region_add_subregion(get_system_memory(), 0x40000000, mr); } + /* nvram */ + dev = qdev_new(TYPE_A1_NVRAM); + di = drive_get(IF_MTD, 0, 0); + if (di) { + qdev_prop_set_drive(dev, "drive", blk_by_legacy_dinfo(di)); + } + sysbus_realize_and_unref(SYS_BUS_DEVICE(dev), &error_fatal); + memory_region_add_subregion(get_system_memory(), NVRAM_ADDR, + sysbus_mmio_get_region(SYS_BUS_DEVICE(dev), 0)); + /* allocate and load firmware */ rom = g_new(MemoryRegion, 1); memory_region_init_rom(rom, NULL, "rom", PROM_SIZE, &error_fatal); @@ -136,7 +243,7 @@ static void amigaone_init(MachineState *machine) pci_mem = sysbus_mmio_get_region(SYS_BUS_DEVICE(dev), 1); mr = g_new(MemoryRegion, 1); memory_region_init_alias(mr, OBJECT(dev), "pci-mem-low", pci_mem, - 0, 0x1000000); + 0, 0xe0000); memory_region_add_subregion(get_system_memory(), 0xfd000000, mr); mr = g_new(MemoryRegion, 1); memory_region_init_alias(mr, OBJECT(dev), "pci-mem-high", pci_mem, @@ -153,7 +260,7 @@ static void amigaone_init(MachineState *machine) qdev_connect_gpio_out_named(DEVICE(via), "intr", 0, qdev_get_gpio_in(DEVICE(cpu), PPC6xx_INPUT_INT)); - for (i = 0; i < PCI_NUM_PINS; i++) { + for (int i = 0; i < PCI_NUM_PINS; i++) { qdev_connect_gpio_out(dev, i, qdev_get_gpio_in_named(DEVICE(via), "pirq", i)); } From patchwork Tue Mar 11 12:58:03 2025 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Nicholas Piggin X-Patchwork-Id: 14011840 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.lore.kernel.org (Postfix) with ESMTPS id 5293AC282EC for ; Tue, 11 Mar 2025 13:13:56 +0000 (UTC) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1trzKO-0007Py-LP; Tue, 11 Mar 2025 09:07:24 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1trzFD-0006Gz-S6; Tue, 11 Mar 2025 09:02:08 -0400 Received: from mail-pj1-x1030.google.com ([2607:f8b0:4864:20::1030]) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_128_GCM_SHA256:128) (Exim 4.90_1) (envelope-from ) id 1trzFB-0000NK-2c; Tue, 11 Mar 2025 09:02:03 -0400 Received: by mail-pj1-x1030.google.com with SMTP id 98e67ed59e1d1-2f9b9c0088fso9069439a91.0; Tue, 11 Mar 2025 06:01:58 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20230601; t=1741698115; x=1742302915; darn=nongnu.org; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to; bh=s/hwfz8W3nE/NCo2dN8T5chquYKvDoTqUnc1wA+QdPA=; b=O/QuBAJs56ueGZj4zD8MuKojOmWcrp5l6QXRuxnZn/nTAyXUs1wjd6APbuyiNjdRQd solIe1mIl9LIfGrqDuyrnGUjjwYKxR67PwPAwvQuRg6V8ipwmr/BdstjSjpz8XXmb5EF JeLF5Pr2SBrFL0MRxCX0Q3s2iobFIZTBxLD5Tbp+aUp2Lg7iRFLShYTr3yTMaPimuKGD HtZa5nLuvULnZjHRmHVdtRfNTsh/CxX5j/HKWUbQbc6y1i0oJHx5Lqm08/skEPacs+A+ iPmgB0QAXYyHQ4KPU2WrAvXai4lNBh7qTi8dYo3oQIlu+Z0aEY143mczC5d8zNoxSmk7 V+Zg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1741698115; x=1742302915; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=s/hwfz8W3nE/NCo2dN8T5chquYKvDoTqUnc1wA+QdPA=; b=h+dQJEI3hCog9DQVtduQEK9Qw17eeNHg2xmS+sXqr6gNm/ixXEPesWZSj8VuG+ycX3 O+T7vbTaZlAWqVuMJTDo7jjtYJn5ipz4L51xRMHw2xsypFyFCmyA8/Dwg5/dEH4gg7M8 bo+MCeBtAm6VrBFEFCGkCpCPxYG+IYzlRVSTfmg7ohi7KWfcmoiTEeODRWiBpBr4qFm4 0o2E+5JqFezWoQG/t4sSL3Isbpqh5oXxxZK9TmOBKn2JEGE7wT1g456mtaQiaXrOpWdB X5F9bVMpBBVDUkSQEbIG0jVQf0r5QDR/DpVRjBdY/R3TTHUcJwK66NjsnShcSU86vFPJ aGkw== X-Forwarded-Encrypted: i=1; AJvYcCWYVe+ZYGJjCZ+inPdzPXHDvb6NksycyupyOCv8o0QrR5e0lqdbHy+Jt7bUtcPUbAsATkhPlU7QKQ==@nongnu.org X-Gm-Message-State: AOJu0YyabGuBYQ/ZemWWa/riuwo+yfXuhEB48Mm8PwP8fckfMX/7bRox iwRuuyvymTDMOCnvM3HGZwkmRYTVObObZlD35lX4MC5Fdbw+y4CiBhxifA== X-Gm-Gg: ASbGnctxMmqtSmHihD+qlX2672UbuL2Lskn6OESLcqfv7oaKqq/2daJUdjz9MCVA70Z +A5oX2g4qtUO5Ri9xyOX6c9SifSqEg0FcZMBQ+bihfSYsEYkxQ39Qd9vPfvd+G2Qdj6Aitq7tw1 tXYPEkb7iOuamMZ43iiGSMI6Rgs5/21tC3qMOkgmPzxjPUR8oP/ujGuguJhUt2UxGUu/9etIKXs 2cvPuPltq6b9jSPm44cZUUEzdKYHyP/7KjtYCFN+jhbu29btASLIT5Kk+CGT257NSFz/VBTwi1/ sKO2kE0wq8fE2I/Dbiu7xEU0MMtladdk8c9tXg8atoAUTtvNz85ppeTI/jw+LQ== X-Google-Smtp-Source: AGHT+IEfSr0Gudn4GDMIT4yBrRsINF1KjueLA3K/k+IuqK9TzELvKvXpXWwdPEKEfe5NbCoDvTjnCQ== X-Received: by 2002:a17:90b:528a:b0:2ee:5c9b:35c0 with SMTP id 98e67ed59e1d1-30100544832mr4123620a91.9.1741698115514; Tue, 11 Mar 2025 06:01:55 -0700 (PDT) Received: from wheely.local0.net ([118.208.151.101]) by smtp.gmail.com with ESMTPSA id 98e67ed59e1d1-2ff4e773dddsm11822318a91.12.2025.03.11.06.01.53 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 11 Mar 2025 06:01:55 -0700 (PDT) From: Nicholas Piggin To: qemu-devel@nongnu.org Cc: Nicholas Piggin , qemu-ppc@nongnu.org, BALATON Zoltan Subject: [PULL 69/72] ppc/amigaone: Add default environment Date: Tue, 11 Mar 2025 22:58:03 +1000 Message-ID: <20250311125815.903177-70-npiggin@gmail.com> X-Mailer: git-send-email 2.47.1 In-Reply-To: <20250311125815.903177-1-npiggin@gmail.com> References: <20250311125815.903177-1-npiggin@gmail.com> MIME-Version: 1.0 Received-SPF: pass client-ip=2607:f8b0:4864:20::1030; envelope-from=npiggin@gmail.com; helo=mail-pj1-x1030.google.com X-Spam_score_int: -20 X-Spam_score: -2.1 X-Spam_bar: -- X-Spam_report: (-2.1 / 5.0 requ) BAYES_00=-1.9, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_AU=-0.1, DKIM_VALID_EF=-0.1, FREEMAIL_FROM=0.001, RCVD_IN_DNSWL_NONE=-0.0001, SPF_HELO_NONE=0.001, SPF_PASS=-0.001 autolearn=ham autolearn_force=no X-Spam_action: no action X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: qemu-devel-bounces+qemu-devel=archiver.kernel.org@nongnu.org Sender: qemu-devel-bounces+qemu-devel=archiver.kernel.org@nongnu.org From: BALATON Zoltan Initialise empty NVRAM with default values. This also enables IDE UDMA mode in AmigaOS that is faster but has to be enabled in environment due to problems with real hardware but that does not affect emulation so we can use faster defaults here. Signed-off-by: BALATON Zoltan Reviewed-by: Nicholas Piggin Message-ID: <4d63f88191612329e0ca8102c7c0d4fc626dc372.1740673173.git.balaton@eik.bme.hu> Signed-off-by: Nicholas Piggin --- hw/ppc/amigaone.c | 37 ++++++++++++++++++++++++++++++++++++- 1 file changed, 36 insertions(+), 1 deletion(-) diff --git a/hw/ppc/amigaone.c b/hw/ppc/amigaone.c index feb2cf452c..1c6f2a944d 100644 --- a/hw/ppc/amigaone.c +++ b/hw/ppc/amigaone.c @@ -52,6 +52,28 @@ static const char dummy_fw[] = { #define NVRAM_ADDR 0xfd0e0000 #define NVRAM_SIZE (4 * KiB) +static char default_env[] = + "baudrate=115200\0" + "stdout=vga\0" + "stdin=ps2kbd\0" + "bootcmd=boota; menu; run menuboot_cmd\0" + "boot1=ide\0" + "boot2=cdrom\0" + "boota_timeout=3\0" + "ide_doreset=on\0" + "pci_irqa=9\0" + "pci_irqa_select=level\0" + "pci_irqb=10\0" + "pci_irqb_select=level\0" + "pci_irqc=11\0" + "pci_irqc_select=level\0" + "pci_irqd=7\0" + "pci_irqd_select=level\0" + "a1ide_irq=1111\0" + "a1ide_xfer=FFFF\0"; +#define CRC32_DEFAULT_ENV 0xb5548481 +#define CRC32_ALL_ZEROS 0x603b0489 + #define TYPE_A1_NVRAM "a1-nvram" OBJECT_DECLARE_SIMPLE_TYPE(A1NVRAMState, A1_NVRAM) @@ -94,7 +116,7 @@ static void nvram_realize(DeviceState *dev, Error **errp) { A1NVRAMState *s = A1_NVRAM(dev); void *p; - uint32_t *c; + uint32_t crc, *c; memory_region_init_rom_device(&s->mr, NULL, &nvram_ops, s, "nvram", NVRAM_SIZE, &error_fatal); @@ -113,12 +135,25 @@ static void nvram_realize(DeviceState *dev, Error **errp) return; } } + crc = crc32(0, p + 4, NVRAM_SIZE - 4); + if (crc == CRC32_ALL_ZEROS) { /* If env is uninitialized set default */ + *c = cpu_to_be32(CRC32_DEFAULT_ENV); + /* Also copies terminating \0 as env is terminated by \0\0 */ + memcpy(p + 4, default_env, sizeof(default_env)); + if (s->blk) { + blk_pwrite(s->blk, 0, sizeof(crc) + sizeof(default_env), p, 0); + } + return; + } if (*c == 0) { *c = cpu_to_be32(crc32(0, p + 4, NVRAM_SIZE - 4)); if (s->blk) { blk_pwrite(s->blk, 0, 4, p, 0); } } + if (be32_to_cpu(*c) != crc) { + warn_report("NVRAM checksum mismatch"); + } } static const Property nvram_properties[] = { From patchwork Tue Mar 11 12:58:04 2025 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Nicholas Piggin X-Patchwork-Id: 14011890 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.lore.kernel.org (Postfix) with ESMTPS id 179ABC28B2E for ; Tue, 11 Mar 2025 13:24:28 +0000 (UTC) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1trzKP-0007RK-EZ; Tue, 11 Mar 2025 09:07:26 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1trzFG-0006Hj-2C; Tue, 11 Mar 2025 09:02:09 -0400 Received: from mail-pj1-x1029.google.com ([2607:f8b0:4864:20::1029]) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_128_GCM_SHA256:128) (Exim 4.90_1) (envelope-from ) id 1trzFD-0000NY-UW; Tue, 11 Mar 2025 09:02:05 -0400 Received: by mail-pj1-x1029.google.com with SMTP id 98e67ed59e1d1-2ff6a98c638so10165510a91.0; Tue, 11 Mar 2025 06:02:02 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20230601; t=1741698119; x=1742302919; darn=nongnu.org; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to; bh=Iy9MYT8fdEi9vMpgSjXfvO+etPc3lGZwDZWPx6oNxPs=; b=ZgUxvN2GDTbONgbtd5S93LMiXrGOdwobqPLcLN7+1MoCUGQcGtc/FhwLP2ypxMK1Yz 50wEN3M04V9aIPdQ0mDt6QXDDgqAi40tSxFQJUnMuq7hqy1tQc3oBsXmBMsIC0OEYVXa RY+V0Hy8bjujuec9dnI5vEbqZyGPxcQ/cfzNWUT0TL0MK7lnd61IACmT7jtcmyPVFBGT 6CJJHGtEzuv+4NwJ3aVWt6Pgpj+pPUvXEj4rpjqmotQKzLD6r3ESdyMipxCJQApPjIlt PpLVZADgnGNPbdrFMFVqiFOqG9DNOvPAzUCblnsRWa4Bgpkjzdpc0RrgpzAjvPMRFJdx pRqA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1741698119; x=1742302919; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=Iy9MYT8fdEi9vMpgSjXfvO+etPc3lGZwDZWPx6oNxPs=; b=fw7rqkscA0T2kIeFxmEc68PYC0wgJtMnhSsWV5LyDOt7DalTwFhia5N37TZ74z2jLY 9J8up8I3NvoImNJ9/T2KtF2czz+JbYdcQTZHmU0K91vkBGC8wGa6RfPABjR64EdRx9ey IImgvBYrUTllp4lfvWpu74Ozp13/cKjEOGU27xAI3STYS2Ej8+cuuW49n6oIfovFC7Gq 2TJb755HaVdIGZ+godcyQlNberzK9GZHFEedfdDadQkWZhal5bRinElU1JrP4cQJ5LBx c1Dx0AeVNXQFxBTdFHHsHpHoWVfjrYD2idEwSTZCQwcLwJZ2C9oKSj1BSRwEkLzjwpcZ STNA== X-Forwarded-Encrypted: i=1; AJvYcCXYewsH9Tz2yTo3mHO1SGifXxjICjhJCQFcW5aVGKy+vpp3R+IuR7r02LB6p3Z1o1xWrDCjM8JffA==@nongnu.org X-Gm-Message-State: AOJu0YxCPQ78b4JJ0E0pQfG3KwgKuEAvD+zIhRy2OJnCS/FBc95CZQN2 th2unRDLJNHBl1tyzYJJMUe3YeVaEkT01aiWZLW1MQ6MyuCCHVrI6OLeuQ== X-Gm-Gg: ASbGncvOOzCmjlcACO+wafeaS0HME1mTGBDjmN9S3rZZH5J+RtPiXGCOO6/3LwH7XXG HKHTKO7C4006jnk+R2hmsbbUdRgEBtdvTQqU0yAiTdFZwyseB6XdU2ETfYbCpg0DpbUBECGoM3n 4ouSsgPf2xYToe1jaYo64SPNZxl5RFNhPYG3JEpCos8U/gWAvEzTg+L+jweeQRgrwQwLKVZ2c0X P88Ij1vMMqbXiK3VK5KEtMpVj9hspvEZmsjgEKgeQ9gLS6NJKUrg1wb3ak+qJgksZeAOAEq0iyC /ZcOZI5TV65w0/1grwL79tQ76alsr6kXwoycIpw+DmCLXEFh/VI= X-Google-Smtp-Source: AGHT+IFgqL9bbZ2fICseOPZfQrNrcT0fAz/HZJGis76AwygYFFwD63MWTP2pBrIZ4Xa8Fl8lXeX+CQ== X-Received: by 2002:a17:90b:3ec2:b0:2ee:9e06:7db0 with SMTP id 98e67ed59e1d1-2ff7ce6349emr28202121a91.11.1741698118226; Tue, 11 Mar 2025 06:01:58 -0700 (PDT) Received: from wheely.local0.net ([118.208.151.101]) by smtp.gmail.com with ESMTPSA id 98e67ed59e1d1-2ff4e773dddsm11822318a91.12.2025.03.11.06.01.55 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 11 Mar 2025 06:01:57 -0700 (PDT) From: Nicholas Piggin To: qemu-devel@nongnu.org Cc: Nicholas Piggin , qemu-ppc@nongnu.org, BALATON Zoltan Subject: [PULL 70/72] ppc/amigaone: Add kernel and initrd support Date: Tue, 11 Mar 2025 22:58:04 +1000 Message-ID: <20250311125815.903177-71-npiggin@gmail.com> X-Mailer: git-send-email 2.47.1 In-Reply-To: <20250311125815.903177-1-npiggin@gmail.com> References: <20250311125815.903177-1-npiggin@gmail.com> MIME-Version: 1.0 Received-SPF: pass client-ip=2607:f8b0:4864:20::1029; envelope-from=npiggin@gmail.com; helo=mail-pj1-x1029.google.com X-Spam_score_int: -20 X-Spam_score: -2.1 X-Spam_bar: -- X-Spam_report: (-2.1 / 5.0 requ) BAYES_00=-1.9, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_AU=-0.1, DKIM_VALID_EF=-0.1, FREEMAIL_FROM=0.001, RCVD_IN_DNSWL_NONE=-0.0001, SPF_HELO_NONE=0.001, SPF_PASS=-0.001 autolearn=ham autolearn_force=no X-Spam_action: no action X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: qemu-devel-bounces+qemu-devel=archiver.kernel.org@nongnu.org Sender: qemu-devel-bounces+qemu-devel=archiver.kernel.org@nongnu.org From: BALATON Zoltan Add support for -kernel, -initrd and -append command line options. Signed-off-by: BALATON Zoltan Reviewed-by: Nicholas Piggin Message-ID: <489b1be5d95d5153e924c95b0691b8b53f9ffb9e.1740673173.git.balaton@eik.bme.hu> Signed-off-by: Nicholas Piggin --- hw/ppc/amigaone.c | 113 +++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 112 insertions(+), 1 deletion(-) diff --git a/hw/ppc/amigaone.c b/hw/ppc/amigaone.c index 1c6f2a944d..359f5fa125 100644 --- a/hw/ppc/amigaone.c +++ b/hw/ppc/amigaone.c @@ -25,11 +25,14 @@ #include "system/qtest.h" #include "system/reset.h" #include "kvm_ppc.h" +#include "elf.h" #include /* for crc32 */ #define BUS_FREQ_HZ 100000000 +#define INITRD_MIN_ADDR 0x600000 + /* * Firmware binary available at * https://www.hyperion-entertainment.com/index.php/downloads?view=files&parent=28 @@ -178,12 +181,68 @@ static const TypeInfo nvram_types[] = { }; DEFINE_TYPES(nvram_types) +struct boot_info { + hwaddr entry; + hwaddr stack; + hwaddr bd_info; + hwaddr initrd_start; + hwaddr initrd_end; + hwaddr cmdline_start; + hwaddr cmdline_end; +}; + +/* Board info struct from U-Boot */ +struct bd_info { + uint32_t bi_memstart; + uint32_t bi_memsize; + uint32_t bi_flashstart; + uint32_t bi_flashsize; + uint32_t bi_flashoffset; + uint32_t bi_sramstart; + uint32_t bi_sramsize; + uint32_t bi_bootflags; + uint32_t bi_ip_addr; + uint8_t bi_enetaddr[6]; + uint16_t bi_ethspeed; + uint32_t bi_intfreq; + uint32_t bi_busfreq; + uint32_t bi_baudrate; +} QEMU_PACKED; + +static void create_bd_info(hwaddr addr, ram_addr_t ram_size) +{ + struct bd_info *bd = g_new0(struct bd_info, 1); + + bd->bi_memsize = cpu_to_be32(ram_size); + bd->bi_flashstart = cpu_to_be32(PROM_ADDR); + bd->bi_flashsize = cpu_to_be32(1); /* match what U-Boot detects */ + bd->bi_bootflags = cpu_to_be32(1); + bd->bi_intfreq = cpu_to_be32(11.5 * BUS_FREQ_HZ); + bd->bi_busfreq = cpu_to_be32(BUS_FREQ_HZ); + bd->bi_baudrate = cpu_to_be32(115200); + + cpu_physical_memory_write(addr, bd, sizeof(*bd)); +} + static void amigaone_cpu_reset(void *opaque) { PowerPCCPU *cpu = opaque; + CPUPPCState *env = &cpu->env; cpu_reset(CPU(cpu)); - cpu_ppc_tb_reset(&cpu->env); + if (env->load_info) { + struct boot_info *bi = env->load_info; + + env->gpr[1] = bi->stack; + env->gpr[2] = 1024; + env->gpr[3] = bi->bd_info; + env->gpr[4] = bi->initrd_start; + env->gpr[5] = bi->initrd_end; + env->gpr[6] = bi->cmdline_start; + env->gpr[7] = bi->cmdline_end; + env->nip = bi->entry; + } + cpu_ppc_tb_reset(env); } static void fix_spd_data(uint8_t *spd) @@ -205,6 +264,8 @@ static void amigaone_init(MachineState *machine) I2CBus *i2c_bus; uint8_t *spd_data; DriveInfo *di; + hwaddr loadaddr; + struct boot_info *bi = NULL; /* init CPU */ cpu = POWERPC_CPU(cpu_create(machine->cpu_type)); @@ -301,6 +362,56 @@ static void amigaone_init(MachineState *machine) } pci_ide_create_devs(PCI_DEVICE(object_resolve_path_component(via, "ide"))); pci_vga_init(pci_bus); + + if (!machine->kernel_filename) { + return; + } + + /* handle -kernel, -initrd, -append options and emulate U-Boot */ + bi = g_new0(struct boot_info, 1); + cpu->env.load_info = bi; + + loadaddr = MIN(machine->ram_size, 256 * MiB); + bi->bd_info = loadaddr - 8 * MiB; + create_bd_info(bi->bd_info, machine->ram_size); + bi->stack = bi->bd_info - 64 * KiB - 8; + + if (machine->kernel_cmdline && machine->kernel_cmdline[0]) { + size_t len = strlen(machine->kernel_cmdline); + + loadaddr = bi->bd_info + 1 * MiB; + cpu_physical_memory_write(loadaddr, machine->kernel_cmdline, len + 1); + bi->cmdline_start = loadaddr; + bi->cmdline_end = loadaddr + len + 1; /* including terminating '\0' */ + } + + sz = load_elf(machine->kernel_filename, NULL, NULL, NULL, + &bi->entry, &loadaddr, NULL, NULL, + ELFDATA2MSB, PPC_ELF_MACHINE, 0, 0); + if (sz <= 0) { + sz = load_uimage(machine->kernel_filename, &bi->entry, &loadaddr, + NULL, NULL, NULL); + } + if (sz <= 0) { + error_report("Could not load kernel '%s'", + machine->kernel_filename); + exit(1); + } + loadaddr += sz; + + if (machine->initrd_filename) { + loadaddr = ROUND_UP(loadaddr + 4 * MiB, 4 * KiB); + loadaddr = MAX(loadaddr, INITRD_MIN_ADDR); + sz = load_image_targphys(machine->initrd_filename, loadaddr, + bi->bd_info - loadaddr); + if (sz <= 0) { + error_report("Could not load initrd '%s'", + machine->initrd_filename); + exit(1); + } + bi->initrd_start = loadaddr; + bi->initrd_end = loadaddr + sz; + } } static void amigaone_machine_init(MachineClass *mc) From patchwork Tue Mar 11 12:58:05 2025 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: Nicholas Piggin X-Patchwork-Id: 14011883 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.lore.kernel.org (Postfix) with ESMTPS id CB1BAC282EC for ; Tue, 11 Mar 2025 13:22:19 +0000 (UTC) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1trzKY-0008CH-3O; Tue, 11 Mar 2025 09:07:34 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1trzFN-0006MY-TJ; Tue, 11 Mar 2025 09:02:15 -0400 Received: from mail-pl1-x62b.google.com ([2607:f8b0:4864:20::62b]) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_128_GCM_SHA256:128) (Exim 4.90_1) (envelope-from ) id 1trzFE-0000Nx-MI; Tue, 11 Mar 2025 09:02:10 -0400 Received: by mail-pl1-x62b.google.com with SMTP id d9443c01a7336-2255003f4c6so49959605ad.0; Tue, 11 Mar 2025 06:02:02 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20230601; t=1741698121; x=1742302921; darn=nongnu.org; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to; bh=elAFXUjF+R6E0+41mljzNOshBJCWfVTXW/A0lm/eOnM=; b=h0SwqOnbiIrZA3nYF4zqtGvYwIn3rpHrgX2XC9MxhsU45poFy58FFxMwy5fWpy3Hz8 qs0fWH26AA5O9AscypFWDLRI1142924qgJC5zHLKqnUzJP07JZpHpcqKnWWrXilSM3eV JmNdhx3ptMxFEaXGEBwAMcx8/fBIzG7V3OfVHgRy9l61dQnr85AsEn3CfQQe1JCIFSpK XCYiS6NSQEd/op0a6XsalPk69YKZz9OqU++rhR2HynxWTVIJmugT4CxwIbLSaN6L9rBJ gbwPx0G+Fn0KiV1nlLufRlJmzX0bxlPVfTEHbQkaqu6vU7p0BGZlQ+U9nkM8SBWwh2A6 4Nww== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1741698121; x=1742302921; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=elAFXUjF+R6E0+41mljzNOshBJCWfVTXW/A0lm/eOnM=; b=Geypf3Id3a6lYFvK2P2aligOQYz6GwbfhgM5FFMQJK+wRaHi/ofZw85cxgLTeBpwiS rlDJ7fWra84yDftRkxxVVGEYFkMjyo7mqQ4bG0uHwC+/RlYt8IxrmZ98GMvHhsqY/1KJ COp9j+BQlQQrPTxH8sCeo2hs2glu0HUM2IvfZ6QWzgHf7mV/1GamukUobLH6UWnDucUv wVTCQZX3LCkm8XnKwguuswUb8UFTU6pMdhJsr/utTFPE8XTIzGxWPmSgaDbw2l5uVGI+ 4fkDLmPi35ZYy1SYfVemh40miQZFd7Ad/OX1IVIHGV4Tcq6mXC+XylsM7XT9eIoRPDoC l90A== X-Forwarded-Encrypted: i=1; AJvYcCVaD2tT9Tj9fTdrupHGxgysO6exY1AiQfpEMUkhovngq+2u1tf0GYchYr81Q9SIvCgnV+rf3G6djw==@nongnu.org X-Gm-Message-State: AOJu0YylgSZ4PEtlS5B+Hvg2bhbsUb1LHUBxDNpZ8W4V1OHLF7sgdw6W 6l0hNr0HuOsd2Q707WM3WfT5XLJ+xgwIaVBI6SjVrA1giLEWhitQ6g+vOw== X-Gm-Gg: ASbGncvXxqvrlUmkVY0aZzZvCfKdCJpPeSqO0ciMue7GUzI661dpOp0MEOUi+NBbtej 4rJEiyqSDbrEzjJFBKm2QJsBKmu72d4qJ/V+C4+Fg/Ov3s0K9IWgOavH3V6K613kqIFYeNfnxTk Te36+0380gNEs3QNiSzQt615U7E64obvjR0eaCeDP6OJK3SF4TVXeJ0zZTahnM0PKWBqW3Ok3S2 3L5mJV3ERkutC5AB39gMChCbHnsqH9+4yfWScvuBlsgvs/RRvIpOM6sfWVG6AdxTlPuxsqu+Cl7 vYFPhN7Z7h+ghw5pA7M0rMY2SUF0d1SFsDe3AdUA92h7U6UvQzw= X-Google-Smtp-Source: AGHT+IEvfuD1NrKWI+2Dv0OL8sLBjxEo6/deJYw1ULxKFwwvAOvUHJYL0oPwf2abozxnkGOzQeBWUA== X-Received: by 2002:a17:90b:528a:b0:2ee:d824:b559 with SMTP id 98e67ed59e1d1-300ff34d5c3mr4672098a91.28.1741698121189; Tue, 11 Mar 2025 06:02:01 -0700 (PDT) Received: from wheely.local0.net ([118.208.151.101]) by smtp.gmail.com with ESMTPSA id 98e67ed59e1d1-2ff4e773dddsm11822318a91.12.2025.03.11.06.01.58 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 11 Mar 2025 06:02:00 -0700 (PDT) From: Nicholas Piggin To: qemu-devel@nongnu.org Cc: Nicholas Piggin , qemu-ppc@nongnu.org, BALATON Zoltan , =?utf-8?q?Philippe_Mathieu-Daud=C3=A9?= Subject: [PULL 71/72] ppc/amigaone: Add #defines for memory map constants Date: Tue, 11 Mar 2025 22:58:05 +1000 Message-ID: <20250311125815.903177-72-npiggin@gmail.com> X-Mailer: git-send-email 2.47.1 In-Reply-To: <20250311125815.903177-1-npiggin@gmail.com> References: <20250311125815.903177-1-npiggin@gmail.com> MIME-Version: 1.0 Received-SPF: pass client-ip=2607:f8b0:4864:20::62b; envelope-from=npiggin@gmail.com; helo=mail-pl1-x62b.google.com X-Spam_score_int: -20 X-Spam_score: -2.1 X-Spam_bar: -- X-Spam_report: (-2.1 / 5.0 requ) BAYES_00=-1.9, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_AU=-0.1, DKIM_VALID_EF=-0.1, FREEMAIL_FROM=0.001, RCVD_IN_DNSWL_NONE=-0.0001, SPF_HELO_NONE=0.001, SPF_PASS=-0.001 autolearn=ham autolearn_force=no X-Spam_action: no action X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: qemu-devel-bounces+qemu-devel=archiver.kernel.org@nongnu.org Sender: qemu-devel-bounces+qemu-devel=archiver.kernel.org@nongnu.org From: BALATON Zoltan Suggested-by: Nicholas Piggin Signed-off-by: BALATON Zoltan Reviewed-by: Philippe Mathieu-Daudé Reviewed-by: Nicholas Piggin Message-ID: <3b8e54ad9220d57e7b0a33f3570e880f26677ce8.1740673173.git.balaton@eik.bme.hu> Signed-off-by: Nicholas Piggin --- hw/ppc/amigaone.c | 20 ++++++++++++++------ 1 file changed, 14 insertions(+), 6 deletions(-) diff --git a/hw/ppc/amigaone.c b/hw/ppc/amigaone.c index 359f5fa125..483512125f 100644 --- a/hw/ppc/amigaone.c +++ b/hw/ppc/amigaone.c @@ -32,6 +32,14 @@ #define BUS_FREQ_HZ 100000000 #define INITRD_MIN_ADDR 0x600000 +#define INIT_RAM_ADDR 0x40000000 + +#define PCI_HIGH_ADDR 0x80000000 +#define PCI_HIGH_SIZE 0x7d000000 +#define PCI_LOW_ADDR 0xfd000000 +#define PCI_LOW_SIZE 0xe0000 + +#define ARTICIA_ADDR 0xfe000000 /* * Firmware binary available at @@ -287,7 +295,7 @@ static void amigaone_init(MachineState *machine) /* Firmware uses this area for startup */ mr = g_new(MemoryRegion, 1); memory_region_init_ram(mr, NULL, "init-cache", 32 * KiB, &error_fatal); - memory_region_add_subregion(get_system_memory(), 0x40000000, mr); + memory_region_add_subregion(get_system_memory(), INIT_RAM_ADDR, mr); } /* nvram */ @@ -322,7 +330,7 @@ static void amigaone_init(MachineState *machine) } /* Articia S */ - dev = sysbus_create_simple(TYPE_ARTICIA, 0xfe000000, NULL); + dev = sysbus_create_simple(TYPE_ARTICIA, ARTICIA_ADDR, NULL); i2c_bus = I2C_BUS(qdev_get_child_bus(dev, "smbus")); if (machine->ram_size > 512 * MiB) { @@ -339,12 +347,12 @@ static void amigaone_init(MachineState *machine) pci_mem = sysbus_mmio_get_region(SYS_BUS_DEVICE(dev), 1); mr = g_new(MemoryRegion, 1); memory_region_init_alias(mr, OBJECT(dev), "pci-mem-low", pci_mem, - 0, 0xe0000); - memory_region_add_subregion(get_system_memory(), 0xfd000000, mr); + 0, PCI_LOW_SIZE); + memory_region_add_subregion(get_system_memory(), PCI_LOW_ADDR, mr); mr = g_new(MemoryRegion, 1); memory_region_init_alias(mr, OBJECT(dev), "pci-mem-high", pci_mem, - 0x80000000, 0x7d000000); - memory_region_add_subregion(get_system_memory(), 0x80000000, mr); + PCI_HIGH_ADDR, PCI_HIGH_SIZE); + memory_region_add_subregion(get_system_memory(), PCI_HIGH_ADDR, mr); pci_bus = PCI_BUS(qdev_get_child_bus(dev, "pci.0")); /* VIA VT82c686B South Bridge (multifunction PCI device) */ From patchwork Tue Mar 11 12:58:06 2025 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: Nicholas Piggin X-Patchwork-Id: 14011893 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.lore.kernel.org (Postfix) with ESMTPS id 35A97C282EC for ; Tue, 11 Mar 2025 13:26:01 +0000 (UTC) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1trzKm-0001LS-KB; Tue, 11 Mar 2025 09:07:48 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1trzFL-0006LS-Pr; Tue, 11 Mar 2025 09:02:14 -0400 Received: from mail-pj1-x102d.google.com ([2607:f8b0:4864:20::102d]) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_128_GCM_SHA256:128) (Exim 4.90_1) (envelope-from ) id 1trzFI-0000Ok-LQ; Tue, 11 Mar 2025 09:02:10 -0400 Received: by mail-pj1-x102d.google.com with SMTP id 98e67ed59e1d1-2fea47bcb51so11359335a91.2; Tue, 11 Mar 2025 06:02:05 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20230601; t=1741698124; x=1742302924; darn=nongnu.org; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to; bh=tAN+HnepXEYeETm6X7cQEpTvdXTBx3EHSfsdgopHuPI=; b=JJZbh2l0Ph+pAKrU4cJQj5kkoQ2p/UBym7ImFEWHMokTBORjMacpx5KSj1cckOxDI9 gPjPah65MNWgo8B0TkuAjAPWYr8tFTuj/CPkDsnhlnz1bUkBb7LAa3WTxCVkF3677u94 3O9f/ZjhVj186sd9u2dPK15H9RTD8rCkWzJan+xBaNtmZymCE5RiEkmoEt2m4wLIkNrD zOHoJ23R/KKzfJx2UiQC2GgiPLLOkVBZ5+Dwt5iB5jRcqy7NB6gILSLn/K2rmQuNF7mt YYZRUdVCdLUIi2ATqVuvnIbr/5gO3R3qTife0uk575D7hhCTvAPvWGxGfQHhEiaLUBty pv6Q== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1741698124; x=1742302924; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=tAN+HnepXEYeETm6X7cQEpTvdXTBx3EHSfsdgopHuPI=; b=NgwPyKNLEuhZM8xXGdWoJ50ckNvYMKG5VTztR/pvHuHfnXvOTJiujkWUuiF7yDMT0h E7C5wq8kSawLCLyTelwve7Q1xtrCqSS/XcsnqgvrQONKaYDdOqu0MsCZmqEdahRodpzT dutR785tqpSh/p7BGvWCoOXOAORDUKZV5rou5Qb7Y6fPzrF0f29H9QGKFN8/xIEBL3/K CNrTu3IdVNPiOT+SD1GuGaqNDgsha3wR+iJqj43HIfkUJraNVLgxuJX2lpFoAyOqVTQf 7iEvO/m4biaMacIKiXsk+2Gr+cgBkSXszIFYZeSDMeyj1PA2ruZgGWMqWgBHA4MPn9X7 tuFw== X-Forwarded-Encrypted: i=1; AJvYcCWyLr06BuYEZIeqJ5U91oO8afNWxpAGWiSdTETwc8x7tDmp5ymYjc5oBOxOLp9dD5tcZxaCUHYumQ==@nongnu.org X-Gm-Message-State: AOJu0Yx6h9FCt/7fHHvFiSxPUJZ1lfe+Miml5hwqEtQW1jfSoO2lpiFN XAK1WL0i5LdtEANLgohsEbveM2FPkPuKF9JZW/iS5vXjqharcWDSHHtKpA== X-Gm-Gg: ASbGncuxvlkwt3AR5OQAFx1taCNqTZtURCgPDMASyen8iD3P1RfQDNXCQoCXR9oAdL8 JOTYKnDq0HUXYUEYs9W934+jF6A4Kgclvi3m7P5Y7Xmf+EaooUmZrKi0lM4NhMTQR6YW9HjBrG3 Hu7JXIBLLingwLkcTIAEk+LUj1NMw3t7tjOjHmw9HJi/eYM3gBWYN9pePGY7X64Al/6BKeMD3MC SmKPy96t7/CbefBxlTJWlmiFgGw+PC7kYNj4M8iGtJ2KZHlCYTDU0CEn9Du74cH4Bo6q5NARI15 Vqn41hyp+EtryMEoH+XAnsf4e+WV4cfvTBf6oBeoW4q4FvH/iFs= X-Google-Smtp-Source: AGHT+IEhxKc7QK2c+anq0I1mojZLWvDqfhA2vOV9L7tDz2FcGcafQoam3LJNySdsaQeq/PjJ9Lg/jw== X-Received: by 2002:a17:90b:2883:b0:2ff:52e1:c4a1 with SMTP id 98e67ed59e1d1-2ff7cf128acmr27247430a91.24.1741698123882; Tue, 11 Mar 2025 06:02:03 -0700 (PDT) Received: from wheely.local0.net ([118.208.151.101]) by smtp.gmail.com with ESMTPSA id 98e67ed59e1d1-2ff4e773dddsm11822318a91.12.2025.03.11.06.02.01 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 11 Mar 2025 06:02:03 -0700 (PDT) From: Nicholas Piggin To: qemu-devel@nongnu.org Cc: Nicholas Piggin , qemu-ppc@nongnu.org, BALATON Zoltan Subject: [PULL 72/72] docs/system/ppc/amigang.rst: Update for NVRAM emulation Date: Tue, 11 Mar 2025 22:58:06 +1000 Message-ID: <20250311125815.903177-73-npiggin@gmail.com> X-Mailer: git-send-email 2.47.1 In-Reply-To: <20250311125815.903177-1-npiggin@gmail.com> References: <20250311125815.903177-1-npiggin@gmail.com> MIME-Version: 1.0 Received-SPF: pass client-ip=2607:f8b0:4864:20::102d; envelope-from=npiggin@gmail.com; helo=mail-pj1-x102d.google.com X-Spam_score_int: -20 X-Spam_score: -2.1 X-Spam_bar: -- X-Spam_report: (-2.1 / 5.0 requ) BAYES_00=-1.9, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_AU=-0.1, DKIM_VALID_EF=-0.1, FREEMAIL_FROM=0.001, RCVD_IN_DNSWL_NONE=-0.0001, SPF_HELO_NONE=0.001, SPF_PASS=-0.001 autolearn=ham autolearn_force=no X-Spam_action: no action X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: qemu-devel-bounces+qemu-devel=archiver.kernel.org@nongnu.org Sender: qemu-devel-bounces+qemu-devel=archiver.kernel.org@nongnu.org From: BALATON Zoltan Add NVRAM and hint on how to make it persistent. Also update Linux boot section which should now boot automatically with the new NVRAM defaults so manual settings in menu may not be needed normally. Signed-off-by: BALATON Zoltan Reviewed-by: Nicholas Piggin Message-ID: <20250304205926.87E364E6010@zero.eik.bme.hu> Signed-off-by: Nicholas Piggin --- docs/system/ppc/amigang.rst | 17 +++++++++-------- 1 file changed, 9 insertions(+), 8 deletions(-) diff --git a/docs/system/ppc/amigang.rst b/docs/system/ppc/amigang.rst index e2c9cb74b7..21bb14ed09 100644 --- a/docs/system/ppc/amigang.rst +++ b/docs/system/ppc/amigang.rst @@ -21,6 +21,7 @@ Emulated devices * VIA VT82C686B south bridge * PCI VGA compatible card (guests may need other card instead) * PS/2 keyboard and mouse + * 4 KiB NVRAM (use ``-drive if=mtd,format=raw,file=nvram.bin`` to keep contents persistent) Firmware -------- @@ -54,14 +55,14 @@ To boot the system run: -cdrom "A1 Linux Net Installer.iso" \ -device ati-vga,model=rv100,romfile=VGABIOS-lgpl-latest.bin -From the firmware menu that appears select ``Boot sequence`` → -``Amiga Multiboot Options`` and set ``Boot device 1`` to -``Onboard VIA IDE CDROM``. Then hit escape until the main screen appears again, -hit escape once more and from the exit menu that appears select either -``Save settings and exit`` or ``Use settings for this session only``. It may -take a long time loading the kernel into memory but eventually it boots and the -installer becomes visible. The ``ati-vga`` RV100 emulation is not -complete yet so only frame buffer works, DRM and 3D is not available. +If a firmware menu appears, select ``Boot sequence`` → ``Amiga Multiboot Options`` +and set ``Boot device 1`` to ``Onboard VIA IDE CDROM``. Then hit escape until +the main screen appears again, hit escape once more and from the exit menu that +appears select either ``Save settings and exit`` or ``Use settings for this +session only``. It may take a long time loading the kernel into memory but +eventually it boots and the installer becomes visible. The ``ati-vga`` RV100 +emulation is not complete yet so only frame buffer works, DRM and 3D is not +available. Genesi/bPlan Pegasos II (``pegasos2``) ======================================