1 /******************************************************************************
3 * Module Name: oslinuxtbl - Linux OSL for obtaining ACPI tables
5 *****************************************************************************/
8 * Copyright (C) 2000 - 2013, 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 (AP_DUMP_SIG_RSDP
, 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
, AP_DUMP_SIG_RSDP
) ||
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
);