xref: /onnv-gate/usr/src/uts/intel/io/acpica/debugger/dbfileio.c (revision 3446:5903aece022d)
1*3446Smrj /*******************************************************************************
2*3446Smrj  *
3*3446Smrj  * Module Name: dbfileio - Debugger file I/O commands.  These can't usually
4*3446Smrj  *              be used when running the debugger in Ring 0 (Kernel mode)
5*3446Smrj  *              $Revision: 1.92 $
6*3446Smrj  *
7*3446Smrj  ******************************************************************************/
8*3446Smrj 
9*3446Smrj /******************************************************************************
10*3446Smrj  *
11*3446Smrj  * 1. Copyright Notice
12*3446Smrj  *
13*3446Smrj  * Some or all of this work - Copyright (c) 1999 - 2006, Intel Corp.
14*3446Smrj  * All rights reserved.
15*3446Smrj  *
16*3446Smrj  * 2. License
17*3446Smrj  *
18*3446Smrj  * 2.1. This is your license from Intel Corp. under its intellectual property
19*3446Smrj  * rights.  You may have additional license terms from the party that provided
20*3446Smrj  * you this software, covering your right to use that party's intellectual
21*3446Smrj  * property rights.
22*3446Smrj  *
23*3446Smrj  * 2.2. Intel grants, free of charge, to any person ("Licensee") obtaining a
24*3446Smrj  * copy of the source code appearing in this file ("Covered Code") an
25*3446Smrj  * irrevocable, perpetual, worldwide license under Intel's copyrights in the
26*3446Smrj  * base code distributed originally by Intel ("Original Intel Code") to copy,
27*3446Smrj  * make derivatives, distribute, use and display any portion of the Covered
28*3446Smrj  * Code in any form, with the right to sublicense such rights; and
29*3446Smrj  *
30*3446Smrj  * 2.3. Intel grants Licensee a non-exclusive and non-transferable patent
31*3446Smrj  * license (with the right to sublicense), under only those claims of Intel
32*3446Smrj  * patents that are infringed by the Original Intel Code, to make, use, sell,
33*3446Smrj  * offer to sell, and import the Covered Code and derivative works thereof
34*3446Smrj  * solely to the minimum extent necessary to exercise the above copyright
35*3446Smrj  * license, and in no event shall the patent license extend to any additions
36*3446Smrj  * to or modifications of the Original Intel Code.  No other license or right
37*3446Smrj  * is granted directly or by implication, estoppel or otherwise;
38*3446Smrj  *
39*3446Smrj  * The above copyright and patent license is granted only if the following
40*3446Smrj  * conditions are met:
41*3446Smrj  *
42*3446Smrj  * 3. Conditions
43*3446Smrj  *
44*3446Smrj  * 3.1. Redistribution of Source with Rights to Further Distribute Source.
45*3446Smrj  * Redistribution of source code of any substantial portion of the Covered
46*3446Smrj  * Code or modification with rights to further distribute source must include
47*3446Smrj  * the above Copyright Notice, the above License, this list of Conditions,
48*3446Smrj  * and the following Disclaimer and Export Compliance provision.  In addition,
49*3446Smrj  * Licensee must cause all Covered Code to which Licensee contributes to
50*3446Smrj  * contain a file documenting the changes Licensee made to create that Covered
51*3446Smrj  * Code and the date of any change.  Licensee must include in that file the
52*3446Smrj  * documentation of any changes made by any predecessor Licensee.  Licensee
53*3446Smrj  * must include a prominent statement that the modification is derived,
54*3446Smrj  * directly or indirectly, from Original Intel Code.
55*3446Smrj  *
56*3446Smrj  * 3.2. Redistribution of Source with no Rights to Further Distribute Source.
57*3446Smrj  * Redistribution of source code of any substantial portion of the Covered
58*3446Smrj  * Code or modification without rights to further distribute source must
59*3446Smrj  * include the following Disclaimer and Export Compliance provision in the
60*3446Smrj  * documentation and/or other materials provided with distribution.  In
61*3446Smrj  * addition, Licensee may not authorize further sublicense of source of any
62*3446Smrj  * portion of the Covered Code, and must include terms to the effect that the
63*3446Smrj  * license from Licensee to its licensee is limited to the intellectual
64*3446Smrj  * property embodied in the software Licensee provides to its licensee, and
65*3446Smrj  * not to intellectual property embodied in modifications its licensee may
66*3446Smrj  * make.
67*3446Smrj  *
68*3446Smrj  * 3.3. Redistribution of Executable. Redistribution in executable form of any
69*3446Smrj  * substantial portion of the Covered Code or modification must reproduce the
70*3446Smrj  * above Copyright Notice, and the following Disclaimer and Export Compliance
71*3446Smrj  * provision in the documentation and/or other materials provided with the
72*3446Smrj  * distribution.
73*3446Smrj  *
74*3446Smrj  * 3.4. Intel retains all right, title, and interest in and to the Original
75*3446Smrj  * Intel Code.
76*3446Smrj  *
77*3446Smrj  * 3.5. Neither the name Intel nor any other trademark owned or controlled by
78*3446Smrj  * Intel shall be used in advertising or otherwise to promote the sale, use or
79*3446Smrj  * other dealings in products derived from or relating to the Covered Code
80*3446Smrj  * without prior written authorization from Intel.
81*3446Smrj  *
82*3446Smrj  * 4. Disclaimer and Export Compliance
83*3446Smrj  *
84*3446Smrj  * 4.1. INTEL MAKES NO WARRANTY OF ANY KIND REGARDING ANY SOFTWARE PROVIDED
85*3446Smrj  * HERE.  ANY SOFTWARE ORIGINATING FROM INTEL OR DERIVED FROM INTEL SOFTWARE
86*3446Smrj  * IS PROVIDED "AS IS," AND INTEL WILL NOT PROVIDE ANY SUPPORT,  ASSISTANCE,
87*3446Smrj  * INSTALLATION, TRAINING OR OTHER SERVICES.  INTEL WILL NOT PROVIDE ANY
88*3446Smrj  * UPDATES, ENHANCEMENTS OR EXTENSIONS.  INTEL SPECIFICALLY DISCLAIMS ANY
89*3446Smrj  * IMPLIED WARRANTIES OF MERCHANTABILITY, NONINFRINGEMENT AND FITNESS FOR A
90*3446Smrj  * PARTICULAR PURPOSE.
91*3446Smrj  *
92*3446Smrj  * 4.2. IN NO EVENT SHALL INTEL HAVE ANY LIABILITY TO LICENSEE, ITS LICENSEES
93*3446Smrj  * OR ANY OTHER THIRD PARTY, FOR ANY LOST PROFITS, LOST DATA, LOSS OF USE OR
94*3446Smrj  * COSTS OF PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES, OR FOR ANY INDIRECT,
95*3446Smrj  * SPECIAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THIS AGREEMENT, UNDER ANY
96*3446Smrj  * CAUSE OF ACTION OR THEORY OF LIABILITY, AND IRRESPECTIVE OF WHETHER INTEL
97*3446Smrj  * HAS ADVANCE NOTICE OF THE POSSIBILITY OF SUCH DAMAGES.  THESE LIMITATIONS
98*3446Smrj  * SHALL APPLY NOTWITHSTANDING THE FAILURE OF THE ESSENTIAL PURPOSE OF ANY
99*3446Smrj  * LIMITED REMEDY.
100*3446Smrj  *
101*3446Smrj  * 4.3. Licensee shall not export, either directly or indirectly, any of this
102*3446Smrj  * software or system incorporating such software without first obtaining any
103*3446Smrj  * required license or other approval from the U. S. Department of Commerce or
104*3446Smrj  * any other agency or department of the United States Government.  In the
105*3446Smrj  * event Licensee exports any such software from the United States or
106*3446Smrj  * re-exports any such software from a foreign destination, Licensee shall
107*3446Smrj  * ensure that the distribution and export/re-export of the software is in
108*3446Smrj  * compliance with all laws, regulations, orders, or other restrictions of the
109*3446Smrj  * U.S. Export Administration Regulations. Licensee agrees that neither it nor
110*3446Smrj  * any of its subsidiaries will export/re-export any technical data, process,
111*3446Smrj  * software, or service, directly or indirectly, to any country for which the
112*3446Smrj  * United States government or any agency thereof requires an export license,
113*3446Smrj  * other governmental approval, or letter of assurance, without first obtaining
114*3446Smrj  * such license, approval or letter.
115*3446Smrj  *
116*3446Smrj  *****************************************************************************/
117*3446Smrj 
118*3446Smrj 
119*3446Smrj #include "acpi.h"
120*3446Smrj #include "acdebug.h"
121*3446Smrj #include "acnamesp.h"
122*3446Smrj #include "actables.h"
123*3446Smrj #include "acdisasm.h"
124*3446Smrj 
125*3446Smrj #if (defined ACPI_DEBUGGER || defined ACPI_DISASSEMBLER)
126*3446Smrj 
127*3446Smrj #define _COMPONENT          ACPI_CA_DEBUGGER
128*3446Smrj         ACPI_MODULE_NAME    ("dbfileio")
129*3446Smrj 
130*3446Smrj /*
131*3446Smrj  * NOTE: this is here for lack of a better place.  It is used in all
132*3446Smrj  * flavors of the debugger, need LCD file
133*3446Smrj  */
134*3446Smrj #ifdef ACPI_APPLICATION
135*3446Smrj #include <stdio.h>
136*3446Smrj FILE                        *AcpiGbl_DebugFile = NULL;
137*3446Smrj #endif
138*3446Smrj 
139*3446Smrj 
140*3446Smrj #ifdef ACPI_DEBUGGER
141*3446Smrj 
142*3446Smrj /* Local prototypes */
143*3446Smrj 
144*3446Smrj #ifdef ACPI_APPLICATION
145*3446Smrj 
146*3446Smrj static ACPI_STATUS
147*3446Smrj AcpiDbCheckTextModeCorruption (
148*3446Smrj     UINT8                   *Table,
149*3446Smrj     UINT32                  TableLength,
150*3446Smrj     UINT32                  FileLength);
151*3446Smrj 
152*3446Smrj static ACPI_STATUS
153*3446Smrj AeLocalLoadTable (
154*3446Smrj     ACPI_TABLE_HEADER       *TablePtr);
155*3446Smrj #endif
156*3446Smrj 
157*3446Smrj /*******************************************************************************
158*3446Smrj  *
159*3446Smrj  * FUNCTION:    AcpiDbCloseDebugFile
160*3446Smrj  *
161*3446Smrj  * PARAMETERS:  None
162*3446Smrj  *
163*3446Smrj  * RETURN:      None
164*3446Smrj  *
165*3446Smrj  * DESCRIPTION: If open, close the current debug output file
166*3446Smrj  *
167*3446Smrj  ******************************************************************************/
168*3446Smrj 
169*3446Smrj void
170*3446Smrj AcpiDbCloseDebugFile (
171*3446Smrj     void)
172*3446Smrj {
173*3446Smrj 
174*3446Smrj #ifdef ACPI_APPLICATION
175*3446Smrj 
176*3446Smrj     if (AcpiGbl_DebugFile)
177*3446Smrj     {
178*3446Smrj        fclose (AcpiGbl_DebugFile);
179*3446Smrj        AcpiGbl_DebugFile = NULL;
180*3446Smrj        AcpiGbl_DbOutputToFile = FALSE;
181*3446Smrj        AcpiOsPrintf ("Debug output file %s closed\n", AcpiGbl_DbDebugFilename);
182*3446Smrj     }
183*3446Smrj #endif
184*3446Smrj }
185*3446Smrj 
186*3446Smrj 
187*3446Smrj /*******************************************************************************
188*3446Smrj  *
189*3446Smrj  * FUNCTION:    AcpiDbOpenDebugFile
190*3446Smrj  *
191*3446Smrj  * PARAMETERS:  Name                - Filename to open
192*3446Smrj  *
193*3446Smrj  * RETURN:      None
194*3446Smrj  *
195*3446Smrj  * DESCRIPTION: Open a file where debug output will be directed.
196*3446Smrj  *
197*3446Smrj  ******************************************************************************/
198*3446Smrj 
199*3446Smrj void
200*3446Smrj AcpiDbOpenDebugFile (
201*3446Smrj     char                    *Name)
202*3446Smrj {
203*3446Smrj 
204*3446Smrj #ifdef ACPI_APPLICATION
205*3446Smrj 
206*3446Smrj     AcpiDbCloseDebugFile ();
207*3446Smrj     AcpiGbl_DebugFile = fopen (Name, "w+");
208*3446Smrj     if (AcpiGbl_DebugFile)
209*3446Smrj     {
210*3446Smrj         AcpiOsPrintf ("Debug output file %s opened\n", Name);
211*3446Smrj         ACPI_STRCPY (AcpiGbl_DbDebugFilename, Name);
212*3446Smrj         AcpiGbl_DbOutputToFile = TRUE;
213*3446Smrj     }
214*3446Smrj     else
215*3446Smrj     {
216*3446Smrj         AcpiOsPrintf ("Could not open debug file %s\n", Name);
217*3446Smrj     }
218*3446Smrj 
219*3446Smrj #endif
220*3446Smrj }
221*3446Smrj #endif
222*3446Smrj 
223*3446Smrj 
224*3446Smrj #ifdef ACPI_APPLICATION
225*3446Smrj /*******************************************************************************
226*3446Smrj  *
227*3446Smrj  * FUNCTION:    AcpiDbCheckTextModeCorruption
228*3446Smrj  *
229*3446Smrj  * PARAMETERS:  Table           - Table buffer
230*3446Smrj  *              TableLength     - Length of table from the table header
231*3446Smrj  *              FileLength      - Length of the file that contains the table
232*3446Smrj  *
233*3446Smrj  * RETURN:      Status
234*3446Smrj  *
235*3446Smrj  * DESCRIPTION: Check table for text mode file corruption where all linefeed
236*3446Smrj  *              characters (LF) have been replaced by carriage return linefeed
237*3446Smrj  *              pairs (CR/LF).
238*3446Smrj  *
239*3446Smrj  ******************************************************************************/
240*3446Smrj 
241*3446Smrj static ACPI_STATUS
242*3446Smrj AcpiDbCheckTextModeCorruption (
243*3446Smrj     UINT8                   *Table,
244*3446Smrj     UINT32                  TableLength,
245*3446Smrj     UINT32                  FileLength)
246*3446Smrj {
247*3446Smrj     UINT32                  i;
248*3446Smrj     UINT32                  Pairs = 0;
249*3446Smrj 
250*3446Smrj 
251*3446Smrj     if (TableLength != FileLength)
252*3446Smrj     {
253*3446Smrj         ACPI_WARNING ((AE_INFO,
254*3446Smrj             "File length (0x%X) is not the same as the table length (0x%X)",
255*3446Smrj             FileLength, TableLength));
256*3446Smrj     }
257*3446Smrj 
258*3446Smrj     /* Scan entire table to determine if each LF has been prefixed with a CR */
259*3446Smrj 
260*3446Smrj     for (i = 1; i < FileLength; i++)
261*3446Smrj     {
262*3446Smrj         if (Table[i] == 0x0A)
263*3446Smrj         {
264*3446Smrj             if (Table[i - 1] != 0x0D)
265*3446Smrj             {
266*3446Smrj                 /* The LF does not have a preceeding CR, table not corrupted */
267*3446Smrj 
268*3446Smrj                 return (AE_OK);
269*3446Smrj             }
270*3446Smrj             else
271*3446Smrj             {
272*3446Smrj                 /* Found a CR/LF pair */
273*3446Smrj 
274*3446Smrj                 Pairs++;
275*3446Smrj             }
276*3446Smrj             i++;
277*3446Smrj         }
278*3446Smrj     }
279*3446Smrj 
280*3446Smrj     if (!Pairs)
281*3446Smrj     {
282*3446Smrj         return (AE_OK);
283*3446Smrj     }
284*3446Smrj 
285*3446Smrj     /*
286*3446Smrj      * Entire table scanned, each CR is part of a CR/LF pair --
287*3446Smrj      * meaning that the table was treated as a text file somewhere.
288*3446Smrj      *
289*3446Smrj      * NOTE: We can't "fix" the table, because any existing CR/LF pairs in the
290*3446Smrj      * original table are left untouched by the text conversion process --
291*3446Smrj      * meaning that we cannot simply replace CR/LF pairs with LFs.
292*3446Smrj      */
293*3446Smrj     AcpiOsPrintf ("Table has been corrupted by text mode conversion\n");
294*3446Smrj     AcpiOsPrintf ("All LFs (%d) were changed to CR/LF pairs\n", Pairs);
295*3446Smrj     AcpiOsPrintf ("Table cannot be repaired!\n");
296*3446Smrj     return (AE_BAD_VALUE);
297*3446Smrj }
298*3446Smrj 
299*3446Smrj 
300*3446Smrj /*******************************************************************************
301*3446Smrj  *
302*3446Smrj  * FUNCTION:    AcpiDbReadTable
303*3446Smrj  *
304*3446Smrj  * PARAMETERS:  fp              - File that contains table
305*3446Smrj  *              Table           - Return value, buffer with table
306*3446Smrj  *              TableLength     - Return value, length of table
307*3446Smrj  *
308*3446Smrj  * RETURN:      Status
309*3446Smrj  *
310*3446Smrj  * DESCRIPTION: Load the DSDT from the file pointer
311*3446Smrj  *
312*3446Smrj  ******************************************************************************/
313*3446Smrj 
314*3446Smrj static ACPI_STATUS
315*3446Smrj AcpiDbReadTable (
316*3446Smrj     FILE                    *fp,
317*3446Smrj     ACPI_TABLE_HEADER       **Table,
318*3446Smrj     UINT32                  *TableLength)
319*3446Smrj {
320*3446Smrj     ACPI_TABLE_HEADER       TableHeader;
321*3446Smrj     UINT32                  Actual;
322*3446Smrj     ACPI_STATUS             Status;
323*3446Smrj     UINT32                  FileSize;
324*3446Smrj     BOOLEAN                 StandardHeader = TRUE;
325*3446Smrj 
326*3446Smrj 
327*3446Smrj     /* Get the file size */
328*3446Smrj 
329*3446Smrj     fseek (fp, 0, SEEK_END);
330*3446Smrj     FileSize = (UINT32) ftell (fp);
331*3446Smrj     fseek (fp, 0, SEEK_SET);
332*3446Smrj 
333*3446Smrj     if (FileSize < 4)
334*3446Smrj     {
335*3446Smrj         return (AE_BAD_HEADER);
336*3446Smrj     }
337*3446Smrj 
338*3446Smrj     /* Read the signature */
339*3446Smrj 
340*3446Smrj     if (fread (&TableHeader, 1, 4, fp) != 4)
341*3446Smrj     {
342*3446Smrj         AcpiOsPrintf ("Could not read the table signature\n");
343*3446Smrj         return (AE_BAD_HEADER);
344*3446Smrj     }
345*3446Smrj 
346*3446Smrj     fseek (fp, 0, SEEK_SET);
347*3446Smrj 
348*3446Smrj     /* The RSDT and FACS tables do not have standard ACPI headers */
349*3446Smrj 
350*3446Smrj     if (ACPI_COMPARE_NAME (TableHeader.Signature, "RSD ") ||
351*3446Smrj         ACPI_COMPARE_NAME (TableHeader.Signature, "FACS"))
352*3446Smrj     {
353*3446Smrj         *TableLength = FileSize;
354*3446Smrj         StandardHeader = FALSE;
355*3446Smrj     }
356*3446Smrj     else
357*3446Smrj     {
358*3446Smrj     /* Read the table header */
359*3446Smrj 
360*3446Smrj         if (fread (&TableHeader, 1, sizeof (TableHeader), fp) !=
361*3446Smrj                 sizeof (ACPI_TABLE_HEADER))
362*3446Smrj         {
363*3446Smrj             AcpiOsPrintf ("Could not read the table header\n");
364*3446Smrj             return (AE_BAD_HEADER);
365*3446Smrj         }
366*3446Smrj 
367*3446Smrj         /* Validate the table header/length */
368*3446Smrj 
369*3446Smrj         Status = AcpiTbValidateTableHeader (&TableHeader);
370*3446Smrj         if (ACPI_FAILURE (Status))
371*3446Smrj         {
372*3446Smrj             AcpiOsPrintf ("Table header is invalid!\n");
373*3446Smrj             return (Status);
374*3446Smrj         }
375*3446Smrj 
376*3446Smrj         /* File size must be at least as long as the Header-specified length */
377*3446Smrj 
378*3446Smrj         if (TableHeader.Length > FileSize)
379*3446Smrj         {
380*3446Smrj             AcpiOsPrintf (
381*3446Smrj                 "TableHeader length [0x%X] greater than the input file size [0x%X]\n",
382*3446Smrj                 TableHeader.Length, FileSize);
383*3446Smrj             return (AE_BAD_HEADER);
384*3446Smrj         }
385*3446Smrj 
386*3446Smrj #ifdef ACPI_OBSOLETE_CODE
387*3446Smrj         /* We only support a limited number of table types */
388*3446Smrj 
389*3446Smrj         if (ACPI_STRNCMP ((char *) TableHeader.Signature, DSDT_SIG, 4) &&
390*3446Smrj             ACPI_STRNCMP ((char *) TableHeader.Signature, PSDT_SIG, 4) &&
391*3446Smrj             ACPI_STRNCMP ((char *) TableHeader.Signature, SSDT_SIG, 4))
392*3446Smrj         {
393*3446Smrj             AcpiOsPrintf ("Table signature [%4.4s] is invalid or not supported\n",
394*3446Smrj                 (char *) TableHeader.Signature);
395*3446Smrj             ACPI_DUMP_BUFFER (&TableHeader, sizeof (ACPI_TABLE_HEADER));
396*3446Smrj             return (AE_ERROR);
397*3446Smrj         }
398*3446Smrj #endif
399*3446Smrj 
400*3446Smrj         *TableLength = TableHeader.Length;
401*3446Smrj     }
402*3446Smrj 
403*3446Smrj     /* Allocate a buffer for the table */
404*3446Smrj 
405*3446Smrj     *Table = AcpiOsAllocate ((size_t) FileSize);
406*3446Smrj     if (!*Table)
407*3446Smrj     {
408*3446Smrj         AcpiOsPrintf (
409*3446Smrj             "Could not allocate memory for ACPI table %4.4s (size=0x%X)\n",
410*3446Smrj             TableHeader.Signature, *TableLength);
411*3446Smrj         return (AE_NO_MEMORY);
412*3446Smrj     }
413*3446Smrj 
414*3446Smrj     /* Get the rest of the table */
415*3446Smrj 
416*3446Smrj     fseek (fp, 0, SEEK_SET);
417*3446Smrj     Actual = fread (*Table, 1, (size_t) FileSize, fp);
418*3446Smrj     if (Actual == FileSize)
419*3446Smrj     {
420*3446Smrj         if (StandardHeader)
421*3446Smrj         {
422*3446Smrj             /* Now validate the checksum */
423*3446Smrj 
424*3446Smrj             Status = AcpiTbVerifyTableChecksum (*Table);
425*3446Smrj 
426*3446Smrj             if (Status == AE_BAD_CHECKSUM)
427*3446Smrj             {
428*3446Smrj                 Status = AcpiDbCheckTextModeCorruption ((UINT8 *) *Table,
429*3446Smrj                             FileSize, (*Table)->Length);
430*3446Smrj                 return (Status);
431*3446Smrj             }
432*3446Smrj         }
433*3446Smrj         return (AE_OK);
434*3446Smrj     }
435*3446Smrj 
436*3446Smrj     if (Actual > 0)
437*3446Smrj     {
438*3446Smrj         AcpiOsPrintf ("Warning - reading table, asked for %X got %X\n",
439*3446Smrj             FileSize, Actual);
440*3446Smrj         return (AE_OK);
441*3446Smrj     }
442*3446Smrj 
443*3446Smrj     AcpiOsPrintf ("Error - could not read the table file\n");
444*3446Smrj     AcpiOsFree (*Table);
445*3446Smrj     *Table = NULL;
446*3446Smrj     *TableLength = 0;
447*3446Smrj 
448*3446Smrj     return (AE_ERROR);
449*3446Smrj }
450*3446Smrj 
451*3446Smrj 
452*3446Smrj /*******************************************************************************
453*3446Smrj  *
454*3446Smrj  * FUNCTION:    AeLocalLoadTable
455*3446Smrj  *
456*3446Smrj  * PARAMETERS:  Table           - pointer to a buffer containing the entire
457*3446Smrj  *                                table to be loaded
458*3446Smrj  *
459*3446Smrj  * RETURN:      Status
460*3446Smrj  *
461*3446Smrj  * DESCRIPTION: This function is called to load a table from the caller's
462*3446Smrj  *              buffer.  The buffer must contain an entire ACPI Table including
463*3446Smrj  *              a valid header.  The header fields will be verified, and if it
464*3446Smrj  *              is determined that the table is invalid, the call will fail.
465*3446Smrj  *
466*3446Smrj  ******************************************************************************/
467*3446Smrj 
468*3446Smrj static ACPI_STATUS
469*3446Smrj AeLocalLoadTable (
470*3446Smrj     ACPI_TABLE_HEADER       *Table)
471*3446Smrj {
472*3446Smrj     ACPI_STATUS             Status;
473*3446Smrj     ACPI_TABLE_DESC         TableInfo;
474*3446Smrj 
475*3446Smrj 
476*3446Smrj     ACPI_FUNCTION_TRACE (AeLocalLoadTable);
477*3446Smrj 
478*3446Smrj 
479*3446Smrj     if (!Table)
480*3446Smrj     {
481*3446Smrj         return_ACPI_STATUS (AE_BAD_PARAMETER);
482*3446Smrj     }
483*3446Smrj 
484*3446Smrj     TableInfo.Pointer = Table;
485*3446Smrj     Status = AcpiTbRecognizeTable (&TableInfo, ACPI_TABLE_ALL);
486*3446Smrj     if (ACPI_FAILURE (Status))
487*3446Smrj     {
488*3446Smrj         return_ACPI_STATUS (Status);
489*3446Smrj     }
490*3446Smrj 
491*3446Smrj     /* Install the new table into the local data structures */
492*3446Smrj 
493*3446Smrj     Status = AcpiTbInstallTable (&TableInfo);
494*3446Smrj     if (ACPI_FAILURE (Status))
495*3446Smrj     {
496*3446Smrj         if (Status == AE_ALREADY_EXISTS)
497*3446Smrj         {
498*3446Smrj             /* Table already exists, no error */
499*3446Smrj 
500*3446Smrj             Status = AE_OK;
501*3446Smrj         }
502*3446Smrj 
503*3446Smrj         /* Free table allocated by AcpiTbGetTable */
504*3446Smrj 
505*3446Smrj         AcpiTbDeleteSingleTable (&TableInfo);
506*3446Smrj         return_ACPI_STATUS (Status);
507*3446Smrj     }
508*3446Smrj 
509*3446Smrj #if (!defined (ACPI_NO_METHOD_EXECUTION) && !defined (ACPI_CONSTANT_EVAL_ONLY))
510*3446Smrj 
511*3446Smrj     Status = AcpiNsLoadTable (TableInfo.InstalledDesc, AcpiGbl_RootNode);
512*3446Smrj     if (ACPI_FAILURE (Status))
513*3446Smrj     {
514*3446Smrj         /* Uninstall table and free the buffer */
515*3446Smrj 
516*3446Smrj         AcpiTbDeleteTablesByType (ACPI_TABLE_ID_DSDT);
517*3446Smrj         return_ACPI_STATUS (Status);
518*3446Smrj     }
519*3446Smrj #endif
520*3446Smrj 
521*3446Smrj     return_ACPI_STATUS (Status);
522*3446Smrj }
523*3446Smrj 
524*3446Smrj 
525*3446Smrj /*******************************************************************************
526*3446Smrj  *
527*3446Smrj  * FUNCTION:    AcpiDbReadTableFromFile
528*3446Smrj  *
529*3446Smrj  * PARAMETERS:  Filename         - File where table is located
530*3446Smrj  *              Table            - Where a pointer to the table is returned
531*3446Smrj  *
532*3446Smrj  * RETURN:      Status
533*3446Smrj  *
534*3446Smrj  * DESCRIPTION: Get an ACPI table from a file
535*3446Smrj  *
536*3446Smrj  ******************************************************************************/
537*3446Smrj 
538*3446Smrj ACPI_STATUS
539*3446Smrj AcpiDbReadTableFromFile (
540*3446Smrj     char                    *Filename,
541*3446Smrj     ACPI_TABLE_HEADER       **Table)
542*3446Smrj {
543*3446Smrj     FILE                    *fp;
544*3446Smrj     UINT32                  TableLength;
545*3446Smrj     ACPI_STATUS             Status;
546*3446Smrj 
547*3446Smrj 
548*3446Smrj     /* Open the file */
549*3446Smrj 
550*3446Smrj     fp = fopen (Filename, "rb");
551*3446Smrj     if (!fp)
552*3446Smrj     {
553*3446Smrj         AcpiOsPrintf ("Could not open input file %s\n", Filename);
554*3446Smrj         return (AE_ERROR);
555*3446Smrj     }
556*3446Smrj 
557*3446Smrj     /* Get the entire file */
558*3446Smrj 
559*3446Smrj     fprintf (stderr, "Loading Acpi table from file %s\n", Filename);
560*3446Smrj     Status = AcpiDbReadTable (fp, Table, &TableLength);
561*3446Smrj     fclose(fp);
562*3446Smrj 
563*3446Smrj     if (ACPI_FAILURE (Status))
564*3446Smrj     {
565*3446Smrj         AcpiOsPrintf ("Could not get table from the file\n");
566*3446Smrj         return (Status);
567*3446Smrj     }
568*3446Smrj 
569*3446Smrj     return (AE_OK);
570*3446Smrj  }
571*3446Smrj #endif
572*3446Smrj 
573*3446Smrj 
574*3446Smrj /*******************************************************************************
575*3446Smrj  *
576*3446Smrj  * FUNCTION:    AcpiDbGetTableFromFile
577*3446Smrj  *
578*3446Smrj  * PARAMETERS:  Filename        - File where table is located
579*3446Smrj  *              ReturnTable     - Where a pointer to the table is returned
580*3446Smrj  *
581*3446Smrj  * RETURN:      Status
582*3446Smrj  *
583*3446Smrj  * DESCRIPTION: Load an ACPI table from a file
584*3446Smrj  *
585*3446Smrj  ******************************************************************************/
586*3446Smrj 
587*3446Smrj ACPI_STATUS
588*3446Smrj AcpiDbGetTableFromFile (
589*3446Smrj     char                    *Filename,
590*3446Smrj     ACPI_TABLE_HEADER       **ReturnTable)
591*3446Smrj {
592*3446Smrj #ifdef ACPI_APPLICATION
593*3446Smrj     ACPI_STATUS             Status;
594*3446Smrj     ACPI_TABLE_HEADER       *Table;
595*3446Smrj     BOOLEAN                 IsAmlTable = TRUE;
596*3446Smrj 
597*3446Smrj 
598*3446Smrj     Status = AcpiDbReadTableFromFile (Filename, &Table);
599*3446Smrj     if (ACPI_FAILURE (Status))
600*3446Smrj     {
601*3446Smrj         return (Status);
602*3446Smrj     }
603*3446Smrj 
604*3446Smrj #ifdef ACPI_DATA_TABLE_DISASSEMBLY
605*3446Smrj     IsAmlTable = AcpiUtIsAmlTable (Table);
606*3446Smrj #endif
607*3446Smrj 
608*3446Smrj     if (IsAmlTable)
609*3446Smrj     {
610*3446Smrj         /* Attempt to recognize and install the table */
611*3446Smrj 
612*3446Smrj         Status = AeLocalLoadTable (Table);
613*3446Smrj         if (ACPI_FAILURE (Status))
614*3446Smrj         {
615*3446Smrj             if (Status == AE_ALREADY_EXISTS)
616*3446Smrj             {
617*3446Smrj                 AcpiOsPrintf ("Table %4.4s is already installed\n",
618*3446Smrj                     Table->Signature);
619*3446Smrj             }
620*3446Smrj             else
621*3446Smrj             {
622*3446Smrj                 AcpiOsPrintf ("Could not install table, %s\n",
623*3446Smrj                     AcpiFormatException (Status));
624*3446Smrj             }
625*3446Smrj 
626*3446Smrj             return (Status);
627*3446Smrj         }
628*3446Smrj 
629*3446Smrj         fprintf (stderr,
630*3446Smrj             "Acpi table [%4.4s] successfully installed and loaded\n",
631*3446Smrj             Table->Signature);
632*3446Smrj     }
633*3446Smrj 
634*3446Smrj     AcpiGbl_AcpiHardwarePresent = FALSE;
635*3446Smrj     if (ReturnTable)
636*3446Smrj     {
637*3446Smrj         *ReturnTable = Table;
638*3446Smrj     }
639*3446Smrj 
640*3446Smrj 
641*3446Smrj #endif  /* ACPI_APPLICATION */
642*3446Smrj     return (AE_OK);
643*3446Smrj }
644*3446Smrj 
645*3446Smrj #endif  /* ACPI_DEBUGGER */
646*3446Smrj 
647