From f0d66bb3979a2bcba84027cb2d09f5de76fec9a4 Mon Sep 17 00:00:00 2001 From: Sami Mujawar Date: Fri, 21 Apr 2017 17:07:03 +0100 Subject: [PATCH] Add support for hex AML C header file generation The iAsl compiler provides a list of options to support 'Firmware Support - C Text Output'. One of the options, '-tc' supports generation of AML hex tables in C. This command generates a character array that represents the AML hex table data. e.g. unsigned char AmlCode[] = { // HEX AML data ... }; However, there is no option to change the name of the generated character array (AmlCode) in the output hex file. This limits the ability to reference more than one table from the firmware code. Also, the generated output does not have header file include guards. This is ideally desired if the hex file is to be included from a C source file. A solution to this is to modify the Hex C output such that the name of the array is derived from the input file name, and to add header file include guards. To address the above, without breaking existing implementations, a new option '-th' is introduced in the list of supported 'Firmware Support - C Text Output' commands. This option generates an AML hex table output in a C header file suitable for including from a C source file. The '-th' option: 1. Uses the input file name as a prefix for the generated C array name. e.g. 'unsigned char DadtAmlCode[]' 2. Adds a header file include guard. e.g. #ifndef DSDT_HEX_ #define DSDT_HEX_ ... unsigned char DadtAmlCode[] = { // HEX AML data ... }; #endif // DSDT_HEX_ Where Dadt.aml is the input file name. Note: The header file include guard uses '_HEX_' format instead of '_H_' to avoid possible collision with an existing header guard. Signed-off-by: Sami Mujawar Signed-off-by: Evan Lloyd Github-Location: https://github.com/acpica/acpica/pull/368/commits/f0d66bb3979a2bcba84027cb2d09f5de76fec9a4 --- source/compiler/aslcompile.c | 12 +++- source/compiler/aslglobal.h | 1 + source/compiler/aslhelp.c | 1 + source/compiler/aslhex.c | 154 +++++++++++++++++++++++++++++++++++++++++++ source/compiler/asloptions.c | 5 ++ source/include/acapps.h | 6 ++ 6 files changed, 176 insertions(+), 3 deletions(-) Index: acpica-unix2-20180209/source/compiler/aslcompile.c =================================================================== --- acpica-unix2-20180209.orig/source/compiler/aslcompile.c +++ acpica-unix2-20180209/source/compiler/aslcompile.c @@ -436,7 +436,8 @@ AslCompilerSignon ( Prefix = "; "; } else if ((Gbl_HexOutputFlag == HEX_OUTPUT_C) || - (Gbl_HexOutputFlag == HEX_OUTPUT_ASL)) + (Gbl_HexOutputFlag == HEX_OUTPUT_ASL) || + (Gbl_HexOutputFlag == HEX_OUTPUT_H)) { FlPrintFile (ASL_FILE_HEX_OUTPUT, "/*\n"); Prefix = " * "; @@ -471,7 +472,11 @@ AslCompilerSignon ( /* Compiler signon with copyright */ FlPrintFile (FileId, "%s\n", Prefix); - FlPrintFile (FileId, ACPI_COMMON_HEADER (UtilityName, Prefix)); + if (Gbl_HexOutputFlag == HEX_OUTPUT_H) { + FlPrintFile (FileId, ACPI_COMMON_HEADER_NO_COPYRIGHT (UtilityName, Prefix)); + } else { + FlPrintFile (FileId, ACPI_COMMON_HEADER (UtilityName, Prefix)); + } } @@ -513,7 +518,8 @@ AslCompilerFileHeader ( Prefix = "; "; } else if ((Gbl_HexOutputFlag == HEX_OUTPUT_C) || - (Gbl_HexOutputFlag == HEX_OUTPUT_ASL)) + (Gbl_HexOutputFlag == HEX_OUTPUT_ASL) || + (Gbl_HexOutputFlag == HEX_OUTPUT_H)) { Prefix = " * "; } Index: acpica-unix2-20180209/source/compiler/aslglobal.h =================================================================== --- acpica-unix2-20180209.orig/source/compiler/aslglobal.h +++ acpica-unix2-20180209/source/compiler/aslglobal.h @@ -220,6 +220,7 @@ ASL_EXTERN BOOLEAN ASL_ #define HEX_OUTPUT_C 1 #define HEX_OUTPUT_ASM 2 #define HEX_OUTPUT_ASL 3 +#define HEX_OUTPUT_H 4 ASL_EXTERN BOOLEAN ASL_INIT_GLOBAL (Gbl_HexOutputFlag, HEX_OUTPUT_NONE); Index: acpica-unix2-20180209/source/compiler/aslhelp.c =================================================================== --- acpica-unix2-20180209.orig/source/compiler/aslhelp.c +++ acpica-unix2-20180209/source/compiler/aslhelp.c @@ -121,6 +121,7 @@ Usage ( printf ("\nFirmware Support - C Text Output:\n"); ACPI_OPTION ("-tc", "Create hex AML table in C (*.hex)"); + ACPI_OPTION ("-th", "Create hex AML table in C header (*.hex)"); ACPI_OPTION ("-sc", "Create named hex AML arrays in C (*.c)"); ACPI_OPTION ("-ic", "Create include file in C for -sc symbols (*.h)"); ACPI_OPTION ("-so", "Create namespace AML offset table in C (*.offset.h)"); Index: acpica-unix2-20180209/source/compiler/aslhex.c =================================================================== --- acpica-unix2-20180209.orig/source/compiler/aslhex.c +++ acpica-unix2-20180209/source/compiler/aslhex.c @@ -46,6 +46,10 @@ #define _COMPONENT ACPI_COMPILER ACPI_MODULE_NAME ("ashex") +#ifndef PATH_MAX +#define PATH_MAX 256 +#endif + /* * This module emits ASCII hex output files in either C, ASM, or ASL format */ @@ -64,6 +68,10 @@ static void HxDoHexOutputAsm ( void); +static void +HxDoHexOutputH ( + void); + static UINT32 HxReadAmlOutputFile ( UINT8 *Buffer); @@ -104,6 +112,11 @@ HxDoHexOutput ( HxDoHexOutputAsl (); break; + case HEX_OUTPUT_H: + + HxDoHexOutputH (); + break; + default: /* No other output types supported */ @@ -233,6 +246,147 @@ HxDoHexOutputC ( } +/******************************************************************************* +* +* FUNCTION: HxDoHexOutputH +* +* PARAMETERS: None +* +* RETURN: None +* +* DESCRIPTION: Create the hex output file. This is the same data as the AML +* output file, but formatted into hex/ASCII bytes suitable for +* inclusion into a C source file. +* +******************************************************************************/ + +static void +HxDoHexOutputH ( + void) +{ + UINT8 FileData[HEX_TABLE_LINE_SIZE]; + UINT32 LineLength; + UINT32 Offset = 0; + UINT32 AmlFileSize; + UINT32 i; + UINT32 FileNamePrefixLength; + char *DotPosition; + char *InputFileName; + char *NamePosition; + char *FileNameEndPosition; + char FileNamePrefix[PATH_MAX]; + char FileGuard[PATH_MAX]; + + /* Get AML size, seek back to start */ + + AmlFileSize = FlGetFileSize (ASL_FILE_AML_OUTPUT); + FlSeekFile (ASL_FILE_AML_OUTPUT, 0); + + /* + * Find the filename and use it as a prefix for + * the AML code array and the header file guard + */ + InputFileName = Gbl_Files[ASL_FILE_INPUT].Filename; + FileNameEndPosition = InputFileName + strlen (InputFileName); + + NamePosition = strrchr (InputFileName, '/'); + if (NamePosition == NULL) { + /* '/' not found. This means the input file name + * does not contain the path and is in the current + * directory. + */ + NamePosition = InputFileName; + } else { + /* '/' was found. So move to the next character + * which is the name of the input file. + */ + NamePosition++; + } + + /* Get the file name without the extension to use + * as a prefix. + */ + DotPosition = strrchr (NamePosition, '.'); + if (DotPosition) { + /* No dot or suffix */ + FileNameEndPosition = DotPosition; + } + + FileNamePrefixLength = FileNameEndPosition - NamePosition; + if (FileNamePrefixLength > (PATH_MAX - 1)) { + AslError (ASL_ERROR, ASL_MSG_STRING_LENGTH, NULL, ": Input file name too long."); + return; + } + + strncpy (FileNamePrefix, NamePosition, FileNamePrefixLength); + /* NULL terminate the string */ + FileNamePrefix[FileNamePrefixLength] = '\0'; + + if (strrchr (FileNamePrefix, ' ')) { + AslError (ASL_ERROR, ASL_MSG_SYNTAX, NULL, "Input file name has space."); + return; + } + + strcpy (FileGuard, FileNamePrefix); + AcpiUtStrupr (FileGuard); + + /* Generate the hex output. */ + FlPrintFile (ASL_FILE_HEX_OUTPUT, " * C header code output\n"); + FlPrintFile (ASL_FILE_HEX_OUTPUT, " * AML code block contains 0x%X bytes\n *\n */\n", + AmlFileSize); + FlPrintFile (ASL_FILE_HEX_OUTPUT, "\n"); + FlPrintFile (ASL_FILE_HEX_OUTPUT, "#ifndef %s_HEX_\n", FileGuard); + FlPrintFile (ASL_FILE_HEX_OUTPUT, "#define %s_HEX_\n", FileGuard); + FlPrintFile (ASL_FILE_HEX_OUTPUT, "\n"); + FlPrintFile (ASL_FILE_HEX_OUTPUT, "unsigned char %sAmlCode[] =\n{\n", FileNamePrefix); + + while (Offset < AmlFileSize) { + /* Read enough bytes needed for one output line */ + + LineLength = HxReadAmlOutputFile (FileData); + if (!LineLength) { + break; + } + + FlPrintFile (ASL_FILE_HEX_OUTPUT, " "); + + for (i = 0; i < LineLength; i++) { + /* + * Print each hex byte. + * Add a comma until the very last byte of the AML file + * (Some C compilers complain about a trailing comma) + */ + FlPrintFile (ASL_FILE_HEX_OUTPUT, "0x%2.2X", FileData[i]); + if ((Offset + i + 1) < AmlFileSize) { + FlPrintFile (ASL_FILE_HEX_OUTPUT, ","); + } else { + FlPrintFile (ASL_FILE_HEX_OUTPUT, " "); + } + } + + /* Add fill spaces if needed for last line */ + + if (LineLength < HEX_TABLE_LINE_SIZE) { + FlPrintFile (ASL_FILE_HEX_OUTPUT, "%*s", + 5 * (HEX_TABLE_LINE_SIZE - LineLength), " "); + } + + /* Emit the offset and ASCII dump for the entire line */ + + FlPrintFile (ASL_FILE_HEX_OUTPUT, " /* %8.8X", Offset); + LsDumpAsciiInComment (ASL_FILE_HEX_OUTPUT, LineLength, FileData); + + FlPrintFile (ASL_FILE_HEX_OUTPUT, "%*s*/\n", + HEX_TABLE_LINE_SIZE - LineLength + 1, " "); + + Offset += LineLength; + } + + FlPrintFile (ASL_FILE_HEX_OUTPUT, "};\n"); + FlPrintFile (ASL_FILE_HEX_OUTPUT, "\n#endif // %s_HEX_\n", FileGuard); +} + + /******************************************************************************* * * FUNCTION: HxDoHexOutputAsl Index: acpica-unix2-20180209/source/compiler/asloptions.c =================================================================== --- acpica-unix2-20180209.orig/source/compiler/asloptions.c +++ acpica-unix2-20180209/source/compiler/asloptions.c @@ -734,6 +734,11 @@ AslDoOptions ( Gbl_HexOutputFlag = HEX_OUTPUT_ASL; break; + case 'h': + + Gbl_HexOutputFlag = HEX_OUTPUT_H; + break; + default: printf ("Unknown option: -t%s\n", AcpiGbl_Optarg); Index: acpica-unix2-20180209/source/include/acapps.h =================================================================== --- acpica-unix2-20180209.orig/source/include/acapps.h +++ acpica-unix2-20180209/source/include/acapps.h @@ -80,6 +80,12 @@ Prefix, ACPICA_COPYRIGHT, \ Prefix +#define ACPI_COMMON_HEADER_NO_COPYRIGHT(UtilityName, Prefix) \ + "%s%s\n%s%s version %8.8X%s\n%s\n", \ + Prefix, ACPICA_NAME, \ + Prefix, UtilityName, ((UINT32) ACPI_CA_VERSION), ACPI_WIDTH, \ + Prefix + #define ACPI_COMMON_BUILD_TIME \ "Build date/time: %s %s\n", __DATE__, __TIME__