1 /******************************************************************************
3 * Module Name: oslinuxtbl - Linux OSL for obtaining ACPI tables
5 *****************************************************************************/
8 * Copyright (C) 2000 - 2014, Intel Corp.
11 * Redistribution and use in source and binary forms, with or without
12 * modification, are permitted provided that the following conditions
14 * 1. Redistributions of source code must retain the above copyright
15 * notice, this list of conditions, and the following disclaimer,
16 * without modification.
17 * 2. Redistributions in binary form must reproduce at minimum a disclaimer
18 * substantially similar to the "NO WARRANTY" disclaimer below
19 * ("Disclaimer") and any redistribution must be conditioned upon
20 * including a substantially similar Disclaimer requirement for further
21 * binary redistribution.
22 * 3. Neither the names of the above-listed copyright holders nor the names
23 * of any contributors may be used to endorse or promote products derived
24 * from this software without specific prior written permission.
26 * Alternatively, this software may be distributed under the terms of the
27 * GNU General Public License ("GPL") version 2 as published by the Free
28 * Software Foundation.
31 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
32 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
33 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR
34 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
35 * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
36 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
37 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
38 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
39 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
40 * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
41 * POSSIBILITY OF SUCH DAMAGES.
47 #define _COMPONENT ACPI_OS_SERVICES
48 ACPI_MODULE_NAME ("oslinuxtbl")
56 /* List of information about obtained ACPI tables */
58 typedef struct table_info
60 struct table_info *Next;
62 char Signature[ACPI_NAME_SIZE];
66 /* Local prototypes */
73 OslTableNameFromFile (
84 OslReadTableFromFile (
88 ACPI_TABLE_HEADER **Table);
94 ACPI_TABLE_HEADER **Table);
98 ACPI_TABLE_HEADER *Table);
100 static ACPI_PHYSICAL_ADDRESS
109 OslListCustomizedTables (
113 OslGetCustomizedTable (
117 ACPI_TABLE_HEADER **Table,
118 ACPI_PHYSICAL_ADDRESS *Address);
128 ACPI_TABLE_HEADER **Table,
129 ACPI_PHYSICAL_ADDRESS *Address);
133 ACPI_STATUS DefaultStatus);
138 #define DYNAMIC_TABLE_DIR "/sys/firmware/acpi/tables/dynamic"
139 #define STATIC_TABLE_DIR "/sys/firmware/acpi/tables"
140 #define EFI_SYSTAB "/sys/firmware/efi/systab"
142 /* Should we get dynamically loaded SSDTs from DYNAMIC_TABLE_DIR? */
144 UINT8 Gbl_DumpDynamicTables = TRUE;
146 /* Initialization flags */
148 UINT8 Gbl_TableListInitialized = FALSE;
150 /* Local copies of main ACPI tables */
152 ACPI_TABLE_RSDP Gbl_Rsdp;
153 ACPI_TABLE_FADT *Gbl_Fadt = NULL;
154 ACPI_TABLE_RSDT *Gbl_Rsdt = NULL;
155 ACPI_TABLE_XSDT *Gbl_Xsdt = NULL;
157 /* Table addresses */
159 ACPI_PHYSICAL_ADDRESS Gbl_FadtAddress = 0;
160 ACPI_PHYSICAL_ADDRESS Gbl_RsdpAddress = 0;
162 /* Revision of RSD PTR */
164 UINT8 Gbl_Revision = 0;
166 OSL_TABLE_INFO *Gbl_TableListHead = NULL;
167 UINT32 Gbl_TableCount = 0;
170 /******************************************************************************
172 * FUNCTION: OslGetLastStatus
174 * PARAMETERS: DefaultStatus - Default error status to return
176 * RETURN: Status; Converted from errno.
178 * DESCRIPTION: Get last errno and conver it to ACPI_STATUS.
180 *****************************************************************************/
184 ACPI_STATUS DefaultStatus)
196 return (AE_NOT_FOUND);
200 return (AE_NO_MEMORY);
204 return (DefaultStatus);
209 /******************************************************************************
211 * FUNCTION: AcpiOsGetTableByAddress
213 * PARAMETERS: Address - Physical address of the ACPI table
214 * Table - Where a pointer to the table is returned
216 * RETURN: Status; Table buffer is returned if AE_OK.
217 * AE_NOT_FOUND: A valid table was not found at the address
219 * DESCRIPTION: Get an ACPI table via a physical memory address.
221 *****************************************************************************/
224 AcpiOsGetTableByAddress (
225 ACPI_PHYSICAL_ADDRESS Address,
226 ACPI_TABLE_HEADER **Table)
229 ACPI_TABLE_HEADER *MappedTable;
230 ACPI_TABLE_HEADER *LocalTable = NULL;
231 ACPI_STATUS Status = AE_OK;
234 /* Get main ACPI tables from memory on first invocation of this function */
236 Status = OslTableInitialize ();
237 if (ACPI_FAILURE (Status))
242 /* Map the table and validate it */
244 Status = OslMapTable (Address, NULL, &MappedTable);
245 if (ACPI_FAILURE (Status))
250 /* Copy table to local buffer and return it */
252 TableLength = ApGetTableLength (MappedTable);
253 if (TableLength == 0)
255 Status = AE_BAD_HEADER;
259 LocalTable = calloc (1, TableLength);
262 Status = AE_NO_MEMORY;
266 ACPI_MEMCPY (LocalTable, MappedTable, TableLength);
269 OslUnmapTable (MappedTable);
275 /******************************************************************************
277 * FUNCTION: AcpiOsGetTableByName
279 * PARAMETERS: Signature - ACPI Signature for desired table. Must be
280 * a null terminated 4-character string.
281 * Instance - Multiple table support for SSDT/UEFI (0...n)
282 * Must be 0 for other tables.
283 * Table - Where a pointer to the table is returned
284 * Address - Where the table physical address is returned
286 * RETURN: Status; Table buffer and physical address returned if AE_OK.
287 * AE_LIMIT: Instance is beyond valid limit
288 * AE_NOT_FOUND: A table with the signature was not found
290 * NOTE: Assumes the input signature is uppercase.
292 *****************************************************************************/
295 AcpiOsGetTableByName (
298 ACPI_TABLE_HEADER **Table,
299 ACPI_PHYSICAL_ADDRESS *Address)
304 /* Get main ACPI tables from memory on first invocation of this function */
306 Status = OslTableInitialize ();
307 if (ACPI_FAILURE (Status))
312 /* Not a main ACPI table, attempt to extract it from the RSDT/XSDT */
314 if (!Gbl_DumpCustomizedTables)
316 /* Attempt to get the table from the memory */
318 Status = OslGetBiosTable (Signature, Instance, Table, Address);
322 /* Attempt to get the table from the static directory */
324 Status = OslGetCustomizedTable (STATIC_TABLE_DIR, Signature,
325 Instance, Table, Address);
328 if (ACPI_FAILURE (Status) && Status == AE_LIMIT)
330 if (Gbl_DumpDynamicTables)
332 /* Attempt to get a dynamic table */
334 Status = OslGetCustomizedTable (DYNAMIC_TABLE_DIR, Signature,
335 Instance, Table, Address);
343 /******************************************************************************
345 * FUNCTION: OslAddTableToList
347 * PARAMETERS: Signature - Table signature
348 * Instance - Table instance
350 * RETURN: Status; Successfully added if AE_OK.
351 * AE_NO_MEMORY: Memory allocation error
353 * DESCRIPTION: Insert a table structure into OSL table list.
355 *****************************************************************************/
362 OSL_TABLE_INFO *NewInfo;
363 OSL_TABLE_INFO *Next;
364 UINT32 NextInstance = 0;
365 BOOLEAN Found = FALSE;
368 NewInfo = calloc (1, sizeof (OSL_TABLE_INFO));
371 return (AE_NO_MEMORY);
374 ACPI_MOVE_NAME (NewInfo->Signature, Signature);
376 if (!Gbl_TableListHead)
378 Gbl_TableListHead = NewInfo;
382 Next = Gbl_TableListHead;
385 if (ACPI_COMPARE_NAME (Next->Signature, Signature))
387 if (Next->Instance == Instance)
391 if (Next->Instance >= NextInstance)
393 NextInstance = Next->Instance + 1;
403 Next->Next = NewInfo;
411 "%4.4s: Warning unmatched table instance %d, expected %d\n",
412 Signature, Instance, NextInstance);
414 Instance = NextInstance;
417 NewInfo->Instance = Instance;
424 /******************************************************************************
426 * FUNCTION: AcpiOsGetTableByIndex
428 * PARAMETERS: Index - Which table to get
429 * Table - Where a pointer to the table is returned
430 * Instance - Where a pointer to the table instance no. is
432 * Address - Where the table physical address is returned
434 * RETURN: Status; Table buffer and physical address returned if AE_OK.
435 * AE_LIMIT: Index is beyond valid limit
437 * DESCRIPTION: Get an ACPI table via an index value (0 through n). Returns
438 * AE_LIMIT when an invalid index is reached. Index is not
439 * necessarily an index into the RSDT/XSDT.
441 *****************************************************************************/
444 AcpiOsGetTableByIndex (
446 ACPI_TABLE_HEADER **Table,
448 ACPI_PHYSICAL_ADDRESS *Address)
450 OSL_TABLE_INFO *Info;
455 /* Get main ACPI tables from memory on first invocation of this function */
457 Status = OslTableInitialize ();
458 if (ACPI_FAILURE (Status))
465 if (Index >= Gbl_TableCount)
470 /* Point to the table list entry specified by the Index argument */
472 Info = Gbl_TableListHead;
473 for (i = 0; i < Index; i++)
478 /* Now we can just get the table via the signature */
480 Status = AcpiOsGetTableByName (Info->Signature, Info->Instance,
483 if (ACPI_SUCCESS (Status))
485 *Instance = Info->Instance;
491 /******************************************************************************
493 * FUNCTION: OslFindRsdpViaEfi
497 * RETURN: RSDP address if found
499 * DESCRIPTION: Find RSDP address via EFI.
501 *****************************************************************************/
503 static ACPI_PHYSICAL_ADDRESS
509 unsigned long Address = 0;
512 File = fopen (EFI_SYSTAB, "r");
515 while (fgets (Buffer, 80, File))
517 if (sscanf (Buffer, "ACPI20=0x%lx", &Address) == 1)
525 return ((ACPI_PHYSICAL_ADDRESS) (Address));
529 /******************************************************************************
531 * FUNCTION: OslLoadRsdp
537 * DESCRIPTION: Scan and load RSDP.
539 *****************************************************************************/
545 ACPI_TABLE_HEADER *MappedTable;
547 ACPI_PHYSICAL_ADDRESS RsdpBase;
551 /* Get RSDP from memory */
553 RsdpSize = sizeof (ACPI_TABLE_RSDP);
556 RsdpBase = Gbl_RsdpBase;
560 RsdpBase = OslFindRsdpViaEfi ();
565 RsdpBase = ACPI_HI_RSDP_WINDOW_BASE;
566 RsdpSize = ACPI_HI_RSDP_WINDOW_SIZE;
569 RsdpAddress = AcpiOsMapMemory (RsdpBase, RsdpSize);
572 return (OslGetLastStatus (AE_BAD_ADDRESS));
575 /* Search low memory for the RSDP */
577 MappedTable = ACPI_CAST_PTR (ACPI_TABLE_HEADER,
578 AcpiTbScanMemoryForRsdp (RsdpAddress, RsdpSize));
581 AcpiOsUnmapMemory (RsdpAddress, RsdpSize);
582 return (AE_NOT_FOUND);
585 Gbl_RsdpAddress = RsdpBase + (ACPI_CAST8 (MappedTable) - RsdpAddress);
587 ACPI_MEMCPY (&Gbl_Rsdp, MappedTable, sizeof (ACPI_TABLE_RSDP));
588 AcpiOsUnmapMemory (RsdpAddress, RsdpSize);
594 /******************************************************************************
596 * FUNCTION: OslTableInitialize
602 * DESCRIPTION: Initialize ACPI table data. Get and store main ACPI tables to
603 * local variables. Main ACPI tables include RSDT, FADT, RSDT,
606 *****************************************************************************/
613 ACPI_PHYSICAL_ADDRESS Address;
616 if (Gbl_TableListInitialized)
621 /* Get RSDP from memory */
623 Status = OslLoadRsdp ();
624 if (ACPI_FAILURE (Status))
629 /* Get XSDT from memory */
631 if (Gbl_Rsdp.Revision)
640 Status = OslGetBiosTable (ACPI_SIG_XSDT, 0,
641 ACPI_CAST_PTR (ACPI_TABLE_HEADER *, &Gbl_Xsdt), &Address);
642 if (ACPI_FAILURE (Status))
648 /* Get RSDT from memory */
650 if (Gbl_Rsdp.RsdtPhysicalAddress)
658 Status = OslGetBiosTable (ACPI_SIG_RSDT, 0,
659 ACPI_CAST_PTR (ACPI_TABLE_HEADER *, &Gbl_Rsdt), &Address);
660 if (ACPI_FAILURE (Status))
666 /* Get FADT from memory */
674 Status = OslGetBiosTable (ACPI_SIG_FADT, 0,
675 ACPI_CAST_PTR (ACPI_TABLE_HEADER *, &Gbl_Fadt), &Gbl_FadtAddress);
676 if (ACPI_FAILURE (Status))
681 if (!Gbl_DumpCustomizedTables)
683 /* Add mandatory tables to global table list first */
685 Status = OslAddTableToList (ACPI_RSDP_NAME, 0);
686 if (ACPI_FAILURE (Status))
691 Status = OslAddTableToList (ACPI_SIG_RSDT, 0);
692 if (ACPI_FAILURE (Status))
697 if (Gbl_Revision == 2)
699 Status = OslAddTableToList (ACPI_SIG_XSDT, 0);
700 if (ACPI_FAILURE (Status))
706 Status = OslAddTableToList (ACPI_SIG_DSDT, 0);
707 if (ACPI_FAILURE (Status))
712 Status = OslAddTableToList (ACPI_SIG_FACS, 0);
713 if (ACPI_FAILURE (Status))
718 /* Add all tables found in the memory */
720 Status = OslListBiosTables ();
721 if (ACPI_FAILURE (Status))
728 /* Add all tables found in the static directory */
730 Status = OslListCustomizedTables (STATIC_TABLE_DIR);
731 if (ACPI_FAILURE (Status))
737 if (Gbl_DumpDynamicTables)
739 /* Add all dynamically loaded tables in the dynamic directory */
741 Status = OslListCustomizedTables (DYNAMIC_TABLE_DIR);
742 if (ACPI_FAILURE (Status))
748 Gbl_TableListInitialized = TRUE;
753 /******************************************************************************
755 * FUNCTION: OslListBiosTables
759 * RETURN: Status; Table list is initialized if AE_OK.
761 * DESCRIPTION: Add ACPI tables to the table list from memory.
763 * NOTE: This works on Linux as table customization does not modify the
764 * addresses stored in RSDP/RSDT/XSDT/FADT.
766 *****************************************************************************/
772 ACPI_TABLE_HEADER *MappedTable = NULL;
774 UINT8 NumberOfTables;
776 ACPI_PHYSICAL_ADDRESS TableAddress = 0;
777 ACPI_STATUS Status = AE_OK;
783 ItemSize = sizeof (UINT64);
784 TableData = ACPI_CAST8 (Gbl_Xsdt) + sizeof (ACPI_TABLE_HEADER);
786 (UINT8) ((Gbl_Xsdt->Header.Length - sizeof (ACPI_TABLE_HEADER))
789 else /* Use RSDT if XSDT is not available */
791 ItemSize = sizeof (UINT32);
792 TableData = ACPI_CAST8 (Gbl_Rsdt) + sizeof (ACPI_TABLE_HEADER);
794 (UINT8) ((Gbl_Rsdt->Header.Length - sizeof (ACPI_TABLE_HEADER))
798 /* Search RSDT/XSDT for the requested table */
800 for (i = 0; i < NumberOfTables; ++i, TableData += ItemSize)
805 (ACPI_PHYSICAL_ADDRESS) (*ACPI_CAST64 (TableData));
810 (ACPI_PHYSICAL_ADDRESS) (*ACPI_CAST32 (TableData));
813 Status = OslMapTable (TableAddress, NULL, &MappedTable);
814 if (ACPI_FAILURE (Status))
819 OslAddTableToList (MappedTable->Signature, 0);
820 OslUnmapTable (MappedTable);
827 /******************************************************************************
829 * FUNCTION: OslGetBiosTable
831 * PARAMETERS: Signature - ACPI Signature for common table. Must be
832 * a null terminated 4-character string.
833 * Instance - Multiple table support for SSDT/UEFI (0...n)
834 * Must be 0 for other tables.
835 * Table - Where a pointer to the table is returned
836 * Address - Where the table physical address is returned
838 * RETURN: Status; Table buffer and physical address returned if AE_OK.
839 * AE_LIMIT: Instance is beyond valid limit
840 * AE_NOT_FOUND: A table with the signature was not found
842 * DESCRIPTION: Get a BIOS provided ACPI table
844 * NOTE: Assumes the input signature is uppercase.
846 *****************************************************************************/
852 ACPI_TABLE_HEADER **Table,
853 ACPI_PHYSICAL_ADDRESS *Address)
855 ACPI_TABLE_HEADER *LocalTable = NULL;
856 ACPI_TABLE_HEADER *MappedTable = NULL;
858 UINT8 NumberOfTables;
860 UINT32 CurrentInstance = 0;
861 ACPI_PHYSICAL_ADDRESS TableAddress = 0;
862 UINT32 TableLength = 0;
863 ACPI_STATUS Status = AE_OK;
867 /* Handle special tables whose addresses are not in RSDT/XSDT */
869 if (ACPI_COMPARE_NAME (Signature, ACPI_RSDP_NAME) ||
870 ACPI_COMPARE_NAME (Signature, ACPI_SIG_RSDT) ||
871 ACPI_COMPARE_NAME (Signature, ACPI_SIG_XSDT) ||
872 ACPI_COMPARE_NAME (Signature, ACPI_SIG_DSDT) ||
873 ACPI_COMPARE_NAME (Signature, ACPI_SIG_FACS))
876 * Get the appropriate address, either 32-bit or 64-bit. Be very
877 * careful about the FADT length and validate table addresses.
878 * Note: The 64-bit addresses have priority.
880 if (ACPI_COMPARE_NAME (Signature, ACPI_SIG_DSDT))
882 if ((Gbl_Fadt->Header.Length >= MIN_FADT_FOR_XDSDT) &&
885 TableAddress = (ACPI_PHYSICAL_ADDRESS) Gbl_Fadt->XDsdt;
887 else if ((Gbl_Fadt->Header.Length >= MIN_FADT_FOR_DSDT) &&
890 TableAddress = (ACPI_PHYSICAL_ADDRESS) Gbl_Fadt->Dsdt;
893 else if (ACPI_COMPARE_NAME (Signature, ACPI_SIG_FACS))
895 if ((Gbl_Fadt->Header.Length >= MIN_FADT_FOR_XFACS) &&
898 TableAddress = (ACPI_PHYSICAL_ADDRESS) Gbl_Fadt->XFacs;
900 else if ((Gbl_Fadt->Header.Length >= MIN_FADT_FOR_FACS) &&
903 TableAddress = (ACPI_PHYSICAL_ADDRESS) Gbl_Fadt->Facs;
906 else if (ACPI_COMPARE_NAME (Signature, ACPI_SIG_XSDT))
910 return (AE_BAD_SIGNATURE);
912 TableAddress = (ACPI_PHYSICAL_ADDRESS) Gbl_Rsdp.XsdtPhysicalAddress;
914 else if (ACPI_COMPARE_NAME (Signature, ACPI_SIG_RSDT))
916 TableAddress = (ACPI_PHYSICAL_ADDRESS) Gbl_Rsdp.RsdtPhysicalAddress;
920 TableAddress = (ACPI_PHYSICAL_ADDRESS) Gbl_RsdpAddress;
921 Signature = ACPI_SIG_RSDP;
924 /* Now we can get the requested special table */
926 Status = OslMapTable (TableAddress, Signature, &MappedTable);
927 if (ACPI_FAILURE (Status))
932 TableLength = ApGetTableLength (MappedTable);
934 else /* Case for a normal ACPI table */
938 ItemSize = sizeof (UINT64);
939 TableData = ACPI_CAST8 (Gbl_Xsdt) + sizeof (ACPI_TABLE_HEADER);
941 (UINT8) ((Gbl_Xsdt->Header.Length - sizeof (ACPI_TABLE_HEADER))
944 else /* Use RSDT if XSDT is not available */
946 ItemSize = sizeof (UINT32);
947 TableData = ACPI_CAST8 (Gbl_Rsdt) + sizeof (ACPI_TABLE_HEADER);
949 (UINT8) ((Gbl_Rsdt->Header.Length - sizeof (ACPI_TABLE_HEADER))
953 /* Search RSDT/XSDT for the requested table */
955 for (i = 0; i < NumberOfTables; ++i, TableData += ItemSize)
960 (ACPI_PHYSICAL_ADDRESS) (*ACPI_CAST64 (TableData));
965 (ACPI_PHYSICAL_ADDRESS) (*ACPI_CAST32 (TableData));
968 Status = OslMapTable (TableAddress, NULL, &MappedTable);
969 if (ACPI_FAILURE (Status))
973 TableLength = MappedTable->Length;
975 /* Does this table match the requested signature? */
977 if (!ACPI_COMPARE_NAME (MappedTable->Signature, Signature))
979 OslUnmapTable (MappedTable);
984 /* Match table instance (for SSDT/UEFI tables) */
986 if (CurrentInstance != Instance)
988 OslUnmapTable (MappedTable);
1003 if (TableLength == 0)
1005 Status = AE_BAD_HEADER;
1009 /* Copy table to local buffer and return it */
1011 LocalTable = calloc (1, TableLength);
1014 Status = AE_NO_MEMORY;
1018 ACPI_MEMCPY (LocalTable, MappedTable, TableLength);
1019 *Address = TableAddress;
1020 *Table = LocalTable;
1023 OslUnmapTable (MappedTable);
1028 /******************************************************************************
1030 * FUNCTION: OslListCustomizedTables
1032 * PARAMETERS: Directory - Directory that contains the tables
1034 * RETURN: Status; Table list is initialized if AE_OK.
1036 * DESCRIPTION: Add ACPI tables to the table list from a directory.
1038 *****************************************************************************/
1041 OslListCustomizedTables (
1046 char TempName[ACPI_NAME_SIZE];
1048 ACPI_STATUS Status = AE_OK;
1051 /* Open the requested directory */
1053 TableDir = AcpiOsOpenDirectory (Directory, "*", REQUEST_FILE_ONLY);
1056 return (OslGetLastStatus (AE_NOT_FOUND));
1059 /* Examine all entries in this directory */
1061 while ((Filename = AcpiOsGetNextFilename (TableDir)))
1063 /* Extract table name and instance number */
1065 Status = OslTableNameFromFile (Filename, TempName, &Instance);
1067 /* Ignore meaningless files */
1069 if (ACPI_FAILURE (Status))
1074 /* Add new info node to global table list */
1076 Status = OslAddTableToList (TempName, Instance);
1077 if (ACPI_FAILURE (Status))
1083 AcpiOsCloseDirectory (TableDir);
1088 /******************************************************************************
1090 * FUNCTION: OslMapTable
1092 * PARAMETERS: Address - Address of the table in memory
1093 * Signature - Optional ACPI Signature for desired table.
1094 * Null terminated 4-character string.
1095 * Table - Where a pointer to the mapped table is
1098 * RETURN: Status; Mapped table is returned if AE_OK.
1099 * AE_NOT_FOUND: A valid table was not found at the address
1101 * DESCRIPTION: Map entire ACPI table into caller's address space.
1103 *****************************************************************************/
1109 ACPI_TABLE_HEADER **Table)
1111 ACPI_TABLE_HEADER *MappedTable;
1117 return (AE_BAD_ADDRESS);
1121 * Map the header so we can get the table length.
1122 * Use sizeof (ACPI_TABLE_HEADER) as:
1123 * 1. it is bigger than 24 to include RSDP->Length
1124 * 2. it is smaller than sizeof (ACPI_TABLE_RSDP)
1126 MappedTable = AcpiOsMapMemory (Address, sizeof (ACPI_TABLE_HEADER));
1129 fprintf (stderr, "Could not map table header at 0x%8.8X%8.8X\n",
1130 ACPI_FORMAT_UINT64 (Address));
1131 return (OslGetLastStatus (AE_BAD_ADDRESS));
1134 /* If specified, signature must match */
1137 !ACPI_COMPARE_NAME (Signature, MappedTable->Signature))
1139 AcpiOsUnmapMemory (MappedTable, sizeof (ACPI_TABLE_HEADER));
1140 return (AE_BAD_SIGNATURE);
1143 /* Map the entire table */
1145 Length = ApGetTableLength (MappedTable);
1146 AcpiOsUnmapMemory (MappedTable, sizeof (ACPI_TABLE_HEADER));
1149 return (AE_BAD_HEADER);
1152 MappedTable = AcpiOsMapMemory (Address, Length);
1155 fprintf (stderr, "Could not map table at 0x%8.8X%8.8X length %8.8X\n",
1156 ACPI_FORMAT_UINT64 (Address), Length);
1157 return (OslGetLastStatus (AE_INVALID_TABLE_LENGTH));
1160 (void) ApIsValidChecksum (MappedTable);
1162 *Table = MappedTable;
1167 /******************************************************************************
1169 * FUNCTION: OslUnmapTable
1171 * PARAMETERS: Table - A pointer to the mapped table
1175 * DESCRIPTION: Unmap entire ACPI table.
1177 *****************************************************************************/
1181 ACPI_TABLE_HEADER *Table)
1185 AcpiOsUnmapMemory (Table, ApGetTableLength (Table));
1190 /******************************************************************************
1192 * FUNCTION: OslTableNameFromFile
1194 * PARAMETERS: Filename - File that contains the desired table
1195 * Signature - Pointer to 4-character buffer to store
1196 * extracted table signature.
1197 * Instance - Pointer to integer to store extracted
1198 * table instance number.
1200 * RETURN: Status; Table name is extracted if AE_OK.
1202 * DESCRIPTION: Extract table signature and instance number from a table file
1205 *****************************************************************************/
1208 OslTableNameFromFile (
1214 /* Ignore meaningless files */
1216 if (strlen (Filename) < ACPI_NAME_SIZE)
1218 return (AE_BAD_SIGNATURE);
1221 /* Extract instance number */
1223 if (isdigit ((int) Filename[ACPI_NAME_SIZE]))
1225 sscanf (&Filename[ACPI_NAME_SIZE], "%d", Instance);
1227 else if (strlen (Filename) != ACPI_NAME_SIZE)
1229 return (AE_BAD_SIGNATURE);
1236 /* Extract signature */
1238 ACPI_MOVE_NAME (Signature, Filename);
1243 /******************************************************************************
1245 * FUNCTION: OslReadTableFromFile
1247 * PARAMETERS: Filename - File that contains the desired table
1248 * FileOffset - Offset of the table in file
1249 * Signature - Optional ACPI Signature for desired table.
1250 * A null terminated 4-character string.
1251 * Table - Where a pointer to the table is returned
1253 * RETURN: Status; Table buffer is returned if AE_OK.
1255 * DESCRIPTION: Read a ACPI table from a file.
1257 *****************************************************************************/
1260 OslReadTableFromFile (
1262 ACPI_SIZE FileOffset,
1264 ACPI_TABLE_HEADER **Table)
1267 ACPI_TABLE_HEADER Header;
1268 ACPI_TABLE_HEADER *LocalTable = NULL;
1272 ACPI_STATUS Status = AE_OK;
1277 TableFile = fopen (Filename, "rb");
1278 if (TableFile == NULL)
1280 fprintf (stderr, "Could not open table file: %s\n", Filename);
1281 return (OslGetLastStatus (AE_NOT_FOUND));
1284 fseek (TableFile, FileOffset, SEEK_SET);
1286 /* Read the Table header to get the table length */
1288 Count = fread (&Header, 1, sizeof (ACPI_TABLE_HEADER), TableFile);
1289 if (Count != sizeof (ACPI_TABLE_HEADER))
1291 fprintf (stderr, "Could not read table header: %s\n", Filename);
1292 Status = AE_BAD_HEADER;
1296 /* If signature is specified, it must match the table */
1299 !ACPI_COMPARE_NAME (Signature, Header.Signature))
1301 fprintf (stderr, "Incorrect signature: Expecting %4.4s, found %4.4s\n",
1302 Signature, Header.Signature);
1303 Status = AE_BAD_SIGNATURE;
1307 TableLength = ApGetTableLength (&Header);
1308 if (TableLength == 0)
1310 Status = AE_BAD_HEADER;
1314 /* Read the entire table into a local buffer */
1316 LocalTable = calloc (1, TableLength);
1320 "%4.4s: Could not allocate buffer for table of length %X\n",
1321 Header.Signature, TableLength);
1322 Status = AE_NO_MEMORY;
1326 fseek (TableFile, FileOffset, SEEK_SET);
1328 while (!feof (TableFile) && Total < TableLength)
1330 Count = fread (LocalTable, 1, TableLength-Total, TableFile);
1333 fprintf (stderr, "%4.4s: Could not read table content\n",
1335 Status = AE_INVALID_TABLE_LENGTH;
1342 /* Validate checksum */
1344 (void) ApIsValidChecksum (LocalTable);
1348 *Table = LocalTable;
1353 /******************************************************************************
1355 * FUNCTION: OslGetCustomizedTable
1357 * PARAMETERS: Pathname - Directory to find Linux customized table
1358 * Signature - ACPI Signature for desired table. Must be
1359 * a null terminated 4-character string.
1360 * Instance - Multiple table support for SSDT/UEFI (0...n)
1361 * Must be 0 for other tables.
1362 * Table - Where a pointer to the table is returned
1363 * Address - Where the table physical address is returned
1365 * RETURN: Status; Table buffer is returned if AE_OK.
1366 * AE_LIMIT: Instance is beyond valid limit
1367 * AE_NOT_FOUND: A table with the signature was not found
1369 * DESCRIPTION: Get an OS customized table.
1371 *****************************************************************************/
1374 OslGetCustomizedTable (
1378 ACPI_TABLE_HEADER **Table,
1379 ACPI_PHYSICAL_ADDRESS *Address)
1382 UINT32 CurrentInstance = 0;
1383 char TempName[ACPI_NAME_SIZE];
1384 char TableFilename[PATH_MAX];
1389 /* Open the directory for customized tables */
1391 TableDir = AcpiOsOpenDirectory (Pathname, "*", REQUEST_FILE_ONLY);
1394 return (OslGetLastStatus (AE_NOT_FOUND));
1397 /* Attempt to find the table in the directory */
1399 while ((Filename = AcpiOsGetNextFilename (TableDir)))
1401 /* Ignore meaningless files */
1403 if (!ACPI_COMPARE_NAME (Filename, Signature))
1408 /* Extract table name and instance number */
1410 Status = OslTableNameFromFile (Filename, TempName, &CurrentInstance);
1412 /* Ignore meaningless files */
1414 if (ACPI_FAILURE (Status) || CurrentInstance != Instance)
1419 /* Create the table pathname */
1423 sprintf (TableFilename, "%s/%4.4s%d", Pathname, TempName, Instance);
1427 sprintf (TableFilename, "%s/%4.4s", Pathname, TempName);
1432 AcpiOsCloseDirectory (TableDir);
1439 /* There is no physical address saved for customized tables, use zero */
1442 Status = OslReadTableFromFile (TableFilename, 0, NULL, Table);