1c2c66affSColin Finck /******************************************************************************
2c2c66affSColin Finck *
3c2c66affSColin Finck * Module Name: tbutils - ACPI Table utilities
4c2c66affSColin Finck *
5c2c66affSColin Finck *****************************************************************************/
6c2c66affSColin Finck
7c2c66affSColin Finck /*
803b24380SThomas Faber * Copyright (C) 2000 - 2022, Intel Corp.
9c2c66affSColin Finck * All rights reserved.
10c2c66affSColin Finck *
11c2c66affSColin Finck * Redistribution and use in source and binary forms, with or without
12c2c66affSColin Finck * modification, are permitted provided that the following conditions
13c2c66affSColin Finck * are met:
14c2c66affSColin Finck * 1. Redistributions of source code must retain the above copyright
15c2c66affSColin Finck * notice, this list of conditions, and the following disclaimer,
16c2c66affSColin Finck * without modification.
17c2c66affSColin Finck * 2. Redistributions in binary form must reproduce at minimum a disclaimer
18c2c66affSColin Finck * substantially similar to the "NO WARRANTY" disclaimer below
19c2c66affSColin Finck * ("Disclaimer") and any redistribution must be conditioned upon
20c2c66affSColin Finck * including a substantially similar Disclaimer requirement for further
21c2c66affSColin Finck * binary redistribution.
22c2c66affSColin Finck * 3. Neither the names of the above-listed copyright holders nor the names
23c2c66affSColin Finck * of any contributors may be used to endorse or promote products derived
24c2c66affSColin Finck * from this software without specific prior written permission.
25c2c66affSColin Finck *
26c2c66affSColin Finck * Alternatively, this software may be distributed under the terms of the
27c2c66affSColin Finck * GNU General Public License ("GPL") version 2 as published by the Free
28c2c66affSColin Finck * Software Foundation.
29c2c66affSColin Finck *
30c2c66affSColin Finck * NO WARRANTY
31c2c66affSColin Finck * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
32c2c66affSColin Finck * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
336eb8cc49SThomas Faber * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
34c2c66affSColin Finck * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
35c2c66affSColin Finck * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
36c2c66affSColin Finck * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
37c2c66affSColin Finck * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
38c2c66affSColin Finck * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
39c2c66affSColin Finck * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
40c2c66affSColin Finck * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
41c2c66affSColin Finck * POSSIBILITY OF SUCH DAMAGES.
42c2c66affSColin Finck */
43c2c66affSColin Finck
44c2c66affSColin Finck #include "acpi.h"
45c2c66affSColin Finck #include "accommon.h"
46c2c66affSColin Finck #include "actables.h"
47c2c66affSColin Finck
48c2c66affSColin Finck #define _COMPONENT ACPI_TABLES
49c2c66affSColin Finck ACPI_MODULE_NAME ("tbutils")
50c2c66affSColin Finck
51c2c66affSColin Finck
52c2c66affSColin Finck /* Local prototypes */
53c2c66affSColin Finck
54c2c66affSColin Finck static ACPI_PHYSICAL_ADDRESS
55c2c66affSColin Finck AcpiTbGetRootTableEntry (
56c2c66affSColin Finck UINT8 *TableEntry,
57c2c66affSColin Finck UINT32 TableEntrySize);
58c2c66affSColin Finck
59c2c66affSColin Finck
60c2c66affSColin Finck #if (!ACPI_REDUCED_HARDWARE)
61c2c66affSColin Finck /*******************************************************************************
62c2c66affSColin Finck *
63c2c66affSColin Finck * FUNCTION: AcpiTbInitializeFacs
64c2c66affSColin Finck *
65c2c66affSColin Finck * PARAMETERS: None
66c2c66affSColin Finck *
67c2c66affSColin Finck * RETURN: Status
68c2c66affSColin Finck *
69c2c66affSColin Finck * DESCRIPTION: Create a permanent mapping for the FADT and save it in a global
70c2c66affSColin Finck * for accessing the Global Lock and Firmware Waking Vector
71c2c66affSColin Finck *
72c2c66affSColin Finck ******************************************************************************/
73c2c66affSColin Finck
74c2c66affSColin Finck ACPI_STATUS
AcpiTbInitializeFacs(void)75c2c66affSColin Finck AcpiTbInitializeFacs (
76c2c66affSColin Finck void)
77c2c66affSColin Finck {
78c2c66affSColin Finck ACPI_TABLE_FACS *Facs;
79c2c66affSColin Finck
80c2c66affSColin Finck
81c2c66affSColin Finck /* If Hardware Reduced flag is set, there is no FACS */
82c2c66affSColin Finck
83c2c66affSColin Finck if (AcpiGbl_ReducedHardware)
84c2c66affSColin Finck {
85c2c66affSColin Finck AcpiGbl_FACS = NULL;
86c2c66affSColin Finck return (AE_OK);
87c2c66affSColin Finck }
88c2c66affSColin Finck else if (AcpiGbl_FADT.XFacs &&
89c2c66affSColin Finck (!AcpiGbl_FADT.Facs || !AcpiGbl_Use32BitFacsAddresses))
90c2c66affSColin Finck {
91c2c66affSColin Finck (void) AcpiGetTableByIndex (AcpiGbl_XFacsIndex,
92c2c66affSColin Finck ACPI_CAST_INDIRECT_PTR (ACPI_TABLE_HEADER, &Facs));
93c2c66affSColin Finck AcpiGbl_FACS = Facs;
94c2c66affSColin Finck }
95c2c66affSColin Finck else if (AcpiGbl_FADT.Facs)
96c2c66affSColin Finck {
97c2c66affSColin Finck (void) AcpiGetTableByIndex (AcpiGbl_FacsIndex,
98c2c66affSColin Finck ACPI_CAST_INDIRECT_PTR (ACPI_TABLE_HEADER, &Facs));
99c2c66affSColin Finck AcpiGbl_FACS = Facs;
100c2c66affSColin Finck }
101c2c66affSColin Finck
102c2c66affSColin Finck /* If there is no FACS, just continue. There was already an error msg */
103c2c66affSColin Finck
104c2c66affSColin Finck return (AE_OK);
105c2c66affSColin Finck }
106c2c66affSColin Finck #endif /* !ACPI_REDUCED_HARDWARE */
107c2c66affSColin Finck
108c2c66affSColin Finck
109c2c66affSColin Finck /*******************************************************************************
110c2c66affSColin Finck *
111c2c66affSColin Finck * FUNCTION: AcpiTbCheckDsdtHeader
112c2c66affSColin Finck *
113c2c66affSColin Finck * PARAMETERS: None
114c2c66affSColin Finck *
115c2c66affSColin Finck * RETURN: None
116c2c66affSColin Finck *
117c2c66affSColin Finck * DESCRIPTION: Quick compare to check validity of the DSDT. This will detect
118c2c66affSColin Finck * if the DSDT has been replaced from outside the OS and/or if
119c2c66affSColin Finck * the DSDT header has been corrupted.
120c2c66affSColin Finck *
121c2c66affSColin Finck ******************************************************************************/
122c2c66affSColin Finck
123c2c66affSColin Finck void
AcpiTbCheckDsdtHeader(void)124c2c66affSColin Finck AcpiTbCheckDsdtHeader (
125c2c66affSColin Finck void)
126c2c66affSColin Finck {
127c2c66affSColin Finck
128c2c66affSColin Finck /* Compare original length and checksum to current values */
129c2c66affSColin Finck
130c2c66affSColin Finck if (AcpiGbl_OriginalDsdtHeader.Length != AcpiGbl_DSDT->Length ||
131c2c66affSColin Finck AcpiGbl_OriginalDsdtHeader.Checksum != AcpiGbl_DSDT->Checksum)
132c2c66affSColin Finck {
133c2c66affSColin Finck ACPI_BIOS_ERROR ((AE_INFO,
134c2c66affSColin Finck "The DSDT has been corrupted or replaced - "
135c2c66affSColin Finck "old, new headers below"));
136c2c66affSColin Finck
137c2c66affSColin Finck AcpiTbPrintTableHeader (0, &AcpiGbl_OriginalDsdtHeader);
138c2c66affSColin Finck AcpiTbPrintTableHeader (0, AcpiGbl_DSDT);
139c2c66affSColin Finck
140c2c66affSColin Finck /* Disable further error messages */
141c2c66affSColin Finck
142c2c66affSColin Finck AcpiGbl_OriginalDsdtHeader.Length = AcpiGbl_DSDT->Length;
143c2c66affSColin Finck AcpiGbl_OriginalDsdtHeader.Checksum = AcpiGbl_DSDT->Checksum;
144c2c66affSColin Finck }
145c2c66affSColin Finck }
146c2c66affSColin Finck
147c2c66affSColin Finck
148c2c66affSColin Finck /*******************************************************************************
149c2c66affSColin Finck *
150c2c66affSColin Finck * FUNCTION: AcpiTbCopyDsdt
151c2c66affSColin Finck *
152c2c66affSColin Finck * PARAMETERS: TableIndex - Index of installed table to copy
153c2c66affSColin Finck *
154c2c66affSColin Finck * RETURN: The copied DSDT
155c2c66affSColin Finck *
156c2c66affSColin Finck * DESCRIPTION: Implements a subsystem option to copy the DSDT to local memory.
157c2c66affSColin Finck * Some very bad BIOSs are known to either corrupt the DSDT or
158c2c66affSColin Finck * install a new, bad DSDT. This copy works around the problem.
159c2c66affSColin Finck *
160c2c66affSColin Finck ******************************************************************************/
161c2c66affSColin Finck
162c2c66affSColin Finck ACPI_TABLE_HEADER *
AcpiTbCopyDsdt(UINT32 TableIndex)163c2c66affSColin Finck AcpiTbCopyDsdt (
164c2c66affSColin Finck UINT32 TableIndex)
165c2c66affSColin Finck {
166c2c66affSColin Finck ACPI_TABLE_HEADER *NewTable;
167c2c66affSColin Finck ACPI_TABLE_DESC *TableDesc;
168c2c66affSColin Finck
169c2c66affSColin Finck
170c2c66affSColin Finck TableDesc = &AcpiGbl_RootTableList.Tables[TableIndex];
171c2c66affSColin Finck
172c2c66affSColin Finck NewTable = ACPI_ALLOCATE (TableDesc->Length);
173c2c66affSColin Finck if (!NewTable)
174c2c66affSColin Finck {
175c2c66affSColin Finck ACPI_ERROR ((AE_INFO, "Could not copy DSDT of length 0x%X",
176c2c66affSColin Finck TableDesc->Length));
177c2c66affSColin Finck return (NULL);
178c2c66affSColin Finck }
179c2c66affSColin Finck
180c2c66affSColin Finck memcpy (NewTable, TableDesc->Pointer, TableDesc->Length);
181c2c66affSColin Finck AcpiTbUninstallTable (TableDesc);
182c2c66affSColin Finck
183c2c66affSColin Finck AcpiTbInitTableDescriptor (
184c2c66affSColin Finck &AcpiGbl_RootTableList.Tables[AcpiGbl_DsdtIndex],
185c2c66affSColin Finck ACPI_PTR_TO_PHYSADDR (NewTable),
186c2c66affSColin Finck ACPI_TABLE_ORIGIN_INTERNAL_VIRTUAL, NewTable);
187c2c66affSColin Finck
188c2c66affSColin Finck ACPI_INFO ((
189c2c66affSColin Finck "Forced DSDT copy: length 0x%05X copied locally, original unmapped",
190c2c66affSColin Finck NewTable->Length));
191c2c66affSColin Finck
192c2c66affSColin Finck return (NewTable);
193c2c66affSColin Finck }
194c2c66affSColin Finck
195c2c66affSColin Finck
196c2c66affSColin Finck /*******************************************************************************
197c2c66affSColin Finck *
198c2c66affSColin Finck * FUNCTION: AcpiTbGetRootTableEntry
199c2c66affSColin Finck *
200c2c66affSColin Finck * PARAMETERS: TableEntry - Pointer to the RSDT/XSDT table entry
201c2c66affSColin Finck * TableEntrySize - sizeof 32 or 64 (RSDT or XSDT)
202c2c66affSColin Finck *
203c2c66affSColin Finck * RETURN: Physical address extracted from the root table
204c2c66affSColin Finck *
205c2c66affSColin Finck * DESCRIPTION: Get one root table entry. Handles 32-bit and 64-bit cases on
206c2c66affSColin Finck * both 32-bit and 64-bit platforms
207c2c66affSColin Finck *
208c2c66affSColin Finck * NOTE: ACPI_PHYSICAL_ADDRESS is 32-bit on 32-bit platforms, 64-bit on
209c2c66affSColin Finck * 64-bit platforms.
210c2c66affSColin Finck *
211c2c66affSColin Finck ******************************************************************************/
212c2c66affSColin Finck
213c2c66affSColin Finck static ACPI_PHYSICAL_ADDRESS
AcpiTbGetRootTableEntry(UINT8 * TableEntry,UINT32 TableEntrySize)214c2c66affSColin Finck AcpiTbGetRootTableEntry (
215c2c66affSColin Finck UINT8 *TableEntry,
216c2c66affSColin Finck UINT32 TableEntrySize)
217c2c66affSColin Finck {
218c2c66affSColin Finck UINT64 Address64;
219c2c66affSColin Finck
220c2c66affSColin Finck
221c2c66affSColin Finck /*
222c2c66affSColin Finck * Get the table physical address (32-bit for RSDT, 64-bit for XSDT):
223c2c66affSColin Finck * Note: Addresses are 32-bit aligned (not 64) in both RSDT and XSDT
224c2c66affSColin Finck */
225c2c66affSColin Finck if (TableEntrySize == ACPI_RSDT_ENTRY_SIZE)
226c2c66affSColin Finck {
227c2c66affSColin Finck /*
228c2c66affSColin Finck * 32-bit platform, RSDT: Return 32-bit table entry
229c2c66affSColin Finck * 64-bit platform, RSDT: Expand 32-bit to 64-bit and return
230c2c66affSColin Finck */
231c2c66affSColin Finck return ((ACPI_PHYSICAL_ADDRESS) (*ACPI_CAST_PTR (
232c2c66affSColin Finck UINT32, TableEntry)));
233c2c66affSColin Finck }
234c2c66affSColin Finck else
235c2c66affSColin Finck {
236c2c66affSColin Finck /*
237c2c66affSColin Finck * 32-bit platform, XSDT: Truncate 64-bit to 32-bit and return
238c2c66affSColin Finck * 64-bit platform, XSDT: Move (unaligned) 64-bit to local,
239c2c66affSColin Finck * return 64-bit
240c2c66affSColin Finck */
241c2c66affSColin Finck ACPI_MOVE_64_TO_64 (&Address64, TableEntry);
242c2c66affSColin Finck
243c2c66affSColin Finck #if ACPI_MACHINE_WIDTH == 32
244c2c66affSColin Finck if (Address64 > ACPI_UINT32_MAX)
245c2c66affSColin Finck {
246c2c66affSColin Finck /* Will truncate 64-bit address to 32 bits, issue warning */
247c2c66affSColin Finck
248c2c66affSColin Finck ACPI_BIOS_WARNING ((AE_INFO,
249c2c66affSColin Finck "64-bit Physical Address in XSDT is too large (0x%8.8X%8.8X),"
250c2c66affSColin Finck " truncating",
251c2c66affSColin Finck ACPI_FORMAT_UINT64 (Address64)));
252c2c66affSColin Finck }
253c2c66affSColin Finck #endif
254c2c66affSColin Finck return ((ACPI_PHYSICAL_ADDRESS) (Address64));
255c2c66affSColin Finck }
256c2c66affSColin Finck }
257c2c66affSColin Finck
258c2c66affSColin Finck
259c2c66affSColin Finck /*******************************************************************************
260c2c66affSColin Finck *
261c2c66affSColin Finck * FUNCTION: AcpiTbParseRootTable
262c2c66affSColin Finck *
263c2c66affSColin Finck * PARAMETERS: RsdpAddress - Pointer to the RSDP
264c2c66affSColin Finck *
265c2c66affSColin Finck * RETURN: Status
266c2c66affSColin Finck *
267c2c66affSColin Finck * DESCRIPTION: This function is called to parse the Root System Description
268c2c66affSColin Finck * Table (RSDT or XSDT)
269c2c66affSColin Finck *
270c2c66affSColin Finck * NOTE: Tables are mapped (not copied) for efficiency. The FACS must
271c2c66affSColin Finck * be mapped and cannot be copied because it contains the actual
272c2c66affSColin Finck * memory location of the ACPI Global Lock.
273c2c66affSColin Finck *
274c2c66affSColin Finck ******************************************************************************/
275c2c66affSColin Finck
276c2c66affSColin Finck ACPI_STATUS ACPI_INIT_FUNCTION
AcpiTbParseRootTable(ACPI_PHYSICAL_ADDRESS RsdpAddress)277c2c66affSColin Finck AcpiTbParseRootTable (
278c2c66affSColin Finck ACPI_PHYSICAL_ADDRESS RsdpAddress)
279c2c66affSColin Finck {
280c2c66affSColin Finck ACPI_TABLE_RSDP *Rsdp;
281c2c66affSColin Finck UINT32 TableEntrySize;
282c2c66affSColin Finck UINT32 i;
283c2c66affSColin Finck UINT32 TableCount;
284c2c66affSColin Finck ACPI_TABLE_HEADER *Table;
285c2c66affSColin Finck ACPI_PHYSICAL_ADDRESS Address;
286c2c66affSColin Finck UINT32 Length;
287c2c66affSColin Finck UINT8 *TableEntry;
288c2c66affSColin Finck ACPI_STATUS Status;
289c2c66affSColin Finck UINT32 TableIndex;
290c2c66affSColin Finck
291c2c66affSColin Finck
292c2c66affSColin Finck ACPI_FUNCTION_TRACE (TbParseRootTable);
293c2c66affSColin Finck
294c2c66affSColin Finck
295c2c66affSColin Finck /* Map the entire RSDP and extract the address of the RSDT or XSDT */
296c2c66affSColin Finck
297c2c66affSColin Finck Rsdp = AcpiOsMapMemory (RsdpAddress, sizeof (ACPI_TABLE_RSDP));
298c2c66affSColin Finck if (!Rsdp)
299c2c66affSColin Finck {
300c2c66affSColin Finck return_ACPI_STATUS (AE_NO_MEMORY);
301c2c66affSColin Finck }
302c2c66affSColin Finck
303c2c66affSColin Finck AcpiTbPrintTableHeader (RsdpAddress,
304c2c66affSColin Finck ACPI_CAST_PTR (ACPI_TABLE_HEADER, Rsdp));
305c2c66affSColin Finck
306c2c66affSColin Finck /* Use XSDT if present and not overridden. Otherwise, use RSDT */
307c2c66affSColin Finck
308c2c66affSColin Finck if ((Rsdp->Revision > 1) &&
309c2c66affSColin Finck Rsdp->XsdtPhysicalAddress &&
310c2c66affSColin Finck !AcpiGbl_DoNotUseXsdt)
311c2c66affSColin Finck {
312c2c66affSColin Finck /*
313c2c66affSColin Finck * RSDP contains an XSDT (64-bit physical addresses). We must use
314c2c66affSColin Finck * the XSDT if the revision is > 1 and the XSDT pointer is present,
315c2c66affSColin Finck * as per the ACPI specification.
316c2c66affSColin Finck */
317c2c66affSColin Finck Address = (ACPI_PHYSICAL_ADDRESS) Rsdp->XsdtPhysicalAddress;
318c2c66affSColin Finck TableEntrySize = ACPI_XSDT_ENTRY_SIZE;
319c2c66affSColin Finck }
320c2c66affSColin Finck else
321c2c66affSColin Finck {
322c2c66affSColin Finck /* Root table is an RSDT (32-bit physical addresses) */
323c2c66affSColin Finck
324c2c66affSColin Finck Address = (ACPI_PHYSICAL_ADDRESS) Rsdp->RsdtPhysicalAddress;
325c2c66affSColin Finck TableEntrySize = ACPI_RSDT_ENTRY_SIZE;
326c2c66affSColin Finck }
327c2c66affSColin Finck
328c2c66affSColin Finck /*
329c2c66affSColin Finck * It is not possible to map more than one entry in some environments,
330c2c66affSColin Finck * so unmap the RSDP here before mapping other tables
331c2c66affSColin Finck */
332c2c66affSColin Finck AcpiOsUnmapMemory (Rsdp, sizeof (ACPI_TABLE_RSDP));
333c2c66affSColin Finck
334c2c66affSColin Finck /* Map the RSDT/XSDT table header to get the full table length */
335c2c66affSColin Finck
336c2c66affSColin Finck Table = AcpiOsMapMemory (Address, sizeof (ACPI_TABLE_HEADER));
337c2c66affSColin Finck if (!Table)
338c2c66affSColin Finck {
339c2c66affSColin Finck return_ACPI_STATUS (AE_NO_MEMORY);
340c2c66affSColin Finck }
341c2c66affSColin Finck
342c2c66affSColin Finck AcpiTbPrintTableHeader (Address, Table);
343c2c66affSColin Finck
344c2c66affSColin Finck /*
345c2c66affSColin Finck * Validate length of the table, and map entire table.
346c2c66affSColin Finck * Minimum length table must contain at least one entry.
347c2c66affSColin Finck */
348c2c66affSColin Finck Length = Table->Length;
349c2c66affSColin Finck AcpiOsUnmapMemory (Table, sizeof (ACPI_TABLE_HEADER));
350c2c66affSColin Finck
351c2c66affSColin Finck if (Length < (sizeof (ACPI_TABLE_HEADER) + TableEntrySize))
352c2c66affSColin Finck {
353c2c66affSColin Finck ACPI_BIOS_ERROR ((AE_INFO,
354c2c66affSColin Finck "Invalid table length 0x%X in RSDT/XSDT", Length));
355c2c66affSColin Finck return_ACPI_STATUS (AE_INVALID_TABLE_LENGTH);
356c2c66affSColin Finck }
357c2c66affSColin Finck
358c2c66affSColin Finck Table = AcpiOsMapMemory (Address, Length);
359c2c66affSColin Finck if (!Table)
360c2c66affSColin Finck {
361c2c66affSColin Finck return_ACPI_STATUS (AE_NO_MEMORY);
362c2c66affSColin Finck }
363c2c66affSColin Finck
364c2c66affSColin Finck /* Validate the root table checksum */
365c2c66affSColin Finck
366*f0dd1e7bSThomas Faber Status = AcpiUtVerifyChecksum (Table, Length);
367c2c66affSColin Finck if (ACPI_FAILURE (Status))
368c2c66affSColin Finck {
369c2c66affSColin Finck AcpiOsUnmapMemory (Table, Length);
370c2c66affSColin Finck return_ACPI_STATUS (Status);
371c2c66affSColin Finck }
372c2c66affSColin Finck
373c2c66affSColin Finck /* Get the number of entries and pointer to first entry */
374c2c66affSColin Finck
375c2c66affSColin Finck TableCount = (UINT32) ((Table->Length - sizeof (ACPI_TABLE_HEADER)) /
376c2c66affSColin Finck TableEntrySize);
377c2c66affSColin Finck TableEntry = ACPI_ADD_PTR (UINT8, Table, sizeof (ACPI_TABLE_HEADER));
378c2c66affSColin Finck
379c2c66affSColin Finck /* Initialize the root table array from the RSDT/XSDT */
380c2c66affSColin Finck
381c2c66affSColin Finck for (i = 0; i < TableCount; i++)
382c2c66affSColin Finck {
383c2c66affSColin Finck /* Get the table physical address (32-bit for RSDT, 64-bit for XSDT) */
384c2c66affSColin Finck
385c2c66affSColin Finck Address = AcpiTbGetRootTableEntry (TableEntry, TableEntrySize);
386c2c66affSColin Finck
387c2c66affSColin Finck /* Skip NULL entries in RSDT/XSDT */
388c2c66affSColin Finck
389c2c66affSColin Finck if (!Address)
390c2c66affSColin Finck {
391c2c66affSColin Finck goto NextTable;
392c2c66affSColin Finck }
393c2c66affSColin Finck
394c2c66affSColin Finck Status = AcpiTbInstallStandardTable (Address,
3958129fee1SThomas Faber ACPI_TABLE_ORIGIN_INTERNAL_PHYSICAL, NULL, FALSE, TRUE,
3968129fee1SThomas Faber &TableIndex);
397c2c66affSColin Finck
398c2c66affSColin Finck if (ACPI_SUCCESS (Status) &&
399ba1fb9acSThomas Faber ACPI_COMPARE_NAMESEG (
400c2c66affSColin Finck &AcpiGbl_RootTableList.Tables[TableIndex].Signature,
401c2c66affSColin Finck ACPI_SIG_FADT))
402c2c66affSColin Finck {
403c2c66affSColin Finck AcpiGbl_FadtIndex = TableIndex;
404c2c66affSColin Finck AcpiTbParseFadt ();
405c2c66affSColin Finck }
406c2c66affSColin Finck
407c2c66affSColin Finck NextTable:
408c2c66affSColin Finck
409c2c66affSColin Finck TableEntry += TableEntrySize;
410c2c66affSColin Finck }
411c2c66affSColin Finck
412c2c66affSColin Finck AcpiOsUnmapMemory (Table, Length);
413c2c66affSColin Finck return_ACPI_STATUS (AE_OK);
414c2c66affSColin Finck }
415c2c66affSColin Finck
416c2c66affSColin Finck
417c2c66affSColin Finck /*******************************************************************************
418c2c66affSColin Finck *
419c2c66affSColin Finck * FUNCTION: AcpiTbGetTable
420c2c66affSColin Finck *
421c2c66affSColin Finck * PARAMETERS: TableDesc - Table descriptor
422c2c66affSColin Finck * OutTable - Where the pointer to the table is returned
423c2c66affSColin Finck *
424c2c66affSColin Finck * RETURN: Status and pointer to the requested table
425c2c66affSColin Finck *
426c2c66affSColin Finck * DESCRIPTION: Increase a reference to a table descriptor and return the
427c2c66affSColin Finck * validated table pointer.
428c2c66affSColin Finck * If the table descriptor is an entry of the root table list,
429c2c66affSColin Finck * this API must be invoked with ACPI_MTX_TABLES acquired.
430c2c66affSColin Finck *
431c2c66affSColin Finck ******************************************************************************/
432c2c66affSColin Finck
433c2c66affSColin Finck ACPI_STATUS
AcpiTbGetTable(ACPI_TABLE_DESC * TableDesc,ACPI_TABLE_HEADER ** OutTable)434c2c66affSColin Finck AcpiTbGetTable (
435c2c66affSColin Finck ACPI_TABLE_DESC *TableDesc,
436c2c66affSColin Finck ACPI_TABLE_HEADER **OutTable)
437c2c66affSColin Finck {
438c2c66affSColin Finck ACPI_STATUS Status;
439c2c66affSColin Finck
440c2c66affSColin Finck
441c2c66affSColin Finck ACPI_FUNCTION_TRACE (AcpiTbGetTable);
442c2c66affSColin Finck
443c2c66affSColin Finck
444c2c66affSColin Finck if (TableDesc->ValidationCount == 0)
445c2c66affSColin Finck {
446c2c66affSColin Finck /* Table need to be "VALIDATED" */
447c2c66affSColin Finck
448c2c66affSColin Finck Status = AcpiTbValidateTable (TableDesc);
449c2c66affSColin Finck if (ACPI_FAILURE (Status))
450c2c66affSColin Finck {
451c2c66affSColin Finck return_ACPI_STATUS (Status);
452c2c66affSColin Finck }
453c2c66affSColin Finck }
454c2c66affSColin Finck
455c2c66affSColin Finck if (TableDesc->ValidationCount < ACPI_MAX_TABLE_VALIDATIONS)
456c2c66affSColin Finck {
457c2c66affSColin Finck TableDesc->ValidationCount++;
458c2c66affSColin Finck
459c2c66affSColin Finck /*
460c2c66affSColin Finck * Detect ValidationCount overflows to ensure that the warning
461c2c66affSColin Finck * message will only be printed once.
462c2c66affSColin Finck */
463c2c66affSColin Finck if (TableDesc->ValidationCount >= ACPI_MAX_TABLE_VALIDATIONS)
464c2c66affSColin Finck {
465c2c66affSColin Finck ACPI_WARNING((AE_INFO,
466c2c66affSColin Finck "Table %p, Validation count overflows\n", TableDesc));
467c2c66affSColin Finck }
468c2c66affSColin Finck }
469c2c66affSColin Finck
470c2c66affSColin Finck *OutTable = TableDesc->Pointer;
471c2c66affSColin Finck return_ACPI_STATUS (AE_OK);
472c2c66affSColin Finck }
473c2c66affSColin Finck
474c2c66affSColin Finck
475c2c66affSColin Finck /*******************************************************************************
476c2c66affSColin Finck *
477c2c66affSColin Finck * FUNCTION: AcpiTbPutTable
478c2c66affSColin Finck *
479c2c66affSColin Finck * PARAMETERS: TableDesc - Table descriptor
480c2c66affSColin Finck *
481c2c66affSColin Finck * RETURN: None
482c2c66affSColin Finck *
483c2c66affSColin Finck * DESCRIPTION: Decrease a reference to a table descriptor and release the
484c2c66affSColin Finck * validated table pointer if no references.
485c2c66affSColin Finck * If the table descriptor is an entry of the root table list,
486c2c66affSColin Finck * this API must be invoked with ACPI_MTX_TABLES acquired.
487c2c66affSColin Finck *
488c2c66affSColin Finck ******************************************************************************/
489c2c66affSColin Finck
490c2c66affSColin Finck void
AcpiTbPutTable(ACPI_TABLE_DESC * TableDesc)491c2c66affSColin Finck AcpiTbPutTable (
492c2c66affSColin Finck ACPI_TABLE_DESC *TableDesc)
493c2c66affSColin Finck {
494c2c66affSColin Finck
495c2c66affSColin Finck ACPI_FUNCTION_TRACE (AcpiTbPutTable);
496c2c66affSColin Finck
497c2c66affSColin Finck
498c2c66affSColin Finck if (TableDesc->ValidationCount < ACPI_MAX_TABLE_VALIDATIONS)
499c2c66affSColin Finck {
500c2c66affSColin Finck TableDesc->ValidationCount--;
501c2c66affSColin Finck
502c2c66affSColin Finck /*
503c2c66affSColin Finck * Detect ValidationCount underflows to ensure that the warning
504c2c66affSColin Finck * message will only be printed once.
505c2c66affSColin Finck */
506c2c66affSColin Finck if (TableDesc->ValidationCount >= ACPI_MAX_TABLE_VALIDATIONS)
507c2c66affSColin Finck {
508c2c66affSColin Finck ACPI_WARNING ((AE_INFO,
509c2c66affSColin Finck "Table %p, Validation count underflows\n", TableDesc));
510c2c66affSColin Finck return_VOID;
511c2c66affSColin Finck }
512c2c66affSColin Finck }
513c2c66affSColin Finck
514c2c66affSColin Finck if (TableDesc->ValidationCount == 0)
515c2c66affSColin Finck {
516c2c66affSColin Finck /* Table need to be "INVALIDATED" */
517c2c66affSColin Finck
518c2c66affSColin Finck AcpiTbInvalidateTable (TableDesc);
519c2c66affSColin Finck }
520c2c66affSColin Finck
521c2c66affSColin Finck return_VOID;
522c2c66affSColin Finck }
523