Sync ACPICA with Intel's version 20161117.
[dragonfly.git] / sys / contrib / dev / acpica / source / tools / acpixtract / axutils.c
blob68e51daa2dda2d4402624fe92114348f0df91472
1 /******************************************************************************
3 * Module Name: axutils - Utility functions for acpixtract tool.
5 *****************************************************************************/
7 /*
8 * Copyright (C) 2000 - 2016, Intel Corp.
9 * All rights reserved.
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.
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.
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.
44 #include "acpixtract.h"
47 /*******************************************************************************
49 * FUNCTION: AxCheckAscii
51 * PARAMETERS: Name - Ascii string, at least as long as Count
52 * Count - Number of characters to check
54 * RETURN: None
56 * DESCRIPTION: Ensure that the requested number of characters are printable
57 * Ascii characters. Sets non-printable and null chars to <space>.
59 ******************************************************************************/
61 void
62 AxCheckAscii (
63 char *Name,
64 int Count)
66 int i;
69 for (i = 0; i < Count; i++)
71 if (!Name[i] || !isprint ((int) Name[i]))
73 Name[i] = ' ';
79 /******************************************************************************
81 * FUNCTION: AxIsEmptyLine
83 * PARAMETERS: Buffer - Line from input file
85 * RETURN: TRUE if line is empty (zero or more blanks only)
87 * DESCRIPTION: Determine if an input line is empty.
89 ******************************************************************************/
91 int
92 AxIsEmptyLine (
93 char *Buffer)
96 /* Skip all spaces */
98 while (*Buffer == ' ')
100 Buffer++;
103 /* Line is empty when a Unix or DOS-style line terminator is found. */
105 if ((*Buffer == '\r') || (*Buffer == '\n'))
107 return (1);
110 return (0);
114 /*******************************************************************************
116 * FUNCTION: AxNormalizeSignature
118 * PARAMETERS: Name - Ascii string containing an ACPI signature
120 * RETURN: None
122 * DESCRIPTION: Change "RSD PTR" to "RSDP"
124 ******************************************************************************/
126 void
127 AxNormalizeSignature (
128 char *Signature)
131 if (!strncmp (Signature, "RSD ", 4))
133 Signature[3] = 'P';
138 /******************************************************************************
140 * FUNCTION: AxConvertLine
142 * PARAMETERS: InputLine - One line from the input acpidump file
143 * OutputData - Where the converted data is returned
145 * RETURN: The number of bytes actually converted
147 * DESCRIPTION: Convert one line of ascii text binary (up to 16 bytes)
149 ******************************************************************************/
151 size_t
152 AxConvertLine (
153 char *InputLine,
154 unsigned char *OutputData)
156 char *End;
157 int BytesConverted;
158 int Converted[16];
159 int i;
162 /* Terminate the input line at the end of the actual data (for sscanf) */
164 End = strstr (InputLine + 2, " ");
165 if (!End)
167 return (0); /* Don't understand the format */
169 *End = 0;
172 * Convert one line of table data, of the form:
173 * <offset>: <up to 16 bytes of hex data> <ASCII representation> <newline>
175 * Example:
176 * 02C0: 5F 53 42 5F 4C 4E 4B 44 00 12 13 04 0C FF FF 08 _SB_LNKD........
178 BytesConverted = sscanf (InputLine,
179 "%*s %x %x %x %x %x %x %x %x %x %x %x %x %x %x %x %x",
180 &Converted[0], &Converted[1], &Converted[2], &Converted[3],
181 &Converted[4], &Converted[5], &Converted[6], &Converted[7],
182 &Converted[8], &Converted[9], &Converted[10], &Converted[11],
183 &Converted[12], &Converted[13], &Converted[14], &Converted[15]);
185 /* Pack converted data into a byte array */
187 for (i = 0; i < BytesConverted; i++)
189 OutputData[i] = (unsigned char) Converted[i];
192 return ((size_t) BytesConverted);
196 /******************************************************************************
198 * FUNCTION: AxGetTableHeader
200 * PARAMETERS: InputFile - Handle for the input acpidump file
201 * OutputData - Where the table header is returned
203 * RETURN: The actual number of bytes converted
205 * DESCRIPTION: Extract and convert an ACPI table header
207 ******************************************************************************/
209 size_t
210 AxGetTableHeader (
211 FILE *InputFile,
212 unsigned char *OutputData)
214 size_t BytesConverted;
215 size_t TotalConverted = 0;
216 int i;
219 /* Get the full 36 byte ACPI table header, requires 3 input text lines */
221 for (i = 0; i < 3; i++)
223 if (!fgets (Gbl_HeaderBuffer, AX_LINE_BUFFER_SIZE, InputFile))
225 return (TotalConverted);
228 BytesConverted = AxConvertLine (Gbl_HeaderBuffer, OutputData);
229 TotalConverted += BytesConverted;
230 OutputData += 16;
232 if (BytesConverted != 16)
234 return (TotalConverted);
238 return (TotalConverted);
242 /******************************************************************************
244 * FUNCTION: AxCountTableInstances
246 * PARAMETERS: InputPathname - Filename for acpidump file
247 * Signature - Requested signature to count
249 * RETURN: The number of instances of the signature
251 * DESCRIPTION: Count the instances of tables with the given signature within
252 * the input acpidump file.
254 ******************************************************************************/
256 unsigned int
257 AxCountTableInstances (
258 char *InputPathname,
259 char *Signature)
261 FILE *InputFile;
262 unsigned int Instances = 0;
265 InputFile = fopen (InputPathname, "r");
266 if (!InputFile)
268 printf ("Could not open input file %s\n", InputPathname);
269 return (0);
272 /* Count the number of instances of this signature */
274 while (fgets (Gbl_InstanceBuffer, AX_LINE_BUFFER_SIZE, InputFile))
276 /* Ignore empty lines and lines that start with a space */
278 if (AxIsEmptyLine (Gbl_InstanceBuffer) ||
279 (Gbl_InstanceBuffer[0] == ' '))
281 continue;
284 AxNormalizeSignature (Gbl_InstanceBuffer);
285 if (ACPI_COMPARE_NAME (Gbl_InstanceBuffer, Signature))
287 Instances++;
291 fclose (InputFile);
292 return (Instances);
296 /******************************************************************************
298 * FUNCTION: AxGetNextInstance
300 * PARAMETERS: InputPathname - Filename for acpidump file
301 * Signature - Requested ACPI signature
303 * RETURN: The next instance number for this signature. Zero if this
304 * is the first instance of this signature.
306 * DESCRIPTION: Get the next instance number of the specified table. If this
307 * is the first instance of the table, create a new instance
308 * block. Note: only SSDT and PSDT tables can have multiple
309 * instances.
311 ******************************************************************************/
313 unsigned int
314 AxGetNextInstance (
315 char *InputPathname,
316 char *Signature)
318 AX_TABLE_INFO *Info;
321 Info = Gbl_TableListHead;
322 while (Info)
324 if (*(UINT32 *) Signature == Info->Signature)
326 break;
329 Info = Info->Next;
332 if (!Info)
334 /* Signature not found, create new table info block */
336 Info = malloc (sizeof (AX_TABLE_INFO));
337 if (!Info)
339 printf ("Could not allocate memory (0x%X bytes)\n",
340 (unsigned int) sizeof (AX_TABLE_INFO));
341 exit (0);
344 Info->Signature = *(UINT32 *) Signature;
345 Info->Instances = AxCountTableInstances (InputPathname, Signature);
346 Info->NextInstance = 1;
347 Info->Next = Gbl_TableListHead;
348 Gbl_TableListHead = Info;
351 if (Info->Instances > 1)
353 return (Info->NextInstance++);
356 return (0);
360 /******************************************************************************
362 * FUNCTION: AxIsDataBlockHeader
364 * PARAMETERS: None
366 * RETURN: Status. 1 if the table header is valid, 0 otherwise.
368 * DESCRIPTION: Check if the ACPI table identifier in the input acpidump text
369 * file is valid (of the form: <sig> @ <addr>).
371 ******************************************************************************/
374 AxIsDataBlockHeader (
375 void)
378 /* Ignore lines that are too short to be header lines */
380 if (strlen (Gbl_LineBuffer) < AX_MIN_BLOCK_HEADER_LENGTH)
382 return (0);
385 /* Ignore empty lines and lines that start with a space */
387 if (AxIsEmptyLine (Gbl_LineBuffer) ||
388 (Gbl_LineBuffer[0] == ' '))
390 return (0);
394 * Ignore lines that are not headers of the form <sig> @ <addr>.
395 * Basically, just look for the '@' symbol, surrounded by spaces.
397 * Examples of headers that must be supported:
399 * DSDT @ 0x737e4000
400 * XSDT @ 0x737f2fff
401 * RSD PTR @ 0xf6cd0
402 * SSDT @ (nil)
404 if (!strstr (Gbl_LineBuffer, " @ "))
406 return (0);
409 AxNormalizeSignature (Gbl_LineBuffer);
410 return (1);
414 /******************************************************************************
416 * FUNCTION: AxProcessOneTextLine
418 * PARAMETERS: OutputFile - Where to write the binary data
419 * ThisSignature - Signature of current ACPI table
420 * ThisTableBytesWritten - Total count of data written
422 * RETURN: Length of the converted line
424 * DESCRIPTION: Convert one line of input hex ascii text to binary, and write
425 * the binary data to the table output file.
427 ******************************************************************************/
429 long
430 AxProcessOneTextLine (
431 FILE *OutputFile,
432 char *ThisSignature,
433 unsigned int ThisTableBytesWritten)
435 size_t BytesWritten;
436 size_t BytesConverted;
439 /* Check for the end of this table data block */
441 if (AxIsEmptyLine (Gbl_LineBuffer) ||
442 (Gbl_LineBuffer[0] != ' '))
444 printf (AX_TABLE_INFO_FORMAT,
445 ThisSignature, ThisTableBytesWritten, Gbl_OutputFilename);
446 return (0);
449 /* Convert one line of ascii hex data to binary */
451 BytesConverted = AxConvertLine (Gbl_LineBuffer, Gbl_BinaryData);
453 /* Write the binary data */
455 BytesWritten = fwrite (Gbl_BinaryData, 1, BytesConverted, OutputFile);
456 if (BytesWritten != BytesConverted)
458 printf ("Error while writing file %s\n", Gbl_OutputFilename);
459 return (-1);
462 return (BytesWritten);