xref: /titanic_44/usr/src/cmd/acpi/acpidump/osillumostbl.c (revision cb56572868bfc488bbd3ab847b09db2a25554d44)
1*cb565728SJerry Jelinek /*
2*cb565728SJerry Jelinek  *
3*cb565728SJerry Jelinek  * Module Name: osillumostbl - illumos OSL for obtaining ACPI tables
4*cb565728SJerry Jelinek  * This file is derived from the Intel oslinuxtbl source file.
5*cb565728SJerry Jelinek  *
6*cb565728SJerry Jelinek  */
7*cb565728SJerry Jelinek 
8*cb565728SJerry Jelinek /*
9*cb565728SJerry Jelinek  * Copyright (C) 2000 - 2016, Intel Corp.
10*cb565728SJerry Jelinek  * All rights reserved.
11*cb565728SJerry Jelinek  *
12*cb565728SJerry Jelinek  * Redistribution and use in source and binary forms, with or without
13*cb565728SJerry Jelinek  * modification, are permitted provided that the following conditions
14*cb565728SJerry Jelinek  * are met:
15*cb565728SJerry Jelinek  * 1. Redistributions of source code must retain the above copyright
16*cb565728SJerry Jelinek  *    notice, this list of conditions, and the following disclaimer,
17*cb565728SJerry Jelinek  *    without modification.
18*cb565728SJerry Jelinek  * 2. Redistributions in binary form must reproduce at minimum a disclaimer
19*cb565728SJerry Jelinek  *    substantially similar to the "NO WARRANTY" disclaimer below
20*cb565728SJerry Jelinek  *    ("Disclaimer") and any redistribution must be conditioned upon
21*cb565728SJerry Jelinek  *    including a substantially similar Disclaimer requirement for further
22*cb565728SJerry Jelinek  *    binary redistribution.
23*cb565728SJerry Jelinek  * 3. Neither the names of the above-listed copyright holders nor the names
24*cb565728SJerry Jelinek  *    of any contributors may be used to endorse or promote products derived
25*cb565728SJerry Jelinek  *    from this software without specific prior written permission.
26*cb565728SJerry Jelinek  *
27*cb565728SJerry Jelinek  * Alternatively, this software may be distributed under the terms of the
28*cb565728SJerry Jelinek  * GNU General Public License ("GPL") version 2 as published by the Free
29*cb565728SJerry Jelinek  * Software Foundation.
30*cb565728SJerry Jelinek  *
31*cb565728SJerry Jelinek  * NO WARRANTY
32*cb565728SJerry Jelinek  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
33*cb565728SJerry Jelinek  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
34*cb565728SJerry Jelinek  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR
35*cb565728SJerry Jelinek  * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
36*cb565728SJerry Jelinek  * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
37*cb565728SJerry Jelinek  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
38*cb565728SJerry Jelinek  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
39*cb565728SJerry Jelinek  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
40*cb565728SJerry Jelinek  * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
41*cb565728SJerry Jelinek  * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
42*cb565728SJerry Jelinek  * POSSIBILITY OF SUCH DAMAGES.
43*cb565728SJerry Jelinek  */
44*cb565728SJerry Jelinek 
45*cb565728SJerry Jelinek /*
46*cb565728SJerry Jelinek  * Copyright 2016 Joyent, Inc.
47*cb565728SJerry Jelinek  */
48*cb565728SJerry Jelinek 
49*cb565728SJerry Jelinek #include <stdarg.h>
50*cb565728SJerry Jelinek #include <string.h>
51*cb565728SJerry Jelinek #include <stdlib.h>
52*cb565728SJerry Jelinek #include <unistd.h>
53*cb565728SJerry Jelinek #include "acpidump.h"
54*cb565728SJerry Jelinek 
55*cb565728SJerry Jelinek #define	_COMPONENT	ACPI_OS_SERVICES
56*cb565728SJerry Jelinek     ACPI_MODULE_NAME("osillumostbl")
57*cb565728SJerry Jelinek 
58*cb565728SJerry Jelinek /* List of information about obtained ACPI tables */
59*cb565728SJerry Jelinek 
60*cb565728SJerry Jelinek typedef struct osl_table_info
61*cb565728SJerry Jelinek {
62*cb565728SJerry Jelinek 	struct osl_table_info	*Next;
63*cb565728SJerry Jelinek 	UINT32			Instance;
64*cb565728SJerry Jelinek 	char			Signature[ACPI_NAME_SIZE];
65*cb565728SJerry Jelinek } OSL_TABLE_INFO;
66*cb565728SJerry Jelinek 
67*cb565728SJerry Jelinek /* Local prototypes */
68*cb565728SJerry Jelinek static ACPI_STATUS
69*cb565728SJerry Jelinek OslTableInitialize(void);
70*cb565728SJerry Jelinek static ACPI_STATUS OslTableNameFromFile(char *, char *, UINT32 *);
71*cb565728SJerry Jelinek static ACPI_STATUS OslAddTableToList(char *);
72*cb565728SJerry Jelinek static ACPI_STATUS OslMapTable(ACPI_SIZE, char *, ACPI_TABLE_HEADER **);
73*cb565728SJerry Jelinek static void OslUnmapTable(ACPI_TABLE_HEADER *);
74*cb565728SJerry Jelinek static ACPI_STATUS OslLoadRsdp(void);
75*cb565728SJerry Jelinek static ACPI_STATUS OslListBiosTables(void);
76*cb565728SJerry Jelinek static ACPI_STATUS OslGetBiosTable(char *, UINT32, ACPI_TABLE_HEADER **,
77*cb565728SJerry Jelinek     ACPI_PHYSICAL_ADDRESS *);
78*cb565728SJerry Jelinek static ACPI_STATUS OslGetLastStatus(ACPI_STATUS);
79*cb565728SJerry Jelinek 
80*cb565728SJerry Jelinek static int pagesize;
81*cb565728SJerry Jelinek 
82*cb565728SJerry Jelinek /* Initialization flags */
83*cb565728SJerry Jelinek UINT8			Gbl_TableListInitialized = FALSE;
84*cb565728SJerry Jelinek 
85*cb565728SJerry Jelinek /* Local copies of main ACPI tables */
86*cb565728SJerry Jelinek ACPI_TABLE_RSDP		Gbl_Rsdp;
87*cb565728SJerry Jelinek ACPI_TABLE_FADT		*Gbl_Fadt = NULL;
88*cb565728SJerry Jelinek ACPI_TABLE_RSDT		*Gbl_Rsdt = NULL;
89*cb565728SJerry Jelinek ACPI_TABLE_XSDT		*Gbl_Xsdt = NULL;
90*cb565728SJerry Jelinek 
91*cb565728SJerry Jelinek /* Table addresses */
92*cb565728SJerry Jelinek ACPI_PHYSICAL_ADDRESS	Gbl_FadtAddress = 0;
93*cb565728SJerry Jelinek ACPI_PHYSICAL_ADDRESS	Gbl_RsdpAddress = 0;
94*cb565728SJerry Jelinek 
95*cb565728SJerry Jelinek /* Revision of RSD PTR */
96*cb565728SJerry Jelinek UINT8			Gbl_Revision = 0;
97*cb565728SJerry Jelinek 
98*cb565728SJerry Jelinek OSL_TABLE_INFO		*Gbl_TableListHead = NULL;
99*cb565728SJerry Jelinek UINT32			Gbl_TableCount = 0;
100*cb565728SJerry Jelinek 
101*cb565728SJerry Jelinek /*
102*cb565728SJerry Jelinek  *
103*cb565728SJerry Jelinek  * FUNCTION:    OslGetLastStatus
104*cb565728SJerry Jelinek  *
105*cb565728SJerry Jelinek  * PARAMETERS:  DefaultStatus   - Default error status to return
106*cb565728SJerry Jelinek  *
107*cb565728SJerry Jelinek  * RETURN:      Status; Converted from errno.
108*cb565728SJerry Jelinek  *
109*cb565728SJerry Jelinek  * DESCRIPTION: Get last errno and conver it to ACPI_STATUS.
110*cb565728SJerry Jelinek  *
111*cb565728SJerry Jelinek  */
112*cb565728SJerry Jelinek static ACPI_STATUS
OslGetLastStatus(ACPI_STATUS DefaultStatus)113*cb565728SJerry Jelinek OslGetLastStatus(ACPI_STATUS DefaultStatus)
114*cb565728SJerry Jelinek {
115*cb565728SJerry Jelinek 	switch (errno) {
116*cb565728SJerry Jelinek 	case EACCES:
117*cb565728SJerry Jelinek 	case EPERM:
118*cb565728SJerry Jelinek 		return (AE_ACCESS);
119*cb565728SJerry Jelinek 
120*cb565728SJerry Jelinek 	case ENOENT:
121*cb565728SJerry Jelinek 		return (AE_NOT_FOUND);
122*cb565728SJerry Jelinek 
123*cb565728SJerry Jelinek 	case ENOMEM:
124*cb565728SJerry Jelinek 		return (AE_NO_MEMORY);
125*cb565728SJerry Jelinek 
126*cb565728SJerry Jelinek 	default:
127*cb565728SJerry Jelinek 		return (DefaultStatus);
128*cb565728SJerry Jelinek 	}
129*cb565728SJerry Jelinek }
130*cb565728SJerry Jelinek 
131*cb565728SJerry Jelinek /*
132*cb565728SJerry Jelinek  *
133*cb565728SJerry Jelinek  * FUNCTION:    AcpiOsGetTableByAddress
134*cb565728SJerry Jelinek  *
135*cb565728SJerry Jelinek  * PARAMETERS:  Address         - Physical address of the ACPI table
136*cb565728SJerry Jelinek  *              Table           - Where a pointer to the table is returned
137*cb565728SJerry Jelinek  *
138*cb565728SJerry Jelinek  * RETURN:      Status; Table buffer is returned if AE_OK.
139*cb565728SJerry Jelinek  *              AE_NOT_FOUND: A valid table was not found at the address
140*cb565728SJerry Jelinek  *
141*cb565728SJerry Jelinek  * DESCRIPTION: Get an ACPI table via a physical memory address.
142*cb565728SJerry Jelinek  *
143*cb565728SJerry Jelinek  */
144*cb565728SJerry Jelinek ACPI_STATUS
AcpiOsGetTableByAddress(ACPI_PHYSICAL_ADDRESS Address,ACPI_TABLE_HEADER ** Table)145*cb565728SJerry Jelinek AcpiOsGetTableByAddress(ACPI_PHYSICAL_ADDRESS Address,
146*cb565728SJerry Jelinek     ACPI_TABLE_HEADER **Table)
147*cb565728SJerry Jelinek {
148*cb565728SJerry Jelinek 	UINT32			TableLength;
149*cb565728SJerry Jelinek 	ACPI_TABLE_HEADER	*MappedTable;
150*cb565728SJerry Jelinek 	ACPI_TABLE_HEADER	*LocalTable = NULL;
151*cb565728SJerry Jelinek 	ACPI_STATUS		Status = AE_OK;
152*cb565728SJerry Jelinek 
153*cb565728SJerry Jelinek 	/*
154*cb565728SJerry Jelinek 	 * Get main ACPI tables from memory on first invocation of this
155*cb565728SJerry Jelinek 	 * function
156*cb565728SJerry Jelinek 	 */
157*cb565728SJerry Jelinek 	Status = OslTableInitialize();
158*cb565728SJerry Jelinek 	if (ACPI_FAILURE(Status)) {
159*cb565728SJerry Jelinek 		return (Status);
160*cb565728SJerry Jelinek 	}
161*cb565728SJerry Jelinek 
162*cb565728SJerry Jelinek 	/* Map the table and validate it */
163*cb565728SJerry Jelinek 
164*cb565728SJerry Jelinek 	Status = OslMapTable(Address, NULL, &MappedTable);
165*cb565728SJerry Jelinek 	if (ACPI_FAILURE(Status)) {
166*cb565728SJerry Jelinek 		return (Status);
167*cb565728SJerry Jelinek 	}
168*cb565728SJerry Jelinek 
169*cb565728SJerry Jelinek 	/* Copy table to local buffer and return it */
170*cb565728SJerry Jelinek 
171*cb565728SJerry Jelinek 	TableLength = ApGetTableLength(MappedTable);
172*cb565728SJerry Jelinek 	if (TableLength == 0) {
173*cb565728SJerry Jelinek 		Status = AE_BAD_HEADER;
174*cb565728SJerry Jelinek 		goto Exit;
175*cb565728SJerry Jelinek 	}
176*cb565728SJerry Jelinek 
177*cb565728SJerry Jelinek 	LocalTable = calloc(1, TableLength);
178*cb565728SJerry Jelinek 	if (!LocalTable) {
179*cb565728SJerry Jelinek 		Status = AE_NO_MEMORY;
180*cb565728SJerry Jelinek 		goto Exit;
181*cb565728SJerry Jelinek 	}
182*cb565728SJerry Jelinek 
183*cb565728SJerry Jelinek 	memcpy(LocalTable, MappedTable, TableLength);
184*cb565728SJerry Jelinek 
185*cb565728SJerry Jelinek Exit:
186*cb565728SJerry Jelinek 	OslUnmapTable(MappedTable);
187*cb565728SJerry Jelinek 	*Table = LocalTable;
188*cb565728SJerry Jelinek 	return (Status);
189*cb565728SJerry Jelinek }
190*cb565728SJerry Jelinek 
191*cb565728SJerry Jelinek /*
192*cb565728SJerry Jelinek  *
193*cb565728SJerry Jelinek  * FUNCTION:    AcpiOsGetTableByName
194*cb565728SJerry Jelinek  *
195*cb565728SJerry Jelinek  * PARAMETERS:  Signature       - ACPI Signature for desired table. Must be
196*cb565728SJerry Jelinek  *                                a null terminated 4-character string.
197*cb565728SJerry Jelinek  *              Instance        - Multiple table support for SSDT/UEFI (0...n)
198*cb565728SJerry Jelinek  *                                Must be 0 for other tables.
199*cb565728SJerry Jelinek  *              Table           - Where a pointer to the table is returned
200*cb565728SJerry Jelinek  *              Address         - Where the table physical address is returned
201*cb565728SJerry Jelinek  *
202*cb565728SJerry Jelinek  * RETURN:      Status; Table buffer and physical address returned if AE_OK.
203*cb565728SJerry Jelinek  *              AE_LIMIT: Instance is beyond valid limit
204*cb565728SJerry Jelinek  *              AE_NOT_FOUND: A table with the signature was not found
205*cb565728SJerry Jelinek  *
206*cb565728SJerry Jelinek  * NOTE:        Assumes the input signature is uppercase.
207*cb565728SJerry Jelinek  *
208*cb565728SJerry Jelinek  */
209*cb565728SJerry Jelinek ACPI_STATUS
AcpiOsGetTableByName(char * Signature,UINT32 Instance,ACPI_TABLE_HEADER ** Table,ACPI_PHYSICAL_ADDRESS * Address)210*cb565728SJerry Jelinek AcpiOsGetTableByName(char *Signature, UINT32 Instance,
211*cb565728SJerry Jelinek     ACPI_TABLE_HEADER **Table, ACPI_PHYSICAL_ADDRESS *Address)
212*cb565728SJerry Jelinek {
213*cb565728SJerry Jelinek 	ACPI_STATUS	Status;
214*cb565728SJerry Jelinek 
215*cb565728SJerry Jelinek 	/*
216*cb565728SJerry Jelinek 	 * Get main ACPI tables from memory on first invocation of this
217*cb565728SJerry Jelinek 	 * function
218*cb565728SJerry Jelinek 	 */
219*cb565728SJerry Jelinek 	Status = OslTableInitialize();
220*cb565728SJerry Jelinek 	if (ACPI_FAILURE(Status)) {
221*cb565728SJerry Jelinek 		return (Status);
222*cb565728SJerry Jelinek 	}
223*cb565728SJerry Jelinek 
224*cb565728SJerry Jelinek 	/* attempt to extract it from the RSDT/XSDT */
225*cb565728SJerry Jelinek 	Status = OslGetBiosTable(Signature, Instance, Table, Address);
226*cb565728SJerry Jelinek 
227*cb565728SJerry Jelinek 	return (Status);
228*cb565728SJerry Jelinek }
229*cb565728SJerry Jelinek 
230*cb565728SJerry Jelinek /*
231*cb565728SJerry Jelinek  *
232*cb565728SJerry Jelinek  * FUNCTION:    OslAddTableToList
233*cb565728SJerry Jelinek  *
234*cb565728SJerry Jelinek  * PARAMETERS:  Signature       - Table signature
235*cb565728SJerry Jelinek  *
236*cb565728SJerry Jelinek  * RETURN:      Status; Successfully added if AE_OK.
237*cb565728SJerry Jelinek  *              AE_NO_MEMORY: Memory allocation error
238*cb565728SJerry Jelinek  *
239*cb565728SJerry Jelinek  * DESCRIPTION: Insert a table structure into OSL table list.
240*cb565728SJerry Jelinek  *
241*cb565728SJerry Jelinek  */
242*cb565728SJerry Jelinek static ACPI_STATUS
OslAddTableToList(char * Signature)243*cb565728SJerry Jelinek OslAddTableToList(char *Signature)
244*cb565728SJerry Jelinek {
245*cb565728SJerry Jelinek 	OSL_TABLE_INFO	*NewInfo;
246*cb565728SJerry Jelinek 	OSL_TABLE_INFO	*Next;
247*cb565728SJerry Jelinek 	UINT32		NextInstance = 0;
248*cb565728SJerry Jelinek 	UINT32		Instance = 0;
249*cb565728SJerry Jelinek 	BOOLEAN		Found = FALSE;
250*cb565728SJerry Jelinek 
251*cb565728SJerry Jelinek 	NewInfo = calloc(1, sizeof (OSL_TABLE_INFO));
252*cb565728SJerry Jelinek 	if (NewInfo == NULL) {
253*cb565728SJerry Jelinek 		return (AE_NO_MEMORY);
254*cb565728SJerry Jelinek 	}
255*cb565728SJerry Jelinek 
256*cb565728SJerry Jelinek 	ACPI_MOVE_NAME(NewInfo->Signature, Signature);
257*cb565728SJerry Jelinek 
258*cb565728SJerry Jelinek 	if (!Gbl_TableListHead) {
259*cb565728SJerry Jelinek 		Gbl_TableListHead = NewInfo;
260*cb565728SJerry Jelinek 	} else {
261*cb565728SJerry Jelinek 		Next = Gbl_TableListHead;
262*cb565728SJerry Jelinek 
263*cb565728SJerry Jelinek 		while (1) {
264*cb565728SJerry Jelinek 			if (ACPI_COMPARE_NAME(Next->Signature, Signature)) {
265*cb565728SJerry Jelinek 				if (Next->Instance == 0) {
266*cb565728SJerry Jelinek 					Found = TRUE;
267*cb565728SJerry Jelinek 				}
268*cb565728SJerry Jelinek 				if (Next->Instance >= NextInstance) {
269*cb565728SJerry Jelinek 					NextInstance = Next->Instance + 1;
270*cb565728SJerry Jelinek 				}
271*cb565728SJerry Jelinek 			}
272*cb565728SJerry Jelinek 
273*cb565728SJerry Jelinek 			if (!Next->Next) {
274*cb565728SJerry Jelinek 				break;
275*cb565728SJerry Jelinek 			}
276*cb565728SJerry Jelinek 			Next = Next->Next;
277*cb565728SJerry Jelinek 		}
278*cb565728SJerry Jelinek 		Next->Next = NewInfo;
279*cb565728SJerry Jelinek 	}
280*cb565728SJerry Jelinek 
281*cb565728SJerry Jelinek 	if (Found) {
282*cb565728SJerry Jelinek 		Instance = NextInstance;
283*cb565728SJerry Jelinek 	}
284*cb565728SJerry Jelinek 
285*cb565728SJerry Jelinek 	NewInfo->Instance = Instance;
286*cb565728SJerry Jelinek 	Gbl_TableCount++;
287*cb565728SJerry Jelinek 
288*cb565728SJerry Jelinek 	return (AE_OK);
289*cb565728SJerry Jelinek }
290*cb565728SJerry Jelinek 
291*cb565728SJerry Jelinek /*
292*cb565728SJerry Jelinek  *
293*cb565728SJerry Jelinek  * FUNCTION:    AcpiOsGetTableByIndex
294*cb565728SJerry Jelinek  *
295*cb565728SJerry Jelinek  * PARAMETERS:  Index           - Which table to get
296*cb565728SJerry Jelinek  *              Table           - Where a pointer to the table is returned
297*cb565728SJerry Jelinek  *              Instance        - Where a pointer to the table instance no. is
298*cb565728SJerry Jelinek  *                                returned
299*cb565728SJerry Jelinek  *              Address         - Where the table physical address is returned
300*cb565728SJerry Jelinek  *
301*cb565728SJerry Jelinek  * RETURN:      Status; Table buffer and physical address returned if AE_OK.
302*cb565728SJerry Jelinek  *              AE_LIMIT: Index is beyond valid limit
303*cb565728SJerry Jelinek  *
304*cb565728SJerry Jelinek  * DESCRIPTION: Get an ACPI table via an index value (0 through n). Returns
305*cb565728SJerry Jelinek  *              AE_LIMIT when an invalid index is reached. Index is not
306*cb565728SJerry Jelinek  *              necessarily an index into the RSDT/XSDT.
307*cb565728SJerry Jelinek  *
308*cb565728SJerry Jelinek  */
309*cb565728SJerry Jelinek ACPI_STATUS
AcpiOsGetTableByIndex(UINT32 Index,ACPI_TABLE_HEADER ** Table,UINT32 * Instance,ACPI_PHYSICAL_ADDRESS * Address)310*cb565728SJerry Jelinek AcpiOsGetTableByIndex(UINT32 Index, ACPI_TABLE_HEADER **Table,
311*cb565728SJerry Jelinek     UINT32 *Instance, ACPI_PHYSICAL_ADDRESS *Address)
312*cb565728SJerry Jelinek {
313*cb565728SJerry Jelinek 	OSL_TABLE_INFO	*Info;
314*cb565728SJerry Jelinek 	ACPI_STATUS	Status;
315*cb565728SJerry Jelinek 	UINT32		i;
316*cb565728SJerry Jelinek 
317*cb565728SJerry Jelinek 	/*
318*cb565728SJerry Jelinek 	 * Get main ACPI tables from memory on first invocation of this
319*cb565728SJerry Jelinek 	 * function.
320*cb565728SJerry Jelinek 	 */
321*cb565728SJerry Jelinek 
322*cb565728SJerry Jelinek 	Status = OslTableInitialize();
323*cb565728SJerry Jelinek 	if (ACPI_FAILURE(Status)) {
324*cb565728SJerry Jelinek 		return (Status);
325*cb565728SJerry Jelinek 	}
326*cb565728SJerry Jelinek 
327*cb565728SJerry Jelinek 	/* Validate Index */
328*cb565728SJerry Jelinek 
329*cb565728SJerry Jelinek 	if (Index >= Gbl_TableCount) {
330*cb565728SJerry Jelinek 		return (AE_LIMIT);
331*cb565728SJerry Jelinek 	}
332*cb565728SJerry Jelinek 
333*cb565728SJerry Jelinek 	/* Point to the table list entry specified by the Index argument */
334*cb565728SJerry Jelinek 
335*cb565728SJerry Jelinek 	Info = Gbl_TableListHead;
336*cb565728SJerry Jelinek 	for (i = 0; i < Index; i++) {
337*cb565728SJerry Jelinek 		Info = Info->Next;
338*cb565728SJerry Jelinek 	}
339*cb565728SJerry Jelinek 
340*cb565728SJerry Jelinek 	/* Now we can just get the table via the signature */
341*cb565728SJerry Jelinek 
342*cb565728SJerry Jelinek 	Status = AcpiOsGetTableByName(Info->Signature, Info->Instance,
343*cb565728SJerry Jelinek 	    Table, Address);
344*cb565728SJerry Jelinek 
345*cb565728SJerry Jelinek 	if (ACPI_SUCCESS(Status)) {
346*cb565728SJerry Jelinek 		*Instance = Info->Instance;
347*cb565728SJerry Jelinek 	}
348*cb565728SJerry Jelinek 	return (Status);
349*cb565728SJerry Jelinek }
350*cb565728SJerry Jelinek 
351*cb565728SJerry Jelinek /*
352*cb565728SJerry Jelinek  *
353*cb565728SJerry Jelinek  * FUNCTION:    OslLoadRsdp
354*cb565728SJerry Jelinek  *
355*cb565728SJerry Jelinek  * PARAMETERS:  None
356*cb565728SJerry Jelinek  *
357*cb565728SJerry Jelinek  * RETURN:      Status
358*cb565728SJerry Jelinek  *
359*cb565728SJerry Jelinek  * DESCRIPTION: Scan and load RSDP.
360*cb565728SJerry Jelinek  * See the find_rsdp() function in usr/src/uts/i86pc/os/fakebop.c, which is how
361*cb565728SJerry Jelinek  * the kernel finds the RSDP. That algorithm matches AcpiFindRootPointer().
362*cb565728SJerry Jelinek  * The code here is derived from AcpiFindRootPointer, except that we will try
363*cb565728SJerry Jelinek  * the BIOS if the EBDA fails, and we will copy the table if found.
364*cb565728SJerry Jelinek  */
365*cb565728SJerry Jelinek static ACPI_STATUS
OslLoadRsdp(void)366*cb565728SJerry Jelinek OslLoadRsdp(void)
367*cb565728SJerry Jelinek {
368*cb565728SJerry Jelinek 	UINT8			*mapp;
369*cb565728SJerry Jelinek 	ACPI_TABLE_HEADER	*tblp;
370*cb565728SJerry Jelinek 	ACPI_SIZE		mapsize;
371*cb565728SJerry Jelinek 	ACPI_PHYSICAL_ADDRESS	physaddr;
372*cb565728SJerry Jelinek 
373*cb565728SJerry Jelinek 	/* 1a) Get the location of the Extended BIOS Data Area (EBDA) */
374*cb565728SJerry Jelinek 	mapp = AcpiOsMapMemory((ACPI_PHYSICAL_ADDRESS)ACPI_EBDA_PTR_LOCATION,
375*cb565728SJerry Jelinek 	    ACPI_EBDA_PTR_LENGTH);
376*cb565728SJerry Jelinek 	if (mapp == NULL)
377*cb565728SJerry Jelinek 		goto try_bios;
378*cb565728SJerry Jelinek 
379*cb565728SJerry Jelinek 	ACPI_MOVE_16_TO_32(&physaddr, mapp);
380*cb565728SJerry Jelinek 
381*cb565728SJerry Jelinek 	/* Convert segment part to physical address */
382*cb565728SJerry Jelinek 	physaddr <<= 4;
383*cb565728SJerry Jelinek 	AcpiOsUnmapMemory(mapp, ACPI_EBDA_PTR_LENGTH);
384*cb565728SJerry Jelinek 
385*cb565728SJerry Jelinek 	/* EBDA present? */
386*cb565728SJerry Jelinek 	if (physaddr <= 0x400)
387*cb565728SJerry Jelinek 		goto try_bios;
388*cb565728SJerry Jelinek 
389*cb565728SJerry Jelinek 	/*
390*cb565728SJerry Jelinek 	 * 1b) Search EBDA paragraphs (EBDA is required to be a minimum of 1K
391*cb565728SJerry Jelinek 	 * length)
392*cb565728SJerry Jelinek 	 */
393*cb565728SJerry Jelinek 	mapp = AcpiOsMapMemory(physaddr, ACPI_EBDA_WINDOW_SIZE);
394*cb565728SJerry Jelinek 	if (mapp == NULL) {
395*cb565728SJerry Jelinek 		(void) fprintf(stderr, "EBDA (0x%p) found, but is not "
396*cb565728SJerry Jelinek 		    "mappable\n", physaddr);
397*cb565728SJerry Jelinek 		goto try_bios;
398*cb565728SJerry Jelinek 	}
399*cb565728SJerry Jelinek 
400*cb565728SJerry Jelinek 	tblp = ACPI_CAST_PTR(ACPI_TABLE_HEADER,
401*cb565728SJerry Jelinek 	    AcpiTbScanMemoryForRsdp(mapp, ACPI_EBDA_WINDOW_SIZE));
402*cb565728SJerry Jelinek 	if (tblp != NULL) {
403*cb565728SJerry Jelinek 		physaddr += (ACPI_PHYSICAL_ADDRESS) ACPI_PTR_DIFF(tblp, mapp);
404*cb565728SJerry Jelinek 		Gbl_RsdpAddress = physaddr;
405*cb565728SJerry Jelinek 		memcpy(&Gbl_Rsdp, tblp, sizeof (ACPI_TABLE_RSDP));
406*cb565728SJerry Jelinek 		AcpiOsUnmapMemory(mapp, ACPI_EBDA_WINDOW_SIZE);
407*cb565728SJerry Jelinek 
408*cb565728SJerry Jelinek 		return (AE_OK);
409*cb565728SJerry Jelinek 	}
410*cb565728SJerry Jelinek 	AcpiOsUnmapMemory(mapp, ACPI_EBDA_WINDOW_SIZE);
411*cb565728SJerry Jelinek 
412*cb565728SJerry Jelinek try_bios:
413*cb565728SJerry Jelinek 	/* Try to get RSDP from BIOS memory */
414*cb565728SJerry Jelinek 	if (Gbl_RsdpBase != NULL) {
415*cb565728SJerry Jelinek 		physaddr = Gbl_RsdpBase;
416*cb565728SJerry Jelinek 		mapsize = sizeof (ACPI_TABLE_RSDP);
417*cb565728SJerry Jelinek 	} else {
418*cb565728SJerry Jelinek 		physaddr = ACPI_HI_RSDP_WINDOW_BASE;
419*cb565728SJerry Jelinek 		mapsize = ACPI_HI_RSDP_WINDOW_SIZE;
420*cb565728SJerry Jelinek 	}
421*cb565728SJerry Jelinek 
422*cb565728SJerry Jelinek 	mapp = AcpiOsMapMemory(physaddr, mapsize);
423*cb565728SJerry Jelinek 	if (mapp == NULL)
424*cb565728SJerry Jelinek 		return (OslGetLastStatus(AE_BAD_ADDRESS));
425*cb565728SJerry Jelinek 
426*cb565728SJerry Jelinek 	/* Search low memory for the RSDP */
427*cb565728SJerry Jelinek 	tblp = ACPI_CAST_PTR(ACPI_TABLE_HEADER,
428*cb565728SJerry Jelinek 	    AcpiTbScanMemoryForRsdp(mapp, mapsize));
429*cb565728SJerry Jelinek 	if (tblp == NULL) {
430*cb565728SJerry Jelinek 		AcpiOsUnmapMemory(mapp, mapsize);
431*cb565728SJerry Jelinek 		return (AE_NOT_FOUND);
432*cb565728SJerry Jelinek 	}
433*cb565728SJerry Jelinek 
434*cb565728SJerry Jelinek 	physaddr += (ACPI_PHYSICAL_ADDRESS) ACPI_PTR_DIFF(tblp, mapp);
435*cb565728SJerry Jelinek 	Gbl_RsdpAddress = physaddr;
436*cb565728SJerry Jelinek 	memcpy(&Gbl_Rsdp, tblp, sizeof (ACPI_TABLE_RSDP));
437*cb565728SJerry Jelinek 	AcpiOsUnmapMemory(mapp, mapsize);
438*cb565728SJerry Jelinek 
439*cb565728SJerry Jelinek 	return (AE_OK);
440*cb565728SJerry Jelinek }
441*cb565728SJerry Jelinek 
442*cb565728SJerry Jelinek /*
443*cb565728SJerry Jelinek  *
444*cb565728SJerry Jelinek  * FUNCTION:    OslCanUseXsdt
445*cb565728SJerry Jelinek  *
446*cb565728SJerry Jelinek  * PARAMETERS:  None
447*cb565728SJerry Jelinek  *
448*cb565728SJerry Jelinek  * RETURN:      TRUE if XSDT is allowed to be used.
449*cb565728SJerry Jelinek  *
450*cb565728SJerry Jelinek  * DESCRIPTION: This function collects logic that can be used to determine if
451*cb565728SJerry Jelinek  *              XSDT should be used instead of RSDT.
452*cb565728SJerry Jelinek  *
453*cb565728SJerry Jelinek  */
454*cb565728SJerry Jelinek static BOOLEAN
OslCanUseXsdt(void)455*cb565728SJerry Jelinek OslCanUseXsdt(void)
456*cb565728SJerry Jelinek {
457*cb565728SJerry Jelinek 	if (Gbl_Revision && !AcpiGbl_DoNotUseXsdt) {
458*cb565728SJerry Jelinek 		return (TRUE);
459*cb565728SJerry Jelinek 	} else {
460*cb565728SJerry Jelinek 		return (FALSE);
461*cb565728SJerry Jelinek 	}
462*cb565728SJerry Jelinek }
463*cb565728SJerry Jelinek 
464*cb565728SJerry Jelinek /*
465*cb565728SJerry Jelinek  *
466*cb565728SJerry Jelinek  * FUNCTION:    OslTableInitialize
467*cb565728SJerry Jelinek  *
468*cb565728SJerry Jelinek  * PARAMETERS:  None
469*cb565728SJerry Jelinek  *
470*cb565728SJerry Jelinek  * RETURN:      Status
471*cb565728SJerry Jelinek  *
472*cb565728SJerry Jelinek  * DESCRIPTION: Initialize ACPI table data. Get and store main ACPI tables to
473*cb565728SJerry Jelinek  *              local variables. Main ACPI tables include RSDT, FADT, RSDT,
474*cb565728SJerry Jelinek  *              and/or XSDT.
475*cb565728SJerry Jelinek  *
476*cb565728SJerry Jelinek  */
477*cb565728SJerry Jelinek static ACPI_STATUS
OslTableInitialize(void)478*cb565728SJerry Jelinek OslTableInitialize(void)
479*cb565728SJerry Jelinek {
480*cb565728SJerry Jelinek 	ACPI_STATUS		Status;
481*cb565728SJerry Jelinek 	ACPI_PHYSICAL_ADDRESS	Address;
482*cb565728SJerry Jelinek 
483*cb565728SJerry Jelinek 	if (Gbl_TableListInitialized) {
484*cb565728SJerry Jelinek 		return (AE_OK);
485*cb565728SJerry Jelinek 	}
486*cb565728SJerry Jelinek 
487*cb565728SJerry Jelinek 	/* Get RSDP from memory */
488*cb565728SJerry Jelinek 
489*cb565728SJerry Jelinek 	Status = OslLoadRsdp();
490*cb565728SJerry Jelinek 	if (ACPI_FAILURE(Status)) {
491*cb565728SJerry Jelinek 		return (Status);
492*cb565728SJerry Jelinek 	}
493*cb565728SJerry Jelinek 
494*cb565728SJerry Jelinek 	/* Get XSDT from memory */
495*cb565728SJerry Jelinek 
496*cb565728SJerry Jelinek 	if (Gbl_Rsdp.Revision && !Gbl_DoNotDumpXsdt) {
497*cb565728SJerry Jelinek 		if (Gbl_Xsdt) {
498*cb565728SJerry Jelinek 			free(Gbl_Xsdt);
499*cb565728SJerry Jelinek 			Gbl_Xsdt = NULL;
500*cb565728SJerry Jelinek 		}
501*cb565728SJerry Jelinek 
502*cb565728SJerry Jelinek 		Gbl_Revision = 2;
503*cb565728SJerry Jelinek 		Status = OslGetBiosTable(ACPI_SIG_XSDT, 0,
504*cb565728SJerry Jelinek 		    ACPI_CAST_PTR(ACPI_TABLE_HEADER *, &Gbl_Xsdt), &Address);
505*cb565728SJerry Jelinek 		if (ACPI_FAILURE(Status)) {
506*cb565728SJerry Jelinek 			return (Status);
507*cb565728SJerry Jelinek 		}
508*cb565728SJerry Jelinek 	}
509*cb565728SJerry Jelinek 
510*cb565728SJerry Jelinek 	/* Get RSDT from memory */
511*cb565728SJerry Jelinek 
512*cb565728SJerry Jelinek 	if (Gbl_Rsdp.RsdtPhysicalAddress) {
513*cb565728SJerry Jelinek 		if (Gbl_Rsdt) {
514*cb565728SJerry Jelinek 			free(Gbl_Rsdt);
515*cb565728SJerry Jelinek 			Gbl_Rsdt = NULL;
516*cb565728SJerry Jelinek 		}
517*cb565728SJerry Jelinek 
518*cb565728SJerry Jelinek 		Status = OslGetBiosTable(ACPI_SIG_RSDT, 0,
519*cb565728SJerry Jelinek 		    ACPI_CAST_PTR(ACPI_TABLE_HEADER *, &Gbl_Rsdt), &Address);
520*cb565728SJerry Jelinek 		if (ACPI_FAILURE(Status)) {
521*cb565728SJerry Jelinek 			return (Status);
522*cb565728SJerry Jelinek 		}
523*cb565728SJerry Jelinek 	}
524*cb565728SJerry Jelinek 
525*cb565728SJerry Jelinek 	/* Get FADT from memory */
526*cb565728SJerry Jelinek 
527*cb565728SJerry Jelinek 	if (Gbl_Fadt) {
528*cb565728SJerry Jelinek 		free(Gbl_Fadt);
529*cb565728SJerry Jelinek 		Gbl_Fadt = NULL;
530*cb565728SJerry Jelinek 	}
531*cb565728SJerry Jelinek 
532*cb565728SJerry Jelinek 	Status = OslGetBiosTable(ACPI_SIG_FADT, 0,
533*cb565728SJerry Jelinek 	    ACPI_CAST_PTR(ACPI_TABLE_HEADER *, &Gbl_Fadt), &Gbl_FadtAddress);
534*cb565728SJerry Jelinek 	if (ACPI_FAILURE(Status)) {
535*cb565728SJerry Jelinek 		return (Status);
536*cb565728SJerry Jelinek 	}
537*cb565728SJerry Jelinek 
538*cb565728SJerry Jelinek 	/* Add mandatory tables to global table list first */
539*cb565728SJerry Jelinek 
540*cb565728SJerry Jelinek 	Status = OslAddTableToList(ACPI_RSDP_NAME);
541*cb565728SJerry Jelinek 	if (ACPI_FAILURE(Status)) {
542*cb565728SJerry Jelinek 		return (Status);
543*cb565728SJerry Jelinek 	}
544*cb565728SJerry Jelinek 
545*cb565728SJerry Jelinek 	Status = OslAddTableToList(ACPI_SIG_RSDT);
546*cb565728SJerry Jelinek 	if (ACPI_FAILURE(Status)) {
547*cb565728SJerry Jelinek 		return (Status);
548*cb565728SJerry Jelinek 	}
549*cb565728SJerry Jelinek 
550*cb565728SJerry Jelinek 	if (Gbl_Revision == 2) {
551*cb565728SJerry Jelinek 		Status = OslAddTableToList(ACPI_SIG_XSDT);
552*cb565728SJerry Jelinek 		if (ACPI_FAILURE(Status)) {
553*cb565728SJerry Jelinek 			return (Status);
554*cb565728SJerry Jelinek 		}
555*cb565728SJerry Jelinek 	}
556*cb565728SJerry Jelinek 
557*cb565728SJerry Jelinek 	Status = OslAddTableToList(ACPI_SIG_DSDT);
558*cb565728SJerry Jelinek 	if (ACPI_FAILURE(Status)) {
559*cb565728SJerry Jelinek 		return (Status);
560*cb565728SJerry Jelinek 	}
561*cb565728SJerry Jelinek 
562*cb565728SJerry Jelinek 	Status = OslAddTableToList(ACPI_SIG_FACS);
563*cb565728SJerry Jelinek 	if (ACPI_FAILURE(Status)) {
564*cb565728SJerry Jelinek 		return (Status);
565*cb565728SJerry Jelinek 	}
566*cb565728SJerry Jelinek 
567*cb565728SJerry Jelinek 	/* Add all tables found in the memory */
568*cb565728SJerry Jelinek 
569*cb565728SJerry Jelinek 	Status = OslListBiosTables();
570*cb565728SJerry Jelinek 	if (ACPI_FAILURE(Status)) {
571*cb565728SJerry Jelinek 		return (Status);
572*cb565728SJerry Jelinek 	}
573*cb565728SJerry Jelinek 
574*cb565728SJerry Jelinek 	Gbl_TableListInitialized = TRUE;
575*cb565728SJerry Jelinek 	return (AE_OK);
576*cb565728SJerry Jelinek }
577*cb565728SJerry Jelinek 
578*cb565728SJerry Jelinek 
579*cb565728SJerry Jelinek /*
580*cb565728SJerry Jelinek  *
581*cb565728SJerry Jelinek  * FUNCTION:    OslListBiosTables
582*cb565728SJerry Jelinek  *
583*cb565728SJerry Jelinek  * PARAMETERS:  None
584*cb565728SJerry Jelinek  *
585*cb565728SJerry Jelinek  * RETURN:      Status; Table list is initialized if AE_OK.
586*cb565728SJerry Jelinek  *
587*cb565728SJerry Jelinek  * DESCRIPTION: Add ACPI tables to the table list from memory.
588*cb565728SJerry Jelinek  */
589*cb565728SJerry Jelinek static ACPI_STATUS
OslListBiosTables(void)590*cb565728SJerry Jelinek OslListBiosTables(void)
591*cb565728SJerry Jelinek {
592*cb565728SJerry Jelinek 	ACPI_TABLE_HEADER	*MappedTable = NULL;
593*cb565728SJerry Jelinek 	UINT8			*TableData;
594*cb565728SJerry Jelinek 	UINT32			NumberOfTables;
595*cb565728SJerry Jelinek 	UINT8			ItemSize;
596*cb565728SJerry Jelinek 	ACPI_PHYSICAL_ADDRESS	TableAddress = 0;
597*cb565728SJerry Jelinek 	ACPI_STATUS		Status = AE_OK;
598*cb565728SJerry Jelinek 	UINT32			i;
599*cb565728SJerry Jelinek 
600*cb565728SJerry Jelinek 	if (OslCanUseXsdt()) {
601*cb565728SJerry Jelinek 		ItemSize = sizeof (UINT64);
602*cb565728SJerry Jelinek 		TableData = ACPI_CAST8(Gbl_Xsdt) + sizeof (ACPI_TABLE_HEADER);
603*cb565728SJerry Jelinek 		NumberOfTables = (UINT32)
604*cb565728SJerry Jelinek 		    ((Gbl_Xsdt->Header.Length - sizeof (ACPI_TABLE_HEADER))
605*cb565728SJerry Jelinek 		    / ItemSize);
606*cb565728SJerry Jelinek 
607*cb565728SJerry Jelinek 	} else {
608*cb565728SJerry Jelinek 		/* Use RSDT if XSDT is not available */
609*cb565728SJerry Jelinek 		ItemSize = sizeof (UINT32);
610*cb565728SJerry Jelinek 		TableData = ACPI_CAST8(Gbl_Rsdt) + sizeof (ACPI_TABLE_HEADER);
611*cb565728SJerry Jelinek 		NumberOfTables = (UINT32)
612*cb565728SJerry Jelinek 		    ((Gbl_Rsdt->Header.Length - sizeof (ACPI_TABLE_HEADER))
613*cb565728SJerry Jelinek 		    / ItemSize);
614*cb565728SJerry Jelinek 	}
615*cb565728SJerry Jelinek 
616*cb565728SJerry Jelinek 	/* Search RSDT/XSDT for the requested table */
617*cb565728SJerry Jelinek 
618*cb565728SJerry Jelinek 	for (i = 0; i < NumberOfTables; ++i, TableData += ItemSize) {
619*cb565728SJerry Jelinek 		if (OslCanUseXsdt()) {
620*cb565728SJerry Jelinek 			TableAddress =
621*cb565728SJerry Jelinek 			    (ACPI_PHYSICAL_ADDRESS) (*ACPI_CAST64(TableData));
622*cb565728SJerry Jelinek 		} else {
623*cb565728SJerry Jelinek 			TableAddress =
624*cb565728SJerry Jelinek 			    (ACPI_PHYSICAL_ADDRESS) (*ACPI_CAST32(TableData));
625*cb565728SJerry Jelinek 		}
626*cb565728SJerry Jelinek 
627*cb565728SJerry Jelinek 		/* Skip NULL entries in RSDT/XSDT */
628*cb565728SJerry Jelinek 		if (TableAddress == NULL) {
629*cb565728SJerry Jelinek 			continue;
630*cb565728SJerry Jelinek 		}
631*cb565728SJerry Jelinek 
632*cb565728SJerry Jelinek 		Status = OslMapTable(TableAddress, NULL, &MappedTable);
633*cb565728SJerry Jelinek 		if (ACPI_FAILURE(Status)) {
634*cb565728SJerry Jelinek 			return (Status);
635*cb565728SJerry Jelinek 		}
636*cb565728SJerry Jelinek 
637*cb565728SJerry Jelinek 		OslAddTableToList(MappedTable->Signature);
638*cb565728SJerry Jelinek 		OslUnmapTable(MappedTable);
639*cb565728SJerry Jelinek 	}
640*cb565728SJerry Jelinek 
641*cb565728SJerry Jelinek 	return (AE_OK);
642*cb565728SJerry Jelinek }
643*cb565728SJerry Jelinek 
644*cb565728SJerry Jelinek /*
645*cb565728SJerry Jelinek  *
646*cb565728SJerry Jelinek  * FUNCTION:    OslGetBiosTable
647*cb565728SJerry Jelinek  *
648*cb565728SJerry Jelinek  * PARAMETERS:  Signature       - ACPI Signature for common table. Must be
649*cb565728SJerry Jelinek  *                                a null terminated 4-character string.
650*cb565728SJerry Jelinek  *              Instance        - Multiple table support for SSDT/UEFI (0...n)
651*cb565728SJerry Jelinek  *                                Must be 0 for other tables.
652*cb565728SJerry Jelinek  *              Table           - Where a pointer to the table is returned
653*cb565728SJerry Jelinek  *              Address         - Where the table physical address is returned
654*cb565728SJerry Jelinek  *
655*cb565728SJerry Jelinek  * RETURN:      Status; Table buffer and physical address returned if AE_OK.
656*cb565728SJerry Jelinek  *              AE_LIMIT: Instance is beyond valid limit
657*cb565728SJerry Jelinek  *              AE_NOT_FOUND: A table with the signature was not found
658*cb565728SJerry Jelinek  *
659*cb565728SJerry Jelinek  * DESCRIPTION: Get a BIOS provided ACPI table
660*cb565728SJerry Jelinek  *
661*cb565728SJerry Jelinek  * NOTE:        Assumes the input signature is uppercase.
662*cb565728SJerry Jelinek  *
663*cb565728SJerry Jelinek  */
664*cb565728SJerry Jelinek static ACPI_STATUS
OslGetBiosTable(char * Signature,UINT32 Instance,ACPI_TABLE_HEADER ** Table,ACPI_PHYSICAL_ADDRESS * Address)665*cb565728SJerry Jelinek OslGetBiosTable(char *Signature, UINT32 Instance, ACPI_TABLE_HEADER **Table,
666*cb565728SJerry Jelinek     ACPI_PHYSICAL_ADDRESS *Address)
667*cb565728SJerry Jelinek {
668*cb565728SJerry Jelinek 	ACPI_TABLE_HEADER	*LocalTable = NULL;
669*cb565728SJerry Jelinek 	ACPI_TABLE_HEADER	*MappedTable = NULL;
670*cb565728SJerry Jelinek 	UINT8			*TableData;
671*cb565728SJerry Jelinek 	UINT8			NumberOfTables;
672*cb565728SJerry Jelinek 	UINT8			ItemSize;
673*cb565728SJerry Jelinek 	UINT32			CurrentInstance = 0;
674*cb565728SJerry Jelinek 	ACPI_PHYSICAL_ADDRESS	TableAddress = 0;
675*cb565728SJerry Jelinek 	UINT32			TableLength = 0;
676*cb565728SJerry Jelinek 	ACPI_STATUS		Status = AE_OK;
677*cb565728SJerry Jelinek 	UINT32			i;
678*cb565728SJerry Jelinek 
679*cb565728SJerry Jelinek 	/* Handle special tables whose addresses are not in RSDT/XSDT */
680*cb565728SJerry Jelinek 
681*cb565728SJerry Jelinek 	if (ACPI_COMPARE_NAME(Signature, ACPI_RSDP_NAME) ||
682*cb565728SJerry Jelinek 	    ACPI_COMPARE_NAME(Signature, ACPI_SIG_RSDT) ||
683*cb565728SJerry Jelinek 	    ACPI_COMPARE_NAME(Signature, ACPI_SIG_XSDT) ||
684*cb565728SJerry Jelinek 	    ACPI_COMPARE_NAME(Signature, ACPI_SIG_DSDT) ||
685*cb565728SJerry Jelinek 	    ACPI_COMPARE_NAME(Signature, ACPI_SIG_FACS)) {
686*cb565728SJerry Jelinek 		if (Instance > 0) {
687*cb565728SJerry Jelinek 			return (AE_LIMIT);
688*cb565728SJerry Jelinek 		}
689*cb565728SJerry Jelinek 
690*cb565728SJerry Jelinek 		/*
691*cb565728SJerry Jelinek 		 * Get the appropriate address, either 32-bit or 64-bit. Be very
692*cb565728SJerry Jelinek 		 * careful about the FADT length and validate table addresses.
693*cb565728SJerry Jelinek 		 * Note: The 64-bit addresses have priority.
694*cb565728SJerry Jelinek 		 */
695*cb565728SJerry Jelinek 		if (ACPI_COMPARE_NAME(Signature, ACPI_SIG_DSDT)) {
696*cb565728SJerry Jelinek 			if ((Gbl_Fadt->Header.Length >= MIN_FADT_FOR_XDSDT) &&
697*cb565728SJerry Jelinek 			    Gbl_Fadt->XDsdt) {
698*cb565728SJerry Jelinek 				TableAddress =
699*cb565728SJerry Jelinek 				    (ACPI_PHYSICAL_ADDRESS) Gbl_Fadt->XDsdt;
700*cb565728SJerry Jelinek 
701*cb565728SJerry Jelinek 			} else if (Gbl_Fadt->Header.Length >=
702*cb565728SJerry Jelinek 			    MIN_FADT_FOR_DSDT && Gbl_Fadt->Dsdt) {
703*cb565728SJerry Jelinek 				TableAddress =
704*cb565728SJerry Jelinek 				    (ACPI_PHYSICAL_ADDRESS) Gbl_Fadt->Dsdt;
705*cb565728SJerry Jelinek 			}
706*cb565728SJerry Jelinek 
707*cb565728SJerry Jelinek 		} else if (ACPI_COMPARE_NAME(Signature, ACPI_SIG_FACS)) {
708*cb565728SJerry Jelinek 			if ((Gbl_Fadt->Header.Length >= MIN_FADT_FOR_XFACS) &&
709*cb565728SJerry Jelinek 			    Gbl_Fadt->XFacs) {
710*cb565728SJerry Jelinek 				TableAddress =
711*cb565728SJerry Jelinek 				    (ACPI_PHYSICAL_ADDRESS) Gbl_Fadt->XFacs;
712*cb565728SJerry Jelinek 
713*cb565728SJerry Jelinek 			} else if (Gbl_Fadt->Header.Length >=
714*cb565728SJerry Jelinek 			    MIN_FADT_FOR_FACS && Gbl_Fadt->Facs) {
715*cb565728SJerry Jelinek 				TableAddress =
716*cb565728SJerry Jelinek 				    (ACPI_PHYSICAL_ADDRESS) Gbl_Fadt->Facs;
717*cb565728SJerry Jelinek 			}
718*cb565728SJerry Jelinek 
719*cb565728SJerry Jelinek 		} else if (ACPI_COMPARE_NAME(Signature, ACPI_SIG_XSDT)) {
720*cb565728SJerry Jelinek 			if (!Gbl_Revision) {
721*cb565728SJerry Jelinek 				return (AE_BAD_SIGNATURE);
722*cb565728SJerry Jelinek 			}
723*cb565728SJerry Jelinek 			TableAddress = (ACPI_PHYSICAL_ADDRESS)
724*cb565728SJerry Jelinek 			    Gbl_Rsdp.XsdtPhysicalAddress;
725*cb565728SJerry Jelinek 
726*cb565728SJerry Jelinek 		} else if (ACPI_COMPARE_NAME(Signature, ACPI_SIG_RSDT)) {
727*cb565728SJerry Jelinek 			TableAddress = (ACPI_PHYSICAL_ADDRESS)
728*cb565728SJerry Jelinek 			    Gbl_Rsdp.RsdtPhysicalAddress;
729*cb565728SJerry Jelinek 
730*cb565728SJerry Jelinek 		} else {
731*cb565728SJerry Jelinek 			TableAddress = (ACPI_PHYSICAL_ADDRESS) Gbl_RsdpAddress;
732*cb565728SJerry Jelinek 			Signature = ACPI_SIG_RSDP;
733*cb565728SJerry Jelinek 		}
734*cb565728SJerry Jelinek 
735*cb565728SJerry Jelinek 		/* Now we can get the requested special table */
736*cb565728SJerry Jelinek 
737*cb565728SJerry Jelinek 		Status = OslMapTable(TableAddress, Signature, &MappedTable);
738*cb565728SJerry Jelinek 		if (ACPI_FAILURE(Status)) {
739*cb565728SJerry Jelinek 			return (Status);
740*cb565728SJerry Jelinek 		}
741*cb565728SJerry Jelinek 
742*cb565728SJerry Jelinek 		TableLength = ApGetTableLength(MappedTable);
743*cb565728SJerry Jelinek 
744*cb565728SJerry Jelinek 	} else {
745*cb565728SJerry Jelinek 		/* Case for a normal ACPI table */
746*cb565728SJerry Jelinek 		if (OslCanUseXsdt()) {
747*cb565728SJerry Jelinek 			ItemSize = sizeof (UINT64);
748*cb565728SJerry Jelinek 			TableData = ACPI_CAST8(Gbl_Xsdt) +
749*cb565728SJerry Jelinek 			    sizeof (ACPI_TABLE_HEADER);
750*cb565728SJerry Jelinek 			NumberOfTables = (UINT8) ((Gbl_Xsdt->Header.Length -
751*cb565728SJerry Jelinek 			    sizeof (ACPI_TABLE_HEADER))
752*cb565728SJerry Jelinek 			    / ItemSize);
753*cb565728SJerry Jelinek 
754*cb565728SJerry Jelinek 		} else {
755*cb565728SJerry Jelinek 			/* Use RSDT if XSDT is not available */
756*cb565728SJerry Jelinek 			ItemSize = sizeof (UINT32);
757*cb565728SJerry Jelinek 			TableData = ACPI_CAST8(Gbl_Rsdt) +
758*cb565728SJerry Jelinek 			    sizeof (ACPI_TABLE_HEADER);
759*cb565728SJerry Jelinek 			NumberOfTables = (UINT8) ((Gbl_Rsdt->Header.Length -
760*cb565728SJerry Jelinek 			    sizeof (ACPI_TABLE_HEADER))
761*cb565728SJerry Jelinek 			    / ItemSize);
762*cb565728SJerry Jelinek 		}
763*cb565728SJerry Jelinek 
764*cb565728SJerry Jelinek 		/* Search RSDT/XSDT for the requested table */
765*cb565728SJerry Jelinek 
766*cb565728SJerry Jelinek 		for (i = 0; i < NumberOfTables; ++i, TableData += ItemSize) {
767*cb565728SJerry Jelinek 			if (OslCanUseXsdt()) {
768*cb565728SJerry Jelinek 				TableAddress = (ACPI_PHYSICAL_ADDRESS)
769*cb565728SJerry Jelinek 				    (*ACPI_CAST64(TableData));
770*cb565728SJerry Jelinek 			} else {
771*cb565728SJerry Jelinek 				TableAddress = (ACPI_PHYSICAL_ADDRESS)
772*cb565728SJerry Jelinek 				    (*ACPI_CAST32(TableData));
773*cb565728SJerry Jelinek 			}
774*cb565728SJerry Jelinek 
775*cb565728SJerry Jelinek 			/* Skip NULL entries in RSDT/XSDT */
776*cb565728SJerry Jelinek 
777*cb565728SJerry Jelinek 			if (TableAddress == NULL) {
778*cb565728SJerry Jelinek 				continue;
779*cb565728SJerry Jelinek 			}
780*cb565728SJerry Jelinek 
781*cb565728SJerry Jelinek 			Status = OslMapTable(TableAddress, NULL, &MappedTable);
782*cb565728SJerry Jelinek 			if (ACPI_FAILURE(Status)) {
783*cb565728SJerry Jelinek 				return (Status);
784*cb565728SJerry Jelinek 			}
785*cb565728SJerry Jelinek 			TableLength = MappedTable->Length;
786*cb565728SJerry Jelinek 
787*cb565728SJerry Jelinek 			/* Does this table match the requested signature? */
788*cb565728SJerry Jelinek 
789*cb565728SJerry Jelinek 			if (!ACPI_COMPARE_NAME(MappedTable->Signature,
790*cb565728SJerry Jelinek 			    Signature)) {
791*cb565728SJerry Jelinek 				OslUnmapTable(MappedTable);
792*cb565728SJerry Jelinek 				MappedTable = NULL;
793*cb565728SJerry Jelinek 				continue;
794*cb565728SJerry Jelinek 			}
795*cb565728SJerry Jelinek 
796*cb565728SJerry Jelinek 			/* Match table instance (for SSDT/UEFI tables) */
797*cb565728SJerry Jelinek 
798*cb565728SJerry Jelinek 			if (CurrentInstance != Instance) {
799*cb565728SJerry Jelinek 				OslUnmapTable(MappedTable);
800*cb565728SJerry Jelinek 				MappedTable = NULL;
801*cb565728SJerry Jelinek 				CurrentInstance++;
802*cb565728SJerry Jelinek 				continue;
803*cb565728SJerry Jelinek 			}
804*cb565728SJerry Jelinek 
805*cb565728SJerry Jelinek 			break;
806*cb565728SJerry Jelinek 		}
807*cb565728SJerry Jelinek 	}
808*cb565728SJerry Jelinek 
809*cb565728SJerry Jelinek 	if (MappedTable == NULL) {
810*cb565728SJerry Jelinek 		return (AE_LIMIT);
811*cb565728SJerry Jelinek 	}
812*cb565728SJerry Jelinek 
813*cb565728SJerry Jelinek 	if (TableLength == 0) {
814*cb565728SJerry Jelinek 		Status = AE_BAD_HEADER;
815*cb565728SJerry Jelinek 		goto Exit;
816*cb565728SJerry Jelinek 	}
817*cb565728SJerry Jelinek 
818*cb565728SJerry Jelinek 	/* Copy table to local buffer and return it */
819*cb565728SJerry Jelinek 
820*cb565728SJerry Jelinek 	LocalTable = calloc(1, TableLength);
821*cb565728SJerry Jelinek 	if (LocalTable == NULL) {
822*cb565728SJerry Jelinek 		Status = AE_NO_MEMORY;
823*cb565728SJerry Jelinek 		goto Exit;
824*cb565728SJerry Jelinek 	}
825*cb565728SJerry Jelinek 
826*cb565728SJerry Jelinek 	memcpy(LocalTable, MappedTable, TableLength);
827*cb565728SJerry Jelinek 	*Address = TableAddress;
828*cb565728SJerry Jelinek 	*Table = LocalTable;
829*cb565728SJerry Jelinek 
830*cb565728SJerry Jelinek Exit:
831*cb565728SJerry Jelinek 	OslUnmapTable(MappedTable);
832*cb565728SJerry Jelinek 	return (Status);
833*cb565728SJerry Jelinek }
834*cb565728SJerry Jelinek 
835*cb565728SJerry Jelinek /*
836*cb565728SJerry Jelinek  *
837*cb565728SJerry Jelinek  * FUNCTION:    OslMapTable
838*cb565728SJerry Jelinek  *
839*cb565728SJerry Jelinek  * PARAMETERS:  Address             - Address of the table in memory
840*cb565728SJerry Jelinek  *              Signature           - Optional ACPI Signature for desired table.
841*cb565728SJerry Jelinek  *                                    Null terminated 4-character string.
842*cb565728SJerry Jelinek  *              Table               - Where a pointer to the mapped table is
843*cb565728SJerry Jelinek  *                                    returned
844*cb565728SJerry Jelinek  *
845*cb565728SJerry Jelinek  * RETURN:      Status; Mapped table is returned if AE_OK.
846*cb565728SJerry Jelinek  *              AE_NOT_FOUND: A valid table was not found at the address
847*cb565728SJerry Jelinek  *
848*cb565728SJerry Jelinek  * DESCRIPTION: Map entire ACPI table into caller's address space.
849*cb565728SJerry Jelinek  *
850*cb565728SJerry Jelinek  */
851*cb565728SJerry Jelinek static ACPI_STATUS
OslMapTable(ACPI_SIZE Address,char * Signature,ACPI_TABLE_HEADER ** Table)852*cb565728SJerry Jelinek OslMapTable(ACPI_SIZE Address, char *Signature, ACPI_TABLE_HEADER **Table)
853*cb565728SJerry Jelinek {
854*cb565728SJerry Jelinek 	ACPI_TABLE_HEADER	*MappedTable;
855*cb565728SJerry Jelinek 	UINT32			Length;
856*cb565728SJerry Jelinek 
857*cb565728SJerry Jelinek 	if (Address == NULL) {
858*cb565728SJerry Jelinek 		return (AE_BAD_ADDRESS);
859*cb565728SJerry Jelinek 	}
860*cb565728SJerry Jelinek 
861*cb565728SJerry Jelinek 	/*
862*cb565728SJerry Jelinek 	 * Map the header so we can get the table length.
863*cb565728SJerry Jelinek 	 * Use sizeof (ACPI_TABLE_HEADER) as:
864*cb565728SJerry Jelinek 	 * 1. it is bigger than 24 to include RSDP->Length
865*cb565728SJerry Jelinek 	 * 2. it is smaller than sizeof (ACPI_TABLE_RSDP)
866*cb565728SJerry Jelinek 	 */
867*cb565728SJerry Jelinek 	MappedTable = AcpiOsMapMemory(Address, sizeof (ACPI_TABLE_HEADER));
868*cb565728SJerry Jelinek 	if (MappedTable == NULL) {
869*cb565728SJerry Jelinek 		(void) fprintf(stderr, "Could not map table header at "
870*cb565728SJerry Jelinek 		    "0x%8.8X%8.8X\n", ACPI_FORMAT_UINT64(Address));
871*cb565728SJerry Jelinek 		return (OslGetLastStatus(AE_BAD_ADDRESS));
872*cb565728SJerry Jelinek 	}
873*cb565728SJerry Jelinek 
874*cb565728SJerry Jelinek 	/* If specified, signature must match */
875*cb565728SJerry Jelinek 
876*cb565728SJerry Jelinek 	if (Signature != NULL) {
877*cb565728SJerry Jelinek 		if (ACPI_VALIDATE_RSDP_SIG(Signature)) {
878*cb565728SJerry Jelinek 			if (!ACPI_VALIDATE_RSDP_SIG(MappedTable->Signature)) {
879*cb565728SJerry Jelinek 				AcpiOsUnmapMemory(MappedTable,
880*cb565728SJerry Jelinek 				    sizeof (ACPI_TABLE_HEADER));
881*cb565728SJerry Jelinek 				return (AE_BAD_SIGNATURE);
882*cb565728SJerry Jelinek 			}
883*cb565728SJerry Jelinek 		} else if (!ACPI_COMPARE_NAME(Signature,
884*cb565728SJerry Jelinek 		    MappedTable->Signature)) {
885*cb565728SJerry Jelinek 			AcpiOsUnmapMemory(MappedTable,
886*cb565728SJerry Jelinek 			    sizeof (ACPI_TABLE_HEADER));
887*cb565728SJerry Jelinek 			return (AE_BAD_SIGNATURE);
888*cb565728SJerry Jelinek 		}
889*cb565728SJerry Jelinek 	}
890*cb565728SJerry Jelinek 
891*cb565728SJerry Jelinek 	/* Map the entire table */
892*cb565728SJerry Jelinek 
893*cb565728SJerry Jelinek 	Length = ApGetTableLength(MappedTable);
894*cb565728SJerry Jelinek 	AcpiOsUnmapMemory(MappedTable, sizeof (ACPI_TABLE_HEADER));
895*cb565728SJerry Jelinek 	if (Length == 0) {
896*cb565728SJerry Jelinek 		return (AE_BAD_HEADER);
897*cb565728SJerry Jelinek 	}
898*cb565728SJerry Jelinek 
899*cb565728SJerry Jelinek 	MappedTable = AcpiOsMapMemory(Address, Length);
900*cb565728SJerry Jelinek 	if (MappedTable == NULL) {
901*cb565728SJerry Jelinek 		(void) fprintf(stderr, "Could not map table at 0x%8.8X%8.8X "
902*cb565728SJerry Jelinek 		    "length %8.8X\n", ACPI_FORMAT_UINT64(Address), Length);
903*cb565728SJerry Jelinek 		return (OslGetLastStatus(AE_INVALID_TABLE_LENGTH));
904*cb565728SJerry Jelinek 	}
905*cb565728SJerry Jelinek 
906*cb565728SJerry Jelinek 	(void) ApIsValidChecksum(MappedTable);
907*cb565728SJerry Jelinek 
908*cb565728SJerry Jelinek 	*Table = MappedTable;
909*cb565728SJerry Jelinek 	return (AE_OK);
910*cb565728SJerry Jelinek }
911*cb565728SJerry Jelinek 
912*cb565728SJerry Jelinek 
913*cb565728SJerry Jelinek /*
914*cb565728SJerry Jelinek  *
915*cb565728SJerry Jelinek  * FUNCTION:    OslUnmapTable
916*cb565728SJerry Jelinek  *
917*cb565728SJerry Jelinek  * PARAMETERS:  Table               - A pointer to the mapped table
918*cb565728SJerry Jelinek  *
919*cb565728SJerry Jelinek  * RETURN:      None
920*cb565728SJerry Jelinek  *
921*cb565728SJerry Jelinek  * DESCRIPTION: Unmap entire ACPI table.
922*cb565728SJerry Jelinek  *
923*cb565728SJerry Jelinek  */
924*cb565728SJerry Jelinek static void
OslUnmapTable(ACPI_TABLE_HEADER * Table)925*cb565728SJerry Jelinek OslUnmapTable(ACPI_TABLE_HEADER *Table)
926*cb565728SJerry Jelinek {
927*cb565728SJerry Jelinek 	if (Table != NULL) {
928*cb565728SJerry Jelinek 		AcpiOsUnmapMemory(Table, ApGetTableLength(Table));
929*cb565728SJerry Jelinek 	}
930*cb565728SJerry Jelinek }
931*cb565728SJerry Jelinek 
932*cb565728SJerry Jelinek /*
933*cb565728SJerry Jelinek  *
934*cb565728SJerry Jelinek  * FUNCTION:    OslTableNameFromFile
935*cb565728SJerry Jelinek  *
936*cb565728SJerry Jelinek  * PARAMETERS:  Filename            - File that contains the desired table
937*cb565728SJerry Jelinek  *              Signature           - Pointer to 4-character buffer to store
938*cb565728SJerry Jelinek  *                                    extracted table signature.
939*cb565728SJerry Jelinek  *              Instance            - Pointer to integer to store extracted
940*cb565728SJerry Jelinek  *                                    table instance number.
941*cb565728SJerry Jelinek  *
942*cb565728SJerry Jelinek  * RETURN:      Status; Table name is extracted if AE_OK.
943*cb565728SJerry Jelinek  *
944*cb565728SJerry Jelinek  * DESCRIPTION: Extract table signature and instance number from a table file
945*cb565728SJerry Jelinek  *              name.
946*cb565728SJerry Jelinek  *
947*cb565728SJerry Jelinek  */
948*cb565728SJerry Jelinek static ACPI_STATUS
OslTableNameFromFile(char * Filename,char * Signature,UINT32 * Instance)949*cb565728SJerry Jelinek OslTableNameFromFile(char *Filename, char *Signature, UINT32 *Instance)
950*cb565728SJerry Jelinek {
951*cb565728SJerry Jelinek 	/* Ignore meaningless files */
952*cb565728SJerry Jelinek 
953*cb565728SJerry Jelinek 	if (strlen(Filename) < ACPI_NAME_SIZE) {
954*cb565728SJerry Jelinek 		return (AE_BAD_SIGNATURE);
955*cb565728SJerry Jelinek 	}
956*cb565728SJerry Jelinek 
957*cb565728SJerry Jelinek 	/* Extract instance number */
958*cb565728SJerry Jelinek 
959*cb565728SJerry Jelinek 	if (isdigit((int)Filename[ACPI_NAME_SIZE])) {
960*cb565728SJerry Jelinek 		sscanf(&Filename[ACPI_NAME_SIZE], "%u", Instance);
961*cb565728SJerry Jelinek 	} else if (strlen(Filename) != ACPI_NAME_SIZE) {
962*cb565728SJerry Jelinek 		return (AE_BAD_SIGNATURE);
963*cb565728SJerry Jelinek 	} else {
964*cb565728SJerry Jelinek 		*Instance = 0;
965*cb565728SJerry Jelinek 	}
966*cb565728SJerry Jelinek 
967*cb565728SJerry Jelinek 	/* Extract signature */
968*cb565728SJerry Jelinek 
969*cb565728SJerry Jelinek 	ACPI_MOVE_NAME(Signature, Filename);
970*cb565728SJerry Jelinek 	return (AE_OK);
971*cb565728SJerry Jelinek }
972*cb565728SJerry Jelinek 
973*cb565728SJerry Jelinek UINT32
CmGetFileSize(ACPI_FILE File)974*cb565728SJerry Jelinek CmGetFileSize(ACPI_FILE File)
975*cb565728SJerry Jelinek {
976*cb565728SJerry Jelinek 	int fd;
977*cb565728SJerry Jelinek 	struct stat sb;
978*cb565728SJerry Jelinek 
979*cb565728SJerry Jelinek 	fd = fileno(File);
980*cb565728SJerry Jelinek 	if (fstat(fd, &sb) != 0)
981*cb565728SJerry Jelinek 		return (ACPI_UINT32_MAX);
982*cb565728SJerry Jelinek 	return ((UINT32)sb.st_size);
983*cb565728SJerry Jelinek }
984*cb565728SJerry Jelinek 
985*cb565728SJerry Jelinek void *
AcpiOsAllocateZeroed(ACPI_SIZE Size)986*cb565728SJerry Jelinek AcpiOsAllocateZeroed(ACPI_SIZE Size)
987*cb565728SJerry Jelinek {
988*cb565728SJerry Jelinek 	return (calloc(1, Size));
989*cb565728SJerry Jelinek }
990*cb565728SJerry Jelinek 
991*cb565728SJerry Jelinek void
AcpiOsFree(void * p)992*cb565728SJerry Jelinek AcpiOsFree(void *p)
993*cb565728SJerry Jelinek {
994*cb565728SJerry Jelinek 	free(p);
995*cb565728SJerry Jelinek }
996*cb565728SJerry Jelinek 
997*cb565728SJerry Jelinek ACPI_FILE
AcpiOsOpenFile(const char * Path,UINT8 Modes)998*cb565728SJerry Jelinek AcpiOsOpenFile(const char *Path, UINT8 Modes)
999*cb565728SJerry Jelinek {
1000*cb565728SJerry Jelinek 	char mode[3];
1001*cb565728SJerry Jelinek 
1002*cb565728SJerry Jelinek 	bzero(mode, sizeof (mode));
1003*cb565728SJerry Jelinek 	if ((Modes & ACPI_FILE_READING) != 0)
1004*cb565728SJerry Jelinek 		(void) strlcat(mode, "r", sizeof (mode));
1005*cb565728SJerry Jelinek 
1006*cb565728SJerry Jelinek 	if ((Modes & ACPI_FILE_WRITING) != 0)
1007*cb565728SJerry Jelinek 		(void) strlcat(mode, "w", sizeof (mode));
1008*cb565728SJerry Jelinek 
1009*cb565728SJerry Jelinek 	return (fopen(Path, mode));
1010*cb565728SJerry Jelinek }
1011*cb565728SJerry Jelinek 
1012*cb565728SJerry Jelinek void
AcpiOsCloseFile(ACPI_FILE File)1013*cb565728SJerry Jelinek AcpiOsCloseFile(ACPI_FILE File)
1014*cb565728SJerry Jelinek {
1015*cb565728SJerry Jelinek 	fclose(File);
1016*cb565728SJerry Jelinek }
1017*cb565728SJerry Jelinek 
1018*cb565728SJerry Jelinek int
AcpiOsReadFile(ACPI_FILE File,void * Buffer,ACPI_SIZE Size,ACPI_SIZE Count)1019*cb565728SJerry Jelinek AcpiOsReadFile(ACPI_FILE File, void *Buffer, ACPI_SIZE Size, ACPI_SIZE Count)
1020*cb565728SJerry Jelinek {
1021*cb565728SJerry Jelinek 	return (fread(Buffer, Size, Count, File));
1022*cb565728SJerry Jelinek }
1023*cb565728SJerry Jelinek 
1024*cb565728SJerry Jelinek void *
AcpiOsMapMemory(ACPI_PHYSICAL_ADDRESS Where,ACPI_SIZE Length)1025*cb565728SJerry Jelinek AcpiOsMapMemory(ACPI_PHYSICAL_ADDRESS Where, ACPI_SIZE Length)
1026*cb565728SJerry Jelinek {
1027*cb565728SJerry Jelinek 	int fd;
1028*cb565728SJerry Jelinek 	void *p;
1029*cb565728SJerry Jelinek 	ulong_t offset;
1030*cb565728SJerry Jelinek 
1031*cb565728SJerry Jelinek 	if ((fd = open("/dev/xsvc", O_RDONLY)) < 0)
1032*cb565728SJerry Jelinek 		return (NULL);
1033*cb565728SJerry Jelinek 
1034*cb565728SJerry Jelinek 	if (pagesize == 0) {
1035*cb565728SJerry Jelinek 		pagesize = getpagesize();
1036*cb565728SJerry Jelinek 	}
1037*cb565728SJerry Jelinek 
1038*cb565728SJerry Jelinek 	offset = Where % pagesize;
1039*cb565728SJerry Jelinek 	p = mmap(NULL, Length + offset, PROT_READ, MAP_SHARED | MAP_NORESERVE,
1040*cb565728SJerry Jelinek 	    fd, Where - offset);
1041*cb565728SJerry Jelinek 
1042*cb565728SJerry Jelinek 	(void) close(fd);
1043*cb565728SJerry Jelinek 
1044*cb565728SJerry Jelinek 	if (p == MAP_FAILED)
1045*cb565728SJerry Jelinek 		return (NULL);
1046*cb565728SJerry Jelinek 	p = (char *)p + offset;
1047*cb565728SJerry Jelinek 	return (p);
1048*cb565728SJerry Jelinek }
1049*cb565728SJerry Jelinek 
1050*cb565728SJerry Jelinek void
AcpiOsUnmapMemory(void * LogicalAddress,ACPI_SIZE Size)1051*cb565728SJerry Jelinek AcpiOsUnmapMemory(void *LogicalAddress, ACPI_SIZE Size)
1052*cb565728SJerry Jelinek {
1053*cb565728SJerry Jelinek 	ulong_t offset;
1054*cb565728SJerry Jelinek 	void *p;
1055*cb565728SJerry Jelinek 
1056*cb565728SJerry Jelinek 	offset = (ulong_t)LogicalAddress % pagesize;
1057*cb565728SJerry Jelinek 	p = (void *)((char *)LogicalAddress - offset);
1058*cb565728SJerry Jelinek 
1059*cb565728SJerry Jelinek 	(void) munmap(p, Size + offset);
1060*cb565728SJerry Jelinek }
1061