diff options
author | njl <njl@FreeBSD.org> | 2004-10-05 20:41:44 +0000 |
---|---|---|
committer | njl <njl@FreeBSD.org> | 2004-10-05 20:41:44 +0000 |
commit | 346ca0947871dd5b7b8dd9883a923be9c8f1dcce (patch) | |
tree | afb3659e8f668bb9f7c32301d502301318d998be /sys/dev/acpica | |
parent | 2094122f8670d9cff4fb4a42eba295970cd9522f (diff) | |
download | FreeBSD-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.c | 50 |
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); } |