kernel: Sync ACPICA with Intel's version 20140325.
[dragonfly.git] / sys / contrib / dev / acpica / source / components / debugger / dbfileio.c
1 /*******************************************************************************
2  *
3  * Module Name: dbfileio - Debugger file I/O commands. These can't usually
4  *              be used when running the debugger in Ring 0 (Kernel mode)
5  *
6  ******************************************************************************/
7
8 /*
9  * Copyright (C) 2000 - 2014, Intel Corp.
10  * All rights reserved.
11  *
12  * Redistribution and use in source and binary forms, with or without
13  * modification, are permitted provided that the following conditions
14  * are met:
15  * 1. Redistributions of source code must retain the above copyright
16  *    notice, this list of conditions, and the following disclaimer,
17  *    without modification.
18  * 2. Redistributions in binary form must reproduce at minimum a disclaimer
19  *    substantially similar to the "NO WARRANTY" disclaimer below
20  *    ("Disclaimer") and any redistribution must be conditioned upon
21  *    including a substantially similar Disclaimer requirement for further
22  *    binary redistribution.
23  * 3. Neither the names of the above-listed copyright holders nor the names
24  *    of any contributors may be used to endorse or promote products derived
25  *    from this software without specific prior written permission.
26  *
27  * Alternatively, this software may be distributed under the terms of the
28  * GNU General Public License ("GPL") version 2 as published by the Free
29  * Software Foundation.
30  *
31  * NO WARRANTY
32  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
33  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
34  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR
35  * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
36  * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
37  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
38  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
39  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
40  * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
41  * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
42  * POSSIBILITY OF SUCH DAMAGES.
43  */
44
45
46 #include "acpi.h"
47 #include "accommon.h"
48 #include "acdebug.h"
49
50 #ifdef ACPI_APPLICATION
51 #include "actables.h"
52 #endif
53
54 #ifdef ACPI_ASL_COMPILER
55 #include "aslcompiler.h"
56 #endif
57
58 #if (defined ACPI_DEBUGGER || defined ACPI_DISASSEMBLER)
59
60 #define _COMPONENT          ACPI_CA_DEBUGGER
61         ACPI_MODULE_NAME    ("dbfileio")
62
63 #ifdef ACPI_DEBUGGER
64
65 /* Local prototypes */
66
67 #ifdef ACPI_APPLICATION
68
69 static ACPI_STATUS
70 AcpiDbCheckTextModeCorruption (
71     UINT8                   *Table,
72     UINT32                  TableLength,
73     UINT32                  FileLength);
74
75 #endif
76
77 /*******************************************************************************
78  *
79  * FUNCTION:    AcpiDbCloseDebugFile
80  *
81  * PARAMETERS:  None
82  *
83  * RETURN:      None
84  *
85  * DESCRIPTION: If open, close the current debug output file
86  *
87  ******************************************************************************/
88
89 void
90 AcpiDbCloseDebugFile (
91     void)
92 {
93
94 #ifdef ACPI_APPLICATION
95
96     if (AcpiGbl_DebugFile)
97     {
98        fclose (AcpiGbl_DebugFile);
99        AcpiGbl_DebugFile = NULL;
100        AcpiGbl_DbOutputToFile = FALSE;
101        AcpiOsPrintf ("Debug output file %s closed\n", AcpiGbl_DbDebugFilename);
102     }
103 #endif
104 }
105
106
107 /*******************************************************************************
108  *
109  * FUNCTION:    AcpiDbOpenDebugFile
110  *
111  * PARAMETERS:  Name                - Filename to open
112  *
113  * RETURN:      None
114  *
115  * DESCRIPTION: Open a file where debug output will be directed.
116  *
117  ******************************************************************************/
118
119 void
120 AcpiDbOpenDebugFile (
121     char                    *Name)
122 {
123
124 #ifdef ACPI_APPLICATION
125
126     AcpiDbCloseDebugFile ();
127     AcpiGbl_DebugFile = fopen (Name, "w+");
128     if (!AcpiGbl_DebugFile)
129     {
130         AcpiOsPrintf ("Could not open debug file %s\n", Name);
131         return;
132     }
133
134     AcpiOsPrintf ("Debug output file %s opened\n", Name);
135     ACPI_STRNCPY (AcpiGbl_DbDebugFilename, Name,
136         sizeof (AcpiGbl_DbDebugFilename));
137     AcpiGbl_DbOutputToFile = TRUE;
138
139 #endif
140 }
141 #endif
142
143
144 #ifdef ACPI_APPLICATION
145 #include "acapps.h"
146
147 /*******************************************************************************
148  *
149  * FUNCTION:    AcpiDbCheckTextModeCorruption
150  *
151  * PARAMETERS:  Table           - Table buffer
152  *              TableLength     - Length of table from the table header
153  *              FileLength      - Length of the file that contains the table
154  *
155  * RETURN:      Status
156  *
157  * DESCRIPTION: Check table for text mode file corruption where all linefeed
158  *              characters (LF) have been replaced by carriage return linefeed
159  *              pairs (CR/LF).
160  *
161  ******************************************************************************/
162
163 static ACPI_STATUS
164 AcpiDbCheckTextModeCorruption (
165     UINT8                   *Table,
166     UINT32                  TableLength,
167     UINT32                  FileLength)
168 {
169     UINT32                  i;
170     UINT32                  Pairs = 0;
171
172
173     if (TableLength != FileLength)
174     {
175         ACPI_WARNING ((AE_INFO,
176             "File length (0x%X) is not the same as the table length (0x%X)",
177             FileLength, TableLength));
178     }
179
180     /* Scan entire table to determine if each LF has been prefixed with a CR */
181
182     for (i = 1; i < FileLength; i++)
183     {
184         if (Table[i] == 0x0A)
185         {
186             if (Table[i - 1] != 0x0D)
187             {
188                 /* The LF does not have a preceding CR, table not corrupted */
189
190                 return (AE_OK);
191             }
192             else
193             {
194                 /* Found a CR/LF pair */
195
196                 Pairs++;
197             }
198             i++;
199         }
200     }
201
202     if (!Pairs)
203     {
204         return (AE_OK);
205     }
206
207     /*
208      * Entire table scanned, each CR is part of a CR/LF pair --
209      * meaning that the table was treated as a text file somewhere.
210      *
211      * NOTE: We can't "fix" the table, because any existing CR/LF pairs in the
212      * original table are left untouched by the text conversion process --
213      * meaning that we cannot simply replace CR/LF pairs with LFs.
214      */
215     AcpiOsPrintf ("Table has been corrupted by text mode conversion\n");
216     AcpiOsPrintf ("All LFs (%u) were changed to CR/LF pairs\n", Pairs);
217     AcpiOsPrintf ("Table cannot be repaired!\n");
218     return (AE_BAD_VALUE);
219 }
220
221
222 /*******************************************************************************
223  *
224  * FUNCTION:    AcpiDbReadTable
225  *
226  * PARAMETERS:  fp              - File that contains table
227  *              Table           - Return value, buffer with table
228  *              TableLength     - Return value, length of table
229  *
230  * RETURN:      Status
231  *
232  * DESCRIPTION: Load the DSDT from the file pointer
233  *
234  ******************************************************************************/
235
236 static ACPI_STATUS
237 AcpiDbReadTable (
238     FILE                    *fp,
239     ACPI_TABLE_HEADER       **Table,
240     UINT32                  *TableLength)
241 {
242     ACPI_TABLE_HEADER       TableHeader;
243     UINT32                  Actual;
244     ACPI_STATUS             Status;
245     UINT32                  FileSize;
246     BOOLEAN                 StandardHeader = TRUE;
247
248
249     /* Get the file size */
250
251     FileSize = CmGetFileSize (fp);
252     if (FileSize == ACPI_UINT32_MAX)
253     {
254         return (AE_ERROR);
255     }
256
257     if (FileSize < 4)
258     {
259         return (AE_BAD_HEADER);
260     }
261
262     /* Read the signature */
263
264     if (fread (&TableHeader, 1, 4, fp) != 4)
265     {
266         AcpiOsPrintf ("Could not read the table signature\n");
267         return (AE_BAD_HEADER);
268     }
269
270     fseek (fp, 0, SEEK_SET);
271
272     /* The RSDP table does not have standard ACPI header */
273
274     if (ACPI_COMPARE_NAME (TableHeader.Signature, "RSD "))
275     {
276         *TableLength = FileSize;
277         StandardHeader = FALSE;
278     }
279     else
280     {
281         /* Read the table header */
282
283         if (fread (&TableHeader, 1, sizeof (ACPI_TABLE_HEADER), fp) !=
284                 sizeof (ACPI_TABLE_HEADER))
285         {
286             AcpiOsPrintf ("Could not read the table header\n");
287             return (AE_BAD_HEADER);
288         }
289
290 #if 0
291         /* Validate the table header/length */
292
293         Status = AcpiTbValidateTableHeader (&TableHeader);
294         if (ACPI_FAILURE (Status))
295         {
296             AcpiOsPrintf ("Table header is invalid!\n");
297             return (Status);
298         }
299 #endif
300
301         /* File size must be at least as long as the Header-specified length */
302
303         if (TableHeader.Length > FileSize)
304         {
305             AcpiOsPrintf (
306                 "TableHeader length [0x%X] greater than the input file size [0x%X]\n",
307                 TableHeader.Length, FileSize);
308
309 #ifdef ACPI_ASL_COMPILER
310             Status = FlCheckForAscii (fp, NULL, FALSE);
311             if (ACPI_SUCCESS (Status))
312             {
313                 AcpiOsPrintf ("File appears to be ASCII only, must be binary\n",
314                     TableHeader.Length, FileSize);
315             }
316 #endif
317             return (AE_BAD_HEADER);
318         }
319
320 #ifdef ACPI_OBSOLETE_CODE
321         /* We only support a limited number of table types */
322
323         if (!ACPI_COMPARE_NAME ((char *) TableHeader.Signature, ACPI_SIG_DSDT) &&
324             !ACPI_COMPARE_NAME ((char *) TableHeader.Signature, ACPI_SIG_PSDT) &&
325             !ACPI_COMPARE_NAME ((char *) TableHeader.Signature, ACPI_SIG_SSDT))
326         {
327             AcpiOsPrintf ("Table signature [%4.4s] is invalid or not supported\n",
328                 (char *) TableHeader.Signature);
329             ACPI_DUMP_BUFFER (&TableHeader, sizeof (ACPI_TABLE_HEADER));
330             return (AE_ERROR);
331         }
332 #endif
333
334         *TableLength = TableHeader.Length;
335     }
336
337     /* Allocate a buffer for the table */
338
339     *Table = AcpiOsAllocate ((size_t) FileSize);
340     if (!*Table)
341     {
342         AcpiOsPrintf (
343             "Could not allocate memory for ACPI table %4.4s (size=0x%X)\n",
344             TableHeader.Signature, *TableLength);
345         return (AE_NO_MEMORY);
346     }
347
348     /* Get the rest of the table */
349
350     fseek (fp, 0, SEEK_SET);
351     Actual = fread (*Table, 1, (size_t) FileSize, fp);
352     if (Actual == FileSize)
353     {
354         if (StandardHeader)
355         {
356             /* Now validate the checksum */
357
358             Status = AcpiTbVerifyChecksum ((void *) *Table,
359                         ACPI_CAST_PTR (ACPI_TABLE_HEADER, *Table)->Length);
360
361             if (Status == AE_BAD_CHECKSUM)
362             {
363                 Status = AcpiDbCheckTextModeCorruption ((UINT8 *) *Table,
364                             FileSize, (*Table)->Length);
365                 return (Status);
366             }
367         }
368         return (AE_OK);
369     }
370
371     if (Actual > 0)
372     {
373         AcpiOsPrintf ("Warning - reading table, asked for %X got %X\n",
374             FileSize, Actual);
375         return (AE_OK);
376     }
377
378     AcpiOsPrintf ("Error - could not read the table file\n");
379     AcpiOsFree (*Table);
380     *Table = NULL;
381     *TableLength = 0;
382     return (AE_ERROR);
383 }
384
385
386 /*******************************************************************************
387  *
388  * FUNCTION:    AeLocalLoadTable
389  *
390  * PARAMETERS:  Table           - pointer to a buffer containing the entire
391  *                                table to be loaded
392  *
393  * RETURN:      Status
394  *
395  * DESCRIPTION: This function is called to load a table from the caller's
396  *              buffer. The buffer must contain an entire ACPI Table including
397  *              a valid header. The header fields will be verified, and if it
398  *              is determined that the table is invalid, the call will fail.
399  *
400  ******************************************************************************/
401
402 static ACPI_STATUS
403 AeLocalLoadTable (
404     ACPI_TABLE_HEADER       *Table)
405 {
406     ACPI_STATUS             Status = AE_OK;
407 /*    ACPI_TABLE_DESC         TableInfo; */
408
409
410     ACPI_FUNCTION_TRACE (AeLocalLoadTable);
411 #if 0
412
413
414     if (!Table)
415     {
416         return_ACPI_STATUS (AE_BAD_PARAMETER);
417     }
418
419     TableInfo.Pointer = Table;
420     Status = AcpiTbRecognizeTable (&TableInfo, ACPI_TABLE_ALL);
421     if (ACPI_FAILURE (Status))
422     {
423         return_ACPI_STATUS (Status);
424     }
425
426     /* Install the new table into the local data structures */
427
428     Status = AcpiTbInitTableDescriptor (&TableInfo);
429     if (ACPI_FAILURE (Status))
430     {
431         if (Status == AE_ALREADY_EXISTS)
432         {
433             /* Table already exists, no error */
434
435             Status = AE_OK;
436         }
437
438         /* Free table allocated by AcpiTbGetTable */
439
440         AcpiTbDeleteSingleTable (&TableInfo);
441         return_ACPI_STATUS (Status);
442     }
443
444 #if (!defined (ACPI_NO_METHOD_EXECUTION) && !defined (ACPI_CONSTANT_EVAL_ONLY))
445
446     Status = AcpiNsLoadTable (TableInfo.InstalledDesc, AcpiGbl_RootNode);
447     if (ACPI_FAILURE (Status))
448     {
449         /* Uninstall table and free the buffer */
450
451         AcpiTbDeleteTablesByType (ACPI_TABLE_ID_DSDT);
452         return_ACPI_STATUS (Status);
453     }
454 #endif
455 #endif
456
457     return_ACPI_STATUS (Status);
458 }
459
460
461 /*******************************************************************************
462  *
463  * FUNCTION:    AcpiDbReadTableFromFile
464  *
465  * PARAMETERS:  Filename         - File where table is located
466  *              Table            - Where a pointer to the table is returned
467  *
468  * RETURN:      Status
469  *
470  * DESCRIPTION: Get an ACPI table from a file
471  *
472  ******************************************************************************/
473
474 ACPI_STATUS
475 AcpiDbReadTableFromFile (
476     char                    *Filename,
477     ACPI_TABLE_HEADER       **Table)
478 {
479     FILE                    *File;
480     UINT32                  FileSize;
481     UINT32                  TableLength;
482     ACPI_STATUS             Status = AE_ERROR;
483
484
485     /* Open the file, get current size */
486
487     File = fopen (Filename, "rb");
488     if (!File)
489     {
490         perror ("Could not open input file");
491         return (Status);
492     }
493
494     FileSize = CmGetFileSize (File);
495     if (FileSize == ACPI_UINT32_MAX)
496     {
497         goto Exit;
498     }
499
500     /* Get the entire file */
501
502     fprintf (stderr, "Loading Acpi table from file %10s - Length %.8u (%06X)\n",
503         Filename, FileSize, FileSize);
504
505     Status = AcpiDbReadTable (File, Table, &TableLength);
506     if (ACPI_FAILURE (Status))
507     {
508         AcpiOsPrintf ("Could not get table from the file\n");
509     }
510
511 Exit:
512     fclose(File);
513     return (Status);
514  }
515 #endif
516
517
518 /*******************************************************************************
519  *
520  * FUNCTION:    AcpiDbGetTableFromFile
521  *
522  * PARAMETERS:  Filename        - File where table is located
523  *              ReturnTable     - Where a pointer to the table is returned
524  *
525  * RETURN:      Status
526  *
527  * DESCRIPTION: Load an ACPI table from a file
528  *
529  ******************************************************************************/
530
531 ACPI_STATUS
532 AcpiDbGetTableFromFile (
533     char                    *Filename,
534     ACPI_TABLE_HEADER       **ReturnTable)
535 {
536 #ifdef ACPI_APPLICATION
537     ACPI_STATUS             Status;
538     ACPI_TABLE_HEADER       *Table;
539     BOOLEAN                 IsAmlTable = TRUE;
540
541
542     Status = AcpiDbReadTableFromFile (Filename, &Table);
543     if (ACPI_FAILURE (Status))
544     {
545         return (Status);
546     }
547
548 #ifdef ACPI_DATA_TABLE_DISASSEMBLY
549     IsAmlTable = AcpiUtIsAmlTable (Table);
550 #endif
551
552     if (IsAmlTable)
553     {
554         /* Attempt to recognize and install the table */
555
556         Status = AeLocalLoadTable (Table);
557         if (ACPI_FAILURE (Status))
558         {
559             if (Status == AE_ALREADY_EXISTS)
560             {
561                 AcpiOsPrintf ("Table %4.4s is already installed\n",
562                     Table->Signature);
563             }
564             else
565             {
566                 AcpiOsPrintf ("Could not install table, %s\n",
567                     AcpiFormatException (Status));
568             }
569
570             return (Status);
571         }
572
573         AcpiTbPrintTableHeader (0, Table);
574
575         fprintf (stderr,
576             "Acpi table [%4.4s] successfully installed and loaded\n",
577             Table->Signature);
578     }
579
580     AcpiGbl_AcpiHardwarePresent = FALSE;
581     if (ReturnTable)
582     {
583         *ReturnTable = Table;
584     }
585
586
587 #endif  /* ACPI_APPLICATION */
588     return (AE_OK);
589 }
590
591 #endif  /* ACPI_DEBUGGER */