1 /******************************************************************************
2 *
3 * Module Name: tbutils - ACPI Table utilities
4 *
5 *****************************************************************************/
6
7 /*
8 * Copyright (C) 2000 - 2015, 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 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.
42 */
43
44 #include <contrib/dev/acpica/include/acpi.h>
45 #include <contrib/dev/acpica/include/accommon.h>
46 #include <contrib/dev/acpica/include/actables.h>
47
48 #define _COMPONENT ACPI_TABLES
49 ACPI_MODULE_NAME ("tbutils")
50
51
52 /* Local prototypes */
53
54 static ACPI_PHYSICAL_ADDRESS
55 AcpiTbGetRootTableEntry (
56 UINT8 *TableEntry,
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
74 ACPI_STATUS
AcpiTbInitializeFacs(void)75 AcpiTbInitializeFacs (
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,
92 ACPI_CAST_INDIRECT_PTR (ACPI_TABLE_HEADER, &Facs));
93 AcpiGbl_FACS = Facs;
94 }
95 else if (AcpiGbl_FADT.Facs)
96 {
97 (void) AcpiGetTableByIndex (AcpiGbl_FacsIndex,
98 ACPI_CAST_INDIRECT_PTR (ACPI_TABLE_HEADER, &Facs));
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: AcpiTbTablesLoaded
112 *
113 * PARAMETERS: None
114 *
115 * RETURN: TRUE if required ACPI tables are loaded
116 *
117 * DESCRIPTION: Determine if the minimum required ACPI tables are present
118 * (FADT, FACS, DSDT)
119 *
120 ******************************************************************************/
121
122 BOOLEAN
AcpiTbTablesLoaded(void)123 AcpiTbTablesLoaded (
124 void)
125 {
126
127 if (AcpiGbl_RootTableList.CurrentTableCount >= 4)
128 {
129 return (TRUE);
130 }
131
132 return (FALSE);
133 }
134
135
136 /*******************************************************************************
137 *
138 * FUNCTION: AcpiTbCheckDsdtHeader
139 *
140 * PARAMETERS: None
141 *
142 * RETURN: None
143 *
144 * DESCRIPTION: Quick compare to check validity of the DSDT. This will detect
145 * if the DSDT has been replaced from outside the OS and/or if
146 * the DSDT header has been corrupted.
147 *
148 ******************************************************************************/
149
150 void
AcpiTbCheckDsdtHeader(void)151 AcpiTbCheckDsdtHeader (
152 void)
153 {
154
155 /* Compare original length and checksum to current values */
156
157 if (AcpiGbl_OriginalDsdtHeader.Length != AcpiGbl_DSDT->Length ||
158 AcpiGbl_OriginalDsdtHeader.Checksum != AcpiGbl_DSDT->Checksum)
159 {
160 ACPI_BIOS_ERROR ((AE_INFO,
161 "The DSDT has been corrupted or replaced - "
162 "old, new headers below"));
163 AcpiTbPrintTableHeader (0, &AcpiGbl_OriginalDsdtHeader);
164 AcpiTbPrintTableHeader (0, AcpiGbl_DSDT);
165
166 /* Disable further error messages */
167
168 AcpiGbl_OriginalDsdtHeader.Length = AcpiGbl_DSDT->Length;
169 AcpiGbl_OriginalDsdtHeader.Checksum = AcpiGbl_DSDT->Checksum;
170 }
171 }
172
173
174 /*******************************************************************************
175 *
176 * FUNCTION: AcpiTbCopyDsdt
177 *
178 * PARAMETERS: TableDesc - Installed table to copy
179 *
180 * RETURN: None
181 *
182 * DESCRIPTION: Implements a subsystem option to copy the DSDT to local memory.
183 * Some very bad BIOSs are known to either corrupt the DSDT or
184 * install a new, bad DSDT. This copy works around the problem.
185 *
186 ******************************************************************************/
187
188 ACPI_TABLE_HEADER *
AcpiTbCopyDsdt(UINT32 TableIndex)189 AcpiTbCopyDsdt (
190 UINT32 TableIndex)
191 {
192 ACPI_TABLE_HEADER *NewTable;
193 ACPI_TABLE_DESC *TableDesc;
194
195
196 TableDesc = &AcpiGbl_RootTableList.Tables[TableIndex];
197
198 NewTable = ACPI_ALLOCATE (TableDesc->Length);
199 if (!NewTable)
200 {
201 ACPI_ERROR ((AE_INFO, "Could not copy DSDT of length 0x%X",
202 TableDesc->Length));
203 return (NULL);
204 }
205
206 memcpy (NewTable, TableDesc->Pointer, TableDesc->Length);
207 AcpiTbUninstallTable (TableDesc);
208
209 AcpiTbInitTableDescriptor (
210 &AcpiGbl_RootTableList.Tables[AcpiGbl_DsdtIndex],
211 ACPI_PTR_TO_PHYSADDR (NewTable), ACPI_TABLE_ORIGIN_INTERNAL_VIRTUAL,
212 NewTable);
213
214 ACPI_INFO ((AE_INFO,
215 "Forced DSDT copy: length 0x%05X copied locally, original unmapped",
216 NewTable->Length));
217
218 return (NewTable);
219 }
220
221
222 /*******************************************************************************
223 *
224 * FUNCTION: AcpiTbGetRootTableEntry
225 *
226 * PARAMETERS: TableEntry - Pointer to the RSDT/XSDT table entry
227 * TableEntrySize - sizeof 32 or 64 (RSDT or XSDT)
228 *
229 * RETURN: Physical address extracted from the root table
230 *
231 * DESCRIPTION: Get one root table entry. Handles 32-bit and 64-bit cases on
232 * both 32-bit and 64-bit platforms
233 *
234 * NOTE: ACPI_PHYSICAL_ADDRESS is 32-bit on 32-bit platforms, 64-bit on
235 * 64-bit platforms.
236 *
237 ******************************************************************************/
238
239 static ACPI_PHYSICAL_ADDRESS
AcpiTbGetRootTableEntry(UINT8 * TableEntry,UINT32 TableEntrySize)240 AcpiTbGetRootTableEntry (
241 UINT8 *TableEntry,
242 UINT32 TableEntrySize)
243 {
244 UINT64 Address64;
245
246
247 /*
248 * Get the table physical address (32-bit for RSDT, 64-bit for XSDT):
249 * Note: Addresses are 32-bit aligned (not 64) in both RSDT and XSDT
250 */
251 if (TableEntrySize == ACPI_RSDT_ENTRY_SIZE)
252 {
253 /*
254 * 32-bit platform, RSDT: Return 32-bit table entry
255 * 64-bit platform, RSDT: Expand 32-bit to 64-bit and return
256 */
257 return ((ACPI_PHYSICAL_ADDRESS) (*ACPI_CAST_PTR (UINT32, TableEntry)));
258 }
259 else
260 {
261 /*
262 * 32-bit platform, XSDT: Truncate 64-bit to 32-bit and return
263 * 64-bit platform, XSDT: Move (unaligned) 64-bit to local,
264 * return 64-bit
265 */
266 ACPI_MOVE_64_TO_64 (&Address64, TableEntry);
267
268 #if ACPI_MACHINE_WIDTH == 32
269 if (Address64 > ACPI_UINT32_MAX)
270 {
271 /* Will truncate 64-bit address to 32 bits, issue warning */
272
273 ACPI_BIOS_WARNING ((AE_INFO,
274 "64-bit Physical Address in XSDT is too large (0x%8.8X%8.8X),"
275 " truncating",
276 ACPI_FORMAT_UINT64 (Address64)));
277 }
278 #endif
279 return ((ACPI_PHYSICAL_ADDRESS) (Address64));
280 }
281 }
282
283
284 /*******************************************************************************
285 *
286 * FUNCTION: AcpiTbParseRootTable
287 *
288 * PARAMETERS: Rsdp - Pointer to the RSDP
289 *
290 * RETURN: Status
291 *
292 * DESCRIPTION: This function is called to parse the Root System Description
293 * Table (RSDT or XSDT)
294 *
295 * NOTE: Tables are mapped (not copied) for efficiency. The FACS must
296 * be mapped and cannot be copied because it contains the actual
297 * memory location of the ACPI Global Lock.
298 *
299 ******************************************************************************/
300
301 ACPI_STATUS
AcpiTbParseRootTable(ACPI_PHYSICAL_ADDRESS RsdpAddress)302 AcpiTbParseRootTable (
303 ACPI_PHYSICAL_ADDRESS RsdpAddress)
304 {
305 ACPI_TABLE_RSDP *Rsdp;
306 UINT32 TableEntrySize;
307 UINT32 i;
308 UINT32 TableCount;
309 ACPI_TABLE_HEADER *Table;
310 ACPI_PHYSICAL_ADDRESS Address;
311 UINT32 Length;
312 UINT8 *TableEntry;
313 ACPI_STATUS Status;
314 UINT32 TableIndex;
315
316
317 ACPI_FUNCTION_TRACE (TbParseRootTable);
318
319
320 /* Map the entire RSDP and extract the address of the RSDT or XSDT */
321
322 Rsdp = AcpiOsMapMemory (RsdpAddress, sizeof (ACPI_TABLE_RSDP));
323 if (!Rsdp)
324 {
325 return_ACPI_STATUS (AE_NO_MEMORY);
326 }
327
328 AcpiTbPrintTableHeader (RsdpAddress,
329 ACPI_CAST_PTR (ACPI_TABLE_HEADER, Rsdp));
330
331 /* Use XSDT if present and not overridden. Otherwise, use RSDT */
332
333 if ((Rsdp->Revision > 1) &&
334 Rsdp->XsdtPhysicalAddress &&
335 !AcpiGbl_DoNotUseXsdt)
336 {
337 /*
338 * RSDP contains an XSDT (64-bit physical addresses). We must use
339 * the XSDT if the revision is > 1 and the XSDT pointer is present,
340 * as per the ACPI specification.
341 */
342 Address = (ACPI_PHYSICAL_ADDRESS) Rsdp->XsdtPhysicalAddress;
343 TableEntrySize = ACPI_XSDT_ENTRY_SIZE;
344 }
345 else
346 {
347 /* Root table is an RSDT (32-bit physical addresses) */
348
349 Address = (ACPI_PHYSICAL_ADDRESS) Rsdp->RsdtPhysicalAddress;
350 TableEntrySize = ACPI_RSDT_ENTRY_SIZE;
351 }
352
353 /*
354 * It is not possible to map more than one entry in some environments,
355 * so unmap the RSDP here before mapping other tables
356 */
357 AcpiOsUnmapMemory (Rsdp, sizeof (ACPI_TABLE_RSDP));
358
359 /* Map the RSDT/XSDT table header to get the full table length */
360
361 Table = AcpiOsMapMemory (Address, sizeof (ACPI_TABLE_HEADER));
362 if (!Table)
363 {
364 return_ACPI_STATUS (AE_NO_MEMORY);
365 }
366
367 AcpiTbPrintTableHeader (Address, Table);
368
369 /*
370 * Validate length of the table, and map entire table.
371 * Minimum length table must contain at least one entry.
372 */
373 Length = Table->Length;
374 AcpiOsUnmapMemory (Table, sizeof (ACPI_TABLE_HEADER));
375
376 if (Length < (sizeof (ACPI_TABLE_HEADER) + TableEntrySize))
377 {
378 ACPI_BIOS_ERROR ((AE_INFO,
379 "Invalid table length 0x%X in RSDT/XSDT", Length));
380 return_ACPI_STATUS (AE_INVALID_TABLE_LENGTH);
381 }
382
383 Table = AcpiOsMapMemory (Address, Length);
384 if (!Table)
385 {
386 return_ACPI_STATUS (AE_NO_MEMORY);
387 }
388
389 /* Validate the root table checksum */
390
391 Status = AcpiTbVerifyChecksum (Table, Length);
392 if (ACPI_FAILURE (Status))
393 {
394 AcpiOsUnmapMemory (Table, Length);
395 return_ACPI_STATUS (Status);
396 }
397
398 /* Get the number of entries and pointer to first entry */
399
400 TableCount = (UINT32) ((Table->Length - sizeof (ACPI_TABLE_HEADER)) /
401 TableEntrySize);
402 TableEntry = ACPI_ADD_PTR (UINT8, Table, sizeof (ACPI_TABLE_HEADER));
403
404 /* Initialize the root table array from the RSDT/XSDT */
405
406 for (i = 0; i < TableCount; i++)
407 {
408 /* Get the table physical address (32-bit for RSDT, 64-bit for XSDT) */
409
410 Address = AcpiTbGetRootTableEntry (TableEntry, TableEntrySize);
411
412 /* Skip NULL entries in RSDT/XSDT */
413
414 if (!Address)
415 {
416 goto NextTable;
417 }
418
419 Status = AcpiTbInstallStandardTable (Address,
420 ACPI_TABLE_ORIGIN_INTERNAL_PHYSICAL, FALSE, TRUE, &TableIndex);
421
422 if (ACPI_SUCCESS (Status) &&
423 ACPI_COMPARE_NAME (&AcpiGbl_RootTableList.Tables[TableIndex].Signature,
424 ACPI_SIG_FADT))
425 {
426 AcpiTbParseFadt (TableIndex);
427 }
428
429 NextTable:
430
431 TableEntry += TableEntrySize;
432 }
433
434 AcpiOsUnmapMemory (Table, Length);
435
436 return_ACPI_STATUS (AE_OK);
437 }
438
439
440 /*******************************************************************************
441 *
442 * FUNCTION: AcpiIsValidSignature
443 *
444 * PARAMETERS: Signature - Sig string to be validated
445 *
446 * RETURN: TRUE if signature is correct length and has valid characters
447 *
448 * DESCRIPTION: Validate an ACPI table signature.
449 *
450 ******************************************************************************/
451
452 BOOLEAN
AcpiIsValidSignature(char * Signature)453 AcpiIsValidSignature (
454 char *Signature)
455 {
456 UINT32 i;
457
458
459 /* Validate the signature length */
460
461 if (strlen (Signature) != ACPI_NAME_SIZE)
462 {
463 return (FALSE);
464 }
465
466 /* Validate each character in the signature */
467
468 for (i = 0; i < ACPI_NAME_SIZE; i++)
469 {
470 if (!AcpiUtValidAcpiChar (Signature[i], i))
471 {
472 return (FALSE);
473 }
474 }
475
476 return (TRUE);
477 }
478