dbfileio.c revision 1.1.1.2.20.1 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 - 2013, 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 /*******************************************************************************
146 *
147 * FUNCTION: AcpiDbCheckTextModeCorruption
148 *
149 * PARAMETERS: Table - Table buffer
150 * TableLength - Length of table from the table header
151 * FileLength - Length of the file that contains the table
152 *
153 * RETURN: Status
154 *
155 * DESCRIPTION: Check table for text mode file corruption where all linefeed
156 * characters (LF) have been replaced by carriage return linefeed
157 * pairs (CR/LF).
158 *
159 ******************************************************************************/
160
161 static ACPI_STATUS
162 AcpiDbCheckTextModeCorruption (
163 UINT8 *Table,
164 UINT32 TableLength,
165 UINT32 FileLength)
166 {
167 UINT32 i;
168 UINT32 Pairs = 0;
169
170
171 if (TableLength != FileLength)
172 {
173 ACPI_WARNING ((AE_INFO,
174 "File length (0x%X) is not the same as the table length (0x%X)",
175 FileLength, TableLength));
176 }
177
178 /* Scan entire table to determine if each LF has been prefixed with a CR */
179
180 for (i = 1; i < FileLength; i++)
181 {
182 if (Table[i] == 0x0A)
183 {
184 if (Table[i - 1] != 0x0D)
185 {
186 /* The LF does not have a preceding CR, table not corrupted */
187
188 return (AE_OK);
189 }
190 else
191 {
192 /* Found a CR/LF pair */
193
194 Pairs++;
195 }
196 i++;
197 }
198 }
199
200 if (!Pairs)
201 {
202 return (AE_OK);
203 }
204
205 /*
206 * Entire table scanned, each CR is part of a CR/LF pair --
207 * meaning that the table was treated as a text file somewhere.
208 *
209 * NOTE: We can't "fix" the table, because any existing CR/LF pairs in the
210 * original table are left untouched by the text conversion process --
211 * meaning that we cannot simply replace CR/LF pairs with LFs.
212 */
213 AcpiOsPrintf ("Table has been corrupted by text mode conversion\n");
214 AcpiOsPrintf ("All LFs (%u) were changed to CR/LF pairs\n", Pairs);
215 AcpiOsPrintf ("Table cannot be repaired!\n");
216 return (AE_BAD_VALUE);
217 }
218
219
220 /*******************************************************************************
221 *
222 * FUNCTION: AcpiDbReadTable
223 *
224 * PARAMETERS: fp - File that contains table
225 * Table - Return value, buffer with table
226 * TableLength - Return value, length of table
227 *
228 * RETURN: Status
229 *
230 * DESCRIPTION: Load the DSDT from the file pointer
231 *
232 ******************************************************************************/
233
234 static ACPI_STATUS
235 AcpiDbReadTable (
236 FILE *fp,
237 ACPI_TABLE_HEADER **Table,
238 UINT32 *TableLength)
239 {
240 ACPI_TABLE_HEADER TableHeader;
241 UINT32 Actual;
242 ACPI_STATUS Status;
243 UINT32 FileSize;
244 BOOLEAN StandardHeader = TRUE;
245
246
247 /* Get the file size */
248
249 fseek (fp, 0, SEEK_END);
250 FileSize = (UINT32) ftell (fp);
251 fseek (fp, 0, SEEK_SET);
252
253 if (FileSize < 4)
254 {
255 return (AE_BAD_HEADER);
256 }
257
258 /* Read the signature */
259
260 if (fread (&TableHeader, 1, 4, fp) != 4)
261 {
262 AcpiOsPrintf ("Could not read the table signature\n");
263 return (AE_BAD_HEADER);
264 }
265
266 fseek (fp, 0, SEEK_SET);
267
268 /* The RSDP table does not have standard ACPI header */
269
270 if (ACPI_COMPARE_NAME (TableHeader.Signature, "RSD "))
271 {
272 *TableLength = FileSize;
273 StandardHeader = FALSE;
274 }
275 else
276 {
277 /* Read the table header */
278
279 if (fread (&TableHeader, 1, sizeof (ACPI_TABLE_HEADER), fp) !=
280 sizeof (ACPI_TABLE_HEADER))
281 {
282 AcpiOsPrintf ("Could not read the table header\n");
283 return (AE_BAD_HEADER);
284 }
285
286 #if 0
287 /* Validate the table header/length */
288
289 Status = AcpiTbValidateTableHeader (&TableHeader);
290 if (ACPI_FAILURE (Status))
291 {
292 AcpiOsPrintf ("Table header is invalid!\n");
293 return (Status);
294 }
295 #endif
296
297 /* File size must be at least as long as the Header-specified length */
298
299 if (TableHeader.Length > FileSize)
300 {
301 AcpiOsPrintf (
302 "TableHeader length [0x%X] greater than the input file size [0x%X]\n",
303 TableHeader.Length, FileSize);
304
305 #ifdef ACPI_ASL_COMPILER
306 Status = FlCheckForAscii (fp, NULL, FALSE);
307 if (ACPI_SUCCESS (Status))
308 {
309 AcpiOsPrintf ("File appears to be ASCII only, must be binary\n",
310 TableHeader.Length, FileSize);
311 }
312 #endif
313 return (AE_BAD_HEADER);
314 }
315
316 #ifdef ACPI_OBSOLETE_CODE
317 /* We only support a limited number of table types */
318
319 if (!ACPI_COMPARE_NAME ((char *) TableHeader.Signature, ACPI_SIG_DSDT) &&
320 !ACPI_COMPARE_NAME ((char *) TableHeader.Signature, ACPI_SIG_PSDT) &&
321 !ACPI_COMPARE_NAME ((char *) TableHeader.Signature, ACPI_SIG_SSDT))
322 {
323 AcpiOsPrintf ("Table signature [%4.4s] is invalid or not supported\n",
324 (char *) TableHeader.Signature);
325 ACPI_DUMP_BUFFER (&TableHeader, sizeof (ACPI_TABLE_HEADER));
326 return (AE_ERROR);
327 }
328 #endif
329
330 *TableLength = TableHeader.Length;
331 }
332
333 /* Allocate a buffer for the table */
334
335 *Table = AcpiOsAllocate ((size_t) FileSize);
336 if (!*Table)
337 {
338 AcpiOsPrintf (
339 "Could not allocate memory for ACPI table %4.4s (size=0x%X)\n",
340 TableHeader.Signature, *TableLength);
341 return (AE_NO_MEMORY);
342 }
343
344 /* Get the rest of the table */
345
346 fseek (fp, 0, SEEK_SET);
347 Actual = fread (*Table, 1, (size_t) FileSize, fp);
348 if (Actual == FileSize)
349 {
350 if (StandardHeader)
351 {
352 /* Now validate the checksum */
353
354 Status = AcpiTbVerifyChecksum ((void *) *Table,
355 ACPI_CAST_PTR (ACPI_TABLE_HEADER, *Table)->Length);
356
357 if (Status == AE_BAD_CHECKSUM)
358 {
359 Status = AcpiDbCheckTextModeCorruption ((UINT8 *) *Table,
360 FileSize, (*Table)->Length);
361 return (Status);
362 }
363 }
364 return (AE_OK);
365 }
366
367 if (Actual > 0)
368 {
369 AcpiOsPrintf ("Warning - reading table, asked for %X got %X\n",
370 FileSize, Actual);
371 return (AE_OK);
372 }
373
374 AcpiOsPrintf ("Error - could not read the table file\n");
375 AcpiOsFree (*Table);
376 *Table = NULL;
377 *TableLength = 0;
378 return (AE_ERROR);
379 }
380
381
382 /*******************************************************************************
383 *
384 * FUNCTION: AeLocalLoadTable
385 *
386 * PARAMETERS: Table - pointer to a buffer containing the entire
387 * table to be loaded
388 *
389 * RETURN: Status
390 *
391 * DESCRIPTION: This function is called to load a table from the caller's
392 * buffer. The buffer must contain an entire ACPI Table including
393 * a valid header. The header fields will be verified, and if it
394 * is determined that the table is invalid, the call will fail.
395 *
396 ******************************************************************************/
397
398 static ACPI_STATUS
399 AeLocalLoadTable (
400 ACPI_TABLE_HEADER *Table)
401 {
402 ACPI_STATUS Status = AE_OK;
403 /* ACPI_TABLE_DESC TableInfo; */
404
405
406 ACPI_FUNCTION_TRACE (AeLocalLoadTable);
407 #if 0
408
409
410 if (!Table)
411 {
412 return_ACPI_STATUS (AE_BAD_PARAMETER);
413 }
414
415 TableInfo.Pointer = Table;
416 Status = AcpiTbRecognizeTable (&TableInfo, ACPI_TABLE_ALL);
417 if (ACPI_FAILURE (Status))
418 {
419 return_ACPI_STATUS (Status);
420 }
421
422 /* Install the new table into the local data structures */
423
424 Status = AcpiTbInstallTable (&TableInfo);
425 if (ACPI_FAILURE (Status))
426 {
427 if (Status == AE_ALREADY_EXISTS)
428 {
429 /* Table already exists, no error */
430
431 Status = AE_OK;
432 }
433
434 /* Free table allocated by AcpiTbGetTable */
435
436 AcpiTbDeleteSingleTable (&TableInfo);
437 return_ACPI_STATUS (Status);
438 }
439
440 #if (!defined (ACPI_NO_METHOD_EXECUTION) && !defined (ACPI_CONSTANT_EVAL_ONLY))
441
442 Status = AcpiNsLoadTable (TableInfo.InstalledDesc, AcpiGbl_RootNode);
443 if (ACPI_FAILURE (Status))
444 {
445 /* Uninstall table and free the buffer */
446
447 AcpiTbDeleteTablesByType (ACPI_TABLE_ID_DSDT);
448 return_ACPI_STATUS (Status);
449 }
450 #endif
451 #endif
452
453 return_ACPI_STATUS (Status);
454 }
455
456
457 /*******************************************************************************
458 *
459 * FUNCTION: AcpiDbReadTableFromFile
460 *
461 * PARAMETERS: Filename - File where table is located
462 * Table - Where a pointer to the table is returned
463 *
464 * RETURN: Status
465 *
466 * DESCRIPTION: Get an ACPI table from a file
467 *
468 ******************************************************************************/
469
470 ACPI_STATUS
471 AcpiDbReadTableFromFile (
472 char *Filename,
473 ACPI_TABLE_HEADER **Table)
474 {
475 FILE *File;
476 UINT32 TableLength;
477 ACPI_STATUS Status;
478
479
480 /* Open the file */
481
482 File = fopen (Filename, "rb");
483 if (!File)
484 {
485 perror ("Could not open input file");
486 return (AE_ERROR);
487 }
488
489 /* Get the entire file */
490
491 fprintf (stderr, "Loading Acpi table from file %s\n", Filename);
492 Status = AcpiDbReadTable (File, Table, &TableLength);
493 fclose(File);
494
495 if (ACPI_FAILURE (Status))
496 {
497 AcpiOsPrintf ("Could not get table from the file\n");
498 return (Status);
499 }
500
501 return (AE_OK);
502 }
503 #endif
504
505
506 /*******************************************************************************
507 *
508 * FUNCTION: AcpiDbGetTableFromFile
509 *
510 * PARAMETERS: Filename - File where table is located
511 * ReturnTable - Where a pointer to the table is returned
512 *
513 * RETURN: Status
514 *
515 * DESCRIPTION: Load an ACPI table from a file
516 *
517 ******************************************************************************/
518
519 ACPI_STATUS
520 AcpiDbGetTableFromFile (
521 char *Filename,
522 ACPI_TABLE_HEADER **ReturnTable)
523 {
524 #ifdef ACPI_APPLICATION
525 ACPI_STATUS Status;
526 ACPI_TABLE_HEADER *Table;
527 BOOLEAN IsAmlTable = TRUE;
528
529
530 Status = AcpiDbReadTableFromFile (Filename, &Table);
531 if (ACPI_FAILURE (Status))
532 {
533 return (Status);
534 }
535
536 #ifdef ACPI_DATA_TABLE_DISASSEMBLY
537 IsAmlTable = AcpiUtIsAmlTable (Table);
538 #endif
539
540 if (IsAmlTable)
541 {
542 /* Attempt to recognize and install the table */
543
544 Status = AeLocalLoadTable (Table);
545 if (ACPI_FAILURE (Status))
546 {
547 if (Status == AE_ALREADY_EXISTS)
548 {
549 AcpiOsPrintf ("Table %4.4s is already installed\n",
550 Table->Signature);
551 }
552 else
553 {
554 AcpiOsPrintf ("Could not install table, %s\n",
555 AcpiFormatException (Status));
556 }
557
558 return (Status);
559 }
560
561 fprintf (stderr,
562 "Acpi table [%4.4s] successfully installed and loaded\n",
563 Table->Signature);
564 }
565
566 AcpiGbl_AcpiHardwarePresent = FALSE;
567 if (ReturnTable)
568 {
569 *ReturnTable = Table;
570 }
571
572
573 #endif /* ACPI_APPLICATION */
574 return (AE_OK);
575 }
576
577 #endif /* ACPI_DEBUGGER */
578