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