1a88e22b7SJung-uk Kim /****************************************************************************** 2a88e22b7SJung-uk Kim * 3a88e22b7SJung-uk Kim * Module Name: dtio.c - File I/O support for data table compiler 4a88e22b7SJung-uk Kim * 5a88e22b7SJung-uk Kim *****************************************************************************/ 6a88e22b7SJung-uk Kim 7d244b227SJung-uk Kim /* 8ec3fc72fSJung-uk Kim * Copyright (C) 2000 - 2012, Intel Corp. 9a88e22b7SJung-uk Kim * All rights reserved. 10a88e22b7SJung-uk Kim * 11d244b227SJung-uk Kim * Redistribution and use in source and binary forms, with or without 12d244b227SJung-uk Kim * modification, are permitted provided that the following conditions 13d244b227SJung-uk Kim * are met: 14d244b227SJung-uk Kim * 1. Redistributions of source code must retain the above copyright 15d244b227SJung-uk Kim * notice, this list of conditions, and the following disclaimer, 16d244b227SJung-uk Kim * without modification. 17d244b227SJung-uk Kim * 2. Redistributions in binary form must reproduce at minimum a disclaimer 18d244b227SJung-uk Kim * substantially similar to the "NO WARRANTY" disclaimer below 19d244b227SJung-uk Kim * ("Disclaimer") and any redistribution must be conditioned upon 20d244b227SJung-uk Kim * including a substantially similar Disclaimer requirement for further 21d244b227SJung-uk Kim * binary redistribution. 22d244b227SJung-uk Kim * 3. Neither the names of the above-listed copyright holders nor the names 23d244b227SJung-uk Kim * of any contributors may be used to endorse or promote products derived 24d244b227SJung-uk Kim * from this software without specific prior written permission. 25a88e22b7SJung-uk Kim * 26d244b227SJung-uk Kim * Alternatively, this software may be distributed under the terms of the 27d244b227SJung-uk Kim * GNU General Public License ("GPL") version 2 as published by the Free 28d244b227SJung-uk Kim * Software Foundation. 29a88e22b7SJung-uk Kim * 30d244b227SJung-uk Kim * NO WARRANTY 31d244b227SJung-uk Kim * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 32d244b227SJung-uk Kim * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 33d244b227SJung-uk Kim * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR 34d244b227SJung-uk Kim * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 35d244b227SJung-uk Kim * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 36d244b227SJung-uk Kim * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 37d244b227SJung-uk Kim * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 38d244b227SJung-uk Kim * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 39d244b227SJung-uk Kim * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING 40d244b227SJung-uk Kim * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 41d244b227SJung-uk Kim * POSSIBILITY OF SUCH DAMAGES. 42d244b227SJung-uk Kim */ 43a88e22b7SJung-uk Kim 44a88e22b7SJung-uk Kim #define __DTIO_C__ 45a88e22b7SJung-uk Kim 46a88e22b7SJung-uk Kim #include <contrib/dev/acpica/compiler/aslcompiler.h> 47a88e22b7SJung-uk Kim #include <contrib/dev/acpica/compiler/dtcompiler.h> 48a88e22b7SJung-uk Kim 49a88e22b7SJung-uk Kim #define _COMPONENT DT_COMPILER 50a88e22b7SJung-uk Kim ACPI_MODULE_NAME ("dtio") 51a88e22b7SJung-uk Kim 52a88e22b7SJung-uk Kim 53a88e22b7SJung-uk Kim /* Local prototypes */ 54a88e22b7SJung-uk Kim 55a88e22b7SJung-uk Kim static char * 56a88e22b7SJung-uk Kim DtTrim ( 57a88e22b7SJung-uk Kim char *String); 58a88e22b7SJung-uk Kim 59a88e22b7SJung-uk Kim static void 60a88e22b7SJung-uk Kim DtLinkField ( 61a88e22b7SJung-uk Kim DT_FIELD *Field); 62a88e22b7SJung-uk Kim 63d244b227SJung-uk Kim static ACPI_STATUS 64a88e22b7SJung-uk Kim DtParseLine ( 65a88e22b7SJung-uk Kim char *LineBuffer, 66a88e22b7SJung-uk Kim UINT32 Line, 67a88e22b7SJung-uk Kim UINT32 Offset); 68a88e22b7SJung-uk Kim 69a88e22b7SJung-uk Kim static void 70a88e22b7SJung-uk Kim DtWriteBinary ( 71a88e22b7SJung-uk Kim DT_SUBTABLE *Subtable, 72a88e22b7SJung-uk Kim void *Context, 73a88e22b7SJung-uk Kim void *ReturnValue); 74a88e22b7SJung-uk Kim 75d244b227SJung-uk Kim static void 76d244b227SJung-uk Kim DtDumpBuffer ( 77d244b227SJung-uk Kim UINT32 FileId, 78d244b227SJung-uk Kim UINT8 *Buffer, 790b94ba42SJung-uk Kim UINT32 Offset, 80d244b227SJung-uk Kim UINT32 Length); 81a88e22b7SJung-uk Kim 820b94ba42SJung-uk Kim 83a88e22b7SJung-uk Kim /* States for DtGetNextLine */ 84a88e22b7SJung-uk Kim 85a88e22b7SJung-uk Kim #define DT_NORMAL_TEXT 0 86a88e22b7SJung-uk Kim #define DT_START_QUOTED_STRING 1 87a88e22b7SJung-uk Kim #define DT_START_COMMENT 2 88a88e22b7SJung-uk Kim #define DT_SLASH_ASTERISK_COMMENT 3 89a88e22b7SJung-uk Kim #define DT_SLASH_SLASH_COMMENT 4 90a88e22b7SJung-uk Kim #define DT_END_COMMENT 5 91d052a1ccSJung-uk Kim #define DT_MERGE_LINES 6 92eef1b955SJung-uk Kim #define DT_ESCAPE_SEQUENCE 7 93a88e22b7SJung-uk Kim 9442fecd12SJung-uk Kim static UINT32 Gbl_NextLineOffset; 95a88e22b7SJung-uk Kim 96a88e22b7SJung-uk Kim 97a88e22b7SJung-uk Kim /****************************************************************************** 98a88e22b7SJung-uk Kim * 99a88e22b7SJung-uk Kim * FUNCTION: DtTrim 100a88e22b7SJung-uk Kim * 101a88e22b7SJung-uk Kim * PARAMETERS: String - Current source code line to trim 102a88e22b7SJung-uk Kim * 103a88e22b7SJung-uk Kim * RETURN: Trimmed line. Must be freed by caller. 104a88e22b7SJung-uk Kim * 105a88e22b7SJung-uk Kim * DESCRIPTION: Trim left and right spaces 106a88e22b7SJung-uk Kim * 107a88e22b7SJung-uk Kim *****************************************************************************/ 108a88e22b7SJung-uk Kim 109a88e22b7SJung-uk Kim static char * 110a88e22b7SJung-uk Kim DtTrim ( 111a88e22b7SJung-uk Kim char *String) 112a88e22b7SJung-uk Kim { 113a88e22b7SJung-uk Kim char *Start; 114a88e22b7SJung-uk Kim char *End; 115a88e22b7SJung-uk Kim char *ReturnString; 116a88e22b7SJung-uk Kim ACPI_SIZE Length; 117a88e22b7SJung-uk Kim 118a88e22b7SJung-uk Kim 119a88e22b7SJung-uk Kim /* Skip lines that start with a space */ 120a88e22b7SJung-uk Kim 121a88e22b7SJung-uk Kim if (!ACPI_STRCMP (String, " ")) 122a88e22b7SJung-uk Kim { 123a88e22b7SJung-uk Kim ReturnString = UtLocalCalloc (1); 124a88e22b7SJung-uk Kim return (ReturnString); 125a88e22b7SJung-uk Kim } 126a88e22b7SJung-uk Kim 127a88e22b7SJung-uk Kim /* Setup pointers to start and end of input string */ 128a88e22b7SJung-uk Kim 129a88e22b7SJung-uk Kim Start = String; 130a88e22b7SJung-uk Kim End = String + ACPI_STRLEN (String) - 1; 131a88e22b7SJung-uk Kim 132a88e22b7SJung-uk Kim /* Find first non-whitespace character */ 133a88e22b7SJung-uk Kim 134a88e22b7SJung-uk Kim while ((Start <= End) && ((*Start == ' ') || (*Start == '\t'))) 135a88e22b7SJung-uk Kim { 136a88e22b7SJung-uk Kim Start++; 137a88e22b7SJung-uk Kim } 138a88e22b7SJung-uk Kim 139a88e22b7SJung-uk Kim /* Find last non-space character */ 140a88e22b7SJung-uk Kim 141a88e22b7SJung-uk Kim while (End >= Start) 142a88e22b7SJung-uk Kim { 143a88e22b7SJung-uk Kim if (*End == '\r' || *End == '\n') 144a88e22b7SJung-uk Kim { 145a88e22b7SJung-uk Kim End--; 146a88e22b7SJung-uk Kim continue; 147a88e22b7SJung-uk Kim } 148a88e22b7SJung-uk Kim 149a88e22b7SJung-uk Kim if (*End != ' ') 150a88e22b7SJung-uk Kim { 151a88e22b7SJung-uk Kim break; 152a88e22b7SJung-uk Kim } 153a88e22b7SJung-uk Kim 154a88e22b7SJung-uk Kim End--; 155a88e22b7SJung-uk Kim } 156a88e22b7SJung-uk Kim 157a88e22b7SJung-uk Kim /* Remove any quotes around the string */ 158a88e22b7SJung-uk Kim 159a88e22b7SJung-uk Kim if (*Start == '\"') 160a88e22b7SJung-uk Kim { 161a88e22b7SJung-uk Kim Start++; 162a88e22b7SJung-uk Kim } 163a88e22b7SJung-uk Kim if (*End == '\"') 164a88e22b7SJung-uk Kim { 165a88e22b7SJung-uk Kim End--; 166a88e22b7SJung-uk Kim } 167a88e22b7SJung-uk Kim 168a88e22b7SJung-uk Kim /* Create the trimmed return string */ 169a88e22b7SJung-uk Kim 170a88e22b7SJung-uk Kim Length = ACPI_PTR_DIFF (End, Start) + 1; 171a88e22b7SJung-uk Kim ReturnString = UtLocalCalloc (Length + 1); 172a88e22b7SJung-uk Kim if (ACPI_STRLEN (Start)) 173a88e22b7SJung-uk Kim { 174a88e22b7SJung-uk Kim ACPI_STRNCPY (ReturnString, Start, Length); 175a88e22b7SJung-uk Kim } 176a88e22b7SJung-uk Kim 177a88e22b7SJung-uk Kim ReturnString[Length] = 0; 178a88e22b7SJung-uk Kim return (ReturnString); 179a88e22b7SJung-uk Kim } 180a88e22b7SJung-uk Kim 181a88e22b7SJung-uk Kim 182a88e22b7SJung-uk Kim /****************************************************************************** 183a88e22b7SJung-uk Kim * 184a88e22b7SJung-uk Kim * FUNCTION: DtLinkField 185a88e22b7SJung-uk Kim * 186a88e22b7SJung-uk Kim * PARAMETERS: Field - New field object to link 187a88e22b7SJung-uk Kim * 188a88e22b7SJung-uk Kim * RETURN: None 189a88e22b7SJung-uk Kim * 190a88e22b7SJung-uk Kim * DESCRIPTION: Link one field name and value to the list 191a88e22b7SJung-uk Kim * 192a88e22b7SJung-uk Kim *****************************************************************************/ 193a88e22b7SJung-uk Kim 194a88e22b7SJung-uk Kim static void 195a88e22b7SJung-uk Kim DtLinkField ( 196a88e22b7SJung-uk Kim DT_FIELD *Field) 197a88e22b7SJung-uk Kim { 198a88e22b7SJung-uk Kim DT_FIELD *Prev; 199a88e22b7SJung-uk Kim DT_FIELD *Next; 200a88e22b7SJung-uk Kim 201a88e22b7SJung-uk Kim 202a88e22b7SJung-uk Kim Prev = Next = Gbl_FieldList; 203a88e22b7SJung-uk Kim 204a88e22b7SJung-uk Kim while (Next) 205a88e22b7SJung-uk Kim { 206a88e22b7SJung-uk Kim Prev = Next; 207a88e22b7SJung-uk Kim Next = Next->Next; 208a88e22b7SJung-uk Kim } 209a88e22b7SJung-uk Kim 210a88e22b7SJung-uk Kim if (Prev) 211a88e22b7SJung-uk Kim { 212a88e22b7SJung-uk Kim Prev->Next = Field; 213a88e22b7SJung-uk Kim } 214a88e22b7SJung-uk Kim else 215a88e22b7SJung-uk Kim { 216a88e22b7SJung-uk Kim Gbl_FieldList = Field; 217a88e22b7SJung-uk Kim } 218a88e22b7SJung-uk Kim } 219a88e22b7SJung-uk Kim 220a88e22b7SJung-uk Kim 221a88e22b7SJung-uk Kim /****************************************************************************** 222a88e22b7SJung-uk Kim * 223a88e22b7SJung-uk Kim * FUNCTION: DtParseLine 224a88e22b7SJung-uk Kim * 225a88e22b7SJung-uk Kim * PARAMETERS: LineBuffer - Current source code line 226a88e22b7SJung-uk Kim * Line - Current line number in the source 227a88e22b7SJung-uk Kim * Offset - Current byte offset of the line 228a88e22b7SJung-uk Kim * 229d244b227SJung-uk Kim * RETURN: Status 230a88e22b7SJung-uk Kim * 231a88e22b7SJung-uk Kim * DESCRIPTION: Parse one source line 232a88e22b7SJung-uk Kim * 233a88e22b7SJung-uk Kim *****************************************************************************/ 234a88e22b7SJung-uk Kim 235d244b227SJung-uk Kim static ACPI_STATUS 236a88e22b7SJung-uk Kim DtParseLine ( 237a88e22b7SJung-uk Kim char *LineBuffer, 238a88e22b7SJung-uk Kim UINT32 Line, 239a88e22b7SJung-uk Kim UINT32 Offset) 240a88e22b7SJung-uk Kim { 241a88e22b7SJung-uk Kim char *Start; 242a88e22b7SJung-uk Kim char *End; 243a88e22b7SJung-uk Kim char *TmpName; 244a88e22b7SJung-uk Kim char *TmpValue; 245a88e22b7SJung-uk Kim char *Name; 246a88e22b7SJung-uk Kim char *Value; 247a88e22b7SJung-uk Kim char *Colon; 248a88e22b7SJung-uk Kim UINT32 Length; 249a88e22b7SJung-uk Kim DT_FIELD *Field; 250a88e22b7SJung-uk Kim UINT32 Column; 251a88e22b7SJung-uk Kim UINT32 NameColumn; 252d052a1ccSJung-uk Kim BOOLEAN IsNullString = FALSE; 253a88e22b7SJung-uk Kim 254a88e22b7SJung-uk Kim 255a88e22b7SJung-uk Kim if (!LineBuffer) 256a88e22b7SJung-uk Kim { 257d244b227SJung-uk Kim return (AE_OK); 258d244b227SJung-uk Kim } 259d244b227SJung-uk Kim 260d244b227SJung-uk Kim /* All lines after "Raw Table Data" are ingored */ 261d244b227SJung-uk Kim 262d244b227SJung-uk Kim if (strstr (LineBuffer, ACPI_RAW_TABLE_DATA_HEADER)) 263d244b227SJung-uk Kim { 264d244b227SJung-uk Kim return (AE_NOT_FOUND); 265a88e22b7SJung-uk Kim } 266a88e22b7SJung-uk Kim 267a88e22b7SJung-uk Kim Colon = strchr (LineBuffer, ':'); 268d244b227SJung-uk Kim if (!Colon) 269a88e22b7SJung-uk Kim { 270d244b227SJung-uk Kim return (AE_OK); 271a88e22b7SJung-uk Kim } 272a88e22b7SJung-uk Kim 273a88e22b7SJung-uk Kim Start = LineBuffer; 274a88e22b7SJung-uk Kim End = Colon; 275a88e22b7SJung-uk Kim 276a88e22b7SJung-uk Kim while (Start < Colon) 277a88e22b7SJung-uk Kim { 278a88e22b7SJung-uk Kim if (*Start == ' ') 279a88e22b7SJung-uk Kim { 280a88e22b7SJung-uk Kim Start++; 281a88e22b7SJung-uk Kim continue; 282a88e22b7SJung-uk Kim } 283a88e22b7SJung-uk Kim 284a88e22b7SJung-uk Kim /* Found left bracket, go to the right bracket */ 285a88e22b7SJung-uk Kim 286a88e22b7SJung-uk Kim if (*Start == '[') 287a88e22b7SJung-uk Kim { 288a88e22b7SJung-uk Kim while (Start < Colon && *Start != ']') 289a88e22b7SJung-uk Kim { 290a88e22b7SJung-uk Kim Start++; 291a88e22b7SJung-uk Kim } 292a88e22b7SJung-uk Kim 293a88e22b7SJung-uk Kim if (Start == Colon) 294a88e22b7SJung-uk Kim { 295a88e22b7SJung-uk Kim break; 296a88e22b7SJung-uk Kim } 297a88e22b7SJung-uk Kim 298a88e22b7SJung-uk Kim Start++; 299a88e22b7SJung-uk Kim continue; 300a88e22b7SJung-uk Kim } 301a88e22b7SJung-uk Kim 302a88e22b7SJung-uk Kim break; 303a88e22b7SJung-uk Kim } 304a88e22b7SJung-uk Kim 305a88e22b7SJung-uk Kim /* 306a88e22b7SJung-uk Kim * There are two column values. One for the field name, 307a88e22b7SJung-uk Kim * and one for the field value. 308a88e22b7SJung-uk Kim */ 309a88e22b7SJung-uk Kim Column = ACPI_PTR_DIFF (Colon, LineBuffer) + 3; 310a88e22b7SJung-uk Kim NameColumn = ACPI_PTR_DIFF (Start, LineBuffer) + 1; 311a88e22b7SJung-uk Kim 312a88e22b7SJung-uk Kim Length = ACPI_PTR_DIFF (End, Start); 313a88e22b7SJung-uk Kim 314a88e22b7SJung-uk Kim TmpName = UtLocalCalloc (Length + 1); 315a88e22b7SJung-uk Kim ACPI_STRNCPY (TmpName, Start, Length); 316a88e22b7SJung-uk Kim Name = DtTrim (TmpName); 317a88e22b7SJung-uk Kim ACPI_FREE (TmpName); 318a88e22b7SJung-uk Kim 319a88e22b7SJung-uk Kim Start = End = (Colon + 1); 320a88e22b7SJung-uk Kim while (*End) 321a88e22b7SJung-uk Kim { 322a88e22b7SJung-uk Kim /* Found left quotation, go to the right quotation and break */ 323a88e22b7SJung-uk Kim 324a88e22b7SJung-uk Kim if (*End == '"') 325a88e22b7SJung-uk Kim { 326a88e22b7SJung-uk Kim End++; 327d052a1ccSJung-uk Kim 328d052a1ccSJung-uk Kim /* Check for an explicit null string */ 329d052a1ccSJung-uk Kim 330d052a1ccSJung-uk Kim if (*End == '"') 331d052a1ccSJung-uk Kim { 332d052a1ccSJung-uk Kim IsNullString = TRUE; 333d052a1ccSJung-uk Kim } 3340b94ba42SJung-uk Kim while (*End && (*End != '"')) 335a88e22b7SJung-uk Kim { 336a88e22b7SJung-uk Kim End++; 337a88e22b7SJung-uk Kim } 338a88e22b7SJung-uk Kim 339a88e22b7SJung-uk Kim End++; 340a88e22b7SJung-uk Kim break; 341a88e22b7SJung-uk Kim } 342a88e22b7SJung-uk Kim 3430b94ba42SJung-uk Kim /* 3440b94ba42SJung-uk Kim * Special "comment" fields at line end, ignore them. 3450b94ba42SJung-uk Kim * Note: normal slash-slash and slash-asterisk comments are 3460b94ba42SJung-uk Kim * stripped already by the DtGetNextLine parser. 3470b94ba42SJung-uk Kim * 3480b94ba42SJung-uk Kim * TBD: Perhaps DtGetNextLine should parse the following type 3490b94ba42SJung-uk Kim * of comments also. 3500b94ba42SJung-uk Kim */ 351d052a1ccSJung-uk Kim if (*End == '[') 352a88e22b7SJung-uk Kim { 353d052a1ccSJung-uk Kim End--; 354a88e22b7SJung-uk Kim break; 355a88e22b7SJung-uk Kim } 356a88e22b7SJung-uk Kim End++; 357a88e22b7SJung-uk Kim } 358a88e22b7SJung-uk Kim 359a88e22b7SJung-uk Kim Length = ACPI_PTR_DIFF (End, Start); 360a88e22b7SJung-uk Kim TmpValue = UtLocalCalloc (Length + 1); 361dcbce41eSJung-uk Kim 362a88e22b7SJung-uk Kim ACPI_STRNCPY (TmpValue, Start, Length); 363a88e22b7SJung-uk Kim Value = DtTrim (TmpValue); 364a88e22b7SJung-uk Kim ACPI_FREE (TmpValue); 365a88e22b7SJung-uk Kim 366d052a1ccSJung-uk Kim /* Create a new field object only if we have a valid value field */ 367d052a1ccSJung-uk Kim 368d052a1ccSJung-uk Kim if ((Value && *Value) || IsNullString) 369a88e22b7SJung-uk Kim { 370a88e22b7SJung-uk Kim Field = UtLocalCalloc (sizeof (DT_FIELD)); 371a88e22b7SJung-uk Kim Field->Name = Name; 372a88e22b7SJung-uk Kim Field->Value = Value; 373a88e22b7SJung-uk Kim Field->Line = Line; 374a88e22b7SJung-uk Kim Field->ByteOffset = Offset; 375a88e22b7SJung-uk Kim Field->NameColumn = NameColumn; 376a88e22b7SJung-uk Kim Field->Column = Column; 377a88e22b7SJung-uk Kim 378a88e22b7SJung-uk Kim DtLinkField (Field); 379a88e22b7SJung-uk Kim } 380d052a1ccSJung-uk Kim else /* Ignore this field, it has no valid data */ 381dcbce41eSJung-uk Kim { 382dcbce41eSJung-uk Kim ACPI_FREE (Name); 383dcbce41eSJung-uk Kim ACPI_FREE (Value); 384dcbce41eSJung-uk Kim } 385d244b227SJung-uk Kim 386d244b227SJung-uk Kim return (AE_OK); 387a88e22b7SJung-uk Kim } 388a88e22b7SJung-uk Kim 389a88e22b7SJung-uk Kim 390a88e22b7SJung-uk Kim /****************************************************************************** 391a88e22b7SJung-uk Kim * 392a88e22b7SJung-uk Kim * FUNCTION: DtGetNextLine 393a88e22b7SJung-uk Kim * 394a88e22b7SJung-uk Kim * PARAMETERS: Handle - Open file handle for the source file 395a88e22b7SJung-uk Kim * 396d052a1ccSJung-uk Kim * RETURN: Filled line buffer and offset of start-of-line (ASL_EOF on EOF) 397a88e22b7SJung-uk Kim * 398a88e22b7SJung-uk Kim * DESCRIPTION: Get the next valid source line. Removes all comments. 399a88e22b7SJung-uk Kim * Ignores empty lines. 400a88e22b7SJung-uk Kim * 401a88e22b7SJung-uk Kim * Handles both slash-asterisk and slash-slash comments. 402a88e22b7SJung-uk Kim * Also, quoted strings, but no escapes within. 403a88e22b7SJung-uk Kim * 404a88e22b7SJung-uk Kim * Line is returned in Gbl_CurrentLineBuffer. 405a88e22b7SJung-uk Kim * Line number in original file is returned in Gbl_CurrentLineNumber. 406a88e22b7SJung-uk Kim * 407a88e22b7SJung-uk Kim *****************************************************************************/ 408a88e22b7SJung-uk Kim 4090b94ba42SJung-uk Kim UINT32 410a88e22b7SJung-uk Kim DtGetNextLine ( 411a88e22b7SJung-uk Kim FILE *Handle) 412a88e22b7SJung-uk Kim { 413d052a1ccSJung-uk Kim BOOLEAN LineNotAllBlanks = FALSE; 414a88e22b7SJung-uk Kim UINT32 State = DT_NORMAL_TEXT; 415a88e22b7SJung-uk Kim UINT32 CurrentLineOffset; 416eef1b955SJung-uk Kim UINT32 BeyondBufferCount; 417a88e22b7SJung-uk Kim UINT32 i; 418a88e22b7SJung-uk Kim char c; 419a88e22b7SJung-uk Kim 420a88e22b7SJung-uk Kim 421a88e22b7SJung-uk Kim for (i = 0; i < ASL_LINE_BUFFER_SIZE;) 422a88e22b7SJung-uk Kim { 423a88e22b7SJung-uk Kim c = (char) getc (Handle); 424a88e22b7SJung-uk Kim if (c == EOF) 425a88e22b7SJung-uk Kim { 4260b94ba42SJung-uk Kim switch (State) 4270b94ba42SJung-uk Kim { 4280b94ba42SJung-uk Kim case DT_START_QUOTED_STRING: 4290b94ba42SJung-uk Kim case DT_SLASH_ASTERISK_COMMENT: 4300b94ba42SJung-uk Kim 4310b94ba42SJung-uk Kim AcpiOsPrintf ("**** EOF within comment/string %u\n", State); 4320b94ba42SJung-uk Kim break; 4330b94ba42SJung-uk Kim 4340b94ba42SJung-uk Kim default: 4350b94ba42SJung-uk Kim break; 4360b94ba42SJung-uk Kim } 4370b94ba42SJung-uk Kim 438*a7a3b383SJung-uk Kim /* Standalone EOF is OK */ 439*a7a3b383SJung-uk Kim 440*a7a3b383SJung-uk Kim if (i == 0) 441*a7a3b383SJung-uk Kim { 442d052a1ccSJung-uk Kim return (ASL_EOF); 443a88e22b7SJung-uk Kim } 444a88e22b7SJung-uk Kim 445*a7a3b383SJung-uk Kim /* 446*a7a3b383SJung-uk Kim * Received an EOF in the middle of a line. Terminate the 447*a7a3b383SJung-uk Kim * line with a newline. The next call to this function will 448*a7a3b383SJung-uk Kim * return a standalone EOF. Thus, the upper parsing software 449*a7a3b383SJung-uk Kim * never has to deal with an EOF within a valid line (or 450*a7a3b383SJung-uk Kim * the last line does not get tossed on the floor.) 451*a7a3b383SJung-uk Kim */ 452*a7a3b383SJung-uk Kim c = '\n'; 453*a7a3b383SJung-uk Kim State = DT_NORMAL_TEXT; 454*a7a3b383SJung-uk Kim } 455*a7a3b383SJung-uk Kim 456a88e22b7SJung-uk Kim switch (State) 457a88e22b7SJung-uk Kim { 458a88e22b7SJung-uk Kim case DT_NORMAL_TEXT: 459a88e22b7SJung-uk Kim 460a88e22b7SJung-uk Kim /* Normal text, insert char into line buffer */ 461a88e22b7SJung-uk Kim 462a88e22b7SJung-uk Kim Gbl_CurrentLineBuffer[i] = c; 463a88e22b7SJung-uk Kim switch (c) 464a88e22b7SJung-uk Kim { 465a88e22b7SJung-uk Kim case '/': 466a88e22b7SJung-uk Kim State = DT_START_COMMENT; 467a88e22b7SJung-uk Kim break; 468a88e22b7SJung-uk Kim 469a88e22b7SJung-uk Kim case '"': 470a88e22b7SJung-uk Kim State = DT_START_QUOTED_STRING; 471d052a1ccSJung-uk Kim LineNotAllBlanks = TRUE; 472a88e22b7SJung-uk Kim i++; 473a88e22b7SJung-uk Kim break; 474a88e22b7SJung-uk Kim 475d052a1ccSJung-uk Kim case '\\': 476d052a1ccSJung-uk Kim /* 477d052a1ccSJung-uk Kim * The continuation char MUST be last char on this line. 478d052a1ccSJung-uk Kim * Otherwise, it will be assumed to be a valid ASL char. 479d052a1ccSJung-uk Kim */ 480d052a1ccSJung-uk Kim State = DT_MERGE_LINES; 481d052a1ccSJung-uk Kim break; 482d052a1ccSJung-uk Kim 483a88e22b7SJung-uk Kim case '\n': 484a88e22b7SJung-uk Kim CurrentLineOffset = Gbl_NextLineOffset; 485a88e22b7SJung-uk Kim Gbl_NextLineOffset = (UINT32) ftell (Handle); 486a88e22b7SJung-uk Kim Gbl_CurrentLineNumber++; 487a88e22b7SJung-uk Kim 488d052a1ccSJung-uk Kim /* 489d052a1ccSJung-uk Kim * Exit if line is complete. Ignore empty lines (only \n) 490d052a1ccSJung-uk Kim * or lines that contain nothing but blanks. 491d052a1ccSJung-uk Kim */ 492d052a1ccSJung-uk Kim if ((i != 0) && LineNotAllBlanks) 493a88e22b7SJung-uk Kim { 494d052a1ccSJung-uk Kim Gbl_CurrentLineBuffer[i+1] = 0; /* Terminate string */ 495a88e22b7SJung-uk Kim return (CurrentLineOffset); 496a88e22b7SJung-uk Kim } 497d052a1ccSJung-uk Kim 498d052a1ccSJung-uk Kim /* Toss this line and start a new one */ 499d052a1ccSJung-uk Kim 500d052a1ccSJung-uk Kim i = 0; 501d052a1ccSJung-uk Kim LineNotAllBlanks = FALSE; 502a88e22b7SJung-uk Kim break; 503a88e22b7SJung-uk Kim 504a88e22b7SJung-uk Kim default: 505d052a1ccSJung-uk Kim if (c != ' ') 506d052a1ccSJung-uk Kim { 507d052a1ccSJung-uk Kim LineNotAllBlanks = TRUE; 508d052a1ccSJung-uk Kim } 509d052a1ccSJung-uk Kim 510a88e22b7SJung-uk Kim i++; 511a88e22b7SJung-uk Kim break; 512a88e22b7SJung-uk Kim } 513a88e22b7SJung-uk Kim break; 514a88e22b7SJung-uk Kim 515a88e22b7SJung-uk Kim case DT_START_QUOTED_STRING: 516a88e22b7SJung-uk Kim 517a88e22b7SJung-uk Kim /* Insert raw chars until end of quoted string */ 518a88e22b7SJung-uk Kim 519a88e22b7SJung-uk Kim Gbl_CurrentLineBuffer[i] = c; 520a88e22b7SJung-uk Kim i++; 521a88e22b7SJung-uk Kim 522eef1b955SJung-uk Kim switch (c) 523a88e22b7SJung-uk Kim { 524eef1b955SJung-uk Kim case '"': 525a88e22b7SJung-uk Kim State = DT_NORMAL_TEXT; 526eef1b955SJung-uk Kim break; 527eef1b955SJung-uk Kim 528eef1b955SJung-uk Kim case '\\': 529eef1b955SJung-uk Kim State = DT_ESCAPE_SEQUENCE; 530eef1b955SJung-uk Kim break; 531eef1b955SJung-uk Kim 532eef1b955SJung-uk Kim case '\n': 533eef1b955SJung-uk Kim AcpiOsPrintf ("ERROR at line %u: Unterminated quoted string\n", 534eef1b955SJung-uk Kim Gbl_CurrentLineNumber++); 535eef1b955SJung-uk Kim State = DT_NORMAL_TEXT; 536eef1b955SJung-uk Kim break; 537eef1b955SJung-uk Kim 538eef1b955SJung-uk Kim default: /* Get next character */ 539eef1b955SJung-uk Kim break; 540a88e22b7SJung-uk Kim } 541a88e22b7SJung-uk Kim break; 542a88e22b7SJung-uk Kim 543eef1b955SJung-uk Kim case DT_ESCAPE_SEQUENCE: 544eef1b955SJung-uk Kim 545eef1b955SJung-uk Kim /* Just copy the escaped character. TBD: sufficient for table compiler? */ 546eef1b955SJung-uk Kim 547eef1b955SJung-uk Kim Gbl_CurrentLineBuffer[i] = c; 548eef1b955SJung-uk Kim i++; 549eef1b955SJung-uk Kim State = DT_START_QUOTED_STRING; 550eef1b955SJung-uk Kim break; 551eef1b955SJung-uk Kim 552a88e22b7SJung-uk Kim case DT_START_COMMENT: 553a88e22b7SJung-uk Kim 554a88e22b7SJung-uk Kim /* Open comment if this character is an asterisk or slash */ 555a88e22b7SJung-uk Kim 556a88e22b7SJung-uk Kim switch (c) 557a88e22b7SJung-uk Kim { 558a88e22b7SJung-uk Kim case '*': 559a88e22b7SJung-uk Kim State = DT_SLASH_ASTERISK_COMMENT; 560a88e22b7SJung-uk Kim break; 561a88e22b7SJung-uk Kim 562a88e22b7SJung-uk Kim case '/': 563a88e22b7SJung-uk Kim State = DT_SLASH_SLASH_COMMENT; 564a88e22b7SJung-uk Kim break; 565a88e22b7SJung-uk Kim 566a88e22b7SJung-uk Kim default: /* Not a comment */ 567a88e22b7SJung-uk Kim i++; /* Save the preceeding slash */ 568a88e22b7SJung-uk Kim Gbl_CurrentLineBuffer[i] = c; 569a88e22b7SJung-uk Kim i++; 570a88e22b7SJung-uk Kim State = DT_NORMAL_TEXT; 571a88e22b7SJung-uk Kim break; 572a88e22b7SJung-uk Kim } 573a88e22b7SJung-uk Kim break; 574a88e22b7SJung-uk Kim 575a88e22b7SJung-uk Kim case DT_SLASH_ASTERISK_COMMENT: 576a88e22b7SJung-uk Kim 577a88e22b7SJung-uk Kim /* Ignore chars until an asterisk-slash is found */ 578a88e22b7SJung-uk Kim 579a88e22b7SJung-uk Kim switch (c) 580a88e22b7SJung-uk Kim { 581a88e22b7SJung-uk Kim case '\n': 582a88e22b7SJung-uk Kim Gbl_NextLineOffset = (UINT32) ftell (Handle); 583a88e22b7SJung-uk Kim Gbl_CurrentLineNumber++; 584a88e22b7SJung-uk Kim break; 585a88e22b7SJung-uk Kim 586a88e22b7SJung-uk Kim case '*': 587a88e22b7SJung-uk Kim State = DT_END_COMMENT; 588a88e22b7SJung-uk Kim break; 589a88e22b7SJung-uk Kim 590a88e22b7SJung-uk Kim default: 591a88e22b7SJung-uk Kim break; 592a88e22b7SJung-uk Kim } 593a88e22b7SJung-uk Kim break; 594a88e22b7SJung-uk Kim 595a88e22b7SJung-uk Kim case DT_SLASH_SLASH_COMMENT: 596a88e22b7SJung-uk Kim 597a88e22b7SJung-uk Kim /* Ignore chars until end-of-line */ 598a88e22b7SJung-uk Kim 599a88e22b7SJung-uk Kim if (c == '\n') 600a88e22b7SJung-uk Kim { 601a88e22b7SJung-uk Kim /* We will exit via the NORMAL_TEXT path */ 602a88e22b7SJung-uk Kim 603a88e22b7SJung-uk Kim ungetc (c, Handle); 604a88e22b7SJung-uk Kim State = DT_NORMAL_TEXT; 605a88e22b7SJung-uk Kim } 606a88e22b7SJung-uk Kim break; 607a88e22b7SJung-uk Kim 608a88e22b7SJung-uk Kim case DT_END_COMMENT: 609a88e22b7SJung-uk Kim 610a88e22b7SJung-uk Kim /* End comment if this char is a slash */ 611a88e22b7SJung-uk Kim 612a88e22b7SJung-uk Kim switch (c) 613a88e22b7SJung-uk Kim { 614a88e22b7SJung-uk Kim case '/': 615a88e22b7SJung-uk Kim State = DT_NORMAL_TEXT; 616a88e22b7SJung-uk Kim break; 617a88e22b7SJung-uk Kim 6180b94ba42SJung-uk Kim case '\n': 6190b94ba42SJung-uk Kim CurrentLineOffset = Gbl_NextLineOffset; 6200b94ba42SJung-uk Kim Gbl_NextLineOffset = (UINT32) ftell (Handle); 6210b94ba42SJung-uk Kim Gbl_CurrentLineNumber++; 6220b94ba42SJung-uk Kim break; 6230b94ba42SJung-uk Kim 6240b94ba42SJung-uk Kim case '*': 6250b94ba42SJung-uk Kim /* Consume all adjacent asterisks */ 6260b94ba42SJung-uk Kim break; 6270b94ba42SJung-uk Kim 628a88e22b7SJung-uk Kim default: 629a88e22b7SJung-uk Kim State = DT_SLASH_ASTERISK_COMMENT; 630a88e22b7SJung-uk Kim break; 631a88e22b7SJung-uk Kim } 632a88e22b7SJung-uk Kim break; 633a88e22b7SJung-uk Kim 634d052a1ccSJung-uk Kim case DT_MERGE_LINES: 635d052a1ccSJung-uk Kim 636d052a1ccSJung-uk Kim if (c != '\n') 637d052a1ccSJung-uk Kim { 638d052a1ccSJung-uk Kim /* 639d052a1ccSJung-uk Kim * This is not a continuation backslash, it is a normal 640d052a1ccSJung-uk Kim * normal ASL backslash - for example: Scope(\_SB_) 641d052a1ccSJung-uk Kim */ 642d052a1ccSJung-uk Kim i++; /* Keep the backslash that is already in the buffer */ 643d052a1ccSJung-uk Kim 644d052a1ccSJung-uk Kim ungetc (c, Handle); 645d052a1ccSJung-uk Kim State = DT_NORMAL_TEXT; 646d052a1ccSJung-uk Kim } 647d052a1ccSJung-uk Kim else 648d052a1ccSJung-uk Kim { 649d052a1ccSJung-uk Kim /* 650d052a1ccSJung-uk Kim * This is a continuation line -- a backlash followed 651d052a1ccSJung-uk Kim * immediately by a newline. Insert a space between the 652d052a1ccSJung-uk Kim * lines (overwrite the backslash) 653d052a1ccSJung-uk Kim */ 654d052a1ccSJung-uk Kim Gbl_CurrentLineBuffer[i] = ' '; 655d052a1ccSJung-uk Kim i++; 656d052a1ccSJung-uk Kim 657d052a1ccSJung-uk Kim /* Ignore newline, this will merge the lines */ 658d052a1ccSJung-uk Kim 659d052a1ccSJung-uk Kim CurrentLineOffset = Gbl_NextLineOffset; 660d052a1ccSJung-uk Kim Gbl_NextLineOffset = (UINT32) ftell (Handle); 661d052a1ccSJung-uk Kim Gbl_CurrentLineNumber++; 662d052a1ccSJung-uk Kim State = DT_NORMAL_TEXT; 663d052a1ccSJung-uk Kim } 664d052a1ccSJung-uk Kim break; 665d052a1ccSJung-uk Kim 666a88e22b7SJung-uk Kim default: 667a88e22b7SJung-uk Kim DtFatal (ASL_MSG_COMPILER_INTERNAL, NULL, "Unknown input state"); 668d052a1ccSJung-uk Kim return (ASL_EOF); 669a88e22b7SJung-uk Kim } 670a88e22b7SJung-uk Kim } 671a88e22b7SJung-uk Kim 672eef1b955SJung-uk Kim /* Line is too long for internal buffer. Determine actual length */ 673eef1b955SJung-uk Kim 674eef1b955SJung-uk Kim BeyondBufferCount = 1; 675eef1b955SJung-uk Kim c = (char) getc (Handle); 676eef1b955SJung-uk Kim while (c != '\n') 677eef1b955SJung-uk Kim { 678eef1b955SJung-uk Kim c = (char) getc (Handle); 679eef1b955SJung-uk Kim BeyondBufferCount++; 680eef1b955SJung-uk Kim } 681eef1b955SJung-uk Kim 682eef1b955SJung-uk Kim printf ("ERROR - At %u: Input line (%u bytes) is too long (max %u)\n", 683eef1b955SJung-uk Kim Gbl_CurrentLineNumber++, ASL_LINE_BUFFER_SIZE + BeyondBufferCount, 684eef1b955SJung-uk Kim ASL_LINE_BUFFER_SIZE); 685d052a1ccSJung-uk Kim return (ASL_EOF); 686a88e22b7SJung-uk Kim } 687a88e22b7SJung-uk Kim 688a88e22b7SJung-uk Kim 689a88e22b7SJung-uk Kim /****************************************************************************** 690a88e22b7SJung-uk Kim * 691a88e22b7SJung-uk Kim * FUNCTION: DtScanFile 692a88e22b7SJung-uk Kim * 693a88e22b7SJung-uk Kim * PARAMETERS: Handle - Open file handle for the source file 694a88e22b7SJung-uk Kim * 695a88e22b7SJung-uk Kim * RETURN: Pointer to start of the constructed parse tree. 696a88e22b7SJung-uk Kim * 697a88e22b7SJung-uk Kim * DESCRIPTION: Scan source file, link all field names and values 698a88e22b7SJung-uk Kim * to the global parse tree: Gbl_FieldList 699a88e22b7SJung-uk Kim * 700a88e22b7SJung-uk Kim *****************************************************************************/ 701a88e22b7SJung-uk Kim 702a88e22b7SJung-uk Kim DT_FIELD * 703a88e22b7SJung-uk Kim DtScanFile ( 704a88e22b7SJung-uk Kim FILE *Handle) 705a88e22b7SJung-uk Kim { 706d244b227SJung-uk Kim ACPI_STATUS Status; 707a88e22b7SJung-uk Kim UINT32 Offset; 708d052a1ccSJung-uk Kim DT_FIELD *Next; 709a88e22b7SJung-uk Kim 710a88e22b7SJung-uk Kim 711a88e22b7SJung-uk Kim ACPI_FUNCTION_NAME (DtScanFile); 712a88e22b7SJung-uk Kim 713a88e22b7SJung-uk Kim 714a88e22b7SJung-uk Kim /* Get the file size */ 715a88e22b7SJung-uk Kim 716a88e22b7SJung-uk Kim Gbl_InputByteCount = DtGetFileSize (Handle); 717a88e22b7SJung-uk Kim 718a88e22b7SJung-uk Kim Gbl_CurrentLineNumber = 0; 719a88e22b7SJung-uk Kim Gbl_CurrentLineOffset = 0; 720a88e22b7SJung-uk Kim Gbl_NextLineOffset = 0; 721a88e22b7SJung-uk Kim 722a88e22b7SJung-uk Kim /* Scan line-by-line */ 723a88e22b7SJung-uk Kim 724d052a1ccSJung-uk Kim while ((Offset = DtGetNextLine (Handle)) != ASL_EOF) 725a88e22b7SJung-uk Kim { 726a88e22b7SJung-uk Kim ACPI_DEBUG_PRINT ((ACPI_DB_PARSE, "Line %2.2u/%4.4X - %s", 727a88e22b7SJung-uk Kim Gbl_CurrentLineNumber, Offset, Gbl_CurrentLineBuffer)); 728a88e22b7SJung-uk Kim 729d244b227SJung-uk Kim Status = DtParseLine (Gbl_CurrentLineBuffer, Gbl_CurrentLineNumber, Offset); 730d244b227SJung-uk Kim if (Status == AE_NOT_FOUND) 731d244b227SJung-uk Kim { 732d244b227SJung-uk Kim break; 733d244b227SJung-uk Kim } 734a88e22b7SJung-uk Kim } 735a88e22b7SJung-uk Kim 736d052a1ccSJung-uk Kim /* Dump the parse tree if debug enabled */ 737d052a1ccSJung-uk Kim 738d052a1ccSJung-uk Kim if (Gbl_DebugFlag) 739d052a1ccSJung-uk Kim { 740d052a1ccSJung-uk Kim Next = Gbl_FieldList; 741d052a1ccSJung-uk Kim DbgPrint (ASL_DEBUG_OUTPUT, "Tree: %32s %32s %8s %8s %8s %8s %8s %8s\n\n", 742d052a1ccSJung-uk Kim "Name", "Value", "Line", "ByteOff", "NameCol", "Column", "TableOff", "Flags"); 743d052a1ccSJung-uk Kim 744d052a1ccSJung-uk Kim while (Next) 745d052a1ccSJung-uk Kim { 746d052a1ccSJung-uk Kim DbgPrint (ASL_DEBUG_OUTPUT, "Field: %32.32s %32.32s %.8X %.8X %.8X %.8X %.8X %.8X\n", 747d052a1ccSJung-uk Kim Next->Name, 748d052a1ccSJung-uk Kim Next->Value, 749d052a1ccSJung-uk Kim Next->Line, 750d052a1ccSJung-uk Kim Next->ByteOffset, 751d052a1ccSJung-uk Kim Next->NameColumn, 752d052a1ccSJung-uk Kim Next->Column, 753d052a1ccSJung-uk Kim Next->TableOffset, 754d052a1ccSJung-uk Kim Next->Flags); 755d052a1ccSJung-uk Kim 756d052a1ccSJung-uk Kim Next = Next->Next; 757d052a1ccSJung-uk Kim } 758d052a1ccSJung-uk Kim } 759d052a1ccSJung-uk Kim 760a88e22b7SJung-uk Kim return (Gbl_FieldList); 761a88e22b7SJung-uk Kim } 762a88e22b7SJung-uk Kim 763a88e22b7SJung-uk Kim 764a88e22b7SJung-uk Kim /* 765a88e22b7SJung-uk Kim * Output functions 766a88e22b7SJung-uk Kim */ 767a88e22b7SJung-uk Kim 768a88e22b7SJung-uk Kim /****************************************************************************** 769a88e22b7SJung-uk Kim * 770a88e22b7SJung-uk Kim * FUNCTION: DtWriteBinary 771a88e22b7SJung-uk Kim * 772a88e22b7SJung-uk Kim * PARAMETERS: DT_WALK_CALLBACK 773a88e22b7SJung-uk Kim * 774a88e22b7SJung-uk Kim * RETURN: Status 775a88e22b7SJung-uk Kim * 776a88e22b7SJung-uk Kim * DESCRIPTION: Write one subtable of a binary ACPI table 777a88e22b7SJung-uk Kim * 778a88e22b7SJung-uk Kim *****************************************************************************/ 779a88e22b7SJung-uk Kim 780a88e22b7SJung-uk Kim static void 781a88e22b7SJung-uk Kim DtWriteBinary ( 782a88e22b7SJung-uk Kim DT_SUBTABLE *Subtable, 783a88e22b7SJung-uk Kim void *Context, 784a88e22b7SJung-uk Kim void *ReturnValue) 785a88e22b7SJung-uk Kim { 786a88e22b7SJung-uk Kim 787a88e22b7SJung-uk Kim FlWriteFile (ASL_FILE_AML_OUTPUT, Subtable->Buffer, Subtable->Length); 788a88e22b7SJung-uk Kim } 789a88e22b7SJung-uk Kim 790a88e22b7SJung-uk Kim 791a88e22b7SJung-uk Kim /****************************************************************************** 792a88e22b7SJung-uk Kim * 793a88e22b7SJung-uk Kim * FUNCTION: DtOutputBinary 794a88e22b7SJung-uk Kim * 795a88e22b7SJung-uk Kim * PARAMETERS: 796a88e22b7SJung-uk Kim * 797a88e22b7SJung-uk Kim * RETURN: Status 798a88e22b7SJung-uk Kim * 799a88e22b7SJung-uk Kim * DESCRIPTION: Write entire binary ACPI table (result of compilation) 800a88e22b7SJung-uk Kim * 801a88e22b7SJung-uk Kim *****************************************************************************/ 802a88e22b7SJung-uk Kim 803a88e22b7SJung-uk Kim void 804a88e22b7SJung-uk Kim DtOutputBinary ( 805a88e22b7SJung-uk Kim DT_SUBTABLE *RootTable) 806a88e22b7SJung-uk Kim { 807a88e22b7SJung-uk Kim 808a88e22b7SJung-uk Kim if (!RootTable) 809a88e22b7SJung-uk Kim { 810a88e22b7SJung-uk Kim return; 811a88e22b7SJung-uk Kim } 812a88e22b7SJung-uk Kim 813a88e22b7SJung-uk Kim /* Walk the entire parse tree, emitting the binary data */ 814a88e22b7SJung-uk Kim 815a88e22b7SJung-uk Kim DtWalkTableTree (RootTable, DtWriteBinary, NULL, NULL); 816a88e22b7SJung-uk Kim Gbl_TableLength = DtGetFileSize (Gbl_Files[ASL_FILE_AML_OUTPUT].Handle); 817a88e22b7SJung-uk Kim } 818d244b227SJung-uk Kim 819d244b227SJung-uk Kim 820d244b227SJung-uk Kim /* 821d244b227SJung-uk Kim * Listing support 822d244b227SJung-uk Kim */ 823d244b227SJung-uk Kim 824d244b227SJung-uk Kim /****************************************************************************** 825d244b227SJung-uk Kim * 826d244b227SJung-uk Kim * FUNCTION: DtDumpBuffer 827d244b227SJung-uk Kim * 828d244b227SJung-uk Kim * PARAMETERS: FileID - Where to write buffer data 829d244b227SJung-uk Kim * Buffer - Buffer to dump 8300b94ba42SJung-uk Kim * Offset - Offset in current table 831d244b227SJung-uk Kim * Length - Buffer Length 832d244b227SJung-uk Kim * 833d244b227SJung-uk Kim * RETURN: None 834d244b227SJung-uk Kim * 835d244b227SJung-uk Kim * DESCRIPTION: Another copy of DumpBuffer routine (unfortunately). 836d244b227SJung-uk Kim * 837d244b227SJung-uk Kim * TBD: merge dump buffer routines 838d244b227SJung-uk Kim * 839d244b227SJung-uk Kim *****************************************************************************/ 840d244b227SJung-uk Kim 841d244b227SJung-uk Kim static void 842d244b227SJung-uk Kim DtDumpBuffer ( 843d244b227SJung-uk Kim UINT32 FileId, 844d244b227SJung-uk Kim UINT8 *Buffer, 8450b94ba42SJung-uk Kim UINT32 Offset, 846d244b227SJung-uk Kim UINT32 Length) 847d244b227SJung-uk Kim { 848d244b227SJung-uk Kim UINT32 i; 849d244b227SJung-uk Kim UINT32 j; 850d244b227SJung-uk Kim UINT8 BufChar; 851d244b227SJung-uk Kim 852d244b227SJung-uk Kim 8530b94ba42SJung-uk Kim FlPrintFile (FileId, "Output: [%3.3Xh %4.4d %3d] ", 8540b94ba42SJung-uk Kim Offset, Offset, Length); 8550b94ba42SJung-uk Kim 856d244b227SJung-uk Kim i = 0; 857d244b227SJung-uk Kim while (i < Length) 858d244b227SJung-uk Kim { 8590b94ba42SJung-uk Kim if (i >= 16) 8600b94ba42SJung-uk Kim { 861d052a1ccSJung-uk Kim FlPrintFile (FileId, "%24s", ""); 8620b94ba42SJung-uk Kim } 863d244b227SJung-uk Kim 8640b94ba42SJung-uk Kim /* Print 16 hex chars */ 865d244b227SJung-uk Kim 866d244b227SJung-uk Kim for (j = 0; j < 16;) 867d244b227SJung-uk Kim { 868d244b227SJung-uk Kim if (i + j >= Length) 869d244b227SJung-uk Kim { 870d244b227SJung-uk Kim /* Dump fill spaces */ 871d244b227SJung-uk Kim 872d244b227SJung-uk Kim FlPrintFile (FileId, " "); 873d244b227SJung-uk Kim j++; 874d244b227SJung-uk Kim continue; 875d244b227SJung-uk Kim } 876d244b227SJung-uk Kim 877d244b227SJung-uk Kim FlPrintFile (FileId, "%02X ", Buffer[i+j]); 878d244b227SJung-uk Kim j++; 879d244b227SJung-uk Kim } 880d244b227SJung-uk Kim 881d244b227SJung-uk Kim FlPrintFile (FileId, " "); 882d244b227SJung-uk Kim for (j = 0; j < 16; j++) 883d244b227SJung-uk Kim { 884d244b227SJung-uk Kim if (i + j >= Length) 885d244b227SJung-uk Kim { 886d244b227SJung-uk Kim FlPrintFile (FileId, "\n\n"); 887d244b227SJung-uk Kim return; 888d244b227SJung-uk Kim } 889d244b227SJung-uk Kim 890d244b227SJung-uk Kim BufChar = Buffer[(ACPI_SIZE) i + j]; 891d244b227SJung-uk Kim if (ACPI_IS_PRINT (BufChar)) 892d244b227SJung-uk Kim { 893d244b227SJung-uk Kim FlPrintFile (FileId, "%c", BufChar); 894d244b227SJung-uk Kim } 895d244b227SJung-uk Kim else 896d244b227SJung-uk Kim { 897d244b227SJung-uk Kim FlPrintFile (FileId, "."); 898d244b227SJung-uk Kim } 899d244b227SJung-uk Kim } 900d244b227SJung-uk Kim 901d244b227SJung-uk Kim /* Done with that line. */ 902d244b227SJung-uk Kim 903d244b227SJung-uk Kim FlPrintFile (FileId, "\n"); 904d244b227SJung-uk Kim i += 16; 905d244b227SJung-uk Kim } 906d244b227SJung-uk Kim 907d244b227SJung-uk Kim FlPrintFile (FileId, "\n\n"); 908d244b227SJung-uk Kim } 909d244b227SJung-uk Kim 910d244b227SJung-uk Kim 911d244b227SJung-uk Kim /****************************************************************************** 912d244b227SJung-uk Kim * 913d244b227SJung-uk Kim * FUNCTION: DtWriteFieldToListing 914d244b227SJung-uk Kim * 915d244b227SJung-uk Kim * PARAMETERS: Buffer - Contains the compiled data 916d244b227SJung-uk Kim * Field - Field node for the input line 917d244b227SJung-uk Kim * Length - Length of the output data 918d244b227SJung-uk Kim * 919d244b227SJung-uk Kim * RETURN: None 920d244b227SJung-uk Kim * 921d244b227SJung-uk Kim * DESCRIPTION: Write one field to the listing file (if listing is enabled). 922d244b227SJung-uk Kim * 923d244b227SJung-uk Kim *****************************************************************************/ 924d244b227SJung-uk Kim 925d244b227SJung-uk Kim void 926d244b227SJung-uk Kim DtWriteFieldToListing ( 927d244b227SJung-uk Kim UINT8 *Buffer, 928d244b227SJung-uk Kim DT_FIELD *Field, 929d244b227SJung-uk Kim UINT32 Length) 930d244b227SJung-uk Kim { 931d244b227SJung-uk Kim UINT8 FileByte; 932d244b227SJung-uk Kim 933d244b227SJung-uk Kim 934d244b227SJung-uk Kim if (!Gbl_ListingFlag || !Field) 935d244b227SJung-uk Kim { 936d244b227SJung-uk Kim return; 937d244b227SJung-uk Kim } 938d244b227SJung-uk Kim 939d244b227SJung-uk Kim /* Dump the original source line */ 940d244b227SJung-uk Kim 941d244b227SJung-uk Kim FlPrintFile (ASL_FILE_LISTING_OUTPUT, "Input: "); 942d244b227SJung-uk Kim FlSeekFile (ASL_FILE_INPUT, Field->ByteOffset); 943d244b227SJung-uk Kim 944d244b227SJung-uk Kim while (FlReadFile (ASL_FILE_INPUT, &FileByte, 1) == AE_OK) 945d244b227SJung-uk Kim { 946d244b227SJung-uk Kim FlWriteFile (ASL_FILE_LISTING_OUTPUT, &FileByte, 1); 947d244b227SJung-uk Kim if (FileByte == '\n') 948d244b227SJung-uk Kim { 949d244b227SJung-uk Kim break; 950d244b227SJung-uk Kim } 951d244b227SJung-uk Kim } 952d244b227SJung-uk Kim 953d244b227SJung-uk Kim /* Dump the line as parsed and represented internally */ 954d244b227SJung-uk Kim 955d052a1ccSJung-uk Kim FlPrintFile (ASL_FILE_LISTING_OUTPUT, "Parsed: %*s : %.64s", 956d244b227SJung-uk Kim Field->Column-4, Field->Name, Field->Value); 957d244b227SJung-uk Kim 958d052a1ccSJung-uk Kim if (strlen (Field->Value) > 64) 959d052a1ccSJung-uk Kim { 960d052a1ccSJung-uk Kim FlPrintFile (ASL_FILE_LISTING_OUTPUT, "...Additional data, length 0x%X\n", 961d052a1ccSJung-uk Kim strlen (Field->Value)); 962d052a1ccSJung-uk Kim } 963d052a1ccSJung-uk Kim FlPrintFile (ASL_FILE_LISTING_OUTPUT, "\n"); 964d052a1ccSJung-uk Kim 965d244b227SJung-uk Kim /* Dump the hex data that will be output for this field */ 966d244b227SJung-uk Kim 9670b94ba42SJung-uk Kim DtDumpBuffer (ASL_FILE_LISTING_OUTPUT, Buffer, Field->TableOffset, Length); 968d244b227SJung-uk Kim } 969d244b227SJung-uk Kim 970d244b227SJung-uk Kim 971d244b227SJung-uk Kim /****************************************************************************** 972d244b227SJung-uk Kim * 973d244b227SJung-uk Kim * FUNCTION: DtWriteTableToListing 974d244b227SJung-uk Kim * 975d244b227SJung-uk Kim * PARAMETERS: None 976d244b227SJung-uk Kim * 977d244b227SJung-uk Kim * RETURN: None 978d244b227SJung-uk Kim * 979d244b227SJung-uk Kim * DESCRIPTION: Write the entire compiled table to the listing file 980d244b227SJung-uk Kim * in hex format 981d244b227SJung-uk Kim * 982d244b227SJung-uk Kim *****************************************************************************/ 983d244b227SJung-uk Kim 984d244b227SJung-uk Kim void 985d244b227SJung-uk Kim DtWriteTableToListing ( 986d244b227SJung-uk Kim void) 987d244b227SJung-uk Kim { 988d244b227SJung-uk Kim UINT8 *Buffer; 989d244b227SJung-uk Kim 990d244b227SJung-uk Kim 991d244b227SJung-uk Kim if (!Gbl_ListingFlag) 992d244b227SJung-uk Kim { 993d244b227SJung-uk Kim return; 994d244b227SJung-uk Kim } 995d244b227SJung-uk Kim 996d244b227SJung-uk Kim /* Read the entire table from the output file */ 997d244b227SJung-uk Kim 998d244b227SJung-uk Kim Buffer = UtLocalCalloc (Gbl_TableLength); 999d244b227SJung-uk Kim FlSeekFile (ASL_FILE_AML_OUTPUT, 0); 1000d244b227SJung-uk Kim FlReadFile (ASL_FILE_AML_OUTPUT, Buffer, Gbl_TableLength); 1001d244b227SJung-uk Kim 1002d244b227SJung-uk Kim /* Dump the raw table data */ 1003d244b227SJung-uk Kim 1004d244b227SJung-uk Kim AcpiOsRedirectOutput (Gbl_Files[ASL_FILE_LISTING_OUTPUT].Handle); 1005d244b227SJung-uk Kim 1006d244b227SJung-uk Kim AcpiOsPrintf ("\n%s: Length %d (0x%X)\n\n", 1007d244b227SJung-uk Kim ACPI_RAW_TABLE_DATA_HEADER, Gbl_TableLength, Gbl_TableLength); 1008d244b227SJung-uk Kim AcpiUtDumpBuffer2 (Buffer, Gbl_TableLength, DB_BYTE_DISPLAY); 1009d244b227SJung-uk Kim 1010d244b227SJung-uk Kim AcpiOsRedirectOutput (stdout); 1011d244b227SJung-uk Kim } 1012