summaryrefslogtreecommitdiffstats
path: root/sys/dev/acpica
diff options
context:
space:
mode:
authornjl <njl@FreeBSD.org>2004-10-05 20:41:44 +0000
committernjl <njl@FreeBSD.org>2004-10-05 20:41:44 +0000
commit346ca0947871dd5b7b8dd9883a923be9c8f1dcce (patch)
treeafb3659e8f668bb9f7c32301d502301318d998be /sys/dev/acpica
parent2094122f8670d9cff4fb4a42eba295970cd9522f (diff)
downloadFreeBSD-src-346ca0947871dd5b7b8dd9883a923be9c8f1dcce.zip
FreeBSD-src-346ca0947871dd5b7b8dd9883a923be9c8f1dcce.tar.gz
When the user overrides the DSDT, replace any SSDTs with a simple no-op
table. acpidump(8) concatenates the body of the DSDT and SSDTs so an edited ASL will contain all the necessary information. We can't use a completely empty table since ACPI-CA reports this as a problem. MFC after: 3 days
Diffstat (limited to 'sys/dev/acpica')
-rw-r--r--sys/dev/acpica/Osd/OsdTable.c50
1 files changed, 40 insertions, 10 deletions
diff --git a/sys/dev/acpica/Osd/OsdTable.c b/sys/dev/acpica/Osd/OsdTable.c
index 298c965..0ce25d2 100644
--- a/sys/dev/acpica/Osd/OsdTable.c
+++ b/sys/dev/acpica/Osd/OsdTable.c
@@ -30,17 +30,25 @@
* ACPI Table interfaces
*/
-#include "acpi.h"
-
+#include <sys/param.h>
+#include <sys/endian.h>
#include <sys/kernel.h>
#include <sys/linker.h>
+#include "acpi.h"
+#include <contrib/dev/acpica/actables.h>
+
#undef _COMPONENT
#define _COMPONENT ACPI_TABLES
static char acpi_osname[128];
TUNABLE_STR("hw.acpi.osname", acpi_osname, sizeof(acpi_osname));
+static struct {
+ ACPI_TABLE_HEADER_DEF
+ uint32_t no_op;
+} __packed fake_ssdt;
+
ACPI_STATUS
AcpiOsPredefinedOverride (
const ACPI_PREDEFINED_NAMES *InitVal,
@@ -63,20 +71,42 @@ AcpiOsTableOverride (
ACPI_TABLE_HEADER *ExistingTable,
ACPI_TABLE_HEADER **NewTable)
{
- caddr_t acpi_dsdt, p;
+ caddr_t acpi_dsdt, p;
if (ExistingTable == NULL || NewTable == NULL)
- return(AE_BAD_PARAMETER);
+ return (AE_BAD_PARAMETER);
+ /* If we're not overriding the DSDT, just return. */
*NewTable = NULL;
- if (strncmp(ExistingTable->Signature, "DSDT", 4) != 0)
- return(AE_OK);
if ((acpi_dsdt = preload_search_by_type("acpi_dsdt")) == NULL)
- return(AE_OK);
+ return (AE_OK);
if ((p = preload_search_info(acpi_dsdt, MODINFO_ADDR)) == NULL)
- return(AE_OK);
+ return (AE_OK);
+
+ /*
+ * Override the DSDT with the user's custom version. Override the
+ * contents of any SSDTs with a simple no-op table since the user's
+ * DSDT is expected to contain their contents as well.
+ */
+ if (strncmp(ExistingTable->Signature, "DSDT", 4) == 0) {
+ printf("ACPI: overriding DSDT/SSDT with custom table\n");
+ *NewTable = *(void **)p;
+ } else if (strncmp(ExistingTable->Signature, "SSDT", 4) == 0) {
+ if (fake_ssdt.Length == 0) {
+ sprintf(fake_ssdt.Signature, "%.4s", "SSDT");
+ fake_ssdt.Length = htole32(sizeof(fake_ssdt));
+ fake_ssdt.Revision = 2;
+ fake_ssdt.Checksum = 0;
+ sprintf(fake_ssdt.OemId, "%.6s", "FBSD ");
+ sprintf(fake_ssdt.OemTableId, "%.8s", "NullSSDT");
+ fake_ssdt.OemRevision = htole32(1);
+ sprintf(fake_ssdt.AslCompilerId, "%.4s", "FBSD");
+ fake_ssdt.AslCompilerRevision = htole32(1);
+ fake_ssdt.no_op = htole32(0x005c0310); /* Scope(\) */
+ fake_ssdt.Checksum -= AcpiTbChecksum(&fake_ssdt, sizeof(fake_ssdt));
+ }
+ *NewTable = (void *)&fake_ssdt;
+ }
- *NewTable = *(void **)p;
- printf("ACPI: DSDT was overridden.\n");
return (AE_OK);
}
OpenPOWER on IntegriCloud