1*3eb670e5Sriastradh /* $NetBSD: linux_acpi.c,v 1.2 2022/02/28 17:15:30 riastradh Exp $ */
2c981a879Sriastradh
3c981a879Sriastradh /*-
4c981a879Sriastradh * Copyright (c) 2022 The NetBSD Foundation, Inc.
5c981a879Sriastradh * All rights reserved.
6c981a879Sriastradh *
7c981a879Sriastradh * Redistribution and use in source and binary forms, with or without
8c981a879Sriastradh * modification, are permitted provided that the following conditions
9c981a879Sriastradh * are met:
10c981a879Sriastradh * 1. Redistributions of source code must retain the above copyright
11c981a879Sriastradh * notice, this list of conditions and the following disclaimer.
12c981a879Sriastradh * 2. Redistributions in binary form must reproduce the above copyright
13c981a879Sriastradh * notice, this list of conditions and the following disclaimer in the
14c981a879Sriastradh * documentation and/or other materials provided with the distribution.
15c981a879Sriastradh *
16c981a879Sriastradh * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
17c981a879Sriastradh * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
18c981a879Sriastradh * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
19c981a879Sriastradh * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
20c981a879Sriastradh * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
21c981a879Sriastradh * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
22c981a879Sriastradh * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
23c981a879Sriastradh * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
24c981a879Sriastradh * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
25c981a879Sriastradh * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
26c981a879Sriastradh * POSSIBILITY OF SUCH DAMAGE.
27c981a879Sriastradh */
28c981a879Sriastradh
29c981a879Sriastradh #include <sys/cdefs.h>
30*3eb670e5Sriastradh __KERNEL_RCSID(0, "$NetBSD: linux_acpi.c,v 1.2 2022/02/28 17:15:30 riastradh Exp $");
31*3eb670e5Sriastradh
32*3eb670e5Sriastradh #include <dev/acpi/acpireg.h>
33c981a879Sriastradh
34c981a879Sriastradh #include <linux/acpi.h>
35c981a879Sriastradh
36*3eb670e5Sriastradh #define _COMPONENT ACPI_BUS_COMPONENT
37*3eb670e5Sriastradh ACPI_MODULE_NAME("linux_acpi")
38*3eb670e5Sriastradh
39c981a879Sriastradh union acpi_object *
acpi_evaluate_dsm(acpi_handle handle,const guid_t * uuid,u64 rev,u64 func,union acpi_object * argv4)40c981a879Sriastradh acpi_evaluate_dsm(acpi_handle handle, const guid_t *uuid, u64 rev, u64 func,
41c981a879Sriastradh union acpi_object *argv4)
42c981a879Sriastradh {
43c981a879Sriastradh ACPI_OBJECT_LIST arg;
44c981a879Sriastradh ACPI_OBJECT params[4];
45c981a879Sriastradh ACPI_BUFFER buf;
46c981a879Sriastradh ACPI_STATUS rv;
47c981a879Sriastradh
48c981a879Sriastradh if (handle == NULL)
49c981a879Sriastradh handle = ACPI_ROOT_OBJECT;
50c981a879Sriastradh
51c981a879Sriastradh arg.Count = 4;
52c981a879Sriastradh arg.Pointer = params;
53c981a879Sriastradh params[0].Type = ACPI_TYPE_BUFFER;
54c981a879Sriastradh params[0].Buffer.Length = 16;
55c981a879Sriastradh params[0].Buffer.Pointer = (char *)__UNCONST(uuid);
56c981a879Sriastradh params[1].Type = ACPI_TYPE_INTEGER;
57c981a879Sriastradh params[1].Integer.Value = rev;
58c981a879Sriastradh params[2].Type = ACPI_TYPE_INTEGER;
59c981a879Sriastradh params[2].Integer.Value = func;
60c981a879Sriastradh if (argv4 != NULL) {
61c981a879Sriastradh params[3] = *argv4;
62c981a879Sriastradh } else {
63c981a879Sriastradh params[3].Type = ACPI_TYPE_PACKAGE;
64c981a879Sriastradh params[3].Package.Count = 0;
65c981a879Sriastradh params[3].Package.Elements = NULL;
66c981a879Sriastradh }
67c981a879Sriastradh
68c981a879Sriastradh buf.Pointer = NULL;
69c981a879Sriastradh buf.Length = ACPI_ALLOCATE_LOCAL_BUFFER;
70c981a879Sriastradh
71c981a879Sriastradh rv = AcpiEvaluateObject(handle, "_DSM", &arg, &buf);
72c981a879Sriastradh if (ACPI_SUCCESS(rv))
73c981a879Sriastradh return (ACPI_OBJECT *)buf.Pointer;
74c981a879Sriastradh return NULL;
75c981a879Sriastradh }
76c981a879Sriastradh
77c981a879Sriastradh 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)78c981a879Sriastradh acpi_evaluate_dsm_typed(acpi_handle handle, const guid_t *uuid, u64 rev,
79c981a879Sriastradh u64 func, union acpi_object *argv4, acpi_object_type type)
80c981a879Sriastradh {
81c981a879Sriastradh union acpi_object *obj;
82c981a879Sriastradh
83c981a879Sriastradh obj = acpi_evaluate_dsm(handle, uuid, rev, func, argv4);
84c981a879Sriastradh if (obj != NULL && obj->Type != type) {
85c981a879Sriastradh ACPI_FREE(obj);
86c981a879Sriastradh obj = NULL;
87c981a879Sriastradh }
88c981a879Sriastradh return obj;
89c981a879Sriastradh }
90c981a879Sriastradh
91c981a879Sriastradh #define ACPI_INIT_DSM_ARGV4(cnt, eles) \
92c981a879Sriastradh { \
93c981a879Sriastradh .Package.Type = ACPI_TYPE_PACKAGE, \
94c981a879Sriastradh .Package.Count = (cnt), \
95c981a879Sriastradh .Package.Elements = (eles) \
96c981a879Sriastradh }
97c981a879Sriastradh
98c981a879Sriastradh bool
acpi_check_dsm(acpi_handle handle,const guid_t * uuid,u64 rev,u64 funcs)99c981a879Sriastradh acpi_check_dsm(acpi_handle handle, const guid_t *uuid, u64 rev, u64 funcs)
100c981a879Sriastradh {
101c981a879Sriastradh ACPI_OBJECT *obj;
102c981a879Sriastradh uint64_t mask = 0;
103c981a879Sriastradh int i;
104c981a879Sriastradh
105c981a879Sriastradh if (funcs == 0)
106c981a879Sriastradh return false;
107c981a879Sriastradh
108c981a879Sriastradh obj = acpi_evaluate_dsm(handle, uuid, rev, 0, NULL);
109c981a879Sriastradh if (obj == NULL)
110c981a879Sriastradh return false;
111c981a879Sriastradh
112c981a879Sriastradh if (obj->Type == ACPI_TYPE_INTEGER)
113c981a879Sriastradh mask = obj->Integer.Value;
114c981a879Sriastradh else if (obj->Type == ACPI_TYPE_BUFFER)
115c981a879Sriastradh for (i = 0; i < obj->Buffer.Length && i < 8; i++)
116c981a879Sriastradh mask |= (uint64_t)obj->Buffer.Pointer[i] << (i * 8);
117c981a879Sriastradh ACPI_FREE(obj);
118c981a879Sriastradh
119c981a879Sriastradh if ((mask & 0x1) == 0x1 && (mask & funcs) == funcs)
120c981a879Sriastradh return true;
121c981a879Sriastradh return false;
122c981a879Sriastradh }
123