Module Name: src Committed By: martin Date: Tue Nov 12 13:24:01 UTC 2024
Modified Files: src/sys/dev/acpi: acpi_dev.c Log Message: PR 58817: allow userland access to the TCPA. Patch from Jared. To generate a diff of this commit: cvs rdiff -u -r1.2 -r1.3 src/sys/dev/acpi/acpi_dev.c Please note that diffs are not public domain; they are subject to the copyright notices on the relevant files.
Modified files: Index: src/sys/dev/acpi/acpi_dev.c diff -u src/sys/dev/acpi/acpi_dev.c:1.2 src/sys/dev/acpi/acpi_dev.c:1.3 --- src/sys/dev/acpi/acpi_dev.c:1.2 Sat Jul 24 11:36:41 2021 +++ src/sys/dev/acpi/acpi_dev.c Tue Nov 12 13:24:01 2024 @@ -1,4 +1,4 @@ -/* $NetBSD: acpi_dev.c,v 1.2 2021/07/24 11:36:41 jmcneill Exp $ */ +/* $NetBSD: acpi_dev.c,v 1.3 2024/11/12 13:24:01 martin Exp $ */ /*- * Copyright (c) 2020 Jared McNeill <jmcne...@invisible.ca> @@ -27,7 +27,7 @@ */ #include <sys/cdefs.h> -__KERNEL_RCSID(0, "$NetBSD: acpi_dev.c,v 1.2 2021/07/24 11:36:41 jmcneill Exp $"); +__KERNEL_RCSID(0, "$NetBSD: acpi_dev.c,v 1.3 2024/11/12 13:24:01 martin Exp $"); #include <sys/param.h> #include <sys/conf.h> @@ -151,6 +151,8 @@ acpi_find_table(ACPI_PHYSICAL_ADDRESS pa ACPI_PHYSICAL_ADDRESS *paddr, uint32_t *plen) { ACPI_TABLE_DESC *tdesc; + ACPI_TABLE_TCPA_HDR *tcpa = NULL; + size_t tcpa_tdesc_len = 0; bool found_table; uint32_t i; @@ -171,13 +173,61 @@ acpi_find_table(ACPI_PHYSICAL_ADDRESS pa tdesc = &AcpiGbl_RootTableList.Tables[i]; if (pa >= tdesc->Address && pa < tdesc->Address + tdesc->Length) { + + /* + * allow access to all root table objects + */ *paddr = tdesc->Address; *plen = tdesc->Length; found_table = true; break; + } else if (memcmp(tdesc->Signature.Ascii, ACPI_SIG_TCPA, 4) + == 0) { + + /* + * allow acces to TCPA (which requires mapping) + */ + + /* duplicate TCPA table? buggy firmware? */ + if (tcpa != NULL && tcpa_tdesc_len > 0) + AcpiOsUnmapMemory(tcpa, tcpa_tdesc_len); + + tcpa = (ACPI_TABLE_TCPA_HDR*) + AcpiOsMapMemory(tdesc->Address, tdesc->Length); + if (tcpa != NULL) + tcpa_tdesc_len = tdesc->Length; } } + + if (!found_table && tcpa != NULL) { + ACPI_PHYSICAL_ADDRESS tcpa_addr = 0; + uint32_t tcpa_len = 0; + + if (tcpa->PlatformClass == ACPI_TCPA_CLIENT_TABLE) { + ACPI_TABLE_TCPA_CLIENT *t = + (ACPI_TABLE_TCPA_CLIENT *)(tcpa+1); + tcpa_addr = t->LogAddress; + tcpa_len = t->MinimumLogLength; + } else if (tcpa->PlatformClass == ACPI_TCPA_SERVER_TABLE) { + ACPI_TABLE_TCPA_SERVER *t = + (ACPI_TABLE_TCPA_SERVER *)(tcpa+1); + tcpa_addr = t->LogAddress; + tcpa_len = t->MinimumLogLength; + } + if (tcpa_len != 0 && + pa >= tcpa_addr && + pa < tcpa_addr + tcpa_len) { + *paddr = tcpa_addr; + *plen = tcpa_len; + found_table = true; + } + } + + if (tcpa != NULL && tcpa_tdesc_len != 0) + AcpiOsUnmapMemory(tcpa, tcpa_tdesc_len); + AcpiUtReleaseMutex(ACPI_MTX_TABLES); + return found_table; }