1 /****************************************************************************** 2 * 3 * Module Name: oswintbl - Windows OSL for obtaining ACPI tables 4 * 5 *****************************************************************************/ 6 7 /* 8 * Copyright (C) 2000 - 2013, 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 226 227 /* 228 * Windows has no SSDTs in the registry, so multiple instances are 229 * not supported. 230 */ 231 if (Instance > 0) 232 { 233 return (AE_LIMIT); 234 } 235 236 /* Get a handle to the table key */ 237 238 while (1) 239 { 240 ACPI_STRCPY (KeyBuffer, "HARDWARE\\ACPI\\"); 241 if (AcpiUtSafeStrcat (KeyBuffer, sizeof (KeyBuffer), Signature)) 242 { 243 return (AE_BUFFER_OVERFLOW); 244 } 245 246 WinStatus = RegOpenKeyEx (HKEY_LOCAL_MACHINE, KeyBuffer, 247 0L, KEY_READ, &Handle); 248 249 if (WinStatus != ERROR_SUCCESS) 250 { 251 /* 252 * Somewhere along the way, MS changed the registry entry for 253 * the FADT from 254 * HARDWARE/ACPI/FACP to 255 * HARDWARE/ACPI/FADT. 256 * 257 * This code allows for both. 258 */ 259 if (ACPI_COMPARE_NAME (Signature, "FACP")) 260 { 261 Signature = "FADT"; 262 } 263 else if (ACPI_COMPARE_NAME (Signature, "XSDT")) 264 { 265 Signature = "RSDT"; 266 } 267 else 268 { 269 fprintf (stderr, 270 "Could not find %s in registry at %s: %s (WinStatus=0x%X)\n", 271 Signature, KeyBuffer, WindowsFormatException (WinStatus), WinStatus); 272 return (AE_NOT_FOUND); 273 } 274 } 275 else 276 { 277 break; 278 } 279 } 280 281 /* Actual data for the table is down a couple levels */ 282 283 for (i = 0; ;) 284 { 285 WinStatus = RegEnumKey (Handle, i, KeyBuffer, sizeof (KeyBuffer)); 286 i++; 287 if (WinStatus == ERROR_NO_MORE_ITEMS) 288 { 289 break; 290 } 291 292 WinStatus = RegOpenKey (Handle, KeyBuffer, &SubKey); 293 if (WinStatus != ERROR_SUCCESS) 294 { 295 fprintf (stderr, "Could not open %s entry: %s\n", 296 Signature, WindowsFormatException (WinStatus)); 297 return (AE_ERROR); 298 } 299 300 RegCloseKey (Handle); 301 Handle = SubKey; 302 i = 0; 303 } 304 305 /* Find the (binary) table entry */ 306 307 for (i = 0; ; i++) 308 { 309 NameSize = sizeof (KeyBuffer); 310 WinStatus = RegEnumValue (Handle, i, KeyBuffer, &NameSize, NULL, 311 &Type, NULL, 0); 312 if (WinStatus != ERROR_SUCCESS) 313 { 314 fprintf (stderr, "Could not get %s registry entry: %s\n", 315 Signature, WindowsFormatException (WinStatus)); 316 return (AE_ERROR); 317 } 318 319 if (Type == REG_BINARY) 320 { 321 break; 322 } 323 } 324 325 /* Get the size of the table */ 326 327 WinStatus = RegQueryValueEx (Handle, KeyBuffer, NULL, NULL, 328 NULL, &DataSize); 329 if (WinStatus != ERROR_SUCCESS) 330 { 331 fprintf (stderr, "Could not read the %s table size: %s\n", 332 Signature, WindowsFormatException (WinStatus)); 333 return (AE_ERROR); 334 } 335 336 /* Allocate a new buffer for the table */ 337 338 ReturnTable = malloc (DataSize); 339 if (!ReturnTable) 340 { 341 goto Cleanup; 342 } 343 344 /* Get the actual table from the registry */ 345 346 WinStatus = RegQueryValueEx (Handle, KeyBuffer, NULL, NULL, 347 (UCHAR *) ReturnTable, &DataSize); 348 if (WinStatus != ERROR_SUCCESS) 349 { 350 fprintf (stderr, "Could not read %s data: %s\n", 351 Signature, WindowsFormatException (WinStatus)); 352 free (ReturnTable); 353 return (AE_ERROR); 354 } 355 356 Cleanup: 357 RegCloseKey (Handle); 358 359 *Table = ReturnTable; 360 *Address = 0; 361 return (AE_OK); 362 } 363 364 365 /* These are here for acpidump only, so we don't need to link oswinxf */ 366 367 #ifdef ACPI_DUMP_APP 368 /****************************************************************************** 369 * 370 * FUNCTION: AcpiOsMapMemory 371 * 372 * PARAMETERS: Where - Physical address of memory to be mapped 373 * Length - How much memory to map 374 * 375 * RETURN: Pointer to mapped memory. Null on error. 376 * 377 * DESCRIPTION: Map physical memory into caller's address space 378 * 379 *****************************************************************************/ 380 381 void * 382 AcpiOsMapMemory ( 383 ACPI_PHYSICAL_ADDRESS Where, 384 ACPI_SIZE Length) 385 { 386 387 return (ACPI_TO_POINTER ((ACPI_SIZE) Where)); 388 } 389 390 391 /****************************************************************************** 392 * 393 * FUNCTION: AcpiOsUnmapMemory 394 * 395 * PARAMETERS: Where - Logical address of memory to be unmapped 396 * Length - How much memory to unmap 397 * 398 * RETURN: None. 399 * 400 * DESCRIPTION: Delete a previously created mapping. Where and Length must 401 * correspond to a previous mapping exactly. 402 * 403 *****************************************************************************/ 404 405 void 406 AcpiOsUnmapMemory ( 407 void *Where, 408 ACPI_SIZE Length) 409 { 410 411 return; 412 } 413 #endif