ReactOS 0.4.15-dev-8058-ga7cbb60
tbutils.c
Go to the documentation of this file.
1/******************************************************************************
2 *
3 * Module Name: tbutils - ACPI Table utilities
4 *
5 *****************************************************************************/
6
7/*
8 * Copyright (C) 2000 - 2022, Intel Corp.
9 * All rights reserved.
10 *
11 * Redistribution and use in source and binary forms, with or without
12 * modification, are permitted provided that the following conditions
13 * are met:
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.
25 *
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.
29 *
30 * NO WARRANTY
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 MERCHANTABILITY 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.
42 */
43
44#include "acpi.h"
45#include "accommon.h"
46#include "actables.h"
47
48#define _COMPONENT ACPI_TABLES
49 ACPI_MODULE_NAME ("tbutils")
50
51
52/* Local prototypes */
53
54static ACPI_PHYSICAL_ADDRESS
57 UINT32 TableEntrySize);
58
59
60#if (!ACPI_REDUCED_HARDWARE)
61/*******************************************************************************
62 *
63 * FUNCTION: AcpiTbInitializeFacs
64 *
65 * PARAMETERS: None
66 *
67 * RETURN: Status
68 *
69 * DESCRIPTION: Create a permanent mapping for the FADT and save it in a global
70 * for accessing the Global Lock and Firmware Waking Vector
71 *
72 ******************************************************************************/
73
76 void)
77{
78 ACPI_TABLE_FACS *Facs;
79
80
81 /* If Hardware Reduced flag is set, there is no FACS */
82
83 if (AcpiGbl_ReducedHardware)
84 {
85 AcpiGbl_FACS = NULL;
86 return (AE_OK);
87 }
88 else if (AcpiGbl_FADT.XFacs &&
89 (!AcpiGbl_FADT.Facs || !AcpiGbl_Use32BitFacsAddresses))
90 {
91 (void) AcpiGetTableByIndex (AcpiGbl_XFacsIndex,
93 AcpiGbl_FACS = Facs;
94 }
95 else if (AcpiGbl_FADT.Facs)
96 {
97 (void) AcpiGetTableByIndex (AcpiGbl_FacsIndex,
99 AcpiGbl_FACS = Facs;
100 }
101
102 /* If there is no FACS, just continue. There was already an error msg */
103
104 return (AE_OK);
105}
106#endif /* !ACPI_REDUCED_HARDWARE */
107
108
109/*******************************************************************************
110 *
111 * FUNCTION: AcpiTbCheckDsdtHeader
112 *
113 * PARAMETERS: None
114 *
115 * RETURN: None
116 *
117 * DESCRIPTION: Quick compare to check validity of the DSDT. This will detect
118 * if the DSDT has been replaced from outside the OS and/or if
119 * the DSDT header has been corrupted.
120 *
121 ******************************************************************************/
122
123void
125 void)
126{
127
128 /* Compare original length and checksum to current values */
129
130 if (AcpiGbl_OriginalDsdtHeader.Length != AcpiGbl_DSDT->Length ||
131 AcpiGbl_OriginalDsdtHeader.Checksum != AcpiGbl_DSDT->Checksum)
132 {
134 "The DSDT has been corrupted or replaced - "
135 "old, new headers below"));
136
137 AcpiTbPrintTableHeader (0, &AcpiGbl_OriginalDsdtHeader);
138 AcpiTbPrintTableHeader (0, AcpiGbl_DSDT);
139
140 /* Disable further error messages */
141
142 AcpiGbl_OriginalDsdtHeader.Length = AcpiGbl_DSDT->Length;
143 AcpiGbl_OriginalDsdtHeader.Checksum = AcpiGbl_DSDT->Checksum;
144 }
145}
146
147
148/*******************************************************************************
149 *
150 * FUNCTION: AcpiTbCopyDsdt
151 *
152 * PARAMETERS: TableIndex - Index of installed table to copy
153 *
154 * RETURN: The copied DSDT
155 *
156 * DESCRIPTION: Implements a subsystem option to copy the DSDT to local memory.
157 * Some very bad BIOSs are known to either corrupt the DSDT or
158 * install a new, bad DSDT. This copy works around the problem.
159 *
160 ******************************************************************************/
161
164 UINT32 TableIndex)
165{
166 ACPI_TABLE_HEADER *NewTable;
167 ACPI_TABLE_DESC *TableDesc;
168
169
170 TableDesc = &AcpiGbl_RootTableList.Tables[TableIndex];
171
172 NewTable = ACPI_ALLOCATE (TableDesc->Length);
173 if (!NewTable)
174 {
175 ACPI_ERROR ((AE_INFO, "Could not copy DSDT of length 0x%X",
176 TableDesc->Length));
177 return (NULL);
178 }
179
180 memcpy (NewTable, TableDesc->Pointer, TableDesc->Length);
181 AcpiTbUninstallTable (TableDesc);
182
184 &AcpiGbl_RootTableList.Tables[AcpiGbl_DsdtIndex],
185 ACPI_PTR_TO_PHYSADDR (NewTable),
187
188 ACPI_INFO ((
189 "Forced DSDT copy: length 0x%05X copied locally, original unmapped",
190 NewTable->Length));
191
192 return (NewTable);
193}
194
195
196/*******************************************************************************
197 *
198 * FUNCTION: AcpiTbGetRootTableEntry
199 *
200 * PARAMETERS: TableEntry - Pointer to the RSDT/XSDT table entry
201 * TableEntrySize - sizeof 32 or 64 (RSDT or XSDT)
202 *
203 * RETURN: Physical address extracted from the root table
204 *
205 * DESCRIPTION: Get one root table entry. Handles 32-bit and 64-bit cases on
206 * both 32-bit and 64-bit platforms
207 *
208 * NOTE: ACPI_PHYSICAL_ADDRESS is 32-bit on 32-bit platforms, 64-bit on
209 * 64-bit platforms.
210 *
211 ******************************************************************************/
212
213static ACPI_PHYSICAL_ADDRESS
216 UINT32 TableEntrySize)
217{
218 UINT64 Address64;
219
220
221 /*
222 * Get the table physical address (32-bit for RSDT, 64-bit for XSDT):
223 * Note: Addresses are 32-bit aligned (not 64) in both RSDT and XSDT
224 */
225 if (TableEntrySize == ACPI_RSDT_ENTRY_SIZE)
226 {
227 /*
228 * 32-bit platform, RSDT: Return 32-bit table entry
229 * 64-bit platform, RSDT: Expand 32-bit to 64-bit and return
230 */
231 return ((ACPI_PHYSICAL_ADDRESS) (*ACPI_CAST_PTR (
232 UINT32, TableEntry)));
233 }
234 else
235 {
236 /*
237 * 32-bit platform, XSDT: Truncate 64-bit to 32-bit and return
238 * 64-bit platform, XSDT: Move (unaligned) 64-bit to local,
239 * return 64-bit
240 */
241 ACPI_MOVE_64_TO_64 (&Address64, TableEntry);
242
243#if ACPI_MACHINE_WIDTH == 32
244 if (Address64 > ACPI_UINT32_MAX)
245 {
246 /* Will truncate 64-bit address to 32 bits, issue warning */
247
249 "64-bit Physical Address in XSDT is too large (0x%8.8X%8.8X),"
250 " truncating",
251 ACPI_FORMAT_UINT64 (Address64)));
252 }
253#endif
254 return ((ACPI_PHYSICAL_ADDRESS) (Address64));
255 }
256}
257
258
259/*******************************************************************************
260 *
261 * FUNCTION: AcpiTbParseRootTable
262 *
263 * PARAMETERS: RsdpAddress - Pointer to the RSDP
264 *
265 * RETURN: Status
266 *
267 * DESCRIPTION: This function is called to parse the Root System Description
268 * Table (RSDT or XSDT)
269 *
270 * NOTE: Tables are mapped (not copied) for efficiency. The FACS must
271 * be mapped and cannot be copied because it contains the actual
272 * memory location of the ACPI Global Lock.
273 *
274 ******************************************************************************/
275
278 ACPI_PHYSICAL_ADDRESS RsdpAddress)
279{
280 ACPI_TABLE_RSDP *Rsdp;
281 UINT32 TableEntrySize;
282 UINT32 i;
283 UINT32 TableCount;
285 ACPI_PHYSICAL_ADDRESS Address;
289 UINT32 TableIndex;
290
291
292 ACPI_FUNCTION_TRACE (TbParseRootTable);
293
294
295 /* Map the entire RSDP and extract the address of the RSDT or XSDT */
296
297 Rsdp = AcpiOsMapMemory (RsdpAddress, sizeof (ACPI_TABLE_RSDP));
298 if (!Rsdp)
299 {
301 }
302
303 AcpiTbPrintTableHeader (RsdpAddress,
305
306 /* Use XSDT if present and not overridden. Otherwise, use RSDT */
307
308 if ((Rsdp->Revision > 1) &&
309 Rsdp->XsdtPhysicalAddress &&
310 !AcpiGbl_DoNotUseXsdt)
311 {
312 /*
313 * RSDP contains an XSDT (64-bit physical addresses). We must use
314 * the XSDT if the revision is > 1 and the XSDT pointer is present,
315 * as per the ACPI specification.
316 */
317 Address = (ACPI_PHYSICAL_ADDRESS) Rsdp->XsdtPhysicalAddress;
318 TableEntrySize = ACPI_XSDT_ENTRY_SIZE;
319 }
320 else
321 {
322 /* Root table is an RSDT (32-bit physical addresses) */
323
324 Address = (ACPI_PHYSICAL_ADDRESS) Rsdp->RsdtPhysicalAddress;
325 TableEntrySize = ACPI_RSDT_ENTRY_SIZE;
326 }
327
328 /*
329 * It is not possible to map more than one entry in some environments,
330 * so unmap the RSDP here before mapping other tables
331 */
332 AcpiOsUnmapMemory (Rsdp, sizeof (ACPI_TABLE_RSDP));
333
334 /* Map the RSDT/XSDT table header to get the full table length */
335
337 if (!Table)
338 {
340 }
341
343
344 /*
345 * Validate length of the table, and map entire table.
346 * Minimum length table must contain at least one entry.
347 */
348 Length = Table->Length;
350
351 if (Length < (sizeof (ACPI_TABLE_HEADER) + TableEntrySize))
352 {
354 "Invalid table length 0x%X in RSDT/XSDT", Length));
356 }
357
359 if (!Table)
360 {
362 }
363
364 /* Validate the root table checksum */
365
367 if (ACPI_FAILURE (Status))
368 {
371 }
372
373 /* Get the number of entries and pointer to first entry */
374
375 TableCount = (UINT32) ((Table->Length - sizeof (ACPI_TABLE_HEADER)) /
376 TableEntrySize);
378
379 /* Initialize the root table array from the RSDT/XSDT */
380
381 for (i = 0; i < TableCount; i++)
382 {
383 /* Get the table physical address (32-bit for RSDT, 64-bit for XSDT) */
384
385 Address = AcpiTbGetRootTableEntry (TableEntry, TableEntrySize);
386
387 /* Skip NULL entries in RSDT/XSDT */
388
389 if (!Address)
390 {
391 goto NextTable;
392 }
393
396 &TableIndex);
397
398 if (ACPI_SUCCESS (Status) &&
400 &AcpiGbl_RootTableList.Tables[TableIndex].Signature,
402 {
403 AcpiGbl_FadtIndex = TableIndex;
405 }
406
407NextTable:
408
409 TableEntry += TableEntrySize;
410 }
411
414}
415
416
417/*******************************************************************************
418 *
419 * FUNCTION: AcpiTbGetTable
420 *
421 * PARAMETERS: TableDesc - Table descriptor
422 * OutTable - Where the pointer to the table is returned
423 *
424 * RETURN: Status and pointer to the requested table
425 *
426 * DESCRIPTION: Increase a reference to a table descriptor and return the
427 * validated table pointer.
428 * If the table descriptor is an entry of the root table list,
429 * this API must be invoked with ACPI_MTX_TABLES acquired.
430 *
431 ******************************************************************************/
432
435 ACPI_TABLE_DESC *TableDesc,
436 ACPI_TABLE_HEADER **OutTable)
437{
439
440
442
443
444 if (TableDesc->ValidationCount == 0)
445 {
446 /* Table need to be "VALIDATED" */
447
448 Status = AcpiTbValidateTable (TableDesc);
449 if (ACPI_FAILURE (Status))
450 {
452 }
453 }
454
456 {
457 TableDesc->ValidationCount++;
458
459 /*
460 * Detect ValidationCount overflows to ensure that the warning
461 * message will only be printed once.
462 */
464 {
466 "Table %p, Validation count overflows\n", TableDesc));
467 }
468 }
469
470 *OutTable = TableDesc->Pointer;
472}
473
474
475/*******************************************************************************
476 *
477 * FUNCTION: AcpiTbPutTable
478 *
479 * PARAMETERS: TableDesc - Table descriptor
480 *
481 * RETURN: None
482 *
483 * DESCRIPTION: Decrease a reference to a table descriptor and release the
484 * validated table pointer if no references.
485 * If the table descriptor is an entry of the root table list,
486 * this API must be invoked with ACPI_MTX_TABLES acquired.
487 *
488 ******************************************************************************/
489
490void
492 ACPI_TABLE_DESC *TableDesc)
493{
494
496
497
499 {
500 TableDesc->ValidationCount--;
501
502 /*
503 * Detect ValidationCount underflows to ensure that the warning
504 * message will only be printed once.
505 */
507 {
509 "Table %p, Validation count underflows\n", TableDesc));
511 }
512 }
513
514 if (TableDesc->ValidationCount == 0)
515 {
516 /* Table need to be "INVALIDATED" */
517
518 AcpiTbInvalidateTable (TableDesc);
519 }
520
522}
unsigned long long UINT64
unsigned char UINT8
unsigned int UINT32
#define ACPI_INIT_FUNCTION
Definition: acenv.h:410
#define AE_INVALID_TABLE_LENGTH
Definition: acexcep.h:171
#define ACPI_FAILURE(a)
Definition: acexcep.h:95
#define AE_NO_MEMORY
Definition: acexcep.h:112
#define ACPI_SUCCESS(a)
Definition: acexcep.h:94
#define AE_OK
Definition: acexcep.h:97
#define ACPI_FORMAT_UINT64(i)
Definition: acmacros.h:71
#define ACPI_MOVE_64_TO_64(d, s)
Definition: acmacros.h:155
#define ACPI_MODULE_NAME(Name)
Definition: acoutput.h:216
#define ACPI_WARNING(plist)
Definition: acoutput.h:238
#define ACPI_BIOS_WARNING(plist)
Definition: acoutput.h:241
#define return_ACPI_STATUS(s)
Definition: acoutput.h:496
#define ACPI_FUNCTION_TRACE(a)
Definition: acoutput.h:480
#define ACPI_BIOS_ERROR(plist)
Definition: acoutput.h:243
#define ACPI_ERROR(plist)
Definition: acoutput.h:240
#define AE_INFO
Definition: acoutput.h:230
#define ACPI_INFO(plist)
Definition: acoutput.h:237
#define return_VOID
Definition: acoutput.h:495
void * AcpiOsMapMemory(ACPI_PHYSICAL_ADDRESS Where, ACPI_SIZE Length)
Definition: osl.c:108
void AcpiOsUnmapMemory(void *LogicalAddress, ACPI_SIZE Size)
Definition: osl.c:128
void AcpiTbInvalidateTable(ACPI_TABLE_DESC *TableDesc)
Definition: tbdata.c:414
ACPI_STATUS AcpiTbValidateTable(ACPI_TABLE_DESC *TableDesc)
Definition: tbdata.c:375
void AcpiTbPrintTableHeader(ACPI_PHYSICAL_ADDRESS Address, ACPI_TABLE_HEADER *Header)
Definition: tbprint.c:143
void AcpiTbUninstallTable(ACPI_TABLE_DESC *TableDesc)
Definition: tbinstal.c:336
void AcpiTbInitTableDescriptor(ACPI_TABLE_DESC *TableDesc, ACPI_PHYSICAL_ADDRESS Address, UINT8 Flags, ACPI_TABLE_HEADER *Table)
Definition: tbdata.c:130
void AcpiTbParseFadt(void)
Definition: tbfadt.c:339
ACPI_STATUS AcpiTbInstallStandardTable(ACPI_PHYSICAL_ADDRESS Address, UINT8 Flags, ACPI_TABLE_HEADER *Table, BOOLEAN Reload, BOOLEAN Override, UINT32 *TableIndex)
Definition: tbinstal.c:139
#define ACPI_TABLE_ORIGIN_INTERNAL_VIRTUAL
Definition: actbl.h:431
#define ACPI_SIG_FADT
Definition: actbl.h:68
#define ACPI_RSDT_ENTRY_SIZE
Definition: actbl.h:208
#define ACPI_MAX_TABLE_VALIDATIONS
Definition: actbl.h:425
#define ACPI_XSDT_ENTRY_SIZE
Definition: actbl.h:209
#define ACPI_TABLE_ORIGIN_INTERNAL_PHYSICAL
Definition: actbl.h:430
#define ACPI_CAST_INDIRECT_PTR(t, p)
Definition: actypes.h:545
#define ACPI_COMPARE_NAMESEG(a, b)
Definition: actypes.h:564
UINT32 ACPI_STATUS
Definition: actypes.h:460
#define ACPI_ADD_PTR(t, a, b)
Definition: actypes.h:546
#define ACPI_CAST_PTR(t, p)
Definition: actypes.h:544
#define ACPI_UINT32_MAX
Definition: actypes.h:66
#define ACPI_PTR_TO_PHYSADDR(i)
Definition: actypes.h:559
#define ACPI_ALLOCATE(a)
Definition: actypes.h:384
ACPI_STATUS AcpiUtVerifyChecksum(ACPI_TABLE_HEADER *Table, UINT32 Length)
Definition: utcksum.c:74
#define NULL
Definition: types.h:112
#define TRUE
Definition: types.h:120
#define FALSE
Definition: types.h:117
Status
Definition: gdiplustypes.h:25
ASMGENDATA Table[]
Definition: genincdata.c:61
GLsizei GLenum const GLvoid GLsizei GLenum GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLint GLint GLint GLshort GLshort GLshort GLubyte GLubyte GLubyte GLuint GLuint GLuint GLushort GLushort GLushort GLbyte GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLfloat GLint GLint GLint GLint GLshort GLshort GLshort GLshort GLubyte GLubyte GLubyte GLubyte GLuint GLuint GLuint GLuint GLushort GLushort GLushort GLushort GLboolean const GLdouble const GLfloat const GLint const GLshort const GLbyte const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLdouble const GLfloat const GLfloat const GLint const GLint const GLshort const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort GLenum GLenum GLenum GLfloat GLenum GLint GLenum GLenum GLenum GLfloat GLenum GLenum GLint GLenum GLfloat GLenum GLint GLint GLushort GLenum GLenum GLfloat GLenum GLenum GLint GLfloat const GLubyte GLenum GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLint GLint GLsizei GLsizei GLint GLenum GLenum const GLvoid GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLenum const GLdouble GLenum GLenum const GLfloat GLenum GLenum const GLint GLsizei GLuint GLfloat GLuint GLbitfield GLfloat GLint GLuint GLboolean GLenum GLfloat GLenum GLbitfield GLenum GLfloat GLfloat GLint GLint const GLfloat GLenum GLfloat GLfloat GLint GLint GLfloat GLfloat GLint GLint const GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat const GLdouble const GLfloat const GLdouble const GLfloat GLint i
Definition: glfuncs.h:248
#define memcpy(s1, s2, n)
Definition: mkisofs.h:878
_In_ ULONG _In_ ULONG _In_ ULONG Length
Definition: ntddpcm.h:102
static WCHAR Address[46]
Definition: ping.c:68
UINT16 ValidationCount
Definition: actbl.h:409
UINT32 Length
Definition: actbl.h:405
ACPI_TABLE_HEADER * Pointer
Definition: actbl.h:404
UINT32 Length
Definition: actbl.h:109
UINT8 Revision
Definition: actbl.h:154
UINT64 XsdtPhysicalAddress
Definition: actbl.h:157
UINT32 RsdtPhysicalAddress
Definition: actbl.h:155
ACPI_STATUS ACPI_INIT_FUNCTION AcpiTbParseRootTable(ACPI_PHYSICAL_ADDRESS RsdpAddress)
Definition: tbutils.c:277
void AcpiTbCheckDsdtHeader(void)
Definition: tbutils.c:124
ACPI_STATUS AcpiTbGetTable(ACPI_TABLE_DESC *TableDesc, ACPI_TABLE_HEADER **OutTable)
Definition: tbutils.c:434
ACPI_STATUS AcpiTbInitializeFacs(void)
Definition: tbutils.c:75
ACPI_TABLE_HEADER * AcpiTbCopyDsdt(UINT32 TableIndex)
Definition: tbutils.c:163
void AcpiTbPutTable(ACPI_TABLE_DESC *TableDesc)
Definition: tbutils.c:491
static ACPI_PHYSICAL_ADDRESS AcpiTbGetRootTableEntry(UINT8 *TableEntry, UINT32 TableEntrySize)
Definition: tbutils.c:214
ACPI_STATUS AcpiGetTableByIndex(UINT32 TableIndex, ACPI_TABLE_HEADER **OutTable)
Definition: tbxface.c:491
ActualNumberDriverObjects * sizeof(PDRIVER_OBJECT)) PDRIVER_OBJECT *DriverObjectList
_Must_inspect_result_ typedef _In_ ULONG TableEntry
Definition: iotypes.h:4303