1122765Snjl/*-
2122765Snjl * Copyright (c) 2003 Nate Lawson
3122765Snjl * All rights reserved.
4122765Snjl *
5122765Snjl * Redistribution and use in source and binary forms, with or without
6122765Snjl * modification, are permitted provided that the following conditions
7122765Snjl * are met:
8122765Snjl * 1. Redistributions of source code must retain the above copyright
9122765Snjl *    notice, this list of conditions and the following disclaimer.
10122765Snjl * 2. Redistributions in binary form must reproduce the above copyright
11122765Snjl *    notice, this list of conditions and the following disclaimer in the
12122765Snjl *    documentation and/or other materials provided with the distribution.
13122765Snjl *
14122765Snjl * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
15122765Snjl * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
16122765Snjl * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
17122765Snjl * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
18122765Snjl * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
19122765Snjl * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
20122765Snjl * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
21122765Snjl * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
22122765Snjl * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
23122765Snjl * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
24122765Snjl * SUCH DAMAGE.
25122765Snjl */
26122765Snjl
27148318Snjl#include <sys/cdefs.h>
28148318Snjl__FBSDID("$FreeBSD: stable/10/sys/dev/acpica/acpi_package.c 315021 2017-03-10 19:34:14Z vangyzen $");
29148318Snjl
30122765Snjl#include <sys/param.h>
31122765Snjl#include <sys/kernel.h>
32122765Snjl#include <sys/bus.h>
33122765Snjl#include <sys/sbuf.h>
34122765Snjl
35122765Snjl#include <machine/bus.h>
36122765Snjl#include <machine/resource.h>
37122765Snjl#include <sys/rman.h>
38122765Snjl
39193530Sjkim#include <contrib/dev/acpica/include/acpi.h>
40193530Sjkim
41122765Snjl#include <dev/acpica/acpivar.h>
42122765Snjl
43122765Snjl/*
44122765Snjl * Package manipulation convenience functions
45122765Snjl */
46122765Snjl
47122765Snjlint
48202771Sjkimacpi_PkgInt(ACPI_OBJECT *res, int idx, UINT64 *dst)
49122765Snjl{
50122765Snjl    ACPI_OBJECT		*obj;
51122765Snjl
52122765Snjl    obj = &res->Package.Elements[idx];
53315021Svangyzen    if (obj->Type != ACPI_TYPE_INTEGER)
54123776Snjl	return (EINVAL);
55123776Snjl    *dst = obj->Integer.Value;
56122765Snjl
57122765Snjl    return (0);
58122765Snjl}
59122765Snjl
60122765Snjlint
61123776Snjlacpi_PkgInt32(ACPI_OBJECT *res, int idx, uint32_t *dst)
62122765Snjl{
63202771Sjkim    UINT64		tmp;
64123776Snjl    int			error;
65122765Snjl
66123776Snjl    error = acpi_PkgInt(res, idx, &tmp);
67122765Snjl    if (error == 0)
68122765Snjl	*dst = (uint32_t)tmp;
69123776Snjl
70122765Snjl    return (error);
71122765Snjl}
72122765Snjl
73122765Snjlint
74123776Snjlacpi_PkgStr(ACPI_OBJECT *res, int idx, void *dst, size_t size)
75122765Snjl{
76122765Snjl    ACPI_OBJECT		*obj;
77122765Snjl    void		*ptr;
78122765Snjl    size_t		 length;
79122765Snjl
80122765Snjl    obj = &res->Package.Elements[idx];
81123776Snjl    if (obj == NULL)
82123776Snjl	return (EINVAL);
83122765Snjl    bzero(dst, sizeof(dst));
84122765Snjl
85122765Snjl    switch (obj->Type) {
86122765Snjl    case ACPI_TYPE_STRING:
87122765Snjl	ptr = obj->String.Pointer;
88122765Snjl	length = obj->String.Length;
89122765Snjl	break;
90122765Snjl    case ACPI_TYPE_BUFFER:
91122765Snjl	ptr = obj->Buffer.Pointer;
92122765Snjl	length = obj->Buffer.Length;
93122765Snjl	break;
94122765Snjl    default:
95123776Snjl	return (EINVAL);
96122765Snjl    }
97122765Snjl
98122765Snjl    /* Make sure string will fit, including terminating NUL */
99123776Snjl    if (++length > size)
100123776Snjl	return (E2BIG);
101122765Snjl
102122765Snjl    strlcpy(dst, ptr, length);
103122765Snjl    return (0);
104122765Snjl}
105122765Snjl
106122765Snjlint
107141371Snjlacpi_PkgGas(device_t dev, ACPI_OBJECT *res, int idx, int *type, int *rid,
108165875Snjl    struct resource **dst, u_int flags)
109122765Snjl{
110122765Snjl    ACPI_GENERIC_ADDRESS gas;
111141371Snjl    ACPI_OBJECT *obj;
112122765Snjl
113122765Snjl    obj = &res->Package.Elements[idx];
114122765Snjl    if (obj == NULL || obj->Type != ACPI_TYPE_BUFFER ||
115141294Snjl	obj->Buffer.Length < sizeof(ACPI_GENERIC_ADDRESS) + 3)
116123776Snjl	return (EINVAL);
117122765Snjl
118122765Snjl    memcpy(&gas, obj->Buffer.Pointer + 3, sizeof(gas));
119122765Snjl
120165875Snjl    return (acpi_bus_alloc_gas(dev, type, rid, &gas, dst, flags));
121122765Snjl}
122128045Snjl
123128045SnjlACPI_HANDLE
124128045Snjlacpi_GetReference(ACPI_HANDLE scope, ACPI_OBJECT *obj)
125128045Snjl{
126128045Snjl    ACPI_HANDLE h;
127128045Snjl
128128045Snjl    if (obj == NULL)
129128045Snjl	return (NULL);
130128045Snjl
131128045Snjl    switch (obj->Type) {
132128045Snjl    case ACPI_TYPE_LOCAL_REFERENCE:
133128045Snjl    case ACPI_TYPE_ANY:
134128045Snjl	h = obj->Reference.Handle;
135128045Snjl	break;
136128045Snjl    case ACPI_TYPE_STRING:
137128045Snjl	/*
138128045Snjl	 * The String object usually contains a fully-qualified path, so
139128045Snjl	 * scope can be NULL.
140128045Snjl	 *
141128045Snjl	 * XXX This may not always be the case.
142128045Snjl	 */
143128045Snjl	if (ACPI_FAILURE(AcpiGetHandle(scope, obj->String.Pointer, &h)))
144128045Snjl	    h = NULL;
145128045Snjl	break;
146128045Snjl    default:
147128045Snjl	h = NULL;
148128045Snjl	break;
149128045Snjl    }
150128045Snjl
151128045Snjl    return (h);
152128045Snjl}
153