1 /******************************************************************************
3 * Module Name: axutils - Utility functions for acpixtract tool.
5 *****************************************************************************/
8 * Copyright (C) 2000 - 2016, Intel Corp.
11 * Redistribution and use in source and binary forms, with or without
12 * modification, are permitted provided that the following conditions
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.
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
56 * DESCRIPTION: Ensure that the requested number of characters are printable
57 * Ascii characters. Sets non-printable and null chars to <space>.
59 ******************************************************************************/
69 for (i
= 0; i
< Count
; i
++)
71 if (!Name
[i
] || !isprint ((int) 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 ******************************************************************************/
98 while (*Buffer
== ' ')
103 /* If end-of-line, this line is empty */
114 /*******************************************************************************
116 * FUNCTION: AxNormalizeSignature
118 * PARAMETERS: Name - Ascii string containing an ACPI signature
122 * DESCRIPTION: Change "RSD PTR" to "RSDP"
124 ******************************************************************************/
127 AxNormalizeSignature (
131 if (!strncmp (Signature
, "RSD ", 4))
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 ******************************************************************************/
154 unsigned char *OutputData
)
162 /* Terminate the input line at the end of the actual data (for sscanf) */
164 End
= strstr (InputLine
+ 2, " ");
167 return (0); /* Don't understand the format */
172 * Convert one line of table data, of the form:
173 * <offset>: <up to 16 bytes of hex data> <ASCII representation> <newline>
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 ******************************************************************************/
212 unsigned char *OutputData
)
214 size_t BytesConverted
;
215 size_t TotalConverted
= 0;
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
;
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 ******************************************************************************/
257 AxCountTableInstances (
262 unsigned int Instances
= 0;
265 InputFile
= fopen (InputPathname
, "rt");
268 printf ("Could not open input file %s\n", InputPathname
);
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] == ' '))
284 AxNormalizeSignature (Gbl_InstanceBuffer
);
285 if (ACPI_COMPARE_NAME (Gbl_InstanceBuffer
, Signature
))
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
311 ******************************************************************************/
321 Info
= Gbl_TableListHead
;
324 if (*(UINT32
*) Signature
== Info
->Signature
)
334 /* Signature not found, create new table info block */
336 Info
= malloc (sizeof (AX_TABLE_INFO
));
339 printf ("Could not allocate memory (0x%X bytes)\n",
340 (unsigned int) sizeof (AX_TABLE_INFO
));
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
++);
360 /******************************************************************************
362 * FUNCTION: AxIsDataBlockHeader
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 (
378 /* Ignore lines that are too short to be header lines */
380 if (strlen (Gbl_LineBuffer
) < AX_MIN_BLOCK_HEADER_LENGTH
)
385 /* Ignore empty lines and lines that start with a space */
387 if (AxIsEmptyLine (Gbl_LineBuffer
) ||
388 (Gbl_LineBuffer
[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:
404 if (!strstr (Gbl_LineBuffer
, " @ "))
409 AxNormalizeSignature (Gbl_LineBuffer
);
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 ******************************************************************************/
430 AxProcessOneTextLine (
433 unsigned int ThisTableBytesWritten
)
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
);
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
);
462 return (BytesWritten
);