Sync ACPICA with Intel's version 20150930.
[dragonfly.git] / sys / contrib / dev / acpica / source / components / utilities / utfileio.c
CommitLineData
5f39c7e7
SW
1/*******************************************************************************
2 *
3 * Module Name: utfileio - simple file I/O routines
4 *
5 ******************************************************************************/
6
7/*
fe7b5cb4 8 * Copyright (C) 2000 - 2015, Intel Corp.
5f39c7e7
SW
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
5f39c7e7
SW
44#include "acpi.h"
45#include "accommon.h"
46#include "actables.h"
47#include "acapps.h"
c6400d37 48#include "errno.h"
5f39c7e7
SW
49
50#ifdef ACPI_ASL_COMPILER
51#include "aslcompiler.h"
52#endif
53
54
55#define _COMPONENT ACPI_CA_DEBUGGER
56 ACPI_MODULE_NAME ("utfileio")
57
58
59#ifdef ACPI_APPLICATION
60
61/* Local prototypes */
62
63static ACPI_STATUS
64AcpiUtCheckTextModeCorruption (
65 UINT8 *Table,
66 UINT32 TableLength,
67 UINT32 FileLength);
68
69static ACPI_STATUS
70AcpiUtReadTable (
71 FILE *fp,
72 ACPI_TABLE_HEADER **Table,
73 UINT32 *TableLength);
74
75
76/*******************************************************************************
77 *
78 * FUNCTION: AcpiUtCheckTextModeCorruption
79 *
80 * PARAMETERS: Table - Table buffer
81 * TableLength - Length of table from the table header
82 * FileLength - Length of the file that contains the table
83 *
84 * RETURN: Status
85 *
86 * DESCRIPTION: Check table for text mode file corruption where all linefeed
87 * characters (LF) have been replaced by carriage return linefeed
88 * pairs (CR/LF).
89 *
90 ******************************************************************************/
91
92static ACPI_STATUS
93AcpiUtCheckTextModeCorruption (
94 UINT8 *Table,
95 UINT32 TableLength,
96 UINT32 FileLength)
97{
98 UINT32 i;
99 UINT32 Pairs = 0;
100
101
102 if (TableLength != FileLength)
103 {
104 ACPI_WARNING ((AE_INFO,
105 "File length (0x%X) is not the same as the table length (0x%X)",
106 FileLength, TableLength));
107 }
108
109 /* Scan entire table to determine if each LF has been prefixed with a CR */
110
111 for (i = 1; i < FileLength; i++)
112 {
113 if (Table[i] == 0x0A)
114 {
115 if (Table[i - 1] != 0x0D)
116 {
117 /* The LF does not have a preceding CR, table not corrupted */
118
119 return (AE_OK);
120 }
121 else
122 {
123 /* Found a CR/LF pair */
124
125 Pairs++;
126 }
127 i++;
128 }
129 }
130
131 if (!Pairs)
132 {
133 return (AE_OK);
134 }
135
136 /*
137 * Entire table scanned, each CR is part of a CR/LF pair --
138 * meaning that the table was treated as a text file somewhere.
139 *
140 * NOTE: We can't "fix" the table, because any existing CR/LF pairs in the
141 * original table are left untouched by the text conversion process --
142 * meaning that we cannot simply replace CR/LF pairs with LFs.
143 */
144 AcpiOsPrintf ("Table has been corrupted by text mode conversion\n");
145 AcpiOsPrintf ("All LFs (%u) were changed to CR/LF pairs\n", Pairs);
146 AcpiOsPrintf ("Table cannot be repaired!\n");
147 return (AE_BAD_VALUE);
148}
149
150
151/*******************************************************************************
152 *
153 * FUNCTION: AcpiUtReadTable
154 *
155 * PARAMETERS: fp - File that contains table
156 * Table - Return value, buffer with table
157 * TableLength - Return value, length of table
158 *
159 * RETURN: Status
160 *
161 * DESCRIPTION: Load the DSDT from the file pointer
162 *
163 ******************************************************************************/
164
165static ACPI_STATUS
166AcpiUtReadTable (
167 FILE *fp,
168 ACPI_TABLE_HEADER **Table,
169 UINT32 *TableLength)
170{
171 ACPI_TABLE_HEADER TableHeader;
172 UINT32 Actual;
173 ACPI_STATUS Status;
174 UINT32 FileSize;
175 BOOLEAN StandardHeader = TRUE;
176 INT32 Count;
177
178 /* Get the file size */
179
180 FileSize = CmGetFileSize (fp);
181 if (FileSize == ACPI_UINT32_MAX)
182 {
183 return (AE_ERROR);
184 }
185
186 if (FileSize < 4)
187 {
188 return (AE_BAD_HEADER);
189 }
190
191 /* Read the signature */
192
193 fseek (fp, 0, SEEK_SET);
194
195 Count = fread (&TableHeader, 1, sizeof (ACPI_TABLE_HEADER), fp);
196 if (Count != sizeof (ACPI_TABLE_HEADER))
197 {
198 AcpiOsPrintf ("Could not read the table header\n");
199 return (AE_BAD_HEADER);
200 }
201
202 /* The RSDP table does not have standard ACPI header */
203
204 if (ACPI_VALIDATE_RSDP_SIG (TableHeader.Signature))
205 {
206 *TableLength = FileSize;
207 StandardHeader = FALSE;
208 }
209 else
210 {
211
212#if 0
213 /* Validate the table header/length */
214
215 Status = AcpiTbValidateTableHeader (&TableHeader);
216 if (ACPI_FAILURE (Status))
217 {
218 AcpiOsPrintf ("Table header is invalid!\n");
219 return (Status);
220 }
221#endif
222
223 /* File size must be at least as long as the Header-specified length */
224
225 if (TableHeader.Length > FileSize)
226 {
227 AcpiOsPrintf (
228 "TableHeader length [0x%X] greater than the input file size [0x%X]\n",
229 TableHeader.Length, FileSize);
230
231#ifdef ACPI_ASL_COMPILER
896f2e3a
SW
232 AcpiOsPrintf ("File is corrupt or is ASCII text -- "
233 "it must be a binary file\n");
5f39c7e7
SW
234#endif
235 return (AE_BAD_HEADER);
236 }
237
238#ifdef ACPI_OBSOLETE_CODE
239 /* We only support a limited number of table types */
240
241 if (!ACPI_COMPARE_NAME ((char *) TableHeader.Signature, ACPI_SIG_DSDT) &&
242 !ACPI_COMPARE_NAME ((char *) TableHeader.Signature, ACPI_SIG_PSDT) &&
243 !ACPI_COMPARE_NAME ((char *) TableHeader.Signature, ACPI_SIG_SSDT))
244 {
245 AcpiOsPrintf ("Table signature [%4.4s] is invalid or not supported\n",
246 (char *) TableHeader.Signature);
247 ACPI_DUMP_BUFFER (&TableHeader, sizeof (ACPI_TABLE_HEADER));
248 return (AE_ERROR);
249 }
250#endif
251
252 *TableLength = TableHeader.Length;
253 }
254
255 /* Allocate a buffer for the table */
256
257 *Table = AcpiOsAllocate ((size_t) FileSize);
258 if (!*Table)
259 {
260 AcpiOsPrintf (
261 "Could not allocate memory for ACPI table %4.4s (size=0x%X)\n",
262 TableHeader.Signature, *TableLength);
263 return (AE_NO_MEMORY);
264 }
265
266 /* Get the rest of the table */
267
268 fseek (fp, 0, SEEK_SET);
269 Actual = fread (*Table, 1, (size_t) FileSize, fp);
270 if (Actual == FileSize)
271 {
272 if (StandardHeader)
273 {
274 /* Now validate the checksum */
275
276 Status = AcpiTbVerifyChecksum ((void *) *Table,
277 ACPI_CAST_PTR (ACPI_TABLE_HEADER, *Table)->Length);
278
279 if (Status == AE_BAD_CHECKSUM)
280 {
281 Status = AcpiUtCheckTextModeCorruption ((UINT8 *) *Table,
282 FileSize, (*Table)->Length);
283 return (Status);
284 }
285 }
286 return (AE_OK);
287 }
288
289 if (Actual > 0)
290 {
291 AcpiOsPrintf ("Warning - reading table, asked for %X got %X\n",
292 FileSize, Actual);
293 return (AE_OK);
294 }
295
296 AcpiOsPrintf ("Error - could not read the table file\n");
297 AcpiOsFree (*Table);
298 *Table = NULL;
299 *TableLength = 0;
300 return (AE_ERROR);
301}
302
303
304/*******************************************************************************
305 *
306 * FUNCTION: AcpiUtReadTableFromFile
307 *
308 * PARAMETERS: Filename - File where table is located
309 * Table - Where a pointer to the table is returned
310 *
311 * RETURN: Status
312 *
313 * DESCRIPTION: Get an ACPI table from a file
314 *
315 ******************************************************************************/
316
317ACPI_STATUS
318AcpiUtReadTableFromFile (
319 char *Filename,
320 ACPI_TABLE_HEADER **Table)
321{
322 FILE *File;
323 UINT32 FileSize;
324 UINT32 TableLength;
325 ACPI_STATUS Status = AE_ERROR;
326
327
328 /* Open the file, get current size */
329
330 File = fopen (Filename, "rb");
331 if (!File)
332 {
333 perror ("Could not open input file");
c6400d37
SW
334
335 if (errno == ENOENT)
336 {
337 return (AE_NOT_EXIST);
338 }
339
5f39c7e7
SW
340 return (Status);
341 }
342
343 FileSize = CmGetFileSize (File);
344 if (FileSize == ACPI_UINT32_MAX)
345 {
346 goto Exit;
347 }
348
349 /* Get the entire file */
350
3cc0afc6
SW
351 fprintf (stderr,
352 "Reading ACPI table from file %12s - Length %.8u (0x%06X)\n",
5f39c7e7
SW
353 Filename, FileSize, FileSize);
354
355 Status = AcpiUtReadTable (File, Table, &TableLength);
356 if (ACPI_FAILURE (Status))
357 {
358 AcpiOsPrintf ("Could not get table from the file\n");
359 }
360
361Exit:
362 fclose(File);
363 return (Status);
364}
365
366#endif