1 /****************************************************************************** 2 * 3 * Module Name: oswintbl - Windows OSL for obtaining ACPI tables 4 * 5 *****************************************************************************/ 6 7 /****************************************************************************** 8 * 9 * 1. Copyright Notice 10 * 11 * Some or all of this work - Copyright (c) 1999 - 2020, Intel Corp. 12 * All rights reserved. 13 * 14 * 2. License 15 * 16 * 2.1. This is your license from Intel Corp. under its intellectual property 17 * rights. You may have additional license terms from the party that provided 18 * you this software, covering your right to use that party's intellectual 19 * property rights. 20 * 21 * 2.2. Intel grants, free of charge, to any person ("Licensee") obtaining a 22 * copy of the source code appearing in this file ("Covered Code") an 23 * irrevocable, perpetual, worldwide license under Intel's copyrights in the 24 * base code distributed originally by Intel ("Original Intel Code") to copy, 25 * make derivatives, distribute, use and display any portion of the Covered 26 * Code in any form, with the right to sublicense such rights; and 27 * 28 * 2.3. Intel grants Licensee a non-exclusive and non-transferable patent 29 * license (with the right to sublicense), under only those claims of Intel 30 * patents that are infringed by the Original Intel Code, to make, use, sell, 31 * offer to sell, and import the Covered Code and derivative works thereof 32 * solely to the minimum extent necessary to exercise the above copyright 33 * license, and in no event shall the patent license extend to any additions 34 * to or modifications of the Original Intel Code. No other license or right 35 * is granted directly or by implication, estoppel or otherwise; 36 * 37 * The above copyright and patent license is granted only if the following 38 * conditions are met: 39 * 40 * 3. Conditions 41 * 42 * 3.1. Redistribution of Source with Rights to Further Distribute Source. 43 * Redistribution of source code of any substantial portion of the Covered 44 * Code or modification with rights to further distribute source must include 45 * the above Copyright Notice, the above License, this list of Conditions, 46 * and the following Disclaimer and Export Compliance provision. In addition, 47 * Licensee must cause all Covered Code to which Licensee contributes to 48 * contain a file documenting the changes Licensee made to create that Covered 49 * Code and the date of any change. Licensee must include in that file the 50 * documentation of any changes made by any predecessor Licensee. Licensee 51 * must include a prominent statement that the modification is derived, 52 * directly or indirectly, from Original Intel Code. 53 * 54 * 3.2. Redistribution of Source with no Rights to Further Distribute Source. 55 * Redistribution of source code of any substantial portion of the Covered 56 * Code or modification without rights to further distribute source must 57 * include the following Disclaimer and Export Compliance provision in the 58 * documentation and/or other materials provided with distribution. In 59 * addition, Licensee may not authorize further sublicense of source of any 60 * portion of the Covered Code, and must include terms to the effect that the 61 * license from Licensee to its licensee is limited to the intellectual 62 * property embodied in the software Licensee provides to its licensee, and 63 * not to intellectual property embodied in modifications its licensee may 64 * make. 65 * 66 * 3.3. Redistribution of Executable. Redistribution in executable form of any 67 * substantial portion of the Covered Code or modification must reproduce the 68 * above Copyright Notice, and the following Disclaimer and Export Compliance 69 * provision in the documentation and/or other materials provided with the 70 * distribution. 71 * 72 * 3.4. Intel retains all right, title, and interest in and to the Original 73 * Intel Code. 74 * 75 * 3.5. Neither the name Intel nor any other trademark owned or controlled by 76 * Intel shall be used in advertising or otherwise to promote the sale, use or 77 * other dealings in products derived from or relating to the Covered Code 78 * without prior written authorization from Intel. 79 * 80 * 4. Disclaimer and Export Compliance 81 * 82 * 4.1. INTEL MAKES NO WARRANTY OF ANY KIND REGARDING ANY SOFTWARE PROVIDED 83 * HERE. ANY SOFTWARE ORIGINATING FROM INTEL OR DERIVED FROM INTEL SOFTWARE 84 * IS PROVIDED "AS IS," AND INTEL WILL NOT PROVIDE ANY SUPPORT, ASSISTANCE, 85 * INSTALLATION, TRAINING OR OTHER SERVICES. INTEL WILL NOT PROVIDE ANY 86 * UPDATES, ENHANCEMENTS OR EXTENSIONS. INTEL SPECIFICALLY DISCLAIMS ANY 87 * IMPLIED WARRANTIES OF MERCHANTABILITY, NONINFRINGEMENT AND FITNESS FOR A 88 * PARTICULAR PURPOSE. 89 * 90 * 4.2. IN NO EVENT SHALL INTEL HAVE ANY LIABILITY TO LICENSEE, ITS LICENSEES 91 * OR ANY OTHER THIRD PARTY, FOR ANY LOST PROFITS, LOST DATA, LOSS OF USE OR 92 * COSTS OF PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES, OR FOR ANY INDIRECT, 93 * SPECIAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THIS AGREEMENT, UNDER ANY 94 * CAUSE OF ACTION OR THEORY OF LIABILITY, AND IRRESPECTIVE OF WHETHER INTEL 95 * HAS ADVANCE NOTICE OF THE POSSIBILITY OF SUCH DAMAGES. THESE LIMITATIONS 96 * SHALL APPLY NOTWITHSTANDING THE FAILURE OF THE ESSENTIAL PURPOSE OF ANY 97 * LIMITED REMEDY. 98 * 99 * 4.3. Licensee shall not export, either directly or indirectly, any of this 100 * software or system incorporating such software without first obtaining any 101 * required license or other approval from the U. S. Department of Commerce or 102 * any other agency or department of the United States Government. In the 103 * event Licensee exports any such software from the United States or 104 * re-exports any such software from a foreign destination, Licensee shall 105 * ensure that the distribution and export/re-export of the software is in 106 * compliance with all laws, regulations, orders, or other restrictions of the 107 * U.S. Export Administration Regulations. Licensee agrees that neither it nor 108 * any of its subsidiaries will export/re-export any technical data, process, 109 * software, or service, directly or indirectly, to any country for which the 110 * United States government or any agency thereof requires an export license, 111 * other governmental approval, or letter of assurance, without first obtaining 112 * such license, approval or letter. 113 * 114 ***************************************************************************** 115 * 116 * Alternatively, you may choose to be licensed under the terms of the 117 * following license: 118 * 119 * Redistribution and use in source and binary forms, with or without 120 * modification, are permitted provided that the following conditions 121 * are met: 122 * 1. Redistributions of source code must retain the above copyright 123 * notice, this list of conditions, and the following disclaimer, 124 * without modification. 125 * 2. Redistributions in binary form must reproduce at minimum a disclaimer 126 * substantially similar to the "NO WARRANTY" disclaimer below 127 * ("Disclaimer") and any redistribution must be conditioned upon 128 * including a substantially similar Disclaimer requirement for further 129 * binary redistribution. 130 * 3. Neither the names of the above-listed copyright holders nor the names 131 * of any contributors may be used to endorse or promote products derived 132 * from this software without specific prior written permission. 133 * 134 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 135 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 136 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 137 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 138 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 139 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 140 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 141 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 142 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 143 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 144 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 145 * 146 * Alternatively, you may choose to be licensed under the terms of the 147 * GNU General Public License ("GPL") version 2 as published by the Free 148 * Software Foundation. 149 * 150 *****************************************************************************/ 151 152 #include "acpi.h" 153 #include "accommon.h" 154 #include "acutils.h" 155 #include <stdio.h> 156 157 #ifdef WIN32 158 #pragma warning(disable:4115) /* warning C4115: (caused by rpcasync.h) */ 159 #include <windows.h> 160 161 #elif WIN64 162 #include <windowsx.h> 163 #endif 164 165 #define _COMPONENT ACPI_OS_SERVICES 166 ACPI_MODULE_NAME ("oswintbl") 167 168 /* Local prototypes */ 169 170 static char * 171 WindowsFormatException ( 172 LONG WinStatus); 173 174 /* Globals */ 175 176 #define LOCAL_BUFFER_SIZE 64 177 178 static char KeyBuffer[LOCAL_BUFFER_SIZE]; 179 static char ErrorBuffer[LOCAL_BUFFER_SIZE]; 180 181 /* 182 * Tables supported in the Windows registry. Zero or more SSDTs are assumed to 183 * follow these tables. 184 */ 185 static char *SupportedTables[] = 186 { 187 "DSDT", 188 "RSDT", 189 "FACS", 190 "FACP" 191 }; 192 193 /* Number of table names for the table above. */ 194 195 #define ACPI_OS_NUM_TABLE_ENTRIES 4 196 197 198 /****************************************************************************** 199 * 200 * FUNCTION: WindowsFormatException 201 * 202 * PARAMETERS: WinStatus - Status from a Windows system call 203 * 204 * RETURN: Formatted (ascii) exception code. Front-end to Windows 205 * FormatMessage interface. 206 * 207 * DESCRIPTION: Decode a windows exception 208 * 209 *****************************************************************************/ 210 211 static char * 212 WindowsFormatException ( 213 LONG WinStatus) 214 { 215 216 ErrorBuffer[0] = 0; 217 FormatMessage (FORMAT_MESSAGE_FROM_SYSTEM, NULL, WinStatus, 0, 218 ErrorBuffer, LOCAL_BUFFER_SIZE, NULL); 219 220 return (ErrorBuffer); 221 } 222 223 224 /****************************************************************************** 225 * 226 * FUNCTION: AcpiOsGetTableByAddress 227 * 228 * PARAMETERS: Address - Physical address of the ACPI table 229 * Table - Where a pointer to the table is returned 230 * 231 * RETURN: Status; Table buffer is returned if AE_OK. 232 * AE_NOT_FOUND: A valid table was not found at the address 233 * 234 * DESCRIPTION: Get an ACPI table via a physical memory address. 235 * 236 * NOTE: Cannot be implemented without a Windows device driver. 237 * 238 *****************************************************************************/ 239 240 ACPI_STATUS 241 AcpiOsGetTableByAddress ( 242 ACPI_PHYSICAL_ADDRESS Address, 243 ACPI_TABLE_HEADER **Table) 244 { 245 246 fprintf (stderr, "Get table by address is not supported on Windows\n"); 247 return (AE_SUPPORT); 248 } 249 250 251 /****************************************************************************** 252 * 253 * FUNCTION: AcpiOsGetTableByIndex 254 * 255 * PARAMETERS: Index - Which table to get 256 * Table - Where a pointer to the table is returned 257 * Instance - Where a pointer to the table instance no. is 258 * returned 259 * Address - Where the table physical address is returned 260 * 261 * RETURN: Status; Table buffer and physical address returned if AE_OK. 262 * AE_LIMIT: Index is beyond valid limit 263 * 264 * DESCRIPTION: Get an ACPI table via an index value (0 through n). Returns 265 * AE_LIMIT when an invalid index is reached. Index is not 266 * necessarily an index into the RSDT/XSDT. 267 * Table is obtained from the Windows registry. 268 * 269 * NOTE: Cannot get the physical address from the windows registry; 270 * zero is returned instead. 271 * 272 *****************************************************************************/ 273 274 ACPI_STATUS 275 AcpiOsGetTableByIndex ( 276 UINT32 Index, 277 ACPI_TABLE_HEADER **Table, 278 UINT32 *Instance, 279 ACPI_PHYSICAL_ADDRESS *Address) 280 { 281 ACPI_STATUS Status; 282 char *Signature; 283 284 285 if (Index < ACPI_OS_NUM_TABLE_ENTRIES) 286 { 287 Signature = SupportedTables[Index]; 288 Index = 0; 289 } 290 else 291 { 292 Signature = ACPI_SIG_SSDT; 293 Index -= ACPI_OS_NUM_TABLE_ENTRIES; 294 } 295 296 Status = AcpiOsGetTableByName (Signature, Index, Table, Address); 297 298 if (ACPI_SUCCESS (Status)) 299 { 300 *Instance = Index; 301 } 302 else if (Status == AE_NOT_FOUND && 303 ACPI_COMPARE_NAMESEG (Signature, ACPI_SIG_SSDT)) 304 { 305 /* Treat SSDTs that are not found as invalid index. */ 306 Status = (AE_LIMIT); 307 } 308 309 return (Status); 310 } 311 312 313 /****************************************************************************** 314 * 315 * FUNCTION: AcpiOsGetTableByName 316 * 317 * PARAMETERS: Signature - ACPI Signature for desired table. Must be 318 * a null terminated 4-character string. 319 * Instance - For SSDTs (0...n). Use 0 otherwise. 320 * Table - Where a pointer to the table is returned 321 * Address - Where the table physical address is returned 322 * 323 * RETURN: Status; Table buffer and physical address returned if AE_OK. 324 * AE_LIMIT: Instance is beyond valid limit 325 * AE_NOT_FOUND: A table with the signature was not found 326 * 327 * DESCRIPTION: Get an ACPI table via a table signature (4 ASCII characters). 328 * Returns AE_LIMIT when an invalid instance is reached. 329 * Table is obtained from the Windows registry. 330 * 331 * NOTE: Assumes the input signature is uppercase. 332 * Cannot get the physical address from the windows registry; 333 * zero is returned instead. 334 * 335 *****************************************************************************/ 336 337 ACPI_STATUS 338 AcpiOsGetTableByName ( 339 char *Signature, 340 UINT32 Instance, 341 ACPI_TABLE_HEADER **Table, 342 ACPI_PHYSICAL_ADDRESS *Address) 343 { 344 HKEY Handle = NULL; 345 LONG WinStatus; 346 ULONG Type; 347 ULONG NameSize; 348 ULONG DataSize; 349 HKEY SubKey; 350 ULONG i; 351 ACPI_TABLE_HEADER *ReturnTable; 352 ACPI_STATUS Status = AE_OK; 353 354 355 /* Multiple instances are only supported for SSDT tables. */ 356 357 if (Instance > 0 && !ACPI_COMPARE_NAMESEG (Signature, ACPI_SIG_SSDT)) 358 { 359 return (AE_LIMIT); 360 } 361 362 /* Get a handle to the table key */ 363 364 while (1) 365 { 366 strcpy (KeyBuffer, "HARDWARE\\ACPI\\"); 367 if (AcpiUtSafeStrcat (KeyBuffer, sizeof (KeyBuffer), Signature)) 368 { 369 return (AE_BUFFER_OVERFLOW); 370 } 371 372 /* 373 * Windows stores SSDT at SSDT, SSD1, ..., SSD9, SSDA, ..., SSDS, SSDT, 374 * SSDU, ..., SSDY. If the first (0th) and the 29th tables have the same 375 * OEM ID, Table ID and Revision, then the 29th entry will overwrite the 376 * first entry... Let's hope that we do not have that many entries. 377 */ 378 if (Instance > 0 && ACPI_COMPARE_NAMESEG (Signature, ACPI_SIG_SSDT)) 379 { 380 if (Instance < 10) 381 { 382 KeyBuffer[strlen (KeyBuffer) - 1] = '0' + (char) Instance; 383 } 384 else if (Instance < 29) 385 { 386 KeyBuffer[strlen (KeyBuffer) - 1] = 'A' + (char) (Instance - 10); 387 } 388 else 389 { 390 return (AE_LIMIT); 391 } 392 } 393 394 WinStatus = RegOpenKeyEx (HKEY_LOCAL_MACHINE, KeyBuffer, 395 0L, KEY_READ, &Handle); 396 397 if (WinStatus != ERROR_SUCCESS) 398 { 399 /* 400 * Somewhere along the way, MS changed the registry entry for 401 * the FADT from 402 * HARDWARE/ACPI/FACP to 403 * HARDWARE/ACPI/FADT. 404 * 405 * This code allows for both. 406 */ 407 if (ACPI_COMPARE_NAMESEG (Signature, "FACP")) 408 { 409 Signature = "FADT"; 410 } 411 else if (ACPI_COMPARE_NAMESEG (Signature, "XSDT")) 412 { 413 Signature = "RSDT"; 414 } 415 else if (ACPI_COMPARE_NAMESEG (Signature, ACPI_SIG_SSDT)) 416 { 417 /* SSDT may not be present on older Windows versions, but it is 418 * also possible that the index is not found. */ 419 return (AE_NOT_FOUND); 420 } 421 else 422 { 423 fprintf (stderr, 424 "Could not find %s in registry at %s: %s (WinStatus=0x%X)\n", 425 Signature, KeyBuffer, WindowsFormatException (WinStatus), WinStatus); 426 return (AE_NOT_FOUND); 427 } 428 } 429 else 430 { 431 break; 432 } 433 } 434 435 /* Actual data for the table is down a couple levels */ 436 437 for (i = 0; ;) 438 { 439 WinStatus = RegEnumKey (Handle, i, KeyBuffer, sizeof (KeyBuffer)); 440 i++; 441 if (WinStatus == ERROR_NO_MORE_ITEMS) 442 { 443 break; 444 } 445 446 WinStatus = RegOpenKey (Handle, KeyBuffer, &SubKey); 447 if (WinStatus != ERROR_SUCCESS) 448 { 449 fprintf (stderr, "Could not open %s entry: %s\n", 450 Signature, WindowsFormatException (WinStatus)); 451 Status = AE_ERROR; 452 goto Cleanup; 453 } 454 455 RegCloseKey (Handle); 456 Handle = SubKey; 457 i = 0; 458 } 459 460 /* Find the (binary) table entry */ 461 462 for (i = 0; ; i++) 463 { 464 NameSize = sizeof (KeyBuffer); 465 WinStatus = RegEnumValue (Handle, i, KeyBuffer, &NameSize, NULL, 466 &Type, NULL, 0); 467 if (WinStatus != ERROR_SUCCESS) 468 { 469 fprintf (stderr, "Could not get %s registry entry: %s\n", 470 Signature, WindowsFormatException (WinStatus)); 471 Status = AE_ERROR; 472 goto Cleanup; 473 } 474 475 if (Type == REG_BINARY) 476 { 477 break; 478 } 479 } 480 481 /* Get the size of the table */ 482 483 WinStatus = RegQueryValueEx (Handle, KeyBuffer, NULL, NULL, 484 NULL, &DataSize); 485 if (WinStatus != ERROR_SUCCESS) 486 { 487 fprintf (stderr, "Could not read the %s table size: %s\n", 488 Signature, WindowsFormatException (WinStatus)); 489 Status = AE_ERROR; 490 goto Cleanup; 491 } 492 493 /* Allocate a new buffer for the table */ 494 495 ReturnTable = malloc (DataSize); 496 if (!ReturnTable) 497 { 498 Status = AE_NO_MEMORY; 499 goto Cleanup; 500 } 501 502 /* Get the actual table from the registry */ 503 504 WinStatus = RegQueryValueEx (Handle, KeyBuffer, NULL, NULL, 505 (UCHAR *) ReturnTable, &DataSize); 506 if (WinStatus != ERROR_SUCCESS) 507 { 508 fprintf (stderr, "Could not read %s data: %s\n", 509 Signature, WindowsFormatException (WinStatus)); 510 free (ReturnTable); 511 Status = AE_ERROR; 512 goto Cleanup; 513 } 514 515 *Table = ReturnTable; 516 *Address = 0; 517 518 Cleanup: 519 RegCloseKey (Handle); 520 return (Status); 521 } 522 523 524 /* These are here for acpidump only, so we don't need to link oswinxf */ 525 526 #ifdef ACPI_DUMP_APP 527 /****************************************************************************** 528 * 529 * FUNCTION: AcpiOsMapMemory 530 * 531 * PARAMETERS: Where - Physical address of memory to be mapped 532 * Length - How much memory to map 533 * 534 * RETURN: Pointer to mapped memory. Null on error. 535 * 536 * DESCRIPTION: Map physical memory into caller's address space 537 * 538 *****************************************************************************/ 539 540 void * 541 AcpiOsMapMemory ( 542 ACPI_PHYSICAL_ADDRESS Where, 543 ACPI_SIZE Length) 544 { 545 546 return (ACPI_TO_POINTER ((ACPI_SIZE) Where)); 547 } 548 549 550 /****************************************************************************** 551 * 552 * FUNCTION: AcpiOsUnmapMemory 553 * 554 * PARAMETERS: Where - Logical address of memory to be unmapped 555 * Length - How much memory to unmap 556 * 557 * RETURN: None. 558 * 559 * DESCRIPTION: Delete a previously created mapping. Where and Length must 560 * correspond to a previous mapping exactly. 561 * 562 *****************************************************************************/ 563 564 void 565 AcpiOsUnmapMemory ( 566 void *Where, 567 ACPI_SIZE Length) 568 { 569 570 return; 571 } 572 #endif 573