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 osl_table_info
60 struct osl_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: OslCanUseXsdt
600 * RETURN: TRUE if XSDT is allowed to be used.
602 * DESCRIPTION: This function collects logic that can be used to determine if
603 * XSDT should be used instead of RSDT.
605 *****************************************************************************/
611 if (Gbl_Revision && !AcpiGbl_DoNotUseXsdt)
622 /******************************************************************************
624 * FUNCTION: OslTableInitialize
630 * DESCRIPTION: Initialize ACPI table data. Get and store main ACPI tables to
631 * local variables. Main ACPI tables include RSDT, FADT, RSDT,
634 *****************************************************************************/
641 ACPI_PHYSICAL_ADDRESS Address;
644 if (Gbl_TableListInitialized)
649 /* Get RSDP from memory */
651 Status = OslLoadRsdp ();
652 if (ACPI_FAILURE (Status))
657 /* Get XSDT from memory */
659 if (Gbl_Rsdp.Revision && !Gbl_DoNotDumpXsdt)
668 Status = OslGetBiosTable (ACPI_SIG_XSDT, 0,
669 ACPI_CAST_PTR (ACPI_TABLE_HEADER *, &Gbl_Xsdt), &Address);
670 if (ACPI_FAILURE (Status))
676 /* Get RSDT from memory */
678 if (Gbl_Rsdp.RsdtPhysicalAddress)
686 Status = OslGetBiosTable (ACPI_SIG_RSDT, 0,
687 ACPI_CAST_PTR (ACPI_TABLE_HEADER *, &Gbl_Rsdt), &Address);
688 if (ACPI_FAILURE (Status))
694 /* Get FADT from memory */
702 Status = OslGetBiosTable (ACPI_SIG_FADT, 0,
703 ACPI_CAST_PTR (ACPI_TABLE_HEADER *, &Gbl_Fadt), &Gbl_FadtAddress);
704 if (ACPI_FAILURE (Status))
709 if (!Gbl_DumpCustomizedTables)
711 /* Add mandatory tables to global table list first */
713 Status = OslAddTableToList (ACPI_RSDP_NAME, 0);
714 if (ACPI_FAILURE (Status))
719 Status = OslAddTableToList (ACPI_SIG_RSDT, 0);
720 if (ACPI_FAILURE (Status))
725 if (Gbl_Revision == 2)
727 Status = OslAddTableToList (ACPI_SIG_XSDT, 0);
728 if (ACPI_FAILURE (Status))
734 Status = OslAddTableToList (ACPI_SIG_DSDT, 0);
735 if (ACPI_FAILURE (Status))
740 Status = OslAddTableToList (ACPI_SIG_FACS, 0);
741 if (ACPI_FAILURE (Status))
746 /* Add all tables found in the memory */
748 Status = OslListBiosTables ();
749 if (ACPI_FAILURE (Status))
756 /* Add all tables found in the static directory */
758 Status = OslListCustomizedTables (STATIC_TABLE_DIR);
759 if (ACPI_FAILURE (Status))
765 if (Gbl_DumpDynamicTables)
767 /* Add all dynamically loaded tables in the dynamic directory */
769 Status = OslListCustomizedTables (DYNAMIC_TABLE_DIR);
770 if (ACPI_FAILURE (Status))
776 Gbl_TableListInitialized = TRUE;
781 /******************************************************************************
783 * FUNCTION: OslListBiosTables
787 * RETURN: Status; Table list is initialized if AE_OK.
789 * DESCRIPTION: Add ACPI tables to the table list from memory.
791 * NOTE: This works on Linux as table customization does not modify the
792 * addresses stored in RSDP/RSDT/XSDT/FADT.
794 *****************************************************************************/
800 ACPI_TABLE_HEADER *MappedTable = NULL;
802 UINT8 NumberOfTables;
804 ACPI_PHYSICAL_ADDRESS TableAddress = 0;
805 ACPI_STATUS Status = AE_OK;
809 if (OslCanUseXsdt ())
811 ItemSize = sizeof (UINT64);
812 TableData = ACPI_CAST8 (Gbl_Xsdt) + sizeof (ACPI_TABLE_HEADER);
814 (UINT8) ((Gbl_Xsdt->Header.Length - sizeof (ACPI_TABLE_HEADER))
817 else /* Use RSDT if XSDT is not available */
819 ItemSize = sizeof (UINT32);
820 TableData = ACPI_CAST8 (Gbl_Rsdt) + sizeof (ACPI_TABLE_HEADER);
822 (UINT8) ((Gbl_Rsdt->Header.Length - sizeof (ACPI_TABLE_HEADER))
826 /* Search RSDT/XSDT for the requested table */
828 for (i = 0; i < NumberOfTables; ++i, TableData += ItemSize)
830 if (OslCanUseXsdt ())
833 (ACPI_PHYSICAL_ADDRESS) (*ACPI_CAST64 (TableData));
838 (ACPI_PHYSICAL_ADDRESS) (*ACPI_CAST32 (TableData));
841 /* Skip NULL entries in RSDT/XSDT */
848 Status = OslMapTable (TableAddress, NULL, &MappedTable);
849 if (ACPI_FAILURE (Status))
854 OslAddTableToList (MappedTable->Signature, 0);
855 OslUnmapTable (MappedTable);
862 /******************************************************************************
864 * FUNCTION: OslGetBiosTable
866 * PARAMETERS: Signature - ACPI Signature for common table. Must be
867 * a null terminated 4-character string.
868 * Instance - Multiple table support for SSDT/UEFI (0...n)
869 * Must be 0 for other tables.
870 * Table - Where a pointer to the table is returned
871 * Address - Where the table physical address is returned
873 * RETURN: Status; Table buffer and physical address returned if AE_OK.
874 * AE_LIMIT: Instance is beyond valid limit
875 * AE_NOT_FOUND: A table with the signature was not found
877 * DESCRIPTION: Get a BIOS provided ACPI table
879 * NOTE: Assumes the input signature is uppercase.
881 *****************************************************************************/
887 ACPI_TABLE_HEADER **Table,
888 ACPI_PHYSICAL_ADDRESS *Address)
890 ACPI_TABLE_HEADER *LocalTable = NULL;
891 ACPI_TABLE_HEADER *MappedTable = NULL;
893 UINT8 NumberOfTables;
895 UINT32 CurrentInstance = 0;
896 ACPI_PHYSICAL_ADDRESS TableAddress = 0;
897 UINT32 TableLength = 0;
898 ACPI_STATUS Status = AE_OK;
902 /* Handle special tables whose addresses are not in RSDT/XSDT */
904 if (ACPI_COMPARE_NAME (Signature, ACPI_RSDP_NAME) ||
905 ACPI_COMPARE_NAME (Signature, ACPI_SIG_RSDT) ||
906 ACPI_COMPARE_NAME (Signature, ACPI_SIG_XSDT) ||
907 ACPI_COMPARE_NAME (Signature, ACPI_SIG_DSDT) ||
908 ACPI_COMPARE_NAME (Signature, ACPI_SIG_FACS))
911 * Get the appropriate address, either 32-bit or 64-bit. Be very
912 * careful about the FADT length and validate table addresses.
913 * Note: The 64-bit addresses have priority.
915 if (ACPI_COMPARE_NAME (Signature, ACPI_SIG_DSDT))
917 if ((Gbl_Fadt->Header.Length >= MIN_FADT_FOR_XDSDT) &&
920 TableAddress = (ACPI_PHYSICAL_ADDRESS) Gbl_Fadt->XDsdt;
922 else if ((Gbl_Fadt->Header.Length >= MIN_FADT_FOR_DSDT) &&
925 TableAddress = (ACPI_PHYSICAL_ADDRESS) Gbl_Fadt->Dsdt;
928 else if (ACPI_COMPARE_NAME (Signature, ACPI_SIG_FACS))
930 if ((Gbl_Fadt->Header.Length >= MIN_FADT_FOR_XFACS) &&
933 TableAddress = (ACPI_PHYSICAL_ADDRESS) Gbl_Fadt->XFacs;
935 else if ((Gbl_Fadt->Header.Length >= MIN_FADT_FOR_FACS) &&
938 TableAddress = (ACPI_PHYSICAL_ADDRESS) Gbl_Fadt->Facs;
941 else if (ACPI_COMPARE_NAME (Signature, ACPI_SIG_XSDT))
945 return (AE_BAD_SIGNATURE);
947 TableAddress = (ACPI_PHYSICAL_ADDRESS) Gbl_Rsdp.XsdtPhysicalAddress;
949 else if (ACPI_COMPARE_NAME (Signature, ACPI_SIG_RSDT))
951 TableAddress = (ACPI_PHYSICAL_ADDRESS) Gbl_Rsdp.RsdtPhysicalAddress;
955 TableAddress = (ACPI_PHYSICAL_ADDRESS) Gbl_RsdpAddress;
956 Signature = ACPI_SIG_RSDP;
959 /* Now we can get the requested special table */
961 Status = OslMapTable (TableAddress, Signature, &MappedTable);
962 if (ACPI_FAILURE (Status))
967 TableLength = ApGetTableLength (MappedTable);
969 else /* Case for a normal ACPI table */
971 if (OslCanUseXsdt ())
973 ItemSize = sizeof (UINT64);
974 TableData = ACPI_CAST8 (Gbl_Xsdt) + sizeof (ACPI_TABLE_HEADER);
976 (UINT8) ((Gbl_Xsdt->Header.Length - sizeof (ACPI_TABLE_HEADER))
979 else /* Use RSDT if XSDT is not available */
981 ItemSize = sizeof (UINT32);
982 TableData = ACPI_CAST8 (Gbl_Rsdt) + sizeof (ACPI_TABLE_HEADER);
984 (UINT8) ((Gbl_Rsdt->Header.Length - sizeof (ACPI_TABLE_HEADER))
988 /* Search RSDT/XSDT for the requested table */
990 for (i = 0; i < NumberOfTables; ++i, TableData += ItemSize)
992 if (OslCanUseXsdt ())
995 (ACPI_PHYSICAL_ADDRESS) (*ACPI_CAST64 (TableData));
1000 (ACPI_PHYSICAL_ADDRESS) (*ACPI_CAST32 (TableData));
1003 /* Skip NULL entries in RSDT/XSDT */
1010 Status = OslMapTable (TableAddress, NULL, &MappedTable);
1011 if (ACPI_FAILURE (Status))
1015 TableLength = MappedTable->Length;
1017 /* Does this table match the requested signature? */
1019 if (!ACPI_COMPARE_NAME (MappedTable->Signature, Signature))
1021 OslUnmapTable (MappedTable);
1026 /* Match table instance (for SSDT/UEFI tables) */
1028 if (CurrentInstance != Instance)
1030 OslUnmapTable (MappedTable);
1045 if (TableLength == 0)
1047 Status = AE_BAD_HEADER;
1051 /* Copy table to local buffer and return it */
1053 LocalTable = calloc (1, TableLength);
1056 Status = AE_NO_MEMORY;
1060 ACPI_MEMCPY (LocalTable, MappedTable, TableLength);
1061 *Address = TableAddress;
1062 *Table = LocalTable;
1065 OslUnmapTable (MappedTable);
1070 /******************************************************************************
1072 * FUNCTION: OslListCustomizedTables
1074 * PARAMETERS: Directory - Directory that contains the tables
1076 * RETURN: Status; Table list is initialized if AE_OK.
1078 * DESCRIPTION: Add ACPI tables to the table list from a directory.
1080 *****************************************************************************/
1083 OslListCustomizedTables (
1088 char TempName[ACPI_NAME_SIZE];
1090 ACPI_STATUS Status = AE_OK;
1093 /* Open the requested directory */
1095 TableDir = AcpiOsOpenDirectory (Directory, "*", REQUEST_FILE_ONLY);
1098 return (OslGetLastStatus (AE_NOT_FOUND));
1101 /* Examine all entries in this directory */
1103 while ((Filename = AcpiOsGetNextFilename (TableDir)))
1105 /* Extract table name and instance number */
1107 Status = OslTableNameFromFile (Filename, TempName, &Instance);
1109 /* Ignore meaningless files */
1111 if (ACPI_FAILURE (Status))
1116 /* Add new info node to global table list */
1118 Status = OslAddTableToList (TempName, Instance);
1119 if (ACPI_FAILURE (Status))
1125 AcpiOsCloseDirectory (TableDir);
1130 /******************************************************************************
1132 * FUNCTION: OslMapTable
1134 * PARAMETERS: Address - Address of the table in memory
1135 * Signature - Optional ACPI Signature for desired table.
1136 * Null terminated 4-character string.
1137 * Table - Where a pointer to the mapped table is
1140 * RETURN: Status; Mapped table is returned if AE_OK.
1141 * AE_NOT_FOUND: A valid table was not found at the address
1143 * DESCRIPTION: Map entire ACPI table into caller's address space.
1145 *****************************************************************************/
1151 ACPI_TABLE_HEADER **Table)
1153 ACPI_TABLE_HEADER *MappedTable;
1159 return (AE_BAD_ADDRESS);
1163 * Map the header so we can get the table length.
1164 * Use sizeof (ACPI_TABLE_HEADER) as:
1165 * 1. it is bigger than 24 to include RSDP->Length
1166 * 2. it is smaller than sizeof (ACPI_TABLE_RSDP)
1168 MappedTable = AcpiOsMapMemory (Address, sizeof (ACPI_TABLE_HEADER));
1171 fprintf (stderr, "Could not map table header at 0x%8.8X%8.8X\n",
1172 ACPI_FORMAT_UINT64 (Address));
1173 return (OslGetLastStatus (AE_BAD_ADDRESS));
1176 /* If specified, signature must match */
1180 if (ACPI_VALIDATE_RSDP_SIG (Signature))
1182 if (!ACPI_VALIDATE_RSDP_SIG (MappedTable->Signature))
1184 AcpiOsUnmapMemory (MappedTable, sizeof (ACPI_TABLE_HEADER));
1185 return (AE_BAD_SIGNATURE);
1188 else if (!ACPI_COMPARE_NAME (Signature, MappedTable->Signature))
1190 AcpiOsUnmapMemory (MappedTable, sizeof (ACPI_TABLE_HEADER));
1191 return (AE_BAD_SIGNATURE);
1195 /* Map the entire table */
1197 Length = ApGetTableLength (MappedTable);
1198 AcpiOsUnmapMemory (MappedTable, sizeof (ACPI_TABLE_HEADER));
1201 return (AE_BAD_HEADER);
1204 MappedTable = AcpiOsMapMemory (Address, Length);
1207 fprintf (stderr, "Could not map table at 0x%8.8X%8.8X length %8.8X\n",
1208 ACPI_FORMAT_UINT64 (Address), Length);
1209 return (OslGetLastStatus (AE_INVALID_TABLE_LENGTH));
1212 (void) ApIsValidChecksum (MappedTable);
1214 *Table = MappedTable;
1219 /******************************************************************************
1221 * FUNCTION: OslUnmapTable
1223 * PARAMETERS: Table - A pointer to the mapped table
1227 * DESCRIPTION: Unmap entire ACPI table.
1229 *****************************************************************************/
1233 ACPI_TABLE_HEADER *Table)
1237 AcpiOsUnmapMemory (Table, ApGetTableLength (Table));
1242 /******************************************************************************
1244 * FUNCTION: OslTableNameFromFile
1246 * PARAMETERS: Filename - File that contains the desired table
1247 * Signature - Pointer to 4-character buffer to store
1248 * extracted table signature.
1249 * Instance - Pointer to integer to store extracted
1250 * table instance number.
1252 * RETURN: Status; Table name is extracted if AE_OK.
1254 * DESCRIPTION: Extract table signature and instance number from a table file
1257 *****************************************************************************/
1260 OslTableNameFromFile (
1266 /* Ignore meaningless files */
1268 if (strlen (Filename) < ACPI_NAME_SIZE)
1270 return (AE_BAD_SIGNATURE);
1273 /* Extract instance number */
1275 if (isdigit ((int) Filename[ACPI_NAME_SIZE]))
1277 sscanf (&Filename[ACPI_NAME_SIZE], "%d", Instance);
1279 else if (strlen (Filename) != ACPI_NAME_SIZE)
1281 return (AE_BAD_SIGNATURE);
1288 /* Extract signature */
1290 ACPI_MOVE_NAME (Signature, Filename);
1295 /******************************************************************************
1297 * FUNCTION: OslReadTableFromFile
1299 * PARAMETERS: Filename - File that contains the desired table
1300 * FileOffset - Offset of the table in file
1301 * Signature - Optional ACPI Signature for desired table.
1302 * A null terminated 4-character string.
1303 * Table - Where a pointer to the table is returned
1305 * RETURN: Status; Table buffer is returned if AE_OK.
1307 * DESCRIPTION: Read a ACPI table from a file.
1309 *****************************************************************************/
1312 OslReadTableFromFile (
1314 ACPI_SIZE FileOffset,
1316 ACPI_TABLE_HEADER **Table)
1319 ACPI_TABLE_HEADER Header;
1320 ACPI_TABLE_HEADER *LocalTable = NULL;
1323 ACPI_STATUS Status = AE_OK;
1328 TableFile = fopen (Filename, "rb");
1329 if (TableFile == NULL)
1331 fprintf (stderr, "Could not open table file: %s\n", Filename);
1332 return (OslGetLastStatus (AE_NOT_FOUND));
1335 fseek (TableFile, FileOffset, SEEK_SET);
1337 /* Read the Table header to get the table length */
1339 Count = fread (&Header, 1, sizeof (ACPI_TABLE_HEADER), TableFile);
1340 if (Count != sizeof (ACPI_TABLE_HEADER))
1342 fprintf (stderr, "Could not read table header: %s\n", Filename);
1343 Status = AE_BAD_HEADER;
1347 /* If signature is specified, it must match the table */
1351 if (ACPI_VALIDATE_RSDP_SIG (Signature))
1353 if (!ACPI_VALIDATE_RSDP_SIG (Header.Signature)) {
1354 fprintf (stderr, "Incorrect RSDP signature: found %8.8s\n",
1356 Status = AE_BAD_SIGNATURE;
1360 else if (!ACPI_COMPARE_NAME (Signature, Header.Signature))
1362 fprintf (stderr, "Incorrect signature: Expecting %4.4s, found %4.4s\n",
1363 Signature, Header.Signature);
1364 Status = AE_BAD_SIGNATURE;
1369 TableLength = ApGetTableLength (&Header);
1370 if (TableLength == 0)
1372 Status = AE_BAD_HEADER;
1376 /* Read the entire table into a local buffer */
1378 LocalTable = calloc (1, TableLength);
1382 "%4.4s: Could not allocate buffer for table of length %X\n",
1383 Header.Signature, TableLength);
1384 Status = AE_NO_MEMORY;
1388 fseek (TableFile, FileOffset, SEEK_SET);
1390 Count = fread (LocalTable, 1, TableLength, TableFile);
1391 if (Count != TableLength)
1393 fprintf (stderr, "%4.4s: Could not read table content\n",
1395 Status = AE_INVALID_TABLE_LENGTH;
1399 /* Validate checksum */
1401 (void) ApIsValidChecksum (LocalTable);
1405 *Table = LocalTable;
1410 /******************************************************************************
1412 * FUNCTION: OslGetCustomizedTable
1414 * PARAMETERS: Pathname - Directory to find Linux customized table
1415 * Signature - ACPI Signature for desired table. Must be
1416 * a null terminated 4-character string.
1417 * Instance - Multiple table support for SSDT/UEFI (0...n)
1418 * Must be 0 for other tables.
1419 * Table - Where a pointer to the table is returned
1420 * Address - Where the table physical address is returned
1422 * RETURN: Status; Table buffer is returned if AE_OK.
1423 * AE_LIMIT: Instance is beyond valid limit
1424 * AE_NOT_FOUND: A table with the signature was not found
1426 * DESCRIPTION: Get an OS customized table.
1428 *****************************************************************************/
1431 OslGetCustomizedTable (
1435 ACPI_TABLE_HEADER **Table,
1436 ACPI_PHYSICAL_ADDRESS *Address)
1439 UINT32 CurrentInstance = 0;
1440 char TempName[ACPI_NAME_SIZE];
1441 char TableFilename[PATH_MAX];
1446 /* Open the directory for customized tables */
1448 TableDir = AcpiOsOpenDirectory (Pathname, "*", REQUEST_FILE_ONLY);
1451 return (OslGetLastStatus (AE_NOT_FOUND));
1454 /* Attempt to find the table in the directory */
1456 while ((Filename = AcpiOsGetNextFilename (TableDir)))
1458 /* Ignore meaningless files */
1460 if (!ACPI_COMPARE_NAME (Filename, Signature))
1465 /* Extract table name and instance number */
1467 Status = OslTableNameFromFile (Filename, TempName, &CurrentInstance);
1469 /* Ignore meaningless files */
1471 if (ACPI_FAILURE (Status) || CurrentInstance != Instance)
1476 /* Create the table pathname */
1480 sprintf (TableFilename, "%s/%4.4s%d", Pathname, TempName, Instance);
1484 sprintf (TableFilename, "%s/%4.4s", Pathname, TempName);
1489 AcpiOsCloseDirectory (TableDir);
1496 /* There is no physical address saved for customized tables, use zero */
1499 Status = OslReadTableFromFile (TableFilename, 0, NULL, Table);