1*6bc5d83fSriastradh /* $NetBSD: linux_acpi.c,v 1.2 2022/02/28 17:15:30 riastradh Exp $ */
267337615Sriastradh
367337615Sriastradh /*-
467337615Sriastradh * Copyright (c) 2022 The NetBSD Foundation, Inc.
567337615Sriastradh * All rights reserved.
667337615Sriastradh *
767337615Sriastradh * Redistribution and use in source and binary forms, with or without
867337615Sriastradh * modification, are permitted provided that the following conditions
967337615Sriastradh * are met:
1067337615Sriastradh * 1. Redistributions of source code must retain the above copyright
1167337615Sriastradh * notice, this list of conditions and the following disclaimer.
1267337615Sriastradh * 2. Redistributions in binary form must reproduce the above copyright
1367337615Sriastradh * notice, this list of conditions and the following disclaimer in the
1467337615Sriastradh * documentation and/or other materials provided with the distribution.
1567337615Sriastradh *
1667337615Sriastradh * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
1767337615Sriastradh * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
1867337615Sriastradh * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
1967337615Sriastradh * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
2067337615Sriastradh * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
2167337615Sriastradh * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
2267337615Sriastradh * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
2367337615Sriastradh * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
2467337615Sriastradh * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
2567337615Sriastradh * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
2667337615Sriastradh * POSSIBILITY OF SUCH DAMAGE.
2767337615Sriastradh */
2867337615Sriastradh
2967337615Sriastradh #include <sys/cdefs.h>
30*6bc5d83fSriastradh __KERNEL_RCSID(0, "$NetBSD: linux_acpi.c,v 1.2 2022/02/28 17:15:30 riastradh Exp $");
31*6bc5d83fSriastradh
32*6bc5d83fSriastradh #include <dev/acpi/acpireg.h>
3367337615Sriastradh
3467337615Sriastradh #include <linux/acpi.h>
3567337615Sriastradh
36*6bc5d83fSriastradh #define _COMPONENT ACPI_BUS_COMPONENT
37*6bc5d83fSriastradh ACPI_MODULE_NAME("linux_acpi")
38*6bc5d83fSriastradh
3967337615Sriastradh union acpi_object *
acpi_evaluate_dsm(acpi_handle handle,const guid_t * uuid,u64 rev,u64 func,union acpi_object * argv4)4067337615Sriastradh acpi_evaluate_dsm(acpi_handle handle, const guid_t *uuid, u64 rev, u64 func,
4167337615Sriastradh union acpi_object *argv4)
4267337615Sriastradh {
4367337615Sriastradh ACPI_OBJECT_LIST arg;
4467337615Sriastradh ACPI_OBJECT params[4];
4567337615Sriastradh ACPI_BUFFER buf;
4667337615Sriastradh ACPI_STATUS rv;
4767337615Sriastradh
4867337615Sriastradh if (handle == NULL)
4967337615Sriastradh handle = ACPI_ROOT_OBJECT;
5067337615Sriastradh
5167337615Sriastradh arg.Count = 4;
5267337615Sriastradh arg.Pointer = params;
5367337615Sriastradh params[0].Type = ACPI_TYPE_BUFFER;
5467337615Sriastradh params[0].Buffer.Length = 16;
5567337615Sriastradh params[0].Buffer.Pointer = (char *)__UNCONST(uuid);
5667337615Sriastradh params[1].Type = ACPI_TYPE_INTEGER;
5767337615Sriastradh params[1].Integer.Value = rev;
5867337615Sriastradh params[2].Type = ACPI_TYPE_INTEGER;
5967337615Sriastradh params[2].Integer.Value = func;
6067337615Sriastradh if (argv4 != NULL) {
6167337615Sriastradh params[3] = *argv4;
6267337615Sriastradh } else {
6367337615Sriastradh params[3].Type = ACPI_TYPE_PACKAGE;
6467337615Sriastradh params[3].Package.Count = 0;
6567337615Sriastradh params[3].Package.Elements = NULL;
6667337615Sriastradh }
6767337615Sriastradh
6867337615Sriastradh buf.Pointer = NULL;
6967337615Sriastradh buf.Length = ACPI_ALLOCATE_LOCAL_BUFFER;
7067337615Sriastradh
7167337615Sriastradh rv = AcpiEvaluateObject(handle, "_DSM", &arg, &buf);
7267337615Sriastradh if (ACPI_SUCCESS(rv))
7367337615Sriastradh return (ACPI_OBJECT *)buf.Pointer;
7467337615Sriastradh return NULL;
7567337615Sriastradh }
7667337615Sriastradh
7767337615Sriastradh union acpi_object *
acpi_evaluate_dsm_typed(acpi_handle handle,const guid_t * uuid,u64 rev,u64 func,union acpi_object * argv4,acpi_object_type type)7867337615Sriastradh acpi_evaluate_dsm_typed(acpi_handle handle, const guid_t *uuid, u64 rev,
7967337615Sriastradh u64 func, union acpi_object *argv4, acpi_object_type type)
8067337615Sriastradh {
8167337615Sriastradh union acpi_object *obj;
8267337615Sriastradh
8367337615Sriastradh obj = acpi_evaluate_dsm(handle, uuid, rev, func, argv4);
8467337615Sriastradh if (obj != NULL && obj->Type != type) {
8567337615Sriastradh ACPI_FREE(obj);
8667337615Sriastradh obj = NULL;
8767337615Sriastradh }
8867337615Sriastradh return obj;
8967337615Sriastradh }
9067337615Sriastradh
9167337615Sriastradh #define ACPI_INIT_DSM_ARGV4(cnt, eles) \
9267337615Sriastradh { \
9367337615Sriastradh .Package.Type = ACPI_TYPE_PACKAGE, \
9467337615Sriastradh .Package.Count = (cnt), \
9567337615Sriastradh .Package.Elements = (eles) \
9667337615Sriastradh }
9767337615Sriastradh
9867337615Sriastradh bool
acpi_check_dsm(acpi_handle handle,const guid_t * uuid,u64 rev,u64 funcs)9967337615Sriastradh acpi_check_dsm(acpi_handle handle, const guid_t *uuid, u64 rev, u64 funcs)
10067337615Sriastradh {
10167337615Sriastradh ACPI_OBJECT *obj;
10267337615Sriastradh uint64_t mask = 0;
10367337615Sriastradh int i;
10467337615Sriastradh
10567337615Sriastradh if (funcs == 0)
10667337615Sriastradh return false;
10767337615Sriastradh
10867337615Sriastradh obj = acpi_evaluate_dsm(handle, uuid, rev, 0, NULL);
10967337615Sriastradh if (obj == NULL)
11067337615Sriastradh return false;
11167337615Sriastradh
11267337615Sriastradh if (obj->Type == ACPI_TYPE_INTEGER)
11367337615Sriastradh mask = obj->Integer.Value;
11467337615Sriastradh else if (obj->Type == ACPI_TYPE_BUFFER)
11567337615Sriastradh for (i = 0; i < obj->Buffer.Length && i < 8; i++)
11667337615Sriastradh mask |= (uint64_t)obj->Buffer.Pointer[i] << (i * 8);
11767337615Sriastradh ACPI_FREE(obj);
11867337615Sriastradh
11967337615Sriastradh if ((mask & 0x1) == 0x1 && (mask & funcs) == funcs)
12067337615Sriastradh return true;
12167337615Sriastradh return false;
12267337615Sriastradh }
123