1149703c7Sjruoho /******************************************************************************
2149703c7Sjruoho *
333841f6dSchristos * Module Name: tbutils - ACPI Table utilities
4149703c7Sjruoho *
5149703c7Sjruoho *****************************************************************************/
6149703c7Sjruoho
77af23240Sjruoho /*
8ec12a2faSchristos * Copyright (C) 2000 - 2022, Intel Corp.
9149703c7Sjruoho * All rights reserved.
10149703c7Sjruoho *
117af23240Sjruoho * Redistribution and use in source and binary forms, with or without
127af23240Sjruoho * modification, are permitted provided that the following conditions
137af23240Sjruoho * are met:
147af23240Sjruoho * 1. Redistributions of source code must retain the above copyright
157af23240Sjruoho * notice, this list of conditions, and the following disclaimer,
167af23240Sjruoho * without modification.
177af23240Sjruoho * 2. Redistributions in binary form must reproduce at minimum a disclaimer
187af23240Sjruoho * substantially similar to the "NO WARRANTY" disclaimer below
197af23240Sjruoho * ("Disclaimer") and any redistribution must be conditioned upon
207af23240Sjruoho * including a substantially similar Disclaimer requirement for further
217af23240Sjruoho * binary redistribution.
227af23240Sjruoho * 3. Neither the names of the above-listed copyright holders nor the names
237af23240Sjruoho * of any contributors may be used to endorse or promote products derived
247af23240Sjruoho * from this software without specific prior written permission.
25149703c7Sjruoho *
267af23240Sjruoho * Alternatively, this software may be distributed under the terms of the
277af23240Sjruoho * GNU General Public License ("GPL") version 2 as published by the Free
287af23240Sjruoho * Software Foundation.
29149703c7Sjruoho *
307af23240Sjruoho * NO WARRANTY
317af23240Sjruoho * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
327af23240Sjruoho * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
33adee7055Schristos * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
347af23240Sjruoho * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
357af23240Sjruoho * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
367af23240Sjruoho * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
377af23240Sjruoho * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
387af23240Sjruoho * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
397af23240Sjruoho * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
407af23240Sjruoho * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
417af23240Sjruoho * POSSIBILITY OF SUCH DAMAGES.
427af23240Sjruoho */
43149703c7Sjruoho
44149703c7Sjruoho #include "acpi.h"
45149703c7Sjruoho #include "accommon.h"
46149703c7Sjruoho #include "actables.h"
47149703c7Sjruoho
48149703c7Sjruoho #define _COMPONENT ACPI_TABLES
49149703c7Sjruoho ACPI_MODULE_NAME ("tbutils")
50149703c7Sjruoho
5133841f6dSchristos
52149703c7Sjruoho /* Local prototypes */
53149703c7Sjruoho
54149703c7Sjruoho static ACPI_PHYSICAL_ADDRESS
55149703c7Sjruoho AcpiTbGetRootTableEntry (
56149703c7Sjruoho UINT8 *TableEntry,
57149703c7Sjruoho UINT32 TableEntrySize);
58149703c7Sjruoho
59149703c7Sjruoho
6033841f6dSchristos #if (!ACPI_REDUCED_HARDWARE)
61149703c7Sjruoho /*******************************************************************************
62149703c7Sjruoho *
63149703c7Sjruoho * FUNCTION: AcpiTbInitializeFacs
64149703c7Sjruoho *
65149703c7Sjruoho * PARAMETERS: None
66149703c7Sjruoho *
67149703c7Sjruoho * RETURN: Status
68149703c7Sjruoho *
69149703c7Sjruoho * DESCRIPTION: Create a permanent mapping for the FADT and save it in a global
70149703c7Sjruoho * for accessing the Global Lock and Firmware Waking Vector
71149703c7Sjruoho *
72149703c7Sjruoho ******************************************************************************/
73149703c7Sjruoho
74149703c7Sjruoho ACPI_STATUS
AcpiTbInitializeFacs(void)75149703c7Sjruoho AcpiTbInitializeFacs (
76149703c7Sjruoho void)
77149703c7Sjruoho {
7894e0d463Schristos ACPI_TABLE_FACS *Facs;
7994e0d463Schristos
80149703c7Sjruoho
8133841f6dSchristos /* If Hardware Reduced flag is set, there is no FACS */
8233841f6dSchristos
8333841f6dSchristos if (AcpiGbl_ReducedHardware)
8433841f6dSchristos {
8533841f6dSchristos AcpiGbl_FACS = NULL;
8633841f6dSchristos return (AE_OK);
8733841f6dSchristos }
8894e0d463Schristos else if (AcpiGbl_FADT.XFacs &&
8994e0d463Schristos (!AcpiGbl_FADT.Facs || !AcpiGbl_Use32BitFacsAddresses))
90e34402d4Schristos {
9194e0d463Schristos (void) AcpiGetTableByIndex (AcpiGbl_XFacsIndex,
9294e0d463Schristos ACPI_CAST_INDIRECT_PTR (ACPI_TABLE_HEADER, &Facs));
9394e0d463Schristos AcpiGbl_FACS = Facs;
94e34402d4Schristos }
9594e0d463Schristos else if (AcpiGbl_FADT.Facs)
96e34402d4Schristos {
9794e0d463Schristos (void) AcpiGetTableByIndex (AcpiGbl_FacsIndex,
9894e0d463Schristos ACPI_CAST_INDIRECT_PTR (ACPI_TABLE_HEADER, &Facs));
9994e0d463Schristos AcpiGbl_FACS = Facs;
100e34402d4Schristos }
101e34402d4Schristos
102e34402d4Schristos /* If there is no FACS, just continue. There was already an error msg */
103e34402d4Schristos
104e34402d4Schristos return (AE_OK);
105149703c7Sjruoho }
10633841f6dSchristos #endif /* !ACPI_REDUCED_HARDWARE */
107149703c7Sjruoho
108149703c7Sjruoho
109149703c7Sjruoho /*******************************************************************************
110149703c7Sjruoho *
111149703c7Sjruoho * FUNCTION: AcpiTbCheckDsdtHeader
112149703c7Sjruoho *
113149703c7Sjruoho * PARAMETERS: None
114149703c7Sjruoho *
115149703c7Sjruoho * RETURN: None
116149703c7Sjruoho *
117149703c7Sjruoho * DESCRIPTION: Quick compare to check validity of the DSDT. This will detect
118149703c7Sjruoho * if the DSDT has been replaced from outside the OS and/or if
119149703c7Sjruoho * the DSDT header has been corrupted.
120149703c7Sjruoho *
121149703c7Sjruoho ******************************************************************************/
122149703c7Sjruoho
123149703c7Sjruoho void
AcpiTbCheckDsdtHeader(void)124149703c7Sjruoho AcpiTbCheckDsdtHeader (
125149703c7Sjruoho void)
126149703c7Sjruoho {
127149703c7Sjruoho
128149703c7Sjruoho /* Compare original length and checksum to current values */
129149703c7Sjruoho
130149703c7Sjruoho if (AcpiGbl_OriginalDsdtHeader.Length != AcpiGbl_DSDT->Length ||
131149703c7Sjruoho AcpiGbl_OriginalDsdtHeader.Checksum != AcpiGbl_DSDT->Checksum)
132149703c7Sjruoho {
13333841f6dSchristos ACPI_BIOS_ERROR ((AE_INFO,
13433841f6dSchristos "The DSDT has been corrupted or replaced - "
13533841f6dSchristos "old, new headers below"));
13694e0d463Schristos
137149703c7Sjruoho AcpiTbPrintTableHeader (0, &AcpiGbl_OriginalDsdtHeader);
138149703c7Sjruoho AcpiTbPrintTableHeader (0, AcpiGbl_DSDT);
139149703c7Sjruoho
140149703c7Sjruoho /* Disable further error messages */
141149703c7Sjruoho
142149703c7Sjruoho AcpiGbl_OriginalDsdtHeader.Length = AcpiGbl_DSDT->Length;
143149703c7Sjruoho AcpiGbl_OriginalDsdtHeader.Checksum = AcpiGbl_DSDT->Checksum;
144149703c7Sjruoho }
145149703c7Sjruoho }
146149703c7Sjruoho
147149703c7Sjruoho
148149703c7Sjruoho /*******************************************************************************
149149703c7Sjruoho *
150149703c7Sjruoho * FUNCTION: AcpiTbCopyDsdt
151149703c7Sjruoho *
15235a687ffSchristos * PARAMETERS: TableIndex - Index of installed table to copy
153149703c7Sjruoho *
15435a687ffSchristos * RETURN: The copied DSDT
155149703c7Sjruoho *
156149703c7Sjruoho * DESCRIPTION: Implements a subsystem option to copy the DSDT to local memory.
157149703c7Sjruoho * Some very bad BIOSs are known to either corrupt the DSDT or
158149703c7Sjruoho * install a new, bad DSDT. This copy works around the problem.
159149703c7Sjruoho *
160149703c7Sjruoho ******************************************************************************/
161149703c7Sjruoho
162149703c7Sjruoho ACPI_TABLE_HEADER *
AcpiTbCopyDsdt(UINT32 TableIndex)163149703c7Sjruoho AcpiTbCopyDsdt (
164149703c7Sjruoho UINT32 TableIndex)
165149703c7Sjruoho {
166149703c7Sjruoho ACPI_TABLE_HEADER *NewTable;
167149703c7Sjruoho ACPI_TABLE_DESC *TableDesc;
168149703c7Sjruoho
169149703c7Sjruoho
170149703c7Sjruoho TableDesc = &AcpiGbl_RootTableList.Tables[TableIndex];
171149703c7Sjruoho
172149703c7Sjruoho NewTable = ACPI_ALLOCATE (TableDesc->Length);
173149703c7Sjruoho if (!NewTable)
174149703c7Sjruoho {
175149703c7Sjruoho ACPI_ERROR ((AE_INFO, "Could not copy DSDT of length 0x%X",
176149703c7Sjruoho TableDesc->Length));
177149703c7Sjruoho return (NULL);
178149703c7Sjruoho }
179149703c7Sjruoho
180e34402d4Schristos memcpy (NewTable, TableDesc->Pointer, TableDesc->Length);
181ea4d7e80Schristos AcpiTbUninstallTable (TableDesc);
182ea4d7e80Schristos
183ea4d7e80Schristos AcpiTbInitTableDescriptor (
18494e0d463Schristos &AcpiGbl_RootTableList.Tables[AcpiGbl_DsdtIndex],
18594e0d463Schristos ACPI_PTR_TO_PHYSADDR (NewTable),
18694e0d463Schristos ACPI_TABLE_ORIGIN_INTERNAL_VIRTUAL, NewTable);
187149703c7Sjruoho
188dc79220aSchristos ACPI_INFO ((
189149703c7Sjruoho "Forced DSDT copy: length 0x%05X copied locally, original unmapped",
190149703c7Sjruoho NewTable->Length));
191149703c7Sjruoho
192149703c7Sjruoho return (NewTable);
193149703c7Sjruoho }
194149703c7Sjruoho
195149703c7Sjruoho
196149703c7Sjruoho /*******************************************************************************
197149703c7Sjruoho *
198149703c7Sjruoho * FUNCTION: AcpiTbGetRootTableEntry
199149703c7Sjruoho *
200149703c7Sjruoho * PARAMETERS: TableEntry - Pointer to the RSDT/XSDT table entry
201149703c7Sjruoho * TableEntrySize - sizeof 32 or 64 (RSDT or XSDT)
202149703c7Sjruoho *
203149703c7Sjruoho * RETURN: Physical address extracted from the root table
204149703c7Sjruoho *
205149703c7Sjruoho * DESCRIPTION: Get one root table entry. Handles 32-bit and 64-bit cases on
206149703c7Sjruoho * both 32-bit and 64-bit platforms
207149703c7Sjruoho *
208149703c7Sjruoho * NOTE: ACPI_PHYSICAL_ADDRESS is 32-bit on 32-bit platforms, 64-bit on
209149703c7Sjruoho * 64-bit platforms.
210149703c7Sjruoho *
211149703c7Sjruoho ******************************************************************************/
212149703c7Sjruoho
213149703c7Sjruoho static ACPI_PHYSICAL_ADDRESS
AcpiTbGetRootTableEntry(UINT8 * TableEntry,UINT32 TableEntrySize)214149703c7Sjruoho AcpiTbGetRootTableEntry (
215149703c7Sjruoho UINT8 *TableEntry,
216149703c7Sjruoho UINT32 TableEntrySize)
217149703c7Sjruoho {
218149703c7Sjruoho UINT64 Address64;
219149703c7Sjruoho
220149703c7Sjruoho
221149703c7Sjruoho /*
222149703c7Sjruoho * Get the table physical address (32-bit for RSDT, 64-bit for XSDT):
223149703c7Sjruoho * Note: Addresses are 32-bit aligned (not 64) in both RSDT and XSDT
224149703c7Sjruoho */
22533841f6dSchristos if (TableEntrySize == ACPI_RSDT_ENTRY_SIZE)
226149703c7Sjruoho {
227149703c7Sjruoho /*
228149703c7Sjruoho * 32-bit platform, RSDT: Return 32-bit table entry
229149703c7Sjruoho * 64-bit platform, RSDT: Expand 32-bit to 64-bit and return
230149703c7Sjruoho */
231bff9fc28Schristos return ((ACPI_PHYSICAL_ADDRESS) (*ACPI_CAST_PTR (
232bff9fc28Schristos UINT32, TableEntry)));
233149703c7Sjruoho }
234149703c7Sjruoho else
235149703c7Sjruoho {
236149703c7Sjruoho /*
237149703c7Sjruoho * 32-bit platform, XSDT: Truncate 64-bit to 32-bit and return
238149703c7Sjruoho * 64-bit platform, XSDT: Move (unaligned) 64-bit to local,
239149703c7Sjruoho * return 64-bit
240149703c7Sjruoho */
241149703c7Sjruoho ACPI_MOVE_64_TO_64 (&Address64, TableEntry);
242149703c7Sjruoho
243149703c7Sjruoho #if ACPI_MACHINE_WIDTH == 32
244149703c7Sjruoho if (Address64 > ACPI_UINT32_MAX)
245149703c7Sjruoho {
246149703c7Sjruoho /* Will truncate 64-bit address to 32 bits, issue warning */
247149703c7Sjruoho
24833841f6dSchristos ACPI_BIOS_WARNING ((AE_INFO,
249149703c7Sjruoho "64-bit Physical Address in XSDT is too large (0x%8.8X%8.8X),"
250149703c7Sjruoho " truncating",
251149703c7Sjruoho ACPI_FORMAT_UINT64 (Address64)));
252149703c7Sjruoho }
253149703c7Sjruoho #endif
254149703c7Sjruoho return ((ACPI_PHYSICAL_ADDRESS) (Address64));
255149703c7Sjruoho }
256149703c7Sjruoho }
257149703c7Sjruoho
258149703c7Sjruoho
259149703c7Sjruoho /*******************************************************************************
260149703c7Sjruoho *
261149703c7Sjruoho * FUNCTION: AcpiTbParseRootTable
262149703c7Sjruoho *
26335a687ffSchristos * PARAMETERS: RsdpAddress - Pointer to the RSDP
264149703c7Sjruoho *
265149703c7Sjruoho * RETURN: Status
266149703c7Sjruoho *
267149703c7Sjruoho * DESCRIPTION: This function is called to parse the Root System Description
268149703c7Sjruoho * Table (RSDT or XSDT)
269149703c7Sjruoho *
270149703c7Sjruoho * NOTE: Tables are mapped (not copied) for efficiency. The FACS must
271149703c7Sjruoho * be mapped and cannot be copied because it contains the actual
272149703c7Sjruoho * memory location of the ACPI Global Lock.
273149703c7Sjruoho *
274149703c7Sjruoho ******************************************************************************/
275149703c7Sjruoho
276abb0e338Schristos ACPI_STATUS ACPI_INIT_FUNCTION
AcpiTbParseRootTable(ACPI_PHYSICAL_ADDRESS RsdpAddress)277149703c7Sjruoho AcpiTbParseRootTable (
278149703c7Sjruoho ACPI_PHYSICAL_ADDRESS RsdpAddress)
279149703c7Sjruoho {
280149703c7Sjruoho ACPI_TABLE_RSDP *Rsdp;
281149703c7Sjruoho UINT32 TableEntrySize;
282149703c7Sjruoho UINT32 i;
283149703c7Sjruoho UINT32 TableCount;
284149703c7Sjruoho ACPI_TABLE_HEADER *Table;
285149703c7Sjruoho ACPI_PHYSICAL_ADDRESS Address;
286149703c7Sjruoho UINT32 Length;
287149703c7Sjruoho UINT8 *TableEntry;
288149703c7Sjruoho ACPI_STATUS Status;
289ea4d7e80Schristos UINT32 TableIndex;
290149703c7Sjruoho
291149703c7Sjruoho
292149703c7Sjruoho ACPI_FUNCTION_TRACE (TbParseRootTable);
293149703c7Sjruoho
294149703c7Sjruoho
29533841f6dSchristos /* Map the entire RSDP and extract the address of the RSDT or XSDT */
29633841f6dSchristos
297149703c7Sjruoho Rsdp = AcpiOsMapMemory (RsdpAddress, sizeof (ACPI_TABLE_RSDP));
298149703c7Sjruoho if (!Rsdp)
299149703c7Sjruoho {
300149703c7Sjruoho return_ACPI_STATUS (AE_NO_MEMORY);
301149703c7Sjruoho }
302149703c7Sjruoho
303149703c7Sjruoho AcpiTbPrintTableHeader (RsdpAddress,
304149703c7Sjruoho ACPI_CAST_PTR (ACPI_TABLE_HEADER, Rsdp));
305149703c7Sjruoho
30633841f6dSchristos /* Use XSDT if present and not overridden. Otherwise, use RSDT */
307149703c7Sjruoho
30833841f6dSchristos if ((Rsdp->Revision > 1) &&
30933841f6dSchristos Rsdp->XsdtPhysicalAddress &&
31033841f6dSchristos !AcpiGbl_DoNotUseXsdt)
311149703c7Sjruoho {
312149703c7Sjruoho /*
31333841f6dSchristos * RSDP contains an XSDT (64-bit physical addresses). We must use
31433841f6dSchristos * the XSDT if the revision is > 1 and the XSDT pointer is present,
31533841f6dSchristos * as per the ACPI specification.
316149703c7Sjruoho */
317149703c7Sjruoho Address = (ACPI_PHYSICAL_ADDRESS) Rsdp->XsdtPhysicalAddress;
31833841f6dSchristos TableEntrySize = ACPI_XSDT_ENTRY_SIZE;
319149703c7Sjruoho }
320149703c7Sjruoho else
321149703c7Sjruoho {
322149703c7Sjruoho /* Root table is an RSDT (32-bit physical addresses) */
323149703c7Sjruoho
324149703c7Sjruoho Address = (ACPI_PHYSICAL_ADDRESS) Rsdp->RsdtPhysicalAddress;
32533841f6dSchristos TableEntrySize = ACPI_RSDT_ENTRY_SIZE;
326149703c7Sjruoho }
327149703c7Sjruoho
328149703c7Sjruoho /*
32934dabbfeSriastradh * It is not possible to map more than one entry in some environments,
33034dabbfeSriastradh * so unmap the RSDP here before mapping other tables
33134dabbfeSriastradh */
33234dabbfeSriastradh AcpiOsUnmapMemory (Rsdp, sizeof (ACPI_TABLE_RSDP));
33334dabbfeSriastradh
334149703c7Sjruoho /* Map the RSDT/XSDT table header to get the full table length */
335149703c7Sjruoho
336149703c7Sjruoho Table = AcpiOsMapMemory (Address, sizeof (ACPI_TABLE_HEADER));
337149703c7Sjruoho if (!Table)
338149703c7Sjruoho {
339149703c7Sjruoho return_ACPI_STATUS (AE_NO_MEMORY);
340149703c7Sjruoho }
341149703c7Sjruoho
342149703c7Sjruoho AcpiTbPrintTableHeader (Address, Table);
343149703c7Sjruoho
34433841f6dSchristos /*
34533841f6dSchristos * Validate length of the table, and map entire table.
34633841f6dSchristos * Minimum length table must contain at least one entry.
34733841f6dSchristos */
348149703c7Sjruoho Length = Table->Length;
349149703c7Sjruoho AcpiOsUnmapMemory (Table, sizeof (ACPI_TABLE_HEADER));
350149703c7Sjruoho
35133841f6dSchristos if (Length < (sizeof (ACPI_TABLE_HEADER) + TableEntrySize))
352149703c7Sjruoho {
35333841f6dSchristos ACPI_BIOS_ERROR ((AE_INFO,
35433841f6dSchristos "Invalid table length 0x%X in RSDT/XSDT", Length));
355149703c7Sjruoho return_ACPI_STATUS (AE_INVALID_TABLE_LENGTH);
356149703c7Sjruoho }
357149703c7Sjruoho
358149703c7Sjruoho Table = AcpiOsMapMemory (Address, Length);
359149703c7Sjruoho if (!Table)
360149703c7Sjruoho {
361149703c7Sjruoho return_ACPI_STATUS (AE_NO_MEMORY);
362149703c7Sjruoho }
363149703c7Sjruoho
364149703c7Sjruoho /* Validate the root table checksum */
365149703c7Sjruoho
366*1d995a70Schristos Status = AcpiUtVerifyChecksum (Table, Length);
367149703c7Sjruoho if (ACPI_FAILURE (Status))
368149703c7Sjruoho {
369149703c7Sjruoho AcpiOsUnmapMemory (Table, Length);
370149703c7Sjruoho return_ACPI_STATUS (Status);
371149703c7Sjruoho }
372149703c7Sjruoho
37333841f6dSchristos /* Get the number of entries and pointer to first entry */
374149703c7Sjruoho
375149703c7Sjruoho TableCount = (UINT32) ((Table->Length - sizeof (ACPI_TABLE_HEADER)) /
376149703c7Sjruoho TableEntrySize);
37733841f6dSchristos TableEntry = ACPI_ADD_PTR (UINT8, Table, sizeof (ACPI_TABLE_HEADER));
378149703c7Sjruoho
37933841f6dSchristos /* Initialize the root table array from the RSDT/XSDT */
38033841f6dSchristos
381149703c7Sjruoho for (i = 0; i < TableCount; i++)
382149703c7Sjruoho {
383149703c7Sjruoho /* Get the table physical address (32-bit for RSDT, 64-bit for XSDT) */
384149703c7Sjruoho
385ea4d7e80Schristos Address = AcpiTbGetRootTableEntry (TableEntry, TableEntrySize);
386ea4d7e80Schristos
387ea4d7e80Schristos /* Skip NULL entries in RSDT/XSDT */
388ea4d7e80Schristos
389ea4d7e80Schristos if (!Address)
390ea4d7e80Schristos {
391ea4d7e80Schristos goto NextTable;
392ea4d7e80Schristos }
393ea4d7e80Schristos
394ea4d7e80Schristos Status = AcpiTbInstallStandardTable (Address,
395bff9fc28Schristos ACPI_TABLE_ORIGIN_INTERNAL_PHYSICAL, NULL, FALSE, TRUE,
396bff9fc28Schristos &TableIndex);
397ea4d7e80Schristos
398ea4d7e80Schristos if (ACPI_SUCCESS (Status) &&
399f5a85da7Schristos ACPI_COMPARE_NAMESEG (
40094e0d463Schristos &AcpiGbl_RootTableList.Tables[TableIndex].Signature,
401ea4d7e80Schristos ACPI_SIG_FADT))
402ea4d7e80Schristos {
40394e0d463Schristos AcpiGbl_FadtIndex = TableIndex;
40494e0d463Schristos AcpiTbParseFadt ();
405ea4d7e80Schristos }
406ea4d7e80Schristos
407ea4d7e80Schristos NextTable:
408149703c7Sjruoho
409149703c7Sjruoho TableEntry += TableEntrySize;
410149703c7Sjruoho }
411149703c7Sjruoho
412149703c7Sjruoho AcpiOsUnmapMemory (Table, Length);
413149703c7Sjruoho return_ACPI_STATUS (AE_OK);
414149703c7Sjruoho }
415d592fd16Schristos
416d592fd16Schristos
417d592fd16Schristos /*******************************************************************************
418d592fd16Schristos *
419d592fd16Schristos * FUNCTION: AcpiTbGetTable
420d592fd16Schristos *
421d592fd16Schristos * PARAMETERS: TableDesc - Table descriptor
422d592fd16Schristos * OutTable - Where the pointer to the table is returned
423d592fd16Schristos *
424d592fd16Schristos * RETURN: Status and pointer to the requested table
425d592fd16Schristos *
426d592fd16Schristos * DESCRIPTION: Increase a reference to a table descriptor and return the
427d592fd16Schristos * validated table pointer.
428d592fd16Schristos * If the table descriptor is an entry of the root table list,
429d592fd16Schristos * this API must be invoked with ACPI_MTX_TABLES acquired.
430d592fd16Schristos *
431d592fd16Schristos ******************************************************************************/
432d592fd16Schristos
433d592fd16Schristos ACPI_STATUS
AcpiTbGetTable(ACPI_TABLE_DESC * TableDesc,ACPI_TABLE_HEADER ** OutTable)434d592fd16Schristos AcpiTbGetTable (
435d592fd16Schristos ACPI_TABLE_DESC *TableDesc,
436d592fd16Schristos ACPI_TABLE_HEADER **OutTable)
437d592fd16Schristos {
438d592fd16Schristos ACPI_STATUS Status;
439d592fd16Schristos
440d592fd16Schristos
441d592fd16Schristos ACPI_FUNCTION_TRACE (AcpiTbGetTable);
442d592fd16Schristos
443d592fd16Schristos
444d592fd16Schristos if (TableDesc->ValidationCount == 0)
445d592fd16Schristos {
446d592fd16Schristos /* Table need to be "VALIDATED" */
447d592fd16Schristos
448d592fd16Schristos Status = AcpiTbValidateTable (TableDesc);
449d592fd16Schristos if (ACPI_FAILURE (Status))
450d592fd16Schristos {
451d592fd16Schristos return_ACPI_STATUS (Status);
452d592fd16Schristos }
453d592fd16Schristos }
454d592fd16Schristos
45535a687ffSchristos if (TableDesc->ValidationCount < ACPI_MAX_TABLE_VALIDATIONS)
456d592fd16Schristos {
45735a687ffSchristos TableDesc->ValidationCount++;
45835a687ffSchristos
45935a687ffSchristos /*
46035a687ffSchristos * Detect ValidationCount overflows to ensure that the warning
46135a687ffSchristos * message will only be printed once.
46235a687ffSchristos */
46335a687ffSchristos if (TableDesc->ValidationCount >= ACPI_MAX_TABLE_VALIDATIONS)
46435a687ffSchristos {
46535a687ffSchristos ACPI_WARNING((AE_INFO,
46635a687ffSchristos "Table %p, Validation count overflows\n", TableDesc));
46735a687ffSchristos }
468d592fd16Schristos }
469d592fd16Schristos
470d592fd16Schristos *OutTable = TableDesc->Pointer;
471d592fd16Schristos return_ACPI_STATUS (AE_OK);
472d592fd16Schristos }
473d592fd16Schristos
474d592fd16Schristos
475d592fd16Schristos /*******************************************************************************
476d592fd16Schristos *
477d592fd16Schristos * FUNCTION: AcpiTbPutTable
478d592fd16Schristos *
479d592fd16Schristos * PARAMETERS: TableDesc - Table descriptor
480d592fd16Schristos *
481d592fd16Schristos * RETURN: None
482d592fd16Schristos *
483d592fd16Schristos * DESCRIPTION: Decrease a reference to a table descriptor and release the
484d592fd16Schristos * validated table pointer if no references.
485d592fd16Schristos * If the table descriptor is an entry of the root table list,
486d592fd16Schristos * this API must be invoked with ACPI_MTX_TABLES acquired.
487d592fd16Schristos *
488d592fd16Schristos ******************************************************************************/
489d592fd16Schristos
490d592fd16Schristos void
AcpiTbPutTable(ACPI_TABLE_DESC * TableDesc)491d592fd16Schristos AcpiTbPutTable (
492d592fd16Schristos ACPI_TABLE_DESC *TableDesc)
493d592fd16Schristos {
494d592fd16Schristos
495d592fd16Schristos ACPI_FUNCTION_TRACE (AcpiTbPutTable);
496d592fd16Schristos
497d592fd16Schristos
49835a687ffSchristos if (TableDesc->ValidationCount < ACPI_MAX_TABLE_VALIDATIONS)
49935a687ffSchristos {
50035a687ffSchristos TableDesc->ValidationCount--;
50135a687ffSchristos
50235a687ffSchristos /*
50335a687ffSchristos * Detect ValidationCount underflows to ensure that the warning
50435a687ffSchristos * message will only be printed once.
50535a687ffSchristos */
50635a687ffSchristos if (TableDesc->ValidationCount >= ACPI_MAX_TABLE_VALIDATIONS)
507d592fd16Schristos {
508d592fd16Schristos ACPI_WARNING ((AE_INFO,
50935a687ffSchristos "Table %p, Validation count underflows\n", TableDesc));
510d592fd16Schristos return_VOID;
511d592fd16Schristos }
51235a687ffSchristos }
513d592fd16Schristos
514d592fd16Schristos if (TableDesc->ValidationCount == 0)
515d592fd16Schristos {
516d592fd16Schristos /* Table need to be "INVALIDATED" */
517d592fd16Schristos
518d592fd16Schristos AcpiTbInvalidateTable (TableDesc);
519d592fd16Schristos }
520d592fd16Schristos
521d592fd16Schristos return_VOID;
522d592fd16Schristos }
523