diff options
-rw-r--r-- | sys/dev/acpica/acpi_cpu.c | 39 |
1 files changed, 32 insertions, 7 deletions
diff --git a/sys/dev/acpica/acpi_cpu.c b/sys/dev/acpica/acpi_cpu.c index b9a89d390ed8..324f0a430cb9 100644 --- a/sys/dev/acpica/acpi_cpu.c +++ b/sys/dev/acpica/acpi_cpu.c @@ -257,7 +257,7 @@ static int acpi_cpu_attach(device_t dev) { ACPI_BUFFER buf; - ACPI_OBJECT arg, *obj; + ACPI_OBJECT arg[4], *obj; ACPI_OBJECT_LIST arglist; struct pcpu *pcpu_data; struct acpi_cpu_softc *sc; @@ -268,6 +268,11 @@ acpi_cpu_attach(device_t dev) driver_t **drivers; uint32_t cap_set[3]; + /* UUID needed by _OSC evaluation */ + static uint8_t cpu_oscuuid[16] = { 0x16, 0xA6, 0x77, 0x40, 0x0C, 0x29, + 0xBE, 0x47, 0x9E, 0xBD, 0xD8, 0x70, + 0x58, 0x71, 0x39, 0x53 }; + ACPI_FUNCTION_TRACE((char *)(uintptr_t)__func__); sc = device_get_softc(dev); @@ -334,19 +339,39 @@ acpi_cpu_attach(device_t dev) /* * CPU capabilities are specified as a buffer of 32-bit integers: * revision, count, and one or more capabilities. The revision of - * "1" is not specified anywhere but seems to match Linux. We should - * also support _OSC here. + * "1" is not specified anywhere but seems to match Linux. */ if (sc->cpu_features) { - arglist.Pointer = &arg; + arglist.Pointer = arg; arglist.Count = 1; - arg.Type = ACPI_TYPE_BUFFER; - arg.Buffer.Length = sizeof(cap_set); - arg.Buffer.Pointer = (uint8_t *)cap_set; + arg[0].Type = ACPI_TYPE_BUFFER; + arg[0].Buffer.Length = sizeof(cap_set); + arg[0].Buffer.Pointer = (uint8_t *)cap_set; cap_set[0] = 1; /* revision */ cap_set[1] = 1; /* number of capabilities integers */ cap_set[2] = sc->cpu_features; AcpiEvaluateObject(sc->cpu_handle, "_PDC", &arglist, NULL); + + /* + * On some systems we need to evaluate _OSC so that the ASL + * loads the _PSS and/or _PDC methods at runtime. + * + * TODO: evaluate failure of _OSC. + */ + arglist.Pointer = arg; + arglist.Count = 4; + arg[0].Type = ACPI_TYPE_BUFFER; + arg[0].Buffer.Length = sizeof(cpu_oscuuid); + arg[0].Buffer.Pointer = cpu_oscuuid; /* UUID */ + arg[1].Type = ACPI_TYPE_INTEGER; + arg[1].Integer.Value = 1; /* revision */ + arg[2].Type = ACPI_TYPE_INTEGER; + arg[2].Integer.Value = 1; /* count */ + arg[3].Type = ACPI_TYPE_BUFFER; + arg[3].Buffer.Length = sizeof(cap_set); /* Capabilities buffer */ + arg[3].Buffer.Pointer = (uint8_t *)cap_set; + cap_set[0] = 0; + AcpiEvaluateObject(sc->cpu_handle, "_OSC", &arglist, NULL); } /* Probe for Cx state support. */ |