From fe64ff3c0404bc2a6eae884cc86ff4755ed21483 Mon Sep 17 00:00:00 2001 From: Vladimir Kondratyev Date: Sat, 31 Oct 2020 19:47:34 +0000 Subject: [PATCH] acpi: Tweak _DSM method evaluation helpers. - Use ACPI style for _DSM evaluation helper parameter types. - Constify UUID parameter. - Increase size of returned DSM function bitmap by acpi_DSMQuery() up to 64 items. Old limit of 8 functions is not sufficient for JEDEC JESD245 NVDIMMs. - Add new acpi_EvaluateDSMTyped() helper which performs additional return value type check as compared with acpi_EvaluateDSM(). - Reimplement acpi_EvaluateDSM() on top of the acpi_EvaluateDSMTyped() call. Reviewed by: scottph, manu Differential Revision: https://reviews.freebsd.org/D26602 --- sys/dev/acpica/acpi.c | 29 ++++++++++++++++++++--------- sys/dev/acpica/acpivar.h | 11 ++++++++--- 2 files changed, 28 insertions(+), 12 deletions(-) diff --git a/sys/dev/acpica/acpi.c b/sys/dev/acpica/acpi.c index 719c0ae0f97..6e8e12e42f7 100644 --- a/sys/dev/acpica/acpi.c +++ b/sys/dev/acpica/acpi.c @@ -2632,8 +2632,8 @@ acpi_AppendBufferResource(ACPI_BUFFER *buf, ACPI_RESOURCE *res) return (AE_OK); } -UINT8 -acpi_DSMQuery(ACPI_HANDLE h, uint8_t *uuid, int revision) +UINT64 +acpi_DSMQuery(ACPI_HANDLE h, const uint8_t *uuid, int revision) { /* * ACPI spec 9.1.1 defines this. @@ -2645,7 +2645,8 @@ acpi_DSMQuery(ACPI_HANDLE h, uint8_t *uuid, int revision) */ ACPI_BUFFER buf; ACPI_OBJECT *obj; - UINT8 ret = 0; + UINT64 ret = 0; + int i; if (!ACPI_SUCCESS(acpi_EvaluateDSM(h, uuid, revision, 0, NULL, &buf))) { ACPI_INFO(("Failed to enumerate DSM functions\n")); @@ -2663,12 +2664,13 @@ acpi_DSMQuery(ACPI_HANDLE h, uint8_t *uuid, int revision) */ switch (obj->Type) { case ACPI_TYPE_BUFFER: - ret = *(uint8_t *)obj->Buffer.Pointer; + for (i = 0; i < MIN(obj->Buffer.Length, sizeof(ret)); i++) + ret |= (((uint64_t)obj->Buffer.Pointer[i]) << (i * 8)); break; case ACPI_TYPE_INTEGER: ACPI_BIOS_WARNING((AE_INFO, "Possibly buggy BIOS with ACPI_TYPE_INTEGER for function enumeration\n")); - ret = obj->Integer.Value & 0xFF; + ret = obj->Integer.Value; break; default: ACPI_WARNING((AE_INFO, "Unexpected return type %u\n", obj->Type)); @@ -2684,8 +2686,17 @@ acpi_DSMQuery(ACPI_HANDLE h, uint8_t *uuid, int revision) * check the type of the returned object. */ ACPI_STATUS -acpi_EvaluateDSM(ACPI_HANDLE handle, uint8_t *uuid, int revision, - uint64_t function, union acpi_object *package, ACPI_BUFFER *out_buf) +acpi_EvaluateDSM(ACPI_HANDLE handle, const uint8_t *uuid, int revision, + UINT64 function, ACPI_OBJECT *package, ACPI_BUFFER *out_buf) +{ + return (acpi_EvaluateDSMTyped(handle, uuid, revision, function, + package, out_buf, ACPI_TYPE_ANY)); +} + +ACPI_STATUS +acpi_EvaluateDSMTyped(ACPI_HANDLE handle, const uint8_t *uuid, int revision, + UINT64 function, ACPI_OBJECT *package, ACPI_BUFFER *out_buf, + ACPI_OBJECT_TYPE type) { ACPI_OBJECT arg[4]; ACPI_OBJECT_LIST arglist; @@ -2697,7 +2708,7 @@ acpi_EvaluateDSM(ACPI_HANDLE handle, uint8_t *uuid, int revision, arg[0].Type = ACPI_TYPE_BUFFER; arg[0].Buffer.Length = ACPI_UUID_LENGTH; - arg[0].Buffer.Pointer = uuid; + arg[0].Buffer.Pointer = __DECONST(uint8_t *, uuid); arg[1].Type = ACPI_TYPE_INTEGER; arg[1].Integer.Value = revision; arg[2].Type = ACPI_TYPE_INTEGER; @@ -2714,7 +2725,7 @@ acpi_EvaluateDSM(ACPI_HANDLE handle, uint8_t *uuid, int revision, arglist.Count = 4; buf.Pointer = NULL; buf.Length = ACPI_ALLOCATE_BUFFER; - status = AcpiEvaluateObject(handle, "_DSM", &arglist, &buf); + status = AcpiEvaluateObjectTyped(handle, "_DSM", &arglist, &buf, type); if (ACPI_FAILURE(status)) return (status); diff --git a/sys/dev/acpica/acpivar.h b/sys/dev/acpica/acpivar.h index 80b75f69ff5..8e23b9049b8 100644 --- a/sys/dev/acpica/acpivar.h +++ b/sys/dev/acpica/acpivar.h @@ -349,10 +349,15 @@ ACPI_STATUS acpi_FindIndexedResource(ACPI_BUFFER *buf, int index, ACPI_RESOURCE **resp); ACPI_STATUS acpi_AppendBufferResource(ACPI_BUFFER *buf, ACPI_RESOURCE *res); -UINT8 acpi_DSMQuery(ACPI_HANDLE h, uint8_t *uuid, int revision); -ACPI_STATUS acpi_EvaluateDSM(ACPI_HANDLE handle, uint8_t *uuid, - int revision, uint64_t function, union acpi_object *package, +UINT64 acpi_DSMQuery(ACPI_HANDLE h, const uint8_t *uuid, + int revision); +ACPI_STATUS acpi_EvaluateDSM(ACPI_HANDLE handle, const uint8_t *uuid, + int revision, UINT64 function, ACPI_OBJECT *package, ACPI_BUFFER *out_buf); +ACPI_STATUS acpi_EvaluateDSMTyped(ACPI_HANDLE handle, + const uint8_t *uuid, int revision, UINT64 function, + ACPI_OBJECT *package, ACPI_BUFFER *out_buf, + ACPI_OBJECT_TYPE type); ACPI_STATUS acpi_EvaluateOSC(ACPI_HANDLE handle, uint8_t *uuid, int revision, int count, uint32_t *caps_in, uint32_t *caps_out, bool query);