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 - 2017, 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 && ACPI_COMPARE_NAME (Signature, ACPI_SIG_SSDT)) 303 { 304 /* Treat SSDTs that are not found as invalid index. */ 305 Status = (AE_LIMIT); 306 } 307 308 return (Status); 309 } 310 311 312 /****************************************************************************** 313 * 314 * FUNCTION: AcpiOsGetTableByName 315 * 316 * PARAMETERS: Signature - ACPI Signature for desired table. Must be 317 * a null terminated 4-character string. 318 * Instance - For SSDTs (0...n). Use 0 otherwise. 319 * Table - Where a pointer to the table is returned 320 * Address - Where the table physical address is returned 321 * 322 * RETURN: Status; Table buffer and physical address returned if AE_OK. 323 * AE_LIMIT: Instance is beyond valid limit 324 * AE_NOT_FOUND: A table with the signature was not found 325 * 326 * DESCRIPTION: Get an ACPI table via a table signature (4 ASCII characters). 327 * Returns AE_LIMIT when an invalid instance is reached. 328 * Table is obtained from the Windows registry. 329 * 330 * NOTE: Assumes the input signature is uppercase. 331 * Cannot get the physical address from the windows registry; 332 * zero is returned instead. 333 * 334 *****************************************************************************/ 335 336 ACPI_STATUS 337 AcpiOsGetTableByName ( 338 char *Signature, 339 UINT32 Instance, 340 ACPI_TABLE_HEADER **Table, 341 ACPI_PHYSICAL_ADDRESS *Address) 342 { 343 HKEY Handle = NULL; 344 LONG WinStatus; 345 ULONG Type; 346 ULONG NameSize; 347 ULONG DataSize; 348 HKEY SubKey; 349 ULONG i; 350 ACPI_TABLE_HEADER *ReturnTable; 351 ACPI_STATUS Status = AE_OK; 352 353 354 /* Multiple instances are only supported for SSDT tables. */ 355 356 if (Instance > 0 && !ACPI_COMPARE_NAME (Signature, ACPI_SIG_SSDT)) 357 { 358 return (AE_LIMIT); 359 } 360 361 /* Get a handle to the table key */ 362 363 while (1) 364 { 365 strcpy (KeyBuffer, "HARDWARE\\ACPI\\"); 366 if (AcpiUtSafeStrcat (KeyBuffer, sizeof (KeyBuffer), Signature)) 367 { 368 return (AE_BUFFER_OVERFLOW); 369 } 370 371 /* 372 * Windows stores SSDT at SSDT, SSD1, ..., SSD9, SSDA, ..., SSDS, SSDT, 373 * SSDU, ..., SSDY. If the first (0th) and the 29th tables have the same 374 * OEM ID, Table ID and Revision, then the 29th entry will overwrite the 375 * first entry... Let's hope that we do not have that many entries. 376 */ 377 if (Instance > 0 && ACPI_COMPARE_NAME (Signature, ACPI_SIG_SSDT)) 378 { 379 if (Instance < 10) 380 { 381 KeyBuffer[strlen (KeyBuffer) - 1] = '0' + (char) Instance; 382 } 383 else if (Instance < 29) 384 { 385 KeyBuffer[strlen (KeyBuffer) - 1] = 'A' + (char) (Instance - 10); 386 } 387 else 388 { 389 return (AE_LIMIT); 390 } 391 } 392 393 WinStatus = RegOpenKeyEx (HKEY_LOCAL_MACHINE, KeyBuffer, 394 0L, KEY_READ, &Handle); 395 396 if (WinStatus != ERROR_SUCCESS) 397 { 398 /* 399 * Somewhere along the way, MS changed the registry entry for 400 * the FADT from 401 * HARDWARE/ACPI/FACP to 402 * HARDWARE/ACPI/FADT. 403 * 404 * This code allows for both. 405 */ 406 if (ACPI_COMPARE_NAME (Signature, "FACP")) 407 { 408 Signature = "FADT"; 409 } 410 else if (ACPI_COMPARE_NAME (Signature, "XSDT")) 411 { 412 Signature = "RSDT"; 413 } 414 else if (ACPI_COMPARE_NAME (Signature, ACPI_SIG_SSDT)) 415 { 416 /* SSDT may not be present on older Windows versions, but it is 417 * also possible that the index is not found. */ 418 return (AE_NOT_FOUND); 419 } 420 else 421 { 422 fprintf (stderr, 423 "Could not find %s in registry at %s: %s (WinStatus=0x%X)\n", 424 Signature, KeyBuffer, WindowsFormatException (WinStatus), WinStatus); 425 return (AE_NOT_FOUND); 426 } 427 } 428 else 429 { 430 break; 431 } 432 } 433 434 /* Actual data for the table is down a couple levels */ 435 436 for (i = 0; ;) 437 { 438 WinStatus = RegEnumKey (Handle, i, KeyBuffer, sizeof (KeyBuffer)); 439 i++; 440 if (WinStatus == ERROR_NO_MORE_ITEMS) 441 { 442 break; 443 } 444 445 WinStatus = RegOpenKey (Handle, KeyBuffer, &SubKey); 446 if (WinStatus != ERROR_SUCCESS) 447 { 448 fprintf (stderr, "Could not open %s entry: %s\n", 449 Signature, WindowsFormatException (WinStatus)); 450 Status = AE_ERROR; 451 goto Cleanup; 452 } 453 454 RegCloseKey (Handle); 455 Handle = SubKey; 456 i = 0; 457 } 458 459 /* Find the (binary) table entry */ 460 461 for (i = 0; ; i++) 462 { 463 NameSize = sizeof (KeyBuffer); 464 WinStatus = RegEnumValue (Handle, i, KeyBuffer, &NameSize, NULL, 465 &Type, NULL, 0); 466 if (WinStatus != ERROR_SUCCESS) 467 { 468 fprintf (stderr, "Could not get %s registry entry: %s\n", 469 Signature, WindowsFormatException (WinStatus)); 470 Status = AE_ERROR; 471 goto Cleanup; 472 } 473 474 if (Type == REG_BINARY) 475 { 476 break; 477 } 478 } 479 480 /* Get the size of the table */ 481 482 WinStatus = RegQueryValueEx (Handle, KeyBuffer, NULL, NULL, 483 NULL, &DataSize); 484 if (WinStatus != ERROR_SUCCESS) 485 { 486 fprintf (stderr, "Could not read the %s table size: %s\n", 487 Signature, WindowsFormatException (WinStatus)); 488 Status = AE_ERROR; 489 goto Cleanup; 490 } 491 492 /* Allocate a new buffer for the table */ 493 494 ReturnTable = malloc (DataSize); 495 if (!ReturnTable) 496 { 497 Status = AE_NO_MEMORY; 498 goto Cleanup; 499 } 500 501 /* Get the actual table from the registry */ 502 503 WinStatus = RegQueryValueEx (Handle, KeyBuffer, NULL, NULL, 504 (UCHAR *) ReturnTable, &DataSize); 505 if (WinStatus != ERROR_SUCCESS) 506 { 507 fprintf (stderr, "Could not read %s data: %s\n", 508 Signature, WindowsFormatException (WinStatus)); 509 free (ReturnTable); 510 Status = AE_ERROR; 511 goto Cleanup; 512 } 513 514 *Table = ReturnTable; 515 *Address = 0; 516 517 Cleanup: 518 RegCloseKey (Handle); 519 return (Status); 520 } 521 522 523 /* These are here for acpidump only, so we don't need to link oswinxf */ 524 525 #ifdef ACPI_DUMP_APP 526 /****************************************************************************** 527 * 528 * FUNCTION: AcpiOsMapMemory 529 * 530 * PARAMETERS: Where - Physical address of memory to be mapped 531 * Length - How much memory to map 532 * 533 * RETURN: Pointer to mapped memory. Null on error. 534 * 535 * DESCRIPTION: Map physical memory into caller's address space 536 * 537 *****************************************************************************/ 538 539 void * 540 AcpiOsMapMemory ( 541 ACPI_PHYSICAL_ADDRESS Where, 542 ACPI_SIZE Length) 543 { 544 545 return (ACPI_TO_POINTER ((ACPI_SIZE) Where)); 546 } 547 548 549 /****************************************************************************** 550 * 551 * FUNCTION: AcpiOsUnmapMemory 552 * 553 * PARAMETERS: Where - Logical address of memory to be unmapped 554 * Length - How much memory to unmap 555 * 556 * RETURN: None. 557 * 558 * DESCRIPTION: Delete a previously created mapping. Where and Length must 559 * correspond to a previous mapping exactly. 560 * 561 *****************************************************************************/ 562 563 void 564 AcpiOsUnmapMemory ( 565 void *Where, 566 ACPI_SIZE Length) 567 { 568 569 return; 570 } 571 #endif 572