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