From nobody Tue Nov 26 16:38:46 2024 Delivered-To: importer@patchew.org Authentication-Results: mx.zohomail.com; spf=pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org; dmarc=pass(p=none dis=none) header.from=nongnu.org ARC-Seal: i=1; a=rsa-sha256; t=1707142971; cv=none; d=zohomail.com; s=zohoarc; b=HoFSnh7wiWI2w3ajVFzEs+7Zohv4iGBqhZ+5fQi6JRGKNCUKiQDD/H4nUsN33Pc+X33OxBgzORq1cl4TD56n2dTxDhJpW17wVPiBC+l5UjGnoMaAYImvDwpr7DWzL36d6vjQa4NUlJ4piq3FG62dlqhGR+SXfrTfB0dz4Bdr9GE= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zohomail.com; s=zohoarc; t=1707142971; h=Content-Type:Content-Transfer-Encoding:Cc:Cc:Date:Date:From:From:In-Reply-To:List-Subscribe:List-Post:List-Id:List-Archive:List-Help:List-Unsubscribe:MIME-Version:Message-ID:Reply-To:Reply-To:References:Sender:Subject:Subject:To:To:Message-Id; bh=tlKUuIuYucBYepOlrwXlErWvcTaQSer6TJWCXRFhPrA=; b=kHvZcibKpINRI8alph3rr/2Nv4jo7u+sMAhDpYslK8yyWhnWeFBrpIwcfSmkAbwwwA7tKNoPbfjbQV0/H0hP+hxJ7zl4XdL4kZOEVCfwB3Mr8t9VwPsVHCpIeMan6Ty7askPU539UmEXa4uGwe4+PM5k4lQWJ8eutZvJNjrAYu0= ARC-Authentication-Results: i=1; mx.zohomail.com; spf=pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org; dmarc=pass header.from= (p=none dis=none) Return-Path: Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) by mx.zohomail.com with SMTPS id 1707142971230641.4186870745494; Mon, 5 Feb 2024 06:22:51 -0800 (PST) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1rWzrw-0007Lc-Us; Mon, 05 Feb 2024 09:22:44 -0500 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 1rWzrw-0007LI-4V for qemu-devel@nongnu.org; Mon, 05 Feb 2024 09:22:44 -0500 Received: from frasgout.his.huawei.com ([185.176.79.56]) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1rWzrt-00051A-PK for qemu-devel@nongnu.org; Mon, 05 Feb 2024 09:22:43 -0500 Received: from mail.maildlp.com (unknown [172.18.186.231]) by frasgout.his.huawei.com (SkyGuard) with ESMTP id 4TT7mb4xTgz6J66m; Mon, 5 Feb 2024 22:19:27 +0800 (CST) Received: from lhrpeml500005.china.huawei.com (unknown [7.191.163.240]) by mail.maildlp.com (Postfix) with ESMTPS id F2A0D1404F5; Mon, 5 Feb 2024 22:22:39 +0800 (CST) Received: from SecurePC-101-06.china.huawei.com (10.122.247.231) by lhrpeml500005.china.huawei.com (7.191.163.240) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256) id 15.1.2507.35; Mon, 5 Feb 2024 14:22:39 +0000 To: , CC: Igor Mammedov , Ani Sinha , Shannon Zhao , Dongjiu Geng , , "Michael S . Tsirkin" , Ira Weiny , Peter Maydell , Fan Ni , Marcel Apfelbaum Subject: [RFC PATCH 06/11] acpi: pci/cxl: Stash the OSC control parameters. Date: Mon, 5 Feb 2024 14:19:35 +0000 Message-ID: <20240205141940.31111-7-Jonathan.Cameron@huawei.com> X-Mailer: git-send-email 2.39.2 In-Reply-To: <20240205141940.31111-1-Jonathan.Cameron@huawei.com> References: <20240205141940.31111-1-Jonathan.Cameron@huawei.com> MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable X-Originating-IP: [10.122.247.231] X-ClientProxiedBy: lhrpeml500004.china.huawei.com (7.191.163.9) To lhrpeml500005.china.huawei.com (7.191.163.240) Received-SPF: pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) client-ip=209.51.188.17; envelope-from=qemu-devel-bounces+importer=patchew.org@nongnu.org; helo=lists.gnu.org; Received-SPF: pass client-ip=185.176.79.56; envelope-from=jonathan.cameron@huawei.com; helo=frasgout.his.huawei.com X-Spam_score_int: -41 X-Spam_score: -4.2 X-Spam_bar: ---- X-Spam_report: (-4.2 / 5.0 requ) BAYES_00=-1.9, RCVD_IN_DNSWL_MED=-2.3, RCVD_IN_MSPIKE_H5=0.001, RCVD_IN_MSPIKE_WL=0.001, SPF_HELO_NONE=0.001, SPF_PASS=-0.001, T_SCC_BODY_TEXT_LINE=-0.01 autolearn=ham autolearn_force=no X-Spam_action: no action X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Reply-to: Jonathan Cameron From: Jonathan Cameron via Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: qemu-devel-bounces+importer=patchew.org@nongnu.org X-ZM-MESSAGEID: 1707142972846100003 Content-Type: text/plain; charset="utf-8" Allow QEMU to know what was successfully requested by the OS via _OSC. Note this handling is very minimal and assumes last written Control parameters were accepted (which they should be if the OS is obeying the rules for negotiating this stuff). Signed-off-by: Jonathan Cameron --- include/hw/acpi/ghes.h | 3 +++ hw/acpi/cxl.c | 16 +++++++++++++++ hw/acpi/ghes-stub.c | 10 +++++++++ hw/acpi/ghes.c | 44 ++++++++++++++++++++++++++++++++++++++++ hw/arm/virt-acpi-build.c | 41 ++++++++++++++++++++++++++++++++++++- 5 files changed, 113 insertions(+), 1 deletion(-) diff --git a/include/hw/acpi/ghes.h b/include/hw/acpi/ghes.h index 4f1ab1a73a..3210c19c14 100644 --- a/include/hw/acpi/ghes.h +++ b/include/hw/acpi/ghes.h @@ -66,6 +66,7 @@ enum { typedef struct AcpiGhesState { uint64_t ghes_addr_le; bool present; /* True if GHES is present at all on this board */ + uint64_t pci_osc_addr_le; } AcpiGhesState; =20 void build_ghes_error_table(GArray *hardware_errors, BIOSLinker *linker); @@ -82,4 +83,6 @@ int acpi_ghes_record_errors(uint8_t notify, uint64_t erro= r_physical_addr); * safe to call acpi_ghes_record_errors() to record a memory error. */ bool acpi_ghes_present(void); +bool acpi_fw_first_pci(void); +bool acpi_fw_first_cxl_mem(void); #endif diff --git a/hw/acpi/cxl.c b/hw/acpi/cxl.c index 1d6dadbddd..2ce3488943 100644 --- a/hw/acpi/cxl.c +++ b/hw/acpi/cxl.c @@ -228,11 +228,27 @@ static Aml *__build_cxl_osc_method(bool fw_first) Aml *method, *if_uuid, *else_uuid, *if_arg1_not_1, *if_cxl, *if_caps_m= asked; Aml *a_ctrl =3D aml_local(0); Aml *a_cdw1 =3D aml_name("CDW1"); + Aml *cxl_osc_mem =3D aml_local(1); Aml *cxl_ctrl =3D aml_local(2); =20 + Aml *field; + method =3D aml_method("_OSC", 4, AML_NOTSERIALIZED); /* CDW1 is used for the return value so is present whether or not a ma= tch occurs */ aml_append(method, aml_create_dword_field(aml_arg(3), aml_int(0), "CDW= 1")); + if (acpi_ghes_present()) { + aml_append(method, aml_store(aml_name("COSC"), cxl_osc_mem)); + aml_append(method, aml_operation_region("CXLA", AML_SYSTEM_MEMORY, + cxl_osc_mem, 64)); + + field =3D aml_field("CXLA", AML_DWORD_ACC, AML_NOLOCK, AML_PRESERV= E); + aml_append(field, aml_named_field("ODW1", 32)); + aml_append(field, aml_named_field("ODW2", 32)); + aml_append(method, field); + /* Store the value for querying later */ + aml_append(method, aml_store(aml_name("CTRL"), aml_name("ODW1"))); + aml_append(method, aml_store(aml_name("CTRC"), aml_name("ODW2"))); + } =20 /* * Generate shared section between: diff --git a/hw/acpi/ghes-stub.c b/hw/acpi/ghes-stub.c index c315de1802..1ad7b9f776 100644 --- a/hw/acpi/ghes-stub.c +++ b/hw/acpi/ghes-stub.c @@ -20,3 +20,13 @@ bool acpi_ghes_present(void) { return false; } + +bool acpi_fw_first_pci(void) +{ + return false; +} + +bool acpi_fw_first_cxl_mem(void) +{ + return false; +} diff --git a/hw/acpi/ghes.c b/hw/acpi/ghes.c index 5b8bc6eeb4..9f99202e1f 100644 --- a/hw/acpi/ghes.c +++ b/hw/acpi/ghes.c @@ -462,3 +462,47 @@ bool acpi_ghes_present(void) ags =3D &acpi_ged_state->ghes_state; return ags->present; } + +bool acpi_fw_first_pci(void) +{ + if (acpi_ghes_present()) { + AcpiGhesState *ags =3D + &ACPI_GED(object_resolve_path_type("", TYPE_ACPI_GED, + NULL))->ghes_state; + uint32_t pci_osc; + + cpu_physical_memory_read(le64_to_cpu(ags->pci_osc_addr_le), + &pci_osc, sizeof(pci_osc)); + if (pci_osc =3D=3D 0) { + printf("OSC not called yet\n"); + return true; /* OSC not run yet */ + } + printf("OSC has been called %x\n", pci_osc); + return !(pci_osc & (1 << 3)); + } + return false; +} + +bool acpi_fw_first_cxl_mem(void) +{ + if (!acpi_fw_first_pci()) { + return false; + } + if (acpi_ghes_present()) { + AcpiGhesState *ags =3D + &ACPI_GED(object_resolve_path_type("", TYPE_ACPI_GED, + NULL))->ghes_state; + uint32_t cxl_osc; + + cpu_physical_memory_read(le64_to_cpu(ags->pci_osc_addr_le) + + sizeof(uint32_t), + &cxl_osc, sizeof(cxl_osc)); + if (cxl_osc =3D=3D 0) { + printf("CXL OSC not called yet or memory error not requested\n= "); + return true; /* OSC not run yet */ + } + printf("OSC has been called %x\n", cxl_osc); + return !(cxl_osc & (1 << 0)); + } + return false; +} diff --git a/hw/arm/virt-acpi-build.c b/hw/arm/virt-acpi-build.c index 297fa5f8b2..93ec095b0f 100644 --- a/hw/arm/virt-acpi-build.c +++ b/hw/arm/virt-acpi-build.c @@ -916,6 +916,7 @@ build_dsdt(GArray *table_data, BIOSLinker *linker, Virt= MachineState *vms) const int *irqmap =3D vms->irqmap; AcpiTable table =3D { .sig =3D "DSDT", .rev =3D 2, .oem_id =3D vms->oe= m_id, .oem_table_id =3D vms->oem_table_id }; + int mem_addr_offset; =20 acpi_table_begin(&table, table_data); dsdt =3D init_aml_allocator(); @@ -972,6 +973,16 @@ build_dsdt(GArray *table_data, BIOSLinker *linker, Vir= tMachineState *vms) /* copy AML table into ACPI tables blob */ g_array_append_vals(table_data, dsdt->buf->data, dsdt->buf->len); =20 + /* Outside of the DSDT creation because we need the final address */ + mem_addr_offset =3D build_append_named_dword(table_data, "COSC"); + /* Patch COSC to point to the cxl-osc FW_CFG file */ + bios_linker_loader_add_pointer(linker, ACPI_BUILD_TABLE_FILE, + mem_addr_offset, sizeof(uint32_t), + "etc/acpi/cxl-osc", 0); + /* Store address of cxl-osc FW_CFG file in cxl-osc-addr FW_CFG file */ + bios_linker_loader_write_pointer(linker, "etc/acpi/cxl-osc-addr", 0, + sizeof(uint64_t), "etc/acpi/cxl-osc",= 0); + acpi_table_end(linker, &table); free_aml_allocator(); } @@ -995,6 +1006,8 @@ static void acpi_align_size(GArray *blob, unsigned ali= gn) g_array_set_size(blob, ROUND_UP(acpi_data_len(blob), align)); } =20 +static GArray *test; + static void virt_acpi_build(VirtMachineState *vms, AcpiBuildTables *tables) { @@ -1004,6 +1017,10 @@ void virt_acpi_build(VirtMachineState *vms, AcpiBuil= dTables *tables) GArray *tables_blob =3D tables->table_data; MachineState *ms =3D MACHINE(vms); =20 + /* Load the cxl-osc FW_CFG file into guest memory */ + bios_linker_loader_alloc(tables->linker, "etc/acpi/cxl-osc", + test, 64, false); + table_offsets =3D g_array_new(false, true /* clear */, sizeof(uint32_t)); =20 @@ -1202,6 +1219,10 @@ void virt_acpi_setup(VirtMachineState *vms) =20 build_state =3D g_malloc0(sizeof *build_state); =20 + test =3D g_array_new(false, true, 4); + acpi_data_push(test, sizeof(uint64_t)); + *((uint64_t *)test->data) =3D 0xdeadbeefdeadbeef; + acpi_build_tables_init(&tables); virt_acpi_build(vms, &tables); =20 @@ -1234,7 +1255,25 @@ void virt_acpi_setup(VirtMachineState *vms) virt_acpi_build_reset(build_state); vmstate_register(NULL, 0, &vmstate_virt_acpi_build, build_state); =20 - /* Cleanup tables but don't free the memory: we track it + if (acpi_ghes_present()) { + AcpiGhesState *ags =3D + &ACPI_GED(object_resolve_path_type("", TYPE_ACPI_GED, + NULL))->ghes_state; + + /* Add a cxl-osc FW_CFG file that will be used to stash osc outcom= es */ + fw_cfg_add_file(vms->fw_cfg, "etc/acpi/cxl-osc", + test->data, test->len); + /* + * Add a cxl-osc-addr FW_CFG file that will be used to get to the + * address of cxl-osc FW_CFG file. Can be written by FW. + */ + fw_cfg_add_file_callback(vms->fw_cfg, "etc/acpi/cxl-osc-addr", + NULL, NULL, NULL, + &ags->pci_osc_addr_le, sizeof(uint64_t), + false); + } + /* + * Cleanup tables but don't free the memory: we track it * in build_state. */ acpi_build_tables_cleanup(&tables, false); --=20 2.39.2