17b1019a6SJerry Jelinek /*
27b1019a6SJerry Jelinek  *
37b1019a6SJerry Jelinek  * Module Name: osillumostbl - illumos OSL for obtaining ACPI tables
47b1019a6SJerry Jelinek  * This file is derived from the Intel oslinuxtbl source file.
57b1019a6SJerry Jelinek  *
67b1019a6SJerry Jelinek  */
77b1019a6SJerry Jelinek 
87b1019a6SJerry Jelinek /*
97b1019a6SJerry Jelinek  * Copyright (C) 2000 - 2016, Intel Corp.
107b1019a6SJerry Jelinek  * All rights reserved.
117b1019a6SJerry Jelinek  *
127b1019a6SJerry Jelinek  * Redistribution and use in source and binary forms, with or without
137b1019a6SJerry Jelinek  * modification, are permitted provided that the following conditions
147b1019a6SJerry Jelinek  * are met:
157b1019a6SJerry Jelinek  * 1. Redistributions of source code must retain the above copyright
167b1019a6SJerry Jelinek  *    notice, this list of conditions, and the following disclaimer,
177b1019a6SJerry Jelinek  *    without modification.
187b1019a6SJerry Jelinek  * 2. Redistributions in binary form must reproduce at minimum a disclaimer
197b1019a6SJerry Jelinek  *    substantially similar to the "NO WARRANTY" disclaimer below
207b1019a6SJerry Jelinek  *    ("Disclaimer") and any redistribution must be conditioned upon
217b1019a6SJerry Jelinek  *    including a substantially similar Disclaimer requirement for further
227b1019a6SJerry Jelinek  *    binary redistribution.
237b1019a6SJerry Jelinek  * 3. Neither the names of the above-listed copyright holders nor the names
247b1019a6SJerry Jelinek  *    of any contributors may be used to endorse or promote products derived
257b1019a6SJerry Jelinek  *    from this software without specific prior written permission.
267b1019a6SJerry Jelinek  *
277b1019a6SJerry Jelinek  * Alternatively, this software may be distributed under the terms of the
287b1019a6SJerry Jelinek  * GNU General Public License ("GPL") version 2 as published by the Free
297b1019a6SJerry Jelinek  * Software Foundation.
307b1019a6SJerry Jelinek  *
317b1019a6SJerry Jelinek  * NO WARRANTY
327b1019a6SJerry Jelinek  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
337b1019a6SJerry Jelinek  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
347b1019a6SJerry Jelinek  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR
357b1019a6SJerry Jelinek  * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
367b1019a6SJerry Jelinek  * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
377b1019a6SJerry Jelinek  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
387b1019a6SJerry Jelinek  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
397b1019a6SJerry Jelinek  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
407b1019a6SJerry Jelinek  * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
417b1019a6SJerry Jelinek  * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
427b1019a6SJerry Jelinek  * POSSIBILITY OF SUCH DAMAGES.
437b1019a6SJerry Jelinek  */
447b1019a6SJerry Jelinek 
457b1019a6SJerry Jelinek /*
46bc36eafdSMike Gerdts  * Copyright (c) 2018, Joyent, Inc.
477b1019a6SJerry Jelinek  */
487b1019a6SJerry Jelinek 
497b1019a6SJerry Jelinek #include <stdarg.h>
507b1019a6SJerry Jelinek #include <string.h>
517b1019a6SJerry Jelinek #include <stdlib.h>
527b1019a6SJerry Jelinek #include <unistd.h>
53760a9770SToomas Soome #include <libdevinfo.h>
547b1019a6SJerry Jelinek #include "acpidump.h"
557b1019a6SJerry Jelinek 
567b1019a6SJerry Jelinek #define	_COMPONENT	ACPI_OS_SERVICES
577b1019a6SJerry Jelinek     ACPI_MODULE_NAME("osillumostbl")
587b1019a6SJerry Jelinek 
597b1019a6SJerry Jelinek /* List of information about obtained ACPI tables */
607b1019a6SJerry Jelinek 
617b1019a6SJerry Jelinek typedef struct osl_table_info
627b1019a6SJerry Jelinek {
637b1019a6SJerry Jelinek 	struct osl_table_info	*Next;
647b1019a6SJerry Jelinek 	UINT32			Instance;
657b1019a6SJerry Jelinek 	char			Signature[ACPI_NAME_SIZE];
667b1019a6SJerry Jelinek } OSL_TABLE_INFO;
677b1019a6SJerry Jelinek 
687b1019a6SJerry Jelinek /* Local prototypes */
697b1019a6SJerry Jelinek static ACPI_STATUS
707b1019a6SJerry Jelinek OslTableInitialize(void);
717b1019a6SJerry Jelinek static ACPI_STATUS OslTableNameFromFile(char *, char *, UINT32 *);
727b1019a6SJerry Jelinek static ACPI_STATUS OslAddTableToList(char *);
737b1019a6SJerry Jelinek static ACPI_STATUS OslMapTable(ACPI_SIZE, char *, ACPI_TABLE_HEADER **);
747b1019a6SJerry Jelinek static void OslUnmapTable(ACPI_TABLE_HEADER *);
757b1019a6SJerry Jelinek static ACPI_STATUS OslLoadRsdp(void);
767b1019a6SJerry Jelinek static ACPI_STATUS OslListBiosTables(void);
777b1019a6SJerry Jelinek static ACPI_STATUS OslGetBiosTable(char *, UINT32, ACPI_TABLE_HEADER **,
787b1019a6SJerry Jelinek     ACPI_PHYSICAL_ADDRESS *);
797b1019a6SJerry Jelinek static ACPI_STATUS OslGetLastStatus(ACPI_STATUS);
807b1019a6SJerry Jelinek 
817b1019a6SJerry Jelinek static int pagesize;
827b1019a6SJerry Jelinek 
837b1019a6SJerry Jelinek /* Initialization flags */
847b1019a6SJerry Jelinek UINT8			Gbl_TableListInitialized = FALSE;
857b1019a6SJerry Jelinek 
867b1019a6SJerry Jelinek /* Local copies of main ACPI tables */
877b1019a6SJerry Jelinek ACPI_TABLE_RSDP		Gbl_Rsdp;
887b1019a6SJerry Jelinek ACPI_TABLE_FADT		*Gbl_Fadt = NULL;
897b1019a6SJerry Jelinek ACPI_TABLE_RSDT		*Gbl_Rsdt = NULL;
907b1019a6SJerry Jelinek ACPI_TABLE_XSDT		*Gbl_Xsdt = NULL;
917b1019a6SJerry Jelinek 
927b1019a6SJerry Jelinek /* Table addresses */
937b1019a6SJerry Jelinek ACPI_PHYSICAL_ADDRESS	Gbl_FadtAddress = 0;
947b1019a6SJerry Jelinek ACPI_PHYSICAL_ADDRESS	Gbl_RsdpAddress = 0;
957b1019a6SJerry Jelinek 
967b1019a6SJerry Jelinek /* Revision of RSD PTR */
977b1019a6SJerry Jelinek UINT8			Gbl_Revision = 0;
987b1019a6SJerry Jelinek 
997b1019a6SJerry Jelinek OSL_TABLE_INFO		*Gbl_TableListHead = NULL;
1007b1019a6SJerry Jelinek UINT32			Gbl_TableCount = 0;
1017b1019a6SJerry Jelinek 
1027b1019a6SJerry Jelinek /*
1037b1019a6SJerry Jelinek  *
1047b1019a6SJerry Jelinek  * FUNCTION:    OslGetLastStatus
1057b1019a6SJerry Jelinek  *
1067b1019a6SJerry Jelinek  * PARAMETERS:  DefaultStatus   - Default error status to return
1077b1019a6SJerry Jelinek  *
1087b1019a6SJerry Jelinek  * RETURN:      Status; Converted from errno.
1097b1019a6SJerry Jelinek  *
1107b1019a6SJerry Jelinek  * DESCRIPTION: Get last errno and conver it to ACPI_STATUS.
1117b1019a6SJerry Jelinek  *
1127b1019a6SJerry Jelinek  */
1137b1019a6SJerry Jelinek static ACPI_STATUS
OslGetLastStatus(ACPI_STATUS DefaultStatus)1147b1019a6SJerry Jelinek OslGetLastStatus(ACPI_STATUS DefaultStatus)
1157b1019a6SJerry Jelinek {
1167b1019a6SJerry Jelinek 	switch (errno) {
1177b1019a6SJerry Jelinek 	case EACCES:
1187b1019a6SJerry Jelinek 	case EPERM:
1197b1019a6SJerry Jelinek 		return (AE_ACCESS);
1207b1019a6SJerry Jelinek 
1217b1019a6SJerry Jelinek 	case ENOENT:
1227b1019a6SJerry Jelinek 		return (AE_NOT_FOUND);
1237b1019a6SJerry Jelinek 
1247b1019a6SJerry Jelinek 	case ENOMEM:
1257b1019a6SJerry Jelinek 		return (AE_NO_MEMORY);
1267b1019a6SJerry Jelinek 
1277b1019a6SJerry Jelinek 	default:
1287b1019a6SJerry Jelinek 		return (DefaultStatus);
1297b1019a6SJerry Jelinek 	}
1307b1019a6SJerry Jelinek }
1317b1019a6SJerry Jelinek 
1327b1019a6SJerry Jelinek /*
1337b1019a6SJerry Jelinek  *
1347b1019a6SJerry Jelinek  * FUNCTION:    AcpiOsGetTableByAddress
1357b1019a6SJerry Jelinek  *
1367b1019a6SJerry Jelinek  * PARAMETERS:  Address         - Physical address of the ACPI table
1377b1019a6SJerry Jelinek  *              Table           - Where a pointer to the table is returned
1387b1019a6SJerry Jelinek  *
1397b1019a6SJerry Jelinek  * RETURN:      Status; Table buffer is returned if AE_OK.
1407b1019a6SJerry Jelinek  *              AE_NOT_FOUND: A valid table was not found at the address
1417b1019a6SJerry Jelinek  *
1427b1019a6SJerry Jelinek  * DESCRIPTION: Get an ACPI table via a physical memory address.
1437b1019a6SJerry Jelinek  *
1447b1019a6SJerry Jelinek  */
1457b1019a6SJerry Jelinek ACPI_STATUS
AcpiOsGetTableByAddress(ACPI_PHYSICAL_ADDRESS Address,ACPI_TABLE_HEADER ** Table)1467b1019a6SJerry Jelinek AcpiOsGetTableByAddress(ACPI_PHYSICAL_ADDRESS Address,
1477b1019a6SJerry Jelinek     ACPI_TABLE_HEADER **Table)
1487b1019a6SJerry Jelinek {
1497b1019a6SJerry Jelinek 	UINT32			TableLength;
1507b1019a6SJerry Jelinek 	ACPI_TABLE_HEADER	*MappedTable;
1517b1019a6SJerry Jelinek 	ACPI_TABLE_HEADER	*LocalTable = NULL;
1527b1019a6SJerry Jelinek 	ACPI_STATUS		Status = AE_OK;
1537b1019a6SJerry Jelinek 
1547b1019a6SJerry Jelinek 	/*
1557b1019a6SJerry Jelinek 	 * Get main ACPI tables from memory on first invocation of this
1567b1019a6SJerry Jelinek 	 * function
1577b1019a6SJerry Jelinek 	 */
1587b1019a6SJerry Jelinek 	Status = OslTableInitialize();
1597b1019a6SJerry Jelinek 	if (ACPI_FAILURE(Status)) {
1607b1019a6SJerry Jelinek 		return (Status);
1617b1019a6SJerry Jelinek 	}
1627b1019a6SJerry Jelinek 
1637b1019a6SJerry Jelinek 	/* Map the table and validate it */
1647b1019a6SJerry Jelinek 
1657b1019a6SJerry Jelinek 	Status = OslMapTable(Address, NULL, &MappedTable);
1667b1019a6SJerry Jelinek 	if (ACPI_FAILURE(Status)) {
1677b1019a6SJerry Jelinek 		return (Status);
1687b1019a6SJerry Jelinek 	}
1697b1019a6SJerry Jelinek 
1707b1019a6SJerry Jelinek 	/* Copy table to local buffer and return it */
1717b1019a6SJerry Jelinek 
1727b1019a6SJerry Jelinek 	TableLength = ApGetTableLength(MappedTable);
1737b1019a6SJerry Jelinek 	if (TableLength == 0) {
1747b1019a6SJerry Jelinek 		Status = AE_BAD_HEADER;
1757b1019a6SJerry Jelinek 		goto Exit;
1767b1019a6SJerry Jelinek 	}
1777b1019a6SJerry Jelinek 
1787b1019a6SJerry Jelinek 	LocalTable = calloc(1, TableLength);
1797b1019a6SJerry Jelinek 	if (!LocalTable) {
1807b1019a6SJerry Jelinek 		Status = AE_NO_MEMORY;
1817b1019a6SJerry Jelinek 		goto Exit;
1827b1019a6SJerry Jelinek 	}
1837b1019a6SJerry Jelinek 
1847b1019a6SJerry Jelinek 	memcpy(LocalTable, MappedTable, TableLength);
1857b1019a6SJerry Jelinek 
1867b1019a6SJerry Jelinek Exit:
1877b1019a6SJerry Jelinek 	OslUnmapTable(MappedTable);
1887b1019a6SJerry Jelinek 	*Table = LocalTable;
1897b1019a6SJerry Jelinek 	return (Status);
1907b1019a6SJerry Jelinek }
1917b1019a6SJerry Jelinek 
1927b1019a6SJerry Jelinek /*
1937b1019a6SJerry Jelinek  *
1947b1019a6SJerry Jelinek  * FUNCTION:    AcpiOsGetTableByName
1957b1019a6SJerry Jelinek  *
1967b1019a6SJerry Jelinek  * PARAMETERS:  Signature       - ACPI Signature for desired table. Must be
1977b1019a6SJerry Jelinek  *                                a null terminated 4-character string.
1987b1019a6SJerry Jelinek  *              Instance        - Multiple table support for SSDT/UEFI (0...n)
1997b1019a6SJerry Jelinek  *                                Must be 0 for other tables.
2007b1019a6SJerry Jelinek  *              Table           - Where a pointer to the table is returned
2017b1019a6SJerry Jelinek  *              Address         - Where the table physical address is returned
2027b1019a6SJerry Jelinek  *
2037b1019a6SJerry Jelinek  * RETURN:      Status; Table buffer and physical address returned if AE_OK.
2047b1019a6SJerry Jelinek  *              AE_LIMIT: Instance is beyond valid limit
2057b1019a6SJerry Jelinek  *              AE_NOT_FOUND: A table with the signature was not found
2067b1019a6SJerry Jelinek  *
2077b1019a6SJerry Jelinek  * NOTE:        Assumes the input signature is uppercase.
2087b1019a6SJerry Jelinek  *
2097b1019a6SJerry Jelinek  */
2107b1019a6SJerry Jelinek ACPI_STATUS
AcpiOsGetTableByName(char * Signature,UINT32 Instance,ACPI_TABLE_HEADER ** Table,ACPI_PHYSICAL_ADDRESS * Address)2117b1019a6SJerry Jelinek AcpiOsGetTableByName(char *Signature, UINT32 Instance,
2127b1019a6SJerry Jelinek     ACPI_TABLE_HEADER **Table, ACPI_PHYSICAL_ADDRESS *Address)
2137b1019a6SJerry Jelinek {
2147b1019a6SJerry Jelinek 	ACPI_STATUS	Status;
2157b1019a6SJerry Jelinek 
2167b1019a6SJerry Jelinek 	/*
2177b1019a6SJerry Jelinek 	 * Get main ACPI tables from memory on first invocation of this
2187b1019a6SJerry Jelinek 	 * function
2197b1019a6SJerry Jelinek 	 */
2207b1019a6SJerry Jelinek 	Status = OslTableInitialize();
2217b1019a6SJerry Jelinek 	if (ACPI_FAILURE(Status)) {
2227b1019a6SJerry Jelinek 		return (Status);
2237b1019a6SJerry Jelinek 	}
2247b1019a6SJerry Jelinek 
2257b1019a6SJerry Jelinek 	/* attempt to extract it from the RSDT/XSDT */
2267b1019a6SJerry Jelinek 	Status = OslGetBiosTable(Signature, Instance, Table, Address);
2277b1019a6SJerry Jelinek 
2287b1019a6SJerry Jelinek 	return (Status);
2297b1019a6SJerry Jelinek }
2307b1019a6SJerry Jelinek 
2317b1019a6SJerry Jelinek /*
2327b1019a6SJerry Jelinek  *
2337b1019a6SJerry Jelinek  * FUNCTION:    OslAddTableToList
2347b1019a6SJerry Jelinek  *
2357b1019a6SJerry Jelinek  * PARAMETERS:  Signature       - Table signature
2367b1019a6SJerry Jelinek  *
2377b1019a6SJerry Jelinek  * RETURN:      Status; Successfully added if AE_OK.
2387b1019a6SJerry Jelinek  *              AE_NO_MEMORY: Memory allocation error
2397b1019a6SJerry Jelinek  *
2407b1019a6SJerry Jelinek  * DESCRIPTION: Insert a table structure into OSL table list.
2417b1019a6SJerry Jelinek  *
2427b1019a6SJerry Jelinek  */
2437b1019a6SJerry Jelinek static ACPI_STATUS
OslAddTableToList(char * Signature)2447b1019a6SJerry Jelinek OslAddTableToList(char *Signature)
2457b1019a6SJerry Jelinek {
2467b1019a6SJerry Jelinek 	OSL_TABLE_INFO	*NewInfo;
2477b1019a6SJerry Jelinek 	OSL_TABLE_INFO	*Next;
2487b1019a6SJerry Jelinek 	UINT32		NextInstance = 0;
2497b1019a6SJerry Jelinek 	UINT32		Instance = 0;
2507b1019a6SJerry Jelinek 	BOOLEAN		Found = FALSE;
2517b1019a6SJerry Jelinek 
2527b1019a6SJerry Jelinek 	NewInfo = calloc(1, sizeof (OSL_TABLE_INFO));
2537b1019a6SJerry Jelinek 	if (NewInfo == NULL) {
2547b1019a6SJerry Jelinek 		return (AE_NO_MEMORY);
2557b1019a6SJerry Jelinek 	}
2567b1019a6SJerry Jelinek 
2577b1019a6SJerry Jelinek 	ACPI_MOVE_NAME(NewInfo->Signature, Signature);
2587b1019a6SJerry Jelinek 
2597b1019a6SJerry Jelinek 	if (!Gbl_TableListHead) {
2607b1019a6SJerry Jelinek 		Gbl_TableListHead = NewInfo;
2617b1019a6SJerry Jelinek 	} else {
2627b1019a6SJerry Jelinek 		Next = Gbl_TableListHead;
2637b1019a6SJerry Jelinek 
2647b1019a6SJerry Jelinek 		while (1) {
2657b1019a6SJerry Jelinek 			if (ACPI_COMPARE_NAME(Next->Signature, Signature)) {
2667b1019a6SJerry Jelinek 				if (Next->Instance == 0) {
2677b1019a6SJerry Jelinek 					Found = TRUE;
2687b1019a6SJerry Jelinek 				}
2697b1019a6SJerry Jelinek 				if (Next->Instance >= NextInstance) {
2707b1019a6SJerry Jelinek 					NextInstance = Next->Instance + 1;
2717b1019a6SJerry Jelinek 				}
2727b1019a6SJerry Jelinek 			}
2737b1019a6SJerry Jelinek 
2747b1019a6SJerry Jelinek 			if (!Next->Next) {
2757b1019a6SJerry Jelinek 				break;
2767b1019a6SJerry Jelinek 			}
2777b1019a6SJerry Jelinek 			Next = Next->Next;
2787b1019a6SJerry Jelinek 		}
2797b1019a6SJerry Jelinek 		Next->Next = NewInfo;
2807b1019a6SJerry Jelinek 	}
2817b1019a6SJerry Jelinek 
2827b1019a6SJerry Jelinek 	if (Found) {
2837b1019a6SJerry Jelinek 		Instance = NextInstance;
2847b1019a6SJerry Jelinek 	}
2857b1019a6SJerry Jelinek 
2867b1019a6SJerry Jelinek 	NewInfo->Instance = Instance;
2877b1019a6SJerry Jelinek 	Gbl_TableCount++;
2887b1019a6SJerry Jelinek 
2897b1019a6SJerry Jelinek 	return (AE_OK);
2907b1019a6SJerry Jelinek }
2917b1019a6SJerry Jelinek 
2927b1019a6SJerry Jelinek /*
2937b1019a6SJerry Jelinek  *
2947b1019a6SJerry Jelinek  * FUNCTION:    AcpiOsGetTableByIndex
2957b1019a6SJerry Jelinek  *
2967b1019a6SJerry Jelinek  * PARAMETERS:  Index           - Which table to get
2977b1019a6SJerry Jelinek  *              Table           - Where a pointer to the table is returned
2987b1019a6SJerry Jelinek  *              Instance        - Where a pointer to the table instance no. is
2997b1019a6SJerry Jelinek  *                                returned
3007b1019a6SJerry Jelinek  *              Address         - Where the table physical address is returned
3017b1019a6SJerry Jelinek  *
3027b1019a6SJerry Jelinek  * RETURN:      Status; Table buffer and physical address returned if AE_OK.
3037b1019a6SJerry Jelinek  *              AE_LIMIT: Index is beyond valid limit
3047b1019a6SJerry Jelinek  *
3057b1019a6SJerry Jelinek  * DESCRIPTION: Get an ACPI table via an index value (0 through n). Returns
3067b1019a6SJerry Jelinek  *              AE_LIMIT when an invalid index is reached. Index is not
3077b1019a6SJerry Jelinek  *              necessarily an index into the RSDT/XSDT.
3087b1019a6SJerry Jelinek  *
3097b1019a6SJerry Jelinek  */
3107b1019a6SJerry Jelinek ACPI_STATUS
AcpiOsGetTableByIndex(UINT32 Index,ACPI_TABLE_HEADER ** Table,UINT32 * Instance,ACPI_PHYSICAL_ADDRESS * Address)3117b1019a6SJerry Jelinek AcpiOsGetTableByIndex(UINT32 Index, ACPI_TABLE_HEADER **Table,
3127b1019a6SJerry Jelinek     UINT32 *Instance, ACPI_PHYSICAL_ADDRESS *Address)
3137b1019a6SJerry Jelinek {
3147b1019a6SJerry Jelinek 	OSL_TABLE_INFO	*Info;
3157b1019a6SJerry Jelinek 	ACPI_STATUS	Status;
3167b1019a6SJerry Jelinek 	UINT32		i;
3177b1019a6SJerry Jelinek 
3187b1019a6SJerry Jelinek 	/*
3197b1019a6SJerry Jelinek 	 * Get main ACPI tables from memory on first invocation of this
3207b1019a6SJerry Jelinek 	 * function.
3217b1019a6SJerry Jelinek 	 */
3227b1019a6SJerry Jelinek 
3237b1019a6SJerry Jelinek 	Status = OslTableInitialize();
3247b1019a6SJerry Jelinek 	if (ACPI_FAILURE(Status)) {
3257b1019a6SJerry Jelinek 		return (Status);
3267b1019a6SJerry Jelinek 	}
3277b1019a6SJerry Jelinek 
3287b1019a6SJerry Jelinek 	/* Validate Index */
3297b1019a6SJerry Jelinek 
3307b1019a6SJerry Jelinek 	if (Index >= Gbl_TableCount) {
3317b1019a6SJerry Jelinek 		return (AE_LIMIT);
3327b1019a6SJerry Jelinek 	}
3337b1019a6SJerry Jelinek 
3347b1019a6SJerry Jelinek 	/* Point to the table list entry specified by the Index argument */
3357b1019a6SJerry Jelinek 
3367b1019a6SJerry Jelinek 	Info = Gbl_TableListHead;
3377b1019a6SJerry Jelinek 	for (i = 0; i < Index; i++) {
3387b1019a6SJerry Jelinek 		Info = Info->Next;
3397b1019a6SJerry Jelinek 	}
3407b1019a6SJerry Jelinek 
3417b1019a6SJerry Jelinek 	/* Now we can just get the table via the signature */
3427b1019a6SJerry Jelinek 
3437b1019a6SJerry Jelinek 	Status = AcpiOsGetTableByName(Info->Signature, Info->Instance,
3447b1019a6SJerry Jelinek 	    Table, Address);
3457b1019a6SJerry Jelinek 
3467b1019a6SJerry Jelinek 	if (ACPI_SUCCESS(Status)) {
3477b1019a6SJerry Jelinek 		*Instance = Info->Instance;
3487b1019a6SJerry Jelinek 	}
3497b1019a6SJerry Jelinek 	return (Status);
3507b1019a6SJerry Jelinek }
3517b1019a6SJerry Jelinek 
3527b1019a6SJerry Jelinek /*
3537b1019a6SJerry Jelinek  *
3547b1019a6SJerry Jelinek  * FUNCTION:    OslLoadRsdp
3557b1019a6SJerry Jelinek  *
3567b1019a6SJerry Jelinek  * PARAMETERS:  None
3577b1019a6SJerry Jelinek  *
3587b1019a6SJerry Jelinek  * RETURN:      Status
3597b1019a6SJerry Jelinek  *
3607b1019a6SJerry Jelinek  * DESCRIPTION: Scan and load RSDP.
3617b1019a6SJerry Jelinek  * See the find_rsdp() function in usr/src/uts/i86pc/os/fakebop.c, which is how
3627b1019a6SJerry Jelinek  * the kernel finds the RSDP. That algorithm matches AcpiFindRootPointer().
363760a9770SToomas Soome  *
364760a9770SToomas Soome  * If the system is not using BIOS, and ACPI information was passed to the
365760a9770SToomas Soome  * system from the boot loader, then the RSDP is recorded in the "acpi-root-tab"
366760a9770SToomas Soome  * property.
367760a9770SToomas Soome  *
368760a9770SToomas Soome  * The code here is derived from AcpiFindRootPointer, except that we will
369760a9770SToomas Soome  * try the "acpi-root-tab" property first. If the property does not exist or
370760a9770SToomas Soome  * we do not find the root, then we scan the EBDA. Finally, we will search
371760a9770SToomas Soome  * the BIOS and copy the table if found.
3727b1019a6SJerry Jelinek  */
3737b1019a6SJerry Jelinek static ACPI_STATUS
OslLoadRsdp(void)3747b1019a6SJerry Jelinek OslLoadRsdp(void)
3757b1019a6SJerry Jelinek {
376760a9770SToomas Soome 	UINT8			*mapp = NULL;
3777b1019a6SJerry Jelinek 	ACPI_TABLE_HEADER	*tblp;
378760a9770SToomas Soome 	ACPI_SIZE		mapsize = sizeof (ACPI_TABLE_RSDP);
3797b1019a6SJerry Jelinek 	ACPI_PHYSICAL_ADDRESS	physaddr;
380760a9770SToomas Soome 	di_node_t		root;
381760a9770SToomas Soome 	int64_t			*val64;
382760a9770SToomas Soome 
383760a9770SToomas Soome 	if ((root = di_init("/", DINFOPROP)) != DI_NODE_NIL) {
384760a9770SToomas Soome 		if (di_prop_lookup_int64(DDI_DEV_T_ANY, root,
385760a9770SToomas Soome 		    "acpi-root-tab", &val64) == 1) {
386760a9770SToomas Soome 			physaddr = (ACPI_PHYSICAL_ADDRESS)*val64;
387760a9770SToomas Soome 			mapp = AcpiOsMapMemory(physaddr, mapsize);
388760a9770SToomas Soome 		}
389760a9770SToomas Soome 		di_fini(root);
390760a9770SToomas Soome 	}
391760a9770SToomas Soome 
392760a9770SToomas Soome 	if (mapp != NULL) {
393760a9770SToomas Soome 		tblp = ACPI_CAST_PTR(ACPI_TABLE_HEADER,
394760a9770SToomas Soome 		    AcpiTbScanMemoryForRsdp(mapp, mapsize));
395760a9770SToomas Soome 		if (tblp != NULL) {
396760a9770SToomas Soome 			physaddr += (ACPI_PHYSICAL_ADDRESS)
397760a9770SToomas Soome 			    ACPI_PTR_DIFF(tblp, mapp);
398760a9770SToomas Soome 			Gbl_RsdpAddress = physaddr;
399760a9770SToomas Soome 			memcpy(&Gbl_Rsdp, tblp, sizeof (ACPI_TABLE_RSDP));
400760a9770SToomas Soome 			AcpiOsUnmapMemory(mapp, mapsize);
401760a9770SToomas Soome 			return (AE_OK);
402760a9770SToomas Soome 		}
403760a9770SToomas Soome 		AcpiOsUnmapMemory(mapp, mapsize);
404760a9770SToomas Soome 	}
4057b1019a6SJerry Jelinek 
4067b1019a6SJerry Jelinek 	/* 1a) Get the location of the Extended BIOS Data Area (EBDA) */
4077b1019a6SJerry Jelinek 	mapp = AcpiOsMapMemory((ACPI_PHYSICAL_ADDRESS)ACPI_EBDA_PTR_LOCATION,
4087b1019a6SJerry Jelinek 	    ACPI_EBDA_PTR_LENGTH);
4097b1019a6SJerry Jelinek 	if (mapp == NULL)
4107b1019a6SJerry Jelinek 		goto try_bios;
4117b1019a6SJerry Jelinek 
4127b1019a6SJerry Jelinek 	ACPI_MOVE_16_TO_32(&physaddr, mapp);
4137b1019a6SJerry Jelinek 
4147b1019a6SJerry Jelinek 	/* Convert segment part to physical address */
4157b1019a6SJerry Jelinek 	physaddr <<= 4;
4167b1019a6SJerry Jelinek 	AcpiOsUnmapMemory(mapp, ACPI_EBDA_PTR_LENGTH);
4177b1019a6SJerry Jelinek 
4187b1019a6SJerry Jelinek 	/* EBDA present? */
4197b1019a6SJerry Jelinek 	if (physaddr <= 0x400)
4207b1019a6SJerry Jelinek 		goto try_bios;
4217b1019a6SJerry Jelinek 
4227b1019a6SJerry Jelinek 	/*
4237b1019a6SJerry Jelinek 	 * 1b) Search EBDA paragraphs (EBDA is required to be a minimum of 1K
4247b1019a6SJerry Jelinek 	 * length)
4257b1019a6SJerry Jelinek 	 */
4267b1019a6SJerry Jelinek 	mapp = AcpiOsMapMemory(physaddr, ACPI_EBDA_WINDOW_SIZE);
4277b1019a6SJerry Jelinek 	if (mapp == NULL) {
4287b1019a6SJerry Jelinek 		(void) fprintf(stderr, "EBDA (0x%p) found, but is not "
4297b1019a6SJerry Jelinek 		    "mappable\n", physaddr);
4307b1019a6SJerry Jelinek 		goto try_bios;
4317b1019a6SJerry Jelinek 	}
4327b1019a6SJerry Jelinek 
4337b1019a6SJerry Jelinek 	tblp = ACPI_CAST_PTR(ACPI_TABLE_HEADER,
4347b1019a6SJerry Jelinek 	    AcpiTbScanMemoryForRsdp(mapp, ACPI_EBDA_WINDOW_SIZE));
4357b1019a6SJerry Jelinek 	if (tblp != NULL) {
4367b1019a6SJerry Jelinek 		physaddr += (ACPI_PHYSICAL_ADDRESS) ACPI_PTR_DIFF(tblp, mapp);
4377b1019a6SJerry Jelinek 		Gbl_RsdpAddress = physaddr;
4387b1019a6SJerry Jelinek 		memcpy(&Gbl_Rsdp, tblp, sizeof (ACPI_TABLE_RSDP));
4397b1019a6SJerry Jelinek 		AcpiOsUnmapMemory(mapp, ACPI_EBDA_WINDOW_SIZE);
4407b1019a6SJerry Jelinek 
4417b1019a6SJerry Jelinek 		return (AE_OK);
4427b1019a6SJerry Jelinek 	}
4437b1019a6SJerry Jelinek 	AcpiOsUnmapMemory(mapp, ACPI_EBDA_WINDOW_SIZE);
4447b1019a6SJerry Jelinek 
4457b1019a6SJerry Jelinek try_bios:
4467b1019a6SJerry Jelinek 	/* Try to get RSDP from BIOS memory */
447*6eda3793SToomas Soome 	if (Gbl_RsdpBase != 0) {
4487b1019a6SJerry Jelinek 		physaddr = Gbl_RsdpBase;
4497b1019a6SJerry Jelinek 		mapsize = sizeof (ACPI_TABLE_RSDP);
4507b1019a6SJerry Jelinek 	} else {
4517b1019a6SJerry Jelinek 		physaddr = ACPI_HI_RSDP_WINDOW_BASE;
4527b1019a6SJerry Jelinek 		mapsize = ACPI_HI_RSDP_WINDOW_SIZE;
4537b1019a6SJerry Jelinek 	}
4547b1019a6SJerry Jelinek 
4557b1019a6SJerry Jelinek 	mapp = AcpiOsMapMemory(physaddr, mapsize);
4567b1019a6SJerry Jelinek 	if (mapp == NULL)
4577b1019a6SJerry Jelinek 		return (OslGetLastStatus(AE_BAD_ADDRESS));
4587b1019a6SJerry Jelinek 
4597b1019a6SJerry Jelinek 	/* Search low memory for the RSDP */
4607b1019a6SJerry Jelinek 	tblp = ACPI_CAST_PTR(ACPI_TABLE_HEADER,
4617b1019a6SJerry Jelinek 	    AcpiTbScanMemoryForRsdp(mapp, mapsize));
4627b1019a6SJerry Jelinek 	if (tblp == NULL) {
4637b1019a6SJerry Jelinek 		AcpiOsUnmapMemory(mapp, mapsize);
4647b1019a6SJerry Jelinek 		return (AE_NOT_FOUND);
4657b1019a6SJerry Jelinek 	}
4667b1019a6SJerry Jelinek 
4677b1019a6SJerry Jelinek 	physaddr += (ACPI_PHYSICAL_ADDRESS) ACPI_PTR_DIFF(tblp, mapp);
4687b1019a6SJerry Jelinek 	Gbl_RsdpAddress = physaddr;
4697b1019a6SJerry Jelinek 	memcpy(&Gbl_Rsdp, tblp, sizeof (ACPI_TABLE_RSDP));
4707b1019a6SJerry Jelinek 	AcpiOsUnmapMemory(mapp, mapsize);
4717b1019a6SJerry Jelinek 
4727b1019a6SJerry Jelinek 	return (AE_OK);
4737b1019a6SJerry Jelinek }
4747b1019a6SJerry Jelinek 
4757b1019a6SJerry Jelinek /*
4767b1019a6SJerry Jelinek  *
4777b1019a6SJerry Jelinek  * FUNCTION:    OslCanUseXsdt
4787b1019a6SJerry Jelinek  *
4797b1019a6SJerry Jelinek  * PARAMETERS:  None
4807b1019a6SJerry Jelinek  *
4817b1019a6SJerry Jelinek  * RETURN:      TRUE if XSDT is allowed to be used.
4827b1019a6SJerry Jelinek  *
4837b1019a6SJerry Jelinek  * DESCRIPTION: This function collects logic that can be used to determine if
4847b1019a6SJerry Jelinek  *              XSDT should be used instead of RSDT.
4857b1019a6SJerry Jelinek  *
4867b1019a6SJerry Jelinek  */
4877b1019a6SJerry Jelinek static BOOLEAN
OslCanUseXsdt(void)4887b1019a6SJerry Jelinek OslCanUseXsdt(void)
4897b1019a6SJerry Jelinek {
4907b1019a6SJerry Jelinek 	if (Gbl_Revision && !AcpiGbl_DoNotUseXsdt) {
4917b1019a6SJerry Jelinek 		return (TRUE);
4927b1019a6SJerry Jelinek 	} else {
4937b1019a6SJerry Jelinek 		return (FALSE);
4947b1019a6SJerry Jelinek 	}
4957b1019a6SJerry Jelinek }
4967b1019a6SJerry Jelinek 
4977b1019a6SJerry Jelinek /*
4987b1019a6SJerry Jelinek  *
4997b1019a6SJerry Jelinek  * FUNCTION:    OslTableInitialize
5007b1019a6SJerry Jelinek  *
5017b1019a6SJerry Jelinek  * PARAMETERS:  None
5027b1019a6SJerry Jelinek  *
5037b1019a6SJerry Jelinek  * RETURN:      Status
5047b1019a6SJerry Jelinek  *
5057b1019a6SJerry Jelinek  * DESCRIPTION: Initialize ACPI table data. Get and store main ACPI tables to
5067b1019a6SJerry Jelinek  *              local variables. Main ACPI tables include RSDT, FADT, RSDT,
5077b1019a6SJerry Jelinek  *              and/or XSDT.
5087b1019a6SJerry Jelinek  *
5097b1019a6SJerry Jelinek  */
5107b1019a6SJerry Jelinek static ACPI_STATUS
OslTableInitialize(void)5117b1019a6SJerry Jelinek OslTableInitialize(void)
5127b1019a6SJerry Jelinek {
5137b1019a6SJerry Jelinek 	ACPI_STATUS		Status;
5147b1019a6SJerry Jelinek 	ACPI_PHYSICAL_ADDRESS	Address;
5157b1019a6SJerry Jelinek 
5167b1019a6SJerry Jelinek 	if (Gbl_TableListInitialized) {
5177b1019a6SJerry Jelinek 		return (AE_OK);
5187b1019a6SJerry Jelinek 	}
5197b1019a6SJerry Jelinek 
5207b1019a6SJerry Jelinek 	/* Get RSDP from memory */
5217b1019a6SJerry Jelinek 
5227b1019a6SJerry Jelinek 	Status = OslLoadRsdp();
5237b1019a6SJerry Jelinek 	if (ACPI_FAILURE(Status)) {
5247b1019a6SJerry Jelinek 		return (Status);
5257b1019a6SJerry Jelinek 	}
5267b1019a6SJerry Jelinek 
5277b1019a6SJerry Jelinek 	/* Get XSDT from memory */
5287b1019a6SJerry Jelinek 
5297b1019a6SJerry Jelinek 	if (Gbl_Rsdp.Revision && !Gbl_DoNotDumpXsdt) {
5307b1019a6SJerry Jelinek 		if (Gbl_Xsdt) {
5317b1019a6SJerry Jelinek 			free(Gbl_Xsdt);
5327b1019a6SJerry Jelinek 			Gbl_Xsdt = NULL;
5337b1019a6SJerry Jelinek 		}
5347b1019a6SJerry Jelinek 
5357b1019a6SJerry Jelinek 		Gbl_Revision = 2;
5367b1019a6SJerry Jelinek 		Status = OslGetBiosTable(ACPI_SIG_XSDT, 0,
5377b1019a6SJerry Jelinek 		    ACPI_CAST_PTR(ACPI_TABLE_HEADER *, &Gbl_Xsdt), &Address);
5387b1019a6SJerry Jelinek 		if (ACPI_FAILURE(Status)) {
5397b1019a6SJerry Jelinek 			return (Status);
5407b1019a6SJerry Jelinek 		}
5417b1019a6SJerry Jelinek 	}
5427b1019a6SJerry Jelinek 
5437b1019a6SJerry Jelinek 	/* Get RSDT from memory */
5447b1019a6SJerry Jelinek 
5457b1019a6SJerry Jelinek 	if (Gbl_Rsdp.RsdtPhysicalAddress) {
5467b1019a6SJerry Jelinek 		if (Gbl_Rsdt) {
5477b1019a6SJerry Jelinek 			free(Gbl_Rsdt);
5487b1019a6SJerry Jelinek 			Gbl_Rsdt = NULL;
5497b1019a6SJerry Jelinek 		}
5507b1019a6SJerry Jelinek 
5517b1019a6SJerry Jelinek 		Status = OslGetBiosTable(ACPI_SIG_RSDT, 0,
5527b1019a6SJerry Jelinek 		    ACPI_CAST_PTR(ACPI_TABLE_HEADER *, &Gbl_Rsdt), &Address);
5537b1019a6SJerry Jelinek 		if (ACPI_FAILURE(Status)) {
5547b1019a6SJerry Jelinek 			return (Status);
5557b1019a6SJerry Jelinek 		}
5567b1019a6SJerry Jelinek 	}
5577b1019a6SJerry Jelinek 
5587b1019a6SJerry Jelinek 	/* Get FADT from memory */
5597b1019a6SJerry Jelinek 
5607b1019a6SJerry Jelinek 	if (Gbl_Fadt) {
5617b1019a6SJerry Jelinek 		free(Gbl_Fadt);
5627b1019a6SJerry Jelinek 		Gbl_Fadt = NULL;
5637b1019a6SJerry Jelinek 	}
5647b1019a6SJerry Jelinek 
5657b1019a6SJerry Jelinek 	Status = OslGetBiosTable(ACPI_SIG_FADT, 0,
5667b1019a6SJerry Jelinek 	    ACPI_CAST_PTR(ACPI_TABLE_HEADER *, &Gbl_Fadt), &Gbl_FadtAddress);
5677b1019a6SJerry Jelinek 	if (ACPI_FAILURE(Status)) {
5687b1019a6SJerry Jelinek 		return (Status);
5697b1019a6SJerry Jelinek 	}
5707b1019a6SJerry Jelinek 
5717b1019a6SJerry Jelinek 	/* Add mandatory tables to global table list first */
5727b1019a6SJerry Jelinek 
5737b1019a6SJerry Jelinek 	Status = OslAddTableToList(ACPI_RSDP_NAME);
5747b1019a6SJerry Jelinek 	if (ACPI_FAILURE(Status)) {
5757b1019a6SJerry Jelinek 		return (Status);
5767b1019a6SJerry Jelinek 	}
5777b1019a6SJerry Jelinek 
5787b1019a6SJerry Jelinek 	Status = OslAddTableToList(ACPI_SIG_RSDT);
5797b1019a6SJerry Jelinek 	if (ACPI_FAILURE(Status)) {
5807b1019a6SJerry Jelinek 		return (Status);
5817b1019a6SJerry Jelinek 	}
5827b1019a6SJerry Jelinek 
5837b1019a6SJerry Jelinek 	if (Gbl_Revision == 2) {
5847b1019a6SJerry Jelinek 		Status = OslAddTableToList(ACPI_SIG_XSDT);
5857b1019a6SJerry Jelinek 		if (ACPI_FAILURE(Status)) {
5867b1019a6SJerry Jelinek 			return (Status);
5877b1019a6SJerry Jelinek 		}
5887b1019a6SJerry Jelinek 	}
5897b1019a6SJerry Jelinek 
5907b1019a6SJerry Jelinek 	Status = OslAddTableToList(ACPI_SIG_DSDT);
5917b1019a6SJerry Jelinek 	if (ACPI_FAILURE(Status)) {
5927b1019a6SJerry Jelinek 		return (Status);
5937b1019a6SJerry Jelinek 	}
5947b1019a6SJerry Jelinek 
5957b1019a6SJerry Jelinek 	Status = OslAddTableToList(ACPI_SIG_FACS);
5967b1019a6SJerry Jelinek 	if (ACPI_FAILURE(Status)) {
5977b1019a6SJerry Jelinek 		return (Status);
5987b1019a6SJerry Jelinek 	}
5997b1019a6SJerry Jelinek 
6007b1019a6SJerry Jelinek 	/* Add all tables found in the memory */
6017b1019a6SJerry Jelinek 
6027b1019a6SJerry Jelinek 	Status = OslListBiosTables();
6037b1019a6SJerry Jelinek 	if (ACPI_FAILURE(Status)) {
6047b1019a6SJerry Jelinek 		return (Status);
6057b1019a6SJerry Jelinek 	}
6067b1019a6SJerry Jelinek 
6077b1019a6SJerry Jelinek 	Gbl_TableListInitialized = TRUE;
6087b1019a6SJerry Jelinek 	return (AE_OK);
6097b1019a6SJerry Jelinek }
6107b1019a6SJerry Jelinek 
6117b1019a6SJerry Jelinek 
6127b1019a6SJerry Jelinek /*
6137b1019a6SJerry Jelinek  *
6147b1019a6SJerry Jelinek  * FUNCTION:    OslListBiosTables
6157b1019a6SJerry Jelinek  *
6167b1019a6SJerry Jelinek  * PARAMETERS:  None
6177b1019a6SJerry Jelinek  *
6187b1019a6SJerry Jelinek  * RETURN:      Status; Table list is initialized if AE_OK.
6197b1019a6SJerry Jelinek  *
6207b1019a6SJerry Jelinek  * DESCRIPTION: Add ACPI tables to the table list from memory.
6217b1019a6SJerry Jelinek  */
6227b1019a6SJerry Jelinek static ACPI_STATUS
OslListBiosTables(void)6237b1019a6SJerry Jelinek OslListBiosTables(void)
6247b1019a6SJerry Jelinek {
6257b1019a6SJerry Jelinek 	ACPI_TABLE_HEADER	*MappedTable = NULL;
6267b1019a6SJerry Jelinek 	UINT8			*TableData;
6277b1019a6SJerry Jelinek 	UINT32			NumberOfTables;
6287b1019a6SJerry Jelinek 	UINT8			ItemSize;
6297b1019a6SJerry Jelinek 	ACPI_PHYSICAL_ADDRESS	TableAddress = 0;
6307b1019a6SJerry Jelinek 	ACPI_STATUS		Status = AE_OK;
6317b1019a6SJerry Jelinek 	UINT32			i;
6327b1019a6SJerry Jelinek 
6337b1019a6SJerry Jelinek 	if (OslCanUseXsdt()) {
6347b1019a6SJerry Jelinek 		ItemSize = sizeof (UINT64);
6357b1019a6SJerry Jelinek 		TableData = ACPI_CAST8(Gbl_Xsdt) + sizeof (ACPI_TABLE_HEADER);
6367b1019a6SJerry Jelinek 		NumberOfTables = (UINT32)
6377b1019a6SJerry Jelinek 		    ((Gbl_Xsdt->Header.Length - sizeof (ACPI_TABLE_HEADER))
6387b1019a6SJerry Jelinek 		    / ItemSize);
6397b1019a6SJerry Jelinek 
6407b1019a6SJerry Jelinek 	} else {
6417b1019a6SJerry Jelinek 		/* Use RSDT if XSDT is not available */
6427b1019a6SJerry Jelinek 		ItemSize = sizeof (UINT32);
6437b1019a6SJerry Jelinek 		TableData = ACPI_CAST8(Gbl_Rsdt) + sizeof (ACPI_TABLE_HEADER);
6447b1019a6SJerry Jelinek 		NumberOfTables = (UINT32)
6457b1019a6SJerry Jelinek 		    ((Gbl_Rsdt->Header.Length - sizeof (ACPI_TABLE_HEADER))
6467b1019a6SJerry Jelinek 		    / ItemSize);
6477b1019a6SJerry Jelinek 	}
6487b1019a6SJerry Jelinek 
6497b1019a6SJerry Jelinek 	/* Search RSDT/XSDT for the requested table */
6507b1019a6SJerry Jelinek 
6517b1019a6SJerry Jelinek 	for (i = 0; i < NumberOfTables; ++i, TableData += ItemSize) {
6527b1019a6SJerry Jelinek 		if (OslCanUseXsdt()) {
6537b1019a6SJerry Jelinek 			TableAddress =
6547b1019a6SJerry Jelinek 			    (ACPI_PHYSICAL_ADDRESS) (*ACPI_CAST64(TableData));
6557b1019a6SJerry Jelinek 		} else {
6567b1019a6SJerry Jelinek 			TableAddress =
6577b1019a6SJerry Jelinek 			    (ACPI_PHYSICAL_ADDRESS) (*ACPI_CAST32(TableData));
6587b1019a6SJerry Jelinek 		}
6597b1019a6SJerry Jelinek 
6607b1019a6SJerry Jelinek 		/* Skip NULL entries in RSDT/XSDT */
661*6eda3793SToomas Soome 		if (TableAddress == 0) {
6627b1019a6SJerry Jelinek 			continue;
6637b1019a6SJerry Jelinek 		}
6647b1019a6SJerry Jelinek 
6657b1019a6SJerry Jelinek 		Status = OslMapTable(TableAddress, NULL, &MappedTable);
6667b1019a6SJerry Jelinek 		if (ACPI_FAILURE(Status)) {
6677b1019a6SJerry Jelinek 			return (Status);
6687b1019a6SJerry Jelinek 		}
6697b1019a6SJerry Jelinek 
6707b1019a6SJerry Jelinek 		OslAddTableToList(MappedTable->Signature);
6717b1019a6SJerry Jelinek 		OslUnmapTable(MappedTable);
6727b1019a6SJerry Jelinek 	}
6737b1019a6SJerry Jelinek 
6747b1019a6SJerry Jelinek 	return (AE_OK);
6757b1019a6SJerry Jelinek }
6767b1019a6SJerry Jelinek 
6777b1019a6SJerry Jelinek /*
6787b1019a6SJerry Jelinek  *
6797b1019a6SJerry Jelinek  * FUNCTION:    OslGetBiosTable
6807b1019a6SJerry Jelinek  *
6817b1019a6SJerry Jelinek  * PARAMETERS:  Signature       - ACPI Signature for common table. Must be
6827b1019a6SJerry Jelinek  *                                a null terminated 4-character string.
6837b1019a6SJerry Jelinek  *              Instance        - Multiple table support for SSDT/UEFI (0...n)
6847b1019a6SJerry Jelinek  *                                Must be 0 for other tables.
6857b1019a6SJerry Jelinek  *              Table           - Where a pointer to the table is returned
6867b1019a6SJerry Jelinek  *              Address         - Where the table physical address is returned
6877b1019a6SJerry Jelinek  *
6887b1019a6SJerry Jelinek  * RETURN:      Status; Table buffer and physical address returned if AE_OK.
6897b1019a6SJerry Jelinek  *              AE_LIMIT: Instance is beyond valid limit
6907b1019a6SJerry Jelinek  *              AE_NOT_FOUND: A table with the signature was not found
6917b1019a6SJerry Jelinek  *
6927b1019a6SJerry Jelinek  * DESCRIPTION: Get a BIOS provided ACPI table
6937b1019a6SJerry Jelinek  *
6947b1019a6SJerry Jelinek  * NOTE:        Assumes the input signature is uppercase.
6957b1019a6SJerry Jelinek  *
6967b1019a6SJerry Jelinek  */
6977b1019a6SJerry Jelinek static ACPI_STATUS
OslGetBiosTable(char * Signature,UINT32 Instance,ACPI_TABLE_HEADER ** Table,ACPI_PHYSICAL_ADDRESS * Address)6987b1019a6SJerry Jelinek OslGetBiosTable(char *Signature, UINT32 Instance, ACPI_TABLE_HEADER **Table,
6997b1019a6SJerry Jelinek     ACPI_PHYSICAL_ADDRESS *Address)
7007b1019a6SJerry Jelinek {
7017b1019a6SJerry Jelinek 	ACPI_TABLE_HEADER	*LocalTable = NULL;
7027b1019a6SJerry Jelinek 	ACPI_TABLE_HEADER	*MappedTable = NULL;
7037b1019a6SJerry Jelinek 	UINT8			*TableData;
7047b1019a6SJerry Jelinek 	UINT8			NumberOfTables;
7057b1019a6SJerry Jelinek 	UINT8			ItemSize;
7067b1019a6SJerry Jelinek 	UINT32			CurrentInstance = 0;
7077b1019a6SJerry Jelinek 	ACPI_PHYSICAL_ADDRESS	TableAddress = 0;
7087b1019a6SJerry Jelinek 	UINT32			TableLength = 0;
7097b1019a6SJerry Jelinek 	ACPI_STATUS		Status = AE_OK;
7107b1019a6SJerry Jelinek 	UINT32			i;
7117b1019a6SJerry Jelinek 
7127b1019a6SJerry Jelinek 	/* Handle special tables whose addresses are not in RSDT/XSDT */
7137b1019a6SJerry Jelinek 
7147b1019a6SJerry Jelinek 	if (ACPI_COMPARE_NAME(Signature, ACPI_RSDP_NAME) ||
7157b1019a6SJerry Jelinek 	    ACPI_COMPARE_NAME(Signature, ACPI_SIG_RSDT) ||
7167b1019a6SJerry Jelinek 	    ACPI_COMPARE_NAME(Signature, ACPI_SIG_XSDT) ||
7177b1019a6SJerry Jelinek 	    ACPI_COMPARE_NAME(Signature, ACPI_SIG_DSDT) ||
7187b1019a6SJerry Jelinek 	    ACPI_COMPARE_NAME(Signature, ACPI_SIG_FACS)) {
7197b1019a6SJerry Jelinek 		if (Instance > 0) {
7207b1019a6SJerry Jelinek 			return (AE_LIMIT);
7217b1019a6SJerry Jelinek 		}
7227b1019a6SJerry Jelinek 
7237b1019a6SJerry Jelinek 		/*
7247b1019a6SJerry Jelinek 		 * Get the appropriate address, either 32-bit or 64-bit. Be very
7257b1019a6SJerry Jelinek 		 * careful about the FADT length and validate table addresses.
7267b1019a6SJerry Jelinek 		 * Note: The 64-bit addresses have priority.
7277b1019a6SJerry Jelinek 		 */
7287b1019a6SJerry Jelinek 		if (ACPI_COMPARE_NAME(Signature, ACPI_SIG_DSDT)) {
7297b1019a6SJerry Jelinek 			if ((Gbl_Fadt->Header.Length >= MIN_FADT_FOR_XDSDT) &&
7307b1019a6SJerry Jelinek 			    Gbl_Fadt->XDsdt) {
7317b1019a6SJerry Jelinek 				TableAddress =
7327b1019a6SJerry Jelinek 				    (ACPI_PHYSICAL_ADDRESS) Gbl_Fadt->XDsdt;
7337b1019a6SJerry Jelinek 
7347b1019a6SJerry Jelinek 			} else if (Gbl_Fadt->Header.Length >=
7357b1019a6SJerry Jelinek 			    MIN_FADT_FOR_DSDT && Gbl_Fadt->Dsdt) {
7367b1019a6SJerry Jelinek 				TableAddress =
7377b1019a6SJerry Jelinek 				    (ACPI_PHYSICAL_ADDRESS) Gbl_Fadt->Dsdt;
7387b1019a6SJerry Jelinek 			}
7397b1019a6SJerry Jelinek 
7407b1019a6SJerry Jelinek 		} else if (ACPI_COMPARE_NAME(Signature, ACPI_SIG_FACS)) {
7417b1019a6SJerry Jelinek 			if ((Gbl_Fadt->Header.Length >= MIN_FADT_FOR_XFACS) &&
7427b1019a6SJerry Jelinek 			    Gbl_Fadt->XFacs) {
7437b1019a6SJerry Jelinek 				TableAddress =
7447b1019a6SJerry Jelinek 				    (ACPI_PHYSICAL_ADDRESS) Gbl_Fadt->XFacs;
7457b1019a6SJerry Jelinek 
7467b1019a6SJerry Jelinek 			} else if (Gbl_Fadt->Header.Length >=
7477b1019a6SJerry Jelinek 			    MIN_FADT_FOR_FACS && Gbl_Fadt->Facs) {
7487b1019a6SJerry Jelinek 				TableAddress =
7497b1019a6SJerry Jelinek 				    (ACPI_PHYSICAL_ADDRESS) Gbl_Fadt->Facs;
7507b1019a6SJerry Jelinek 			}
7517b1019a6SJerry Jelinek 
7527b1019a6SJerry Jelinek 		} else if (ACPI_COMPARE_NAME(Signature, ACPI_SIG_XSDT)) {
7537b1019a6SJerry Jelinek 			if (!Gbl_Revision) {
7547b1019a6SJerry Jelinek 				return (AE_BAD_SIGNATURE);
7557b1019a6SJerry Jelinek 			}
7567b1019a6SJerry Jelinek 			TableAddress = (ACPI_PHYSICAL_ADDRESS)
7577b1019a6SJerry Jelinek 			    Gbl_Rsdp.XsdtPhysicalAddress;
7587b1019a6SJerry Jelinek 
7597b1019a6SJerry Jelinek 		} else if (ACPI_COMPARE_NAME(Signature, ACPI_SIG_RSDT)) {
7607b1019a6SJerry Jelinek 			TableAddress = (ACPI_PHYSICAL_ADDRESS)
7617b1019a6SJerry Jelinek 			    Gbl_Rsdp.RsdtPhysicalAddress;
7627b1019a6SJerry Jelinek 
7637b1019a6SJerry Jelinek 		} else {
7647b1019a6SJerry Jelinek 			TableAddress = (ACPI_PHYSICAL_ADDRESS) Gbl_RsdpAddress;
7657b1019a6SJerry Jelinek 			Signature = ACPI_SIG_RSDP;
7667b1019a6SJerry Jelinek 		}
7677b1019a6SJerry Jelinek 
7687b1019a6SJerry Jelinek 		/* Now we can get the requested special table */
7697b1019a6SJerry Jelinek 
7707b1019a6SJerry Jelinek 		Status = OslMapTable(TableAddress, Signature, &MappedTable);
7717b1019a6SJerry Jelinek 		if (ACPI_FAILURE(Status)) {
7727b1019a6SJerry Jelinek 			return (Status);
7737b1019a6SJerry Jelinek 		}
7747b1019a6SJerry Jelinek 
7757b1019a6SJerry Jelinek 		TableLength = ApGetTableLength(MappedTable);
7767b1019a6SJerry Jelinek 
7777b1019a6SJerry Jelinek 	} else {
7787b1019a6SJerry Jelinek 		/* Case for a normal ACPI table */
7797b1019a6SJerry Jelinek 		if (OslCanUseXsdt()) {
7807b1019a6SJerry Jelinek 			ItemSize = sizeof (UINT64);
7817b1019a6SJerry Jelinek 			TableData = ACPI_CAST8(Gbl_Xsdt) +
7827b1019a6SJerry Jelinek 			    sizeof (ACPI_TABLE_HEADER);
7837b1019a6SJerry Jelinek 			NumberOfTables = (UINT8) ((Gbl_Xsdt->Header.Length -
7847b1019a6SJerry Jelinek 			    sizeof (ACPI_TABLE_HEADER))
7857b1019a6SJerry Jelinek 			    / ItemSize);
7867b1019a6SJerry Jelinek 
7877b1019a6SJerry Jelinek 		} else {
7887b1019a6SJerry Jelinek 			/* Use RSDT if XSDT is not available */
7897b1019a6SJerry Jelinek 			ItemSize = sizeof (UINT32);
7907b1019a6SJerry Jelinek 			TableData = ACPI_CAST8(Gbl_Rsdt) +
7917b1019a6SJerry Jelinek 			    sizeof (ACPI_TABLE_HEADER);
7927b1019a6SJerry Jelinek 			NumberOfTables = (UINT8) ((Gbl_Rsdt->Header.Length -
7937b1019a6SJerry Jelinek 			    sizeof (ACPI_TABLE_HEADER))
7947b1019a6SJerry Jelinek 			    / ItemSize);
7957b1019a6SJerry Jelinek 		}
7967b1019a6SJerry Jelinek 
7977b1019a6SJerry Jelinek 		/* Search RSDT/XSDT for the requested table */
7987b1019a6SJerry Jelinek 
7997b1019a6SJerry Jelinek 		for (i = 0; i < NumberOfTables; ++i, TableData += ItemSize) {
8007b1019a6SJerry Jelinek 			if (OslCanUseXsdt()) {
8017b1019a6SJerry Jelinek 				TableAddress = (ACPI_PHYSICAL_ADDRESS)
8027b1019a6SJerry Jelinek 				    (*ACPI_CAST64(TableData));
8037b1019a6SJerry Jelinek 			} else {
8047b1019a6SJerry Jelinek 				TableAddress = (ACPI_PHYSICAL_ADDRESS)
8057b1019a6SJerry Jelinek 				    (*ACPI_CAST32(TableData));
8067b1019a6SJerry Jelinek 			}
8077b1019a6SJerry Jelinek 
8087b1019a6SJerry Jelinek 			/* Skip NULL entries in RSDT/XSDT */
8097b1019a6SJerry Jelinek 
810*6eda3793SToomas Soome 			if (TableAddress == 0) {
8117b1019a6SJerry Jelinek 				continue;
8127b1019a6SJerry Jelinek 			}
8137b1019a6SJerry Jelinek 
8147b1019a6SJerry Jelinek 			Status = OslMapTable(TableAddress, NULL, &MappedTable);
8157b1019a6SJerry Jelinek 			if (ACPI_FAILURE(Status)) {
8167b1019a6SJerry Jelinek 				return (Status);
8177b1019a6SJerry Jelinek 			}
8187b1019a6SJerry Jelinek 			TableLength = MappedTable->Length;
8197b1019a6SJerry Jelinek 
8207b1019a6SJerry Jelinek 			/* Does this table match the requested signature? */
8217b1019a6SJerry Jelinek 
8227b1019a6SJerry Jelinek 			if (!ACPI_COMPARE_NAME(MappedTable->Signature,
8237b1019a6SJerry Jelinek 			    Signature)) {
8247b1019a6SJerry Jelinek 				OslUnmapTable(MappedTable);
8257b1019a6SJerry Jelinek 				MappedTable = NULL;
8267b1019a6SJerry Jelinek 				continue;
8277b1019a6SJerry Jelinek 			}
8287b1019a6SJerry Jelinek 
8297b1019a6SJerry Jelinek 			/* Match table instance (for SSDT/UEFI tables) */
8307b1019a6SJerry Jelinek 
8317b1019a6SJerry Jelinek 			if (CurrentInstance != Instance) {
8327b1019a6SJerry Jelinek 				OslUnmapTable(MappedTable);
8337b1019a6SJerry Jelinek 				MappedTable = NULL;
8347b1019a6SJerry Jelinek 				CurrentInstance++;
8357b1019a6SJerry Jelinek 				continue;
8367b1019a6SJerry Jelinek 			}
8377b1019a6SJerry Jelinek 
8387b1019a6SJerry Jelinek 			break;
8397b1019a6SJerry Jelinek 		}
8407b1019a6SJerry Jelinek 	}
8417b1019a6SJerry Jelinek 
8427b1019a6SJerry Jelinek 	if (MappedTable == NULL) {
8437b1019a6SJerry Jelinek 		return (AE_LIMIT);
8447b1019a6SJerry Jelinek 	}
8457b1019a6SJerry Jelinek 
8467b1019a6SJerry Jelinek 	if (TableLength == 0) {
8477b1019a6SJerry Jelinek 		Status = AE_BAD_HEADER;
8487b1019a6SJerry Jelinek 		goto Exit;
8497b1019a6SJerry Jelinek 	}
8507b1019a6SJerry Jelinek 
8517b1019a6SJerry Jelinek 	/* Copy table to local buffer and return it */
8527b1019a6SJerry Jelinek 
8537b1019a6SJerry Jelinek 	LocalTable = calloc(1, TableLength);
8547b1019a6SJerry Jelinek 	if (LocalTable == NULL) {
8557b1019a6SJerry Jelinek 		Status = AE_NO_MEMORY;
8567b1019a6SJerry Jelinek 		goto Exit;
8577b1019a6SJerry Jelinek 	}
8587b1019a6SJerry Jelinek 
8597b1019a6SJerry Jelinek 	memcpy(LocalTable, MappedTable, TableLength);
8607b1019a6SJerry Jelinek 	*Address = TableAddress;
8617b1019a6SJerry Jelinek 	*Table = LocalTable;
8627b1019a6SJerry Jelinek 
8637b1019a6SJerry Jelinek Exit:
8647b1019a6SJerry Jelinek 	OslUnmapTable(MappedTable);
8657b1019a6SJerry Jelinek 	return (Status);
8667b1019a6SJerry Jelinek }
8677b1019a6SJerry Jelinek 
8687b1019a6SJerry Jelinek /*
8697b1019a6SJerry Jelinek  *
8707b1019a6SJerry Jelinek  * FUNCTION:    OslMapTable
8717b1019a6SJerry Jelinek  *
8727b1019a6SJerry Jelinek  * PARAMETERS:  Address             - Address of the table in memory
8737b1019a6SJerry Jelinek  *              Signature           - Optional ACPI Signature for desired table.
8747b1019a6SJerry Jelinek  *                                    Null terminated 4-character string.
8757b1019a6SJerry Jelinek  *              Table               - Where a pointer to the mapped table is
8767b1019a6SJerry Jelinek  *                                    returned
8777b1019a6SJerry Jelinek  *
8787b1019a6SJerry Jelinek  * RETURN:      Status; Mapped table is returned if AE_OK.
8797b1019a6SJerry Jelinek  *              AE_NOT_FOUND: A valid table was not found at the address
8807b1019a6SJerry Jelinek  *
8817b1019a6SJerry Jelinek  * DESCRIPTION: Map entire ACPI table into caller's address space.
8827b1019a6SJerry Jelinek  *
8837b1019a6SJerry Jelinek  */
8847b1019a6SJerry Jelinek static ACPI_STATUS
OslMapTable(ACPI_SIZE Address,char * Signature,ACPI_TABLE_HEADER ** Table)8857b1019a6SJerry Jelinek OslMapTable(ACPI_SIZE Address, char *Signature, ACPI_TABLE_HEADER **Table)
8867b1019a6SJerry Jelinek {
8877b1019a6SJerry Jelinek 	ACPI_TABLE_HEADER	*MappedTable;
8887b1019a6SJerry Jelinek 	UINT32			Length;
8897b1019a6SJerry Jelinek 
890*6eda3793SToomas Soome 	if (Address == 0) {
8917b1019a6SJerry Jelinek 		return (AE_BAD_ADDRESS);
8927b1019a6SJerry Jelinek 	}
8937b1019a6SJerry Jelinek 
8947b1019a6SJerry Jelinek 	/*
8957b1019a6SJerry Jelinek 	 * Map the header so we can get the table length.
8967b1019a6SJerry Jelinek 	 * Use sizeof (ACPI_TABLE_HEADER) as:
8977b1019a6SJerry Jelinek 	 * 1. it is bigger than 24 to include RSDP->Length
8987b1019a6SJerry Jelinek 	 * 2. it is smaller than sizeof (ACPI_TABLE_RSDP)
8997b1019a6SJerry Jelinek 	 */
9007b1019a6SJerry Jelinek 	MappedTable = AcpiOsMapMemory(Address, sizeof (ACPI_TABLE_HEADER));
9017b1019a6SJerry Jelinek 	if (MappedTable == NULL) {
9027b1019a6SJerry Jelinek 		(void) fprintf(stderr, "Could not map table header at "
9037b1019a6SJerry Jelinek 		    "0x%8.8X%8.8X\n", ACPI_FORMAT_UINT64(Address));
9047b1019a6SJerry Jelinek 		return (OslGetLastStatus(AE_BAD_ADDRESS));
9057b1019a6SJerry Jelinek 	}
9067b1019a6SJerry Jelinek 
9077b1019a6SJerry Jelinek 	/* If specified, signature must match */
9087b1019a6SJerry Jelinek 
9097b1019a6SJerry Jelinek 	if (Signature != NULL) {
9107b1019a6SJerry Jelinek 		if (ACPI_VALIDATE_RSDP_SIG(Signature)) {
9117b1019a6SJerry Jelinek 			if (!ACPI_VALIDATE_RSDP_SIG(MappedTable->Signature)) {
9127b1019a6SJerry Jelinek 				AcpiOsUnmapMemory(MappedTable,
9137b1019a6SJerry Jelinek 				    sizeof (ACPI_TABLE_HEADER));
9147b1019a6SJerry Jelinek 				return (AE_BAD_SIGNATURE);
9157b1019a6SJerry Jelinek 			}
9167b1019a6SJerry Jelinek 		} else if (!ACPI_COMPARE_NAME(Signature,
9177b1019a6SJerry Jelinek 		    MappedTable->Signature)) {
9187b1019a6SJerry Jelinek 			AcpiOsUnmapMemory(MappedTable,
9197b1019a6SJerry Jelinek 			    sizeof (ACPI_TABLE_HEADER));
9207b1019a6SJerry Jelinek 			return (AE_BAD_SIGNATURE);
9217b1019a6SJerry Jelinek 		}
9227b1019a6SJerry Jelinek 	}
9237b1019a6SJerry Jelinek 
9247b1019a6SJerry Jelinek 	/* Map the entire table */
9257b1019a6SJerry Jelinek 
9267b1019a6SJerry Jelinek 	Length = ApGetTableLength(MappedTable);
9277b1019a6SJerry Jelinek 	AcpiOsUnmapMemory(MappedTable, sizeof (ACPI_TABLE_HEADER));
9287b1019a6SJerry Jelinek 	if (Length == 0) {
9297b1019a6SJerry Jelinek 		return (AE_BAD_HEADER);
9307b1019a6SJerry Jelinek 	}
9317b1019a6SJerry Jelinek 
9327b1019a6SJerry Jelinek 	MappedTable = AcpiOsMapMemory(Address, Length);
9337b1019a6SJerry Jelinek 	if (MappedTable == NULL) {
9347b1019a6SJerry Jelinek 		(void) fprintf(stderr, "Could not map table at 0x%8.8X%8.8X "
9357b1019a6SJerry Jelinek 		    "length %8.8X\n", ACPI_FORMAT_UINT64(Address), Length);
9367b1019a6SJerry Jelinek 		return (OslGetLastStatus(AE_INVALID_TABLE_LENGTH));
9377b1019a6SJerry Jelinek 	}
9387b1019a6SJerry Jelinek 
9397b1019a6SJerry Jelinek 	(void) ApIsValidChecksum(MappedTable);
9407b1019a6SJerry Jelinek 
9417b1019a6SJerry Jelinek 	*Table = MappedTable;
9427b1019a6SJerry Jelinek 	return (AE_OK);
9437b1019a6SJerry Jelinek }
9447b1019a6SJerry Jelinek 
9457b1019a6SJerry Jelinek 
9467b1019a6SJerry Jelinek /*
9477b1019a6SJerry Jelinek  *
9487b1019a6SJerry Jelinek  * FUNCTION:    OslUnmapTable
9497b1019a6SJerry Jelinek  *
9507b1019a6SJerry Jelinek  * PARAMETERS:  Table               - A pointer to the mapped table
9517b1019a6SJerry Jelinek  *
9527b1019a6SJerry Jelinek  * RETURN:      None
9537b1019a6SJerry Jelinek  *
9547b1019a6SJerry Jelinek  * DESCRIPTION: Unmap entire ACPI table.
9557b1019a6SJerry Jelinek  *
9567b1019a6SJerry Jelinek  */
9577b1019a6SJerry Jelinek static void
OslUnmapTable(ACPI_TABLE_HEADER * Table)9587b1019a6SJerry Jelinek OslUnmapTable(ACPI_TABLE_HEADER *Table)
9597b1019a6SJerry Jelinek {
9607b1019a6SJerry Jelinek 	if (Table != NULL) {
9617b1019a6SJerry Jelinek 		AcpiOsUnmapMemory(Table, ApGetTableLength(Table));
9627b1019a6SJerry Jelinek 	}
9637b1019a6SJerry Jelinek }
9647b1019a6SJerry Jelinek 
9657b1019a6SJerry Jelinek /*
9667b1019a6SJerry Jelinek  *
9677b1019a6SJerry Jelinek  * FUNCTION:    OslTableNameFromFile
9687b1019a6SJerry Jelinek  *
9697b1019a6SJerry Jelinek  * PARAMETERS:  Filename            - File that contains the desired table
9707b1019a6SJerry Jelinek  *              Signature           - Pointer to 4-character buffer to store
9717b1019a6SJerry Jelinek  *                                    extracted table signature.
9727b1019a6SJerry Jelinek  *              Instance            - Pointer to integer to store extracted
9737b1019a6SJerry Jelinek  *                                    table instance number.
9747b1019a6SJerry Jelinek  *
9757b1019a6SJerry Jelinek  * RETURN:      Status; Table name is extracted if AE_OK.
9767b1019a6SJerry Jelinek  *
9777b1019a6SJerry Jelinek  * DESCRIPTION: Extract table signature and instance number from a table file
9787b1019a6SJerry Jelinek  *              name.
9797b1019a6SJerry Jelinek  *
9807b1019a6SJerry Jelinek  */
9817b1019a6SJerry Jelinek static ACPI_STATUS
OslTableNameFromFile(char * Filename,char * Signature,UINT32 * Instance)9827b1019a6SJerry Jelinek OslTableNameFromFile(char *Filename, char *Signature, UINT32 *Instance)
9837b1019a6SJerry Jelinek {
9847b1019a6SJerry Jelinek 	/* Ignore meaningless files */
9857b1019a6SJerry Jelinek 
9867b1019a6SJerry Jelinek 	if (strlen(Filename) < ACPI_NAME_SIZE) {
9877b1019a6SJerry Jelinek 		return (AE_BAD_SIGNATURE);
9887b1019a6SJerry Jelinek 	}
9897b1019a6SJerry Jelinek 
9907b1019a6SJerry Jelinek 	/* Extract instance number */
9917b1019a6SJerry Jelinek 
9927b1019a6SJerry Jelinek 	if (isdigit((int)Filename[ACPI_NAME_SIZE])) {
9937b1019a6SJerry Jelinek 		sscanf(&Filename[ACPI_NAME_SIZE], "%u", Instance);
9947b1019a6SJerry Jelinek 	} else if (strlen(Filename) != ACPI_NAME_SIZE) {
9957b1019a6SJerry Jelinek 		return (AE_BAD_SIGNATURE);
9967b1019a6SJerry Jelinek 	} else {
9977b1019a6SJerry Jelinek 		*Instance = 0;
9987b1019a6SJerry Jelinek 	}
9997b1019a6SJerry Jelinek 
10007b1019a6SJerry Jelinek 	/* Extract signature */
10017b1019a6SJerry Jelinek 
10027b1019a6SJerry Jelinek 	ACPI_MOVE_NAME(Signature, Filename);
10037b1019a6SJerry Jelinek 	return (AE_OK);
10047b1019a6SJerry Jelinek }
10057b1019a6SJerry Jelinek 
10067b1019a6SJerry Jelinek void *
AcpiOsMapMemory(ACPI_PHYSICAL_ADDRESS Where,ACPI_SIZE Length)10077b1019a6SJerry Jelinek AcpiOsMapMemory(ACPI_PHYSICAL_ADDRESS Where, ACPI_SIZE Length)
10087b1019a6SJerry Jelinek {
10097b1019a6SJerry Jelinek 	int fd;
10107b1019a6SJerry Jelinek 	void *p;
10117b1019a6SJerry Jelinek 	ulong_t offset;
10127b1019a6SJerry Jelinek 
10137b1019a6SJerry Jelinek 	if ((fd = open("/dev/xsvc", O_RDONLY)) < 0)
10147b1019a6SJerry Jelinek 		return (NULL);
10157b1019a6SJerry Jelinek 
10167b1019a6SJerry Jelinek 	if (pagesize == 0) {
10177b1019a6SJerry Jelinek 		pagesize = getpagesize();
10187b1019a6SJerry Jelinek 	}
10197b1019a6SJerry Jelinek 
10207b1019a6SJerry Jelinek 	offset = Where % pagesize;
10217b1019a6SJerry Jelinek 	p = mmap(NULL, Length + offset, PROT_READ, MAP_SHARED | MAP_NORESERVE,
10227b1019a6SJerry Jelinek 	    fd, Where - offset);
10237b1019a6SJerry Jelinek 
10247b1019a6SJerry Jelinek 	(void) close(fd);
10257b1019a6SJerry Jelinek 
10267b1019a6SJerry Jelinek 	if (p == MAP_FAILED)
10277b1019a6SJerry Jelinek 		return (NULL);
10287b1019a6SJerry Jelinek 	p = (char *)p + offset;
10297b1019a6SJerry Jelinek 	return (p);
10307b1019a6SJerry Jelinek }
10317b1019a6SJerry Jelinek 
10327b1019a6SJerry Jelinek void
AcpiOsUnmapMemory(void * LogicalAddress,ACPI_SIZE Size)10337b1019a6SJerry Jelinek AcpiOsUnmapMemory(void *LogicalAddress, ACPI_SIZE Size)
10347b1019a6SJerry Jelinek {
10357b1019a6SJerry Jelinek 	ulong_t offset;
10367b1019a6SJerry Jelinek 	void *p;
10377b1019a6SJerry Jelinek 
10387b1019a6SJerry Jelinek 	offset = (ulong_t)LogicalAddress % pagesize;
10397b1019a6SJerry Jelinek 	p = (void *)((char *)LogicalAddress - offset);
10407b1019a6SJerry Jelinek 
10417b1019a6SJerry Jelinek 	(void) munmap(p, Size + offset);
10427b1019a6SJerry Jelinek }
1043