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;
 }
 

Reply via email to