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 - 2021, 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  * List of table signatures reported by EnumSystemFirmwareTables ()
183  */
184 UINT32                  *Gbl_AvailableTableSignatures;
185 UINT32                  Gbl_TableCount = 0;
186 UINT32                  Gbl_SsdtInstance = 0;
187 
188 BOOLEAN                 Gbl_TableListInitialized = FALSE;
189 
190 static ACPI_STATUS
191 OslTableInitialize (
192     void);
193 
194 
195 /******************************************************************************
196  *
197  * FUNCTION:    WindowsFormatException
198  *
199  * PARAMETERS:  WinStatus       - Status from a Windows system call
200  *
201  * RETURN:      Formatted (ascii) exception code. Front-end to Windows
202  *              FormatMessage interface.
203  *
204  * DESCRIPTION: Decode a windows exception
205  *
206  *****************************************************************************/
207 
208 static char *
209 WindowsFormatException (
210     LONG                WinStatus)
211 {
212 
213     ErrorBuffer[0] = 0;
214     FormatMessage (FORMAT_MESSAGE_FROM_SYSTEM, NULL, WinStatus, 0,
215         ErrorBuffer, LOCAL_BUFFER_SIZE, NULL);
216 
217     return (ErrorBuffer);
218 }
219 
220 
221 /******************************************************************************
222  *
223  * FUNCTION:    AcpiOsGetTableByAddress
224  *
225  * PARAMETERS:  Address         - Physical address of the ACPI table
226  *              Table           - Where a pointer to the table is returned
227  *
228  * RETURN:      Status; Table buffer is returned if AE_OK.
229  *              AE_NOT_FOUND: A valid table was not found at the address
230  *
231  * DESCRIPTION: Get an ACPI table via a physical memory address.
232  *
233  * NOTE:        Cannot be implemented without a Windows device driver.
234  *
235  *****************************************************************************/
236 
237 ACPI_STATUS
238 AcpiOsGetTableByAddress (
239     ACPI_PHYSICAL_ADDRESS   Address,
240     ACPI_TABLE_HEADER       **Table)
241 {
242 
243     fprintf (stderr, "Get table by address is not supported on Windows\n");
244     return (AE_SUPPORT);
245 }
246 
247 
248 /******************************************************************************
249  *
250  * FUNCTION:    AcpiOsGetTableByIndex
251  *
252  * PARAMETERS:  Index           - Which table to get
253  *              Table           - Where a pointer to the table is returned
254  *              Instance        - Where a pointer to the table instance no. is
255  *                                returned
256  *              Address         - Where the table physical address is returned
257  *
258  * RETURN:      Status; Table buffer and physical address returned if AE_OK.
259  *              AE_LIMIT: Index is beyond valid limit
260  *
261  * DESCRIPTION: Get an ACPI table via an index value (0 through n). Returns
262  *              AE_LIMIT when an invalid index is reached. Index is not
263  *              necessarily an index into the RSDT/XSDT.
264  *              SSDT tables are obtained from the Windows registry. All other
265  *              tables are obtained through GetSystemFirmwareTable ().
266  *
267  * NOTE:        Cannot get the physical address from the windows registry;
268  *              zero is returned instead.
269  *
270  *****************************************************************************/
271 
272 ACPI_STATUS
273 AcpiOsGetTableByIndex (
274     UINT32                  Index,
275     ACPI_TABLE_HEADER       **Table,
276     UINT32                  *Instance,
277     ACPI_PHYSICAL_ADDRESS   *Address)
278 {
279     ACPI_STATUS             Status;
280     char                    *Signature;
281     UINT32                  CurrentInstance;
282 
283 
284     /* Enumerate all ACPI table signatures on first invocation of this function */
285 
286     Status = OslTableInitialize ();
287     if (ACPI_FAILURE (Status))
288     {
289         return (Status);
290     }
291 
292     /* Validate Index */
293 
294     if (Index < Gbl_TableCount)
295     {
296         Signature = malloc (ACPI_NAMESEG_SIZE + 1);
297         if (!Signature)
298         {
299             return (AE_NO_MEMORY);
300         }
301 
302         Signature = memmove (Signature, &Gbl_AvailableTableSignatures[Index], ACPI_NAMESEG_SIZE);
303     }
304     else
305     {
306         return (AE_LIMIT);
307     }
308 
309     if (ACPI_COMPARE_NAMESEG (Signature, ACPI_SIG_SSDT))
310     {
311         CurrentInstance = Gbl_SsdtInstance;
312         Gbl_SsdtInstance++;
313     }
314     else
315     {
316         CurrentInstance = 0;
317     }
318 
319     Status = AcpiOsGetTableByName (Signature, CurrentInstance, Table, Address);
320     if (ACPI_SUCCESS (Status))
321     {
322         *Instance = CurrentInstance;
323     }
324     else if (Status == AE_NOT_FOUND &&
325         ACPI_COMPARE_NAMESEG (Signature, ACPI_SIG_SSDT))
326     {
327         /* Treat SSDTs that are not found as invalid index. */
328         Status = AE_LIMIT;
329     }
330 
331     free (Signature);
332     return (Status);
333 }
334 
335 /******************************************************************************
336  *
337  * FUNCTION:    OslTableInitialize
338  *
339  * PARAMETERS:  None
340  *
341  * RETURN:      Status
342  *
343  * DESCRIPTION: Initialize ACPI table data. Enumerate all ACPI table signatures
344  *              and save them to a global list.
345  *
346  *****************************************************************************/
347 static ACPI_STATUS
348 OslTableInitialize (
349     void)
350 {
351     UINT32                  ResultSize;
352     UINT32                  DataSize;
353 
354     if (Gbl_TableListInitialized)
355     {
356         return (AE_OK);
357     }
358 
359     /*
360      * ACPI table signatures are always 4 characters. Therefore, the data size
361      * buffer should be a multiple of 4
362      */
363     DataSize = EnumSystemFirmwareTables ('ACPI', NULL, 0);
364     if (DataSize % ACPI_NAMESEG_SIZE)
365     {
366         return (AE_ERROR);
367     }
368 
369     /*
370      * EnumSystemFirmwareTables () does not report the DSDT or XSDT. Work around this
371      * by adding these entries manually.
372      */
373     Gbl_TableCount = 2 + DataSize / ACPI_NAMESEG_SIZE;
374     Gbl_AvailableTableSignatures = malloc (Gbl_TableCount * ACPI_NAMESEG_SIZE);
375     if (!Gbl_AvailableTableSignatures)
376     {
377         return (AE_NO_MEMORY);
378     }
379 
380     ResultSize = EnumSystemFirmwareTables ('ACPI', Gbl_AvailableTableSignatures, DataSize);
381     if (ResultSize > DataSize)
382     {
383         return (AE_ERROR);
384     }
385 
386     /* Insert the DSDT and XSDT tables signatures */
387 
388     Gbl_AvailableTableSignatures [Gbl_TableCount - 1] = 'TDSD';
389     Gbl_AvailableTableSignatures [Gbl_TableCount - 2] = 'TDSX';
390 
391     Gbl_TableListInitialized = TRUE;
392     return (AE_OK);
393 }
394 
395 
396 /******************************************************************************
397  *
398  * FUNCTION:    WindowsGetTableFromRegistry
399  *
400  * PARAMETERS:  Signature       - ACPI Signature for desired table. Must be
401  *                                a null terminated 4-character string.
402  *              Instance        - For SSDTs (0...n). Use 0 otherwise.
403  *              Table           - Where a pointer to the table is returned
404  *              Address         - Where the table physical address is returned
405  *
406  * RETURN:      Status; Table buffer and physical address returned if AE_OK.
407  *              AE_LIMIT: Instance is beyond valid limit
408  *              AE_NOT_FOUND: A table with the signature was not found
409  *
410  * DESCRIPTION: Get an ACPI table via a table signature (4 ASCII characters).
411  *              Returns AE_LIMIT when an invalid instance is reached.
412  *              Table is obtained from the Windows registry.
413  *
414  * NOTE:        Assumes the input signature is uppercase.
415  *              Cannot get the physical address from the windows registry;
416  *              zero is returned instead.
417  *
418  *****************************************************************************/
419 
420 static ACPI_STATUS
421 WindowsGetTableFromRegistry (
422     char                    *Signature,
423     UINT32                  Instance,
424     ACPI_TABLE_HEADER       **Table,
425     ACPI_PHYSICAL_ADDRESS   *Address)
426 {
427     HKEY                    Handle = NULL;
428     LONG                    WinStatus;
429     ULONG                   Type;
430     ULONG                   NameSize;
431     ULONG                   DataSize;
432     HKEY                    SubKey;
433     ULONG                   i;
434     ACPI_TABLE_HEADER       *ReturnTable;
435     ACPI_STATUS             Status = AE_OK;
436 
437 
438     /* Get a handle to the table key */
439 
440     while (1)
441     {
442         strcpy(KeyBuffer, "HARDWARE\\ACPI\\");
443         if (AcpiUtSafeStrcat(KeyBuffer, sizeof(KeyBuffer), Signature))
444         {
445             return (AE_BUFFER_OVERFLOW);
446         }
447 
448         /*
449          * Windows stores SSDT at SSDT, SSD1, ..., SSD9, SSDA, ..., SSDS, SSDT,
450          * SSDU, ..., SSDY. If the first (0th) and the 29th tables have the same
451          * OEM ID, Table ID and Revision, then the 29th entry will overwrite the
452          * first entry... Let's hope that we do not have that many entries.
453          */
454         if (Instance > 0 && ACPI_COMPARE_NAMESEG(Signature, ACPI_SIG_SSDT))
455         {
456             if (Instance < 10)
457             {
458                 KeyBuffer[strlen(KeyBuffer) - 1] = '0' + (char)Instance;
459             }
460             else if (Instance < 29)
461             {
462                 KeyBuffer[strlen(KeyBuffer) - 1] = 'A' + (char)(Instance - 10);
463             }
464             else
465             {
466                 return (AE_LIMIT);
467             }
468         }
469 
470         WinStatus = RegOpenKeyEx(HKEY_LOCAL_MACHINE, KeyBuffer,
471             0L, KEY_READ, &Handle);
472 
473         if (WinStatus != ERROR_SUCCESS)
474         {
475             /*
476              * Somewhere along the way, MS changed the registry entry for
477              * the FADT from
478              * HARDWARE/ACPI/FACP  to
479              * HARDWARE/ACPI/FADT.
480              *
481              * This code allows for both.
482              */
483             if (ACPI_COMPARE_NAMESEG(Signature, "FACP"))
484             {
485                 Signature = "FADT";
486             }
487             else if (ACPI_COMPARE_NAMESEG(Signature, "XSDT"))
488             {
489                 Signature = "RSDT";
490             }
491             else if (ACPI_COMPARE_NAMESEG(Signature, ACPI_SIG_SSDT))
492             {
493                 /*
494                  * SSDT may not be present on older Windows versions, but it is
495                  * also possible that the index is not found.
496                  */
497                 return (AE_NOT_FOUND);
498             }
499             else
500             {
501                 fprintf(stderr,
502                     "Could not find %s in registry at %s: %s (WinStatus=0x%X)\n",
503                     Signature, KeyBuffer, WindowsFormatException(WinStatus), WinStatus);
504                 return (AE_NOT_FOUND);
505             }
506         }
507         else
508         {
509             break;
510         }
511     }
512 
513     /* Actual data for the table is down a couple levels */
514 
515     for (i = 0; ;)
516     {
517         WinStatus = RegEnumKey(Handle, i, KeyBuffer, sizeof(KeyBuffer));
518         i++;
519         if (WinStatus == ERROR_NO_MORE_ITEMS)
520         {
521             break;
522         }
523 
524         WinStatus = RegOpenKey(Handle, KeyBuffer, &SubKey);
525         if (WinStatus != ERROR_SUCCESS)
526         {
527             fprintf(stderr, "Could not open %s entry: %s\n",
528                 Signature, WindowsFormatException(WinStatus));
529             Status = AE_ERROR;
530             goto Cleanup;
531         }
532 
533         RegCloseKey(Handle);
534         Handle = SubKey;
535         i = 0;
536     }
537 
538     /* Find the (binary) table entry */
539 
540     for (i = 0; ; i++)
541     {
542         NameSize = sizeof(KeyBuffer);
543         WinStatus = RegEnumValue(Handle, i, KeyBuffer, &NameSize, NULL,
544             &Type, NULL, 0);
545         if (WinStatus != ERROR_SUCCESS)
546         {
547             fprintf(stderr, "Could not get %s registry entry: %s\n",
548                 Signature, WindowsFormatException(WinStatus));
549             Status = AE_ERROR;
550             goto Cleanup;
551         }
552 
553         if (Type == REG_BINARY)
554         {
555             break;
556         }
557     }
558 
559     /* Get the size of the table */
560 
561     WinStatus = RegQueryValueEx(Handle, KeyBuffer, NULL, NULL,
562         NULL, &DataSize);
563     if (WinStatus != ERROR_SUCCESS)
564     {
565         fprintf(stderr, "Could not read the %s table size: %s\n",
566             Signature, WindowsFormatException(WinStatus));
567         Status = AE_ERROR;
568         goto Cleanup;
569     }
570 
571     /* Allocate a new buffer for the table */
572 
573     ReturnTable = malloc(DataSize);
574     if (!ReturnTable)
575     {
576         Status = AE_NO_MEMORY;
577         goto Cleanup;
578     }
579 
580     /* Get the actual table from the registry */
581 
582     WinStatus = RegQueryValueEx(Handle, KeyBuffer, NULL, NULL,
583         (UCHAR *)ReturnTable, &DataSize);
584 
585     if (WinStatus != ERROR_SUCCESS)
586     {
587         fprintf(stderr, "Could not read %s data: %s\n",
588             Signature, WindowsFormatException(WinStatus));
589         free(ReturnTable);
590         Status = AE_ERROR;
591         goto Cleanup;
592     }
593 
594     *Table = ReturnTable;
595     *Address = 0;
596 
597 Cleanup:
598     RegCloseKey(Handle);
599     return (Status);
600 }
601 
602 
603 /******************************************************************************
604  *
605  * FUNCTION:    AcpiOsGetTableByName
606  *
607  * PARAMETERS:  Signature       - ACPI Signature for desired table. Must be
608  *                                a null terminated 4-character string.
609  *              Instance        - For SSDTs (0...n). Use 0 otherwise.
610  *              Table           - Where a pointer to the table is returned
611  *              Address         - Where the table physical address is returned
612  *
613  * RETURN:      Status; Table buffer and physical address returned if AE_OK.
614  *              AE_LIMIT: Instance is beyond valid limit
615  *              AE_NOT_FOUND: A table with the signature was not found
616  *
617  * DESCRIPTION: Get an ACPI table via a table signature (4 ASCII characters).
618  *              Returns AE_LIMIT when an invalid instance is reached.
619  *              Table is obtained from the Windows registry.
620  *
621  * NOTE:        Assumes the input signature is uppercase.
622  *              Cannot get the physical address from the windows registry;
623  *              zero is returned instead.
624  *
625  *****************************************************************************/
626 
627 ACPI_STATUS
628 AcpiOsGetTableByName(
629     char                    *Signature,
630     UINT32                  Instance,
631     ACPI_TABLE_HEADER       **Table,
632     ACPI_PHYSICAL_ADDRESS   *Address)
633 {
634     LONG                    Result;
635     ACPI_STATUS             Status = AE_OK;
636     UINT32                  DataSize;
637     ACPI_TABLE_HEADER       *ReturnTable;
638     UINT32                  UIntSignature = 0;
639 
640 
641     /* Multiple instances are only supported for SSDT tables. */
642 
643     if (Instance > 0 && !ACPI_COMPARE_NAMESEG (Signature, ACPI_SIG_SSDT))
644     {
645         return (AE_LIMIT);
646     }
647 
648     if (ACPI_COMPARE_NAMESEG (Signature, ACPI_SIG_SSDT))
649     {
650         Status = WindowsGetTableFromRegistry ("SSDT", Instance, Table, Address);
651         return (Status);
652     }
653 
654     /* GetSystemFirmwareTable requires the table signature to be UINT32 */
655 
656     UIntSignature = *ACPI_CAST_PTR (UINT32, Signature);
657     DataSize = GetSystemFirmwareTable('ACPI', UIntSignature, NULL, 0);
658     if (!DataSize)
659     {
660         fprintf(stderr, "The table signature %s does not exist.", Signature);
661         return (AE_ERROR);
662     }
663 
664     ReturnTable = malloc(DataSize);
665     if (!ReturnTable)
666     {
667         return (AE_NO_MEMORY);
668     }
669 
670     Result = GetSystemFirmwareTable('ACPI', UIntSignature, ReturnTable, DataSize);
671     if (Result > (LONG) DataSize)
672     {
673         /* Clean up */
674 
675         fprintf (stderr, "Could not read %s data\n", Signature);
676         free (ReturnTable);
677         return (AE_ERROR);
678     }
679 
680     *Table = ReturnTable;
681     return (Status);
682 }
683 
684 
685 /* These are here for acpidump only, so we don't need to link oswinxf */
686 
687 #ifdef ACPI_DUMP_APP
688 /******************************************************************************
689  *
690  * FUNCTION:    AcpiOsMapMemory
691  *
692  * PARAMETERS:  Where               - Physical address of memory to be mapped
693  *              Length              - How much memory to map
694  *
695  * RETURN:      Pointer to mapped memory. Null on error.
696  *
697  * DESCRIPTION: Map physical memory into caller's address space
698  *
699  *****************************************************************************/
700 
701 void *
702 AcpiOsMapMemory (
703     ACPI_PHYSICAL_ADDRESS   Where,
704     ACPI_SIZE               Length)
705 {
706 
707     return (ACPI_TO_POINTER ((ACPI_SIZE) Where));
708 }
709 
710 
711 /******************************************************************************
712  *
713  * FUNCTION:    AcpiOsUnmapMemory
714  *
715  * PARAMETERS:  Where               - Logical address of memory to be unmapped
716  *              Length              - How much memory to unmap
717  *
718  * RETURN:      None.
719  *
720  * DESCRIPTION: Delete a previously created mapping. Where and Length must
721  *              correspond to a previous mapping exactly.
722  *
723  *****************************************************************************/
724 
725 void
726 AcpiOsUnmapMemory (
727     void                    *Where,
728     ACPI_SIZE               Length)
729 {
730 
731     return;
732 }
733 #endif
734