1 /****************************************************************************** 2 * 3 * Module Name: oswintbl - Windows OSL for obtaining ACPI tables 4 * 5 *****************************************************************************/ 6 7 /* 8 * Copyright (C) 2000 - 2016, 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 "acpi.h" 45 #include "accommon.h" 46 #include "acutils.h" 47 #include <stdio.h> 48 49 #ifdef WIN32 50 #pragma warning(disable:4115) /* warning C4115: (caused by rpcasync.h) */ 51 #include <windows.h> 52 53 #elif WIN64 54 #include <windowsx.h> 55 #endif 56 57 #define _COMPONENT ACPI_OS_SERVICES 58 ACPI_MODULE_NAME ("oswintbl") 59 60 /* Local prototypes */ 61 62 static char * 63 WindowsFormatException ( 64 LONG WinStatus); 65 66 /* Globals */ 67 68 #define LOCAL_BUFFER_SIZE 64 69 70 static char KeyBuffer[LOCAL_BUFFER_SIZE]; 71 static char ErrorBuffer[LOCAL_BUFFER_SIZE]; 72 73 /* 74 * Tables supported in the Windows registry. SSDTs are not placed into 75 * the registry, a limitation. 76 */ 77 static char *SupportedTables[] = 78 { 79 "DSDT", 80 "RSDT", 81 "FACS", 82 "FACP" 83 }; 84 85 /* Max index for table above */ 86 87 #define ACPI_OS_MAX_TABLE_INDEX 3 88 89 90 /****************************************************************************** 91 * 92 * FUNCTION: WindowsFormatException 93 * 94 * PARAMETERS: WinStatus - Status from a Windows system call 95 * 96 * RETURN: Formatted (ascii) exception code. Front-end to Windows 97 * FormatMessage interface. 98 * 99 * DESCRIPTION: Decode a windows exception 100 * 101 *****************************************************************************/ 102 103 static char * 104 WindowsFormatException ( 105 LONG WinStatus) 106 { 107 108 ErrorBuffer[0] = 0; 109 FormatMessage (FORMAT_MESSAGE_FROM_SYSTEM, NULL, WinStatus, 0, 110 ErrorBuffer, LOCAL_BUFFER_SIZE, NULL); 111 112 return (ErrorBuffer); 113 } 114 115 116 /****************************************************************************** 117 * 118 * FUNCTION: AcpiOsGetTableByAddress 119 * 120 * PARAMETERS: Address - Physical address of the ACPI table 121 * Table - Where a pointer to the table is returned 122 * 123 * RETURN: Status; Table buffer is returned if AE_OK. 124 * AE_NOT_FOUND: A valid table was not found at the address 125 * 126 * DESCRIPTION: Get an ACPI table via a physical memory address. 127 * 128 * NOTE: Cannot be implemented without a Windows device driver. 129 * 130 *****************************************************************************/ 131 132 ACPI_STATUS 133 AcpiOsGetTableByAddress ( 134 ACPI_PHYSICAL_ADDRESS Address, 135 ACPI_TABLE_HEADER **Table) 136 { 137 138 fprintf (stderr, "Get table by address is not supported on Windows\n"); 139 return (AE_SUPPORT); 140 } 141 142 143 /****************************************************************************** 144 * 145 * FUNCTION: AcpiOsGetTableByIndex 146 * 147 * PARAMETERS: Index - Which table to get 148 * Table - Where a pointer to the table is returned 149 * Instance - Where a pointer to the table instance no. is 150 * returned 151 * Address - Where the table physical address is returned 152 * 153 * RETURN: Status; Table buffer and physical address returned if AE_OK. 154 * AE_LIMIT: Index is beyond valid limit 155 * 156 * DESCRIPTION: Get an ACPI table via an index value (0 through n). Returns 157 * AE_LIMIT when an invalid index is reached. Index is not 158 * necessarily an index into the RSDT/XSDT. 159 * Table is obtained from the Windows registry. 160 * 161 * NOTE: Cannot get the physical address from the windows registry; 162 * zero is returned instead. 163 * 164 *****************************************************************************/ 165 166 ACPI_STATUS 167 AcpiOsGetTableByIndex ( 168 UINT32 Index, 169 ACPI_TABLE_HEADER **Table, 170 UINT32 *Instance, 171 ACPI_PHYSICAL_ADDRESS *Address) 172 { 173 ACPI_STATUS Status; 174 175 176 if (Index > ACPI_OS_MAX_TABLE_INDEX) 177 { 178 return (AE_LIMIT); 179 } 180 181 Status = AcpiOsGetTableByName (SupportedTables[Index], 0, Table, Address); 182 return (Status); 183 } 184 185 186 /****************************************************************************** 187 * 188 * FUNCTION: AcpiOsGetTableByName 189 * 190 * PARAMETERS: Signature - ACPI Signature for desired table. Must be 191 * a null terminated 4-character string. 192 * Instance - For SSDTs (0...n). Use 0 otherwise. 193 * Table - Where a pointer to the table is returned 194 * Address - Where the table physical address is returned 195 * 196 * RETURN: Status; Table buffer and physical address returned if AE_OK. 197 * AE_LIMIT: Instance is beyond valid limit 198 * AE_NOT_FOUND: A table with the signature was not found 199 * 200 * DESCRIPTION: Get an ACPI table via a table signature (4 ASCII characters). 201 * Returns AE_LIMIT when an invalid instance is reached. 202 * Table is obtained from the Windows registry. 203 * 204 * NOTE: Assumes the input signature is uppercase. 205 * Cannot get the physical address from the windows registry; 206 * zero is returned instead. 207 * 208 *****************************************************************************/ 209 210 ACPI_STATUS 211 AcpiOsGetTableByName ( 212 char *Signature, 213 UINT32 Instance, 214 ACPI_TABLE_HEADER **Table, 215 ACPI_PHYSICAL_ADDRESS *Address) 216 { 217 HKEY Handle = NULL; 218 LONG WinStatus; 219 ULONG Type; 220 ULONG NameSize; 221 ULONG DataSize; 222 HKEY SubKey; 223 ULONG i; 224 ACPI_TABLE_HEADER *ReturnTable; 225 ACPI_STATUS Status = AE_OK; 226 227 228 /* 229 * Windows has no SSDTs in the registry, so multiple instances are 230 * not supported. 231 */ 232 if (Instance > 0) 233 { 234 return (AE_LIMIT); 235 } 236 237 /* Get a handle to the table key */ 238 239 while (1) 240 { 241 strcpy (KeyBuffer, "HARDWARE\\ACPI\\"); 242 if (AcpiUtSafeStrcat (KeyBuffer, sizeof (KeyBuffer), Signature)) 243 { 244 return (AE_BUFFER_OVERFLOW); 245 } 246 247 WinStatus = RegOpenKeyEx (HKEY_LOCAL_MACHINE, KeyBuffer, 248 0L, KEY_READ, &Handle); 249 250 if (WinStatus != ERROR_SUCCESS) 251 { 252 /* 253 * Somewhere along the way, MS changed the registry entry for 254 * the FADT from 255 * HARDWARE/ACPI/FACP to 256 * HARDWARE/ACPI/FADT. 257 * 258 * This code allows for both. 259 */ 260 if (ACPI_COMPARE_NAME (Signature, "FACP")) 261 { 262 Signature = "FADT"; 263 } 264 else if (ACPI_COMPARE_NAME (Signature, "XSDT")) 265 { 266 Signature = "RSDT"; 267 } 268 else 269 { 270 fprintf (stderr, 271 "Could not find %s in registry at %s: %s (WinStatus=0x%X)\n", 272 Signature, KeyBuffer, WindowsFormatException (WinStatus), WinStatus); 273 return (AE_NOT_FOUND); 274 } 275 } 276 else 277 { 278 break; 279 } 280 } 281 282 /* Actual data for the table is down a couple levels */ 283 284 for (i = 0; ;) 285 { 286 WinStatus = RegEnumKey (Handle, i, KeyBuffer, sizeof (KeyBuffer)); 287 i++; 288 if (WinStatus == ERROR_NO_MORE_ITEMS) 289 { 290 break; 291 } 292 293 WinStatus = RegOpenKey (Handle, KeyBuffer, &SubKey); 294 if (WinStatus != ERROR_SUCCESS) 295 { 296 fprintf (stderr, "Could not open %s entry: %s\n", 297 Signature, WindowsFormatException (WinStatus)); 298 Status = AE_ERROR; 299 goto Cleanup; 300 } 301 302 RegCloseKey (Handle); 303 Handle = SubKey; 304 i = 0; 305 } 306 307 /* Find the (binary) table entry */ 308 309 for (i = 0; ; i++) 310 { 311 NameSize = sizeof (KeyBuffer); 312 WinStatus = RegEnumValue (Handle, i, KeyBuffer, &NameSize, NULL, 313 &Type, NULL, 0); 314 if (WinStatus != ERROR_SUCCESS) 315 { 316 fprintf (stderr, "Could not get %s registry entry: %s\n", 317 Signature, WindowsFormatException (WinStatus)); 318 Status = AE_ERROR; 319 goto Cleanup; 320 } 321 322 if (Type == REG_BINARY) 323 { 324 break; 325 } 326 } 327 328 /* Get the size of the table */ 329 330 WinStatus = RegQueryValueEx (Handle, KeyBuffer, NULL, NULL, 331 NULL, &DataSize); 332 if (WinStatus != ERROR_SUCCESS) 333 { 334 fprintf (stderr, "Could not read the %s table size: %s\n", 335 Signature, WindowsFormatException (WinStatus)); 336 Status = AE_ERROR; 337 goto Cleanup; 338 } 339 340 /* Allocate a new buffer for the table */ 341 342 ReturnTable = malloc (DataSize); 343 if (!ReturnTable) 344 { 345 Status = AE_NO_MEMORY; 346 goto Cleanup; 347 } 348 349 /* Get the actual table from the registry */ 350 351 WinStatus = RegQueryValueEx (Handle, KeyBuffer, NULL, NULL, 352 (UCHAR *) ReturnTable, &DataSize); 353 if (WinStatus != ERROR_SUCCESS) 354 { 355 fprintf (stderr, "Could not read %s data: %s\n", 356 Signature, WindowsFormatException (WinStatus)); 357 free (ReturnTable); 358 Status = AE_ERROR; 359 goto Cleanup; 360 } 361 362 *Table = ReturnTable; 363 *Address = 0; 364 365 Cleanup: 366 RegCloseKey (Handle); 367 return (Status); 368 } 369 370 371 /* These are here for acpidump only, so we don't need to link oswinxf */ 372 373 #ifdef ACPI_DUMP_APP 374 /****************************************************************************** 375 * 376 * FUNCTION: AcpiOsMapMemory 377 * 378 * PARAMETERS: Where - Physical address of memory to be mapped 379 * Length - How much memory to map 380 * 381 * RETURN: Pointer to mapped memory. Null on error. 382 * 383 * DESCRIPTION: Map physical memory into caller's address space 384 * 385 *****************************************************************************/ 386 387 void * 388 AcpiOsMapMemory ( 389 ACPI_PHYSICAL_ADDRESS Where, 390 ACPI_SIZE Length) 391 { 392 393 return (ACPI_TO_POINTER ((ACPI_SIZE) Where)); 394 } 395 396 397 /****************************************************************************** 398 * 399 * FUNCTION: AcpiOsUnmapMemory 400 * 401 * PARAMETERS: Where - Logical address of memory to be unmapped 402 * Length - How much memory to unmap 403 * 404 * RETURN: None. 405 * 406 * DESCRIPTION: Delete a previously created mapping. Where and Length must 407 * correspond to a previous mapping exactly. 408 * 409 *****************************************************************************/ 410 411 void 412 AcpiOsUnmapMemory ( 413 void *Where, 414 ACPI_SIZE Length) 415 { 416 417 return; 418 } 419 #endif 420