[BACK]Return to dtcompile.c CVS log [TXT][DIR] Up to [cvs.NetBSD.org] / src / sys / external / bsd / acpica / dist / compiler

Annotation of src/sys/external/bsd/acpica/dist/compiler/dtcompile.c, Revision 1.1.1.2.2.2

1.1.1.2.2.2! bouyer      1: /******************************************************************************
        !             2:  *
        !             3:  * Module Name: dtcompile.c - Front-end for data table compiler
        !             4:  *
        !             5:  *****************************************************************************/
        !             6:
        !             7: /*
        !             8:  * Copyright (C) 2000 - 2011, Intel Corp.
        !             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:
        !            44: #define __DTCOMPILE_C__
        !            45: #define _DECLARE_DT_GLOBALS
        !            46:
        !            47: #include "aslcompiler.h"
        !            48: #include "dtcompiler.h"
        !            49:
        !            50: #define _COMPONENT          DT_COMPILER
        !            51:         ACPI_MODULE_NAME    ("dtcompile")
        !            52:
        !            53: static char                 VersionString[9];
        !            54:
        !            55:
        !            56: /* Local prototypes */
        !            57:
        !            58: static ACPI_STATUS
        !            59: DtInitialize (
        !            60:     void);
        !            61:
        !            62: static ACPI_STATUS
        !            63: DtCompileDataTable (
        !            64:     DT_FIELD                **Field);
        !            65:
        !            66: static void
        !            67: DtInsertCompilerIds (
        !            68:     DT_FIELD                *FieldList);
        !            69:
        !            70:
        !            71: /******************************************************************************
        !            72:  *
        !            73:  * FUNCTION:    DtDoCompile
        !            74:  *
        !            75:  * PARAMETERS:  None
        !            76:  *
        !            77:  * RETURN:      Status
        !            78:  *
        !            79:  * DESCRIPTION: Main entry point for the data table compiler.
        !            80:  *
        !            81:  * Note: Assumes Gbl_Files[ASL_FILE_INPUT] is initialized and the file is
        !            82:  *          open at seek offset zero.
        !            83:  *
        !            84:  *****************************************************************************/
        !            85:
        !            86: ACPI_STATUS
        !            87: DtDoCompile (
        !            88:     void)
        !            89: {
        !            90:     ACPI_STATUS             Status;
        !            91:     UINT8                   Event;
        !            92:     DT_FIELD                *FieldList;
        !            93:
        !            94:
        !            95:     /* Initialize globals */
        !            96:
        !            97:     Status = DtInitialize ();
        !            98:     if (ACPI_FAILURE (Status))
        !            99:     {
        !           100:         printf ("Error during compiler initialization, 0x%X\n", Status);
        !           101:         return (Status);
        !           102:     }
        !           103:
        !           104:     /*
        !           105:      * Scan the input file (file is already open) and
        !           106:      * build the parse tree
        !           107:      */
        !           108:     Event = UtBeginEvent ("Scan and parse input file");
        !           109:     FieldList = DtScanFile (Gbl_Files[ASL_FILE_INPUT].Handle);
        !           110:     UtEndEvent (Event);
        !           111:
        !           112:     /* Did the parse tree get successfully constructed? */
        !           113:
        !           114:     if (!FieldList)
        !           115:     {
        !           116:         /* TBD: temporary error message. Msgs should come from function above */
        !           117:
        !           118:         DtError (ASL_ERROR, ASL_MSG_SYNTAX, NULL,
        !           119:             "Input file does not appear to be an ASL or data table source file");
        !           120:
        !           121:         Status = AE_ERROR;
        !           122:         goto CleanupAndExit;
        !           123:     }
        !           124:
        !           125:     Event = UtBeginEvent ("Compile parse tree");
        !           126:
        !           127:     /*
        !           128:      * Compile the parse tree
        !           129:      */
        !           130:     Status = DtCompileDataTable (&FieldList);
        !           131:     UtEndEvent (Event);
        !           132:
        !           133:     DtFreeFieldList ();
        !           134:
        !           135:     if (ACPI_FAILURE (Status))
        !           136:     {
        !           137:         /* TBD: temporary error message. Msgs should come from function above */
        !           138:
        !           139:         DtError (ASL_ERROR, ASL_MSG_SYNTAX, NULL,
        !           140:             "Could not compile input file");
        !           141:
        !           142:         goto CleanupAndExit;
        !           143:     }
        !           144:
        !           145:     /* Create/open the binary output file */
        !           146:
        !           147:     Gbl_Files[ASL_FILE_AML_OUTPUT].Filename = NULL;
        !           148:     Status = FlOpenAmlOutputFile (Gbl_OutputFilenamePrefix);
        !           149:     if (ACPI_FAILURE (Status))
        !           150:     {
        !           151:         goto CleanupAndExit;
        !           152:     }
        !           153:
        !           154:     /* Write the binary, then the optional hex file */
        !           155:
        !           156:     DtOutputBinary (Gbl_RootTable);
        !           157:     LsDoHexOutput ();
        !           158:     DtWriteTableToListing ();
        !           159:
        !           160: CleanupAndExit:
        !           161:
        !           162:     CmCleanupAndExit ();
        !           163:     return (Status);
        !           164: }
        !           165:
        !           166:
        !           167: /******************************************************************************
        !           168:  *
        !           169:  * FUNCTION:    DtInitialize
        !           170:  *
        !           171:  * PARAMETERS:  None
        !           172:  *
        !           173:  * RETURN:      Status
        !           174:  *
        !           175:  * DESCRIPTION: Initialize data table compiler globals. Enables multiple
        !           176:  *              compiles per invocation.
        !           177:  *
        !           178:  *****************************************************************************/
        !           179:
        !           180: static ACPI_STATUS
        !           181: DtInitialize (
        !           182:     void)
        !           183: {
        !           184:     ACPI_STATUS             Status;
        !           185:
        !           186:
        !           187:     Status = AcpiOsInitialize ();
        !           188:     if (ACPI_FAILURE (Status))
        !           189:     {
        !           190:         return (Status);
        !           191:     }
        !           192:
        !           193:     Status = AcpiUtInitGlobals ();
        !           194:     if (ACPI_FAILURE (Status))
        !           195:     {
        !           196:         return (Status);
        !           197:     }
        !           198:
        !           199:     Gbl_FieldList = NULL;
        !           200:     Gbl_RootTable = NULL;
        !           201:     Gbl_SubtableStack = NULL;
        !           202:
        !           203:     sprintf (VersionString, "%X", (UINT32) ACPI_CA_VERSION);
        !           204:     return (AE_OK);
        !           205: }
        !           206:
        !           207:
        !           208: /******************************************************************************
        !           209:  *
        !           210:  * FUNCTION:    DtInsertCompilerIds
        !           211:  *
        !           212:  * PARAMETERS:  FieldList           - Current field list pointer
        !           213:  *
        !           214:  * RETURN:      None
        !           215:  *
        !           216:  * DESCRIPTION: Insert the IDs (Name, Version) of the current compiler into
        !           217:  *              the original ACPI table header.
        !           218:  *
        !           219:  *****************************************************************************/
        !           220:
        !           221: static void
        !           222: DtInsertCompilerIds (
        !           223:     DT_FIELD                *FieldList)
        !           224: {
        !           225:     DT_FIELD                *Next;
        !           226:     UINT32                  i;
        !           227:
        !           228:
        !           229:     /*
        !           230:      * Don't insert current compiler ID if requested. Used for compiler
        !           231:      * debug/validation only.
        !           232:      */
        !           233:     if (Gbl_UseOriginalCompilerId)
        !           234:     {
        !           235:         return;
        !           236:     }
        !           237:
        !           238:     /* Walk to the Compiler fields at the end of the header */
        !           239:
        !           240:     Next = FieldList;
        !           241:     for (i = 0; i < 7; i++)
        !           242:     {
        !           243:         Next = Next->Next;
        !           244:     }
        !           245:
        !           246:     Next->Value = ASL_CREATOR_ID;
        !           247:     Next->Flags = DT_FIELD_NOT_ALLOCATED;
        !           248:
        !           249:     Next = Next->Next;
        !           250:     Next->Value = VersionString;
        !           251:     Next->Flags = DT_FIELD_NOT_ALLOCATED;
        !           252: }
        !           253:
        !           254:
        !           255: /******************************************************************************
        !           256:  *
        !           257:  * FUNCTION:    DtCompileDataTable
        !           258:  *
        !           259:  * PARAMETERS:  FieldList           - Current field list pointer
        !           260:  *
        !           261:  * RETURN:      Status
        !           262:  *
        !           263:  * DESCRIPTION: Entry point to compile one data table
        !           264:  *
        !           265:  *****************************************************************************/
        !           266:
        !           267: static ACPI_STATUS
        !           268: DtCompileDataTable (
        !           269:     DT_FIELD                **FieldList)
        !           270: {
        !           271:     ACPI_DMTABLE_DATA       *TableData;
        !           272:     DT_SUBTABLE             *Subtable;
        !           273:     char                    *Signature;
        !           274:     ACPI_TABLE_HEADER       *AcpiTableHeader;
        !           275:     ACPI_STATUS             Status;
        !           276:
        !           277:
        !           278:     /* Verify that we at least have a table signature and save it */
        !           279:
        !           280:     Signature = DtGetFieldValue (*FieldList, "Signature");
        !           281:     if (!Signature)
        !           282:     {
        !           283:         sprintf (MsgBuffer, "Expected \"%s\"", "Signature");
        !           284:         DtNameError (ASL_ERROR, ASL_MSG_INVALID_FIELD_NAME,
        !           285:             *FieldList, MsgBuffer);
        !           286:         return (AE_ERROR);
        !           287:     }
        !           288:
        !           289:     Gbl_Signature = UtLocalCalloc (ACPI_STRLEN (Signature) + 1);
        !           290:     strcpy (Gbl_Signature, Signature);
        !           291:
        !           292:     /*
        !           293:      * Handle tables that don't use the common ACPI table header structure.
        !           294:      * Currently, these are the FACS and RSDP. Also check for an OEMx table,
        !           295:      * these tables have user-defined contents.
        !           296:      */
        !           297:     if (ACPI_COMPARE_NAME (Signature, ACPI_SIG_FACS))
        !           298:     {
        !           299:         Status = DtCompileFacs (FieldList);
        !           300:         if (ACPI_FAILURE (Status))
        !           301:         {
        !           302:             return (Status);
        !           303:         }
        !           304:
        !           305:         DtSetTableLength ();
        !           306:         return (Status);
        !           307:     }
        !           308:     else if (ACPI_COMPARE_NAME (Signature, ACPI_SIG_RSDP))
        !           309:     {
        !           310:         Status = DtCompileRsdp (FieldList);
        !           311:         return (Status);
        !           312:     }
        !           313:     else if (!ACPI_STRNCMP (Signature, "OEM", 3))
        !           314:     {
        !           315:         DtFatal (ASL_MSG_OEM_TABLE, *FieldList, Signature);
        !           316:         return (AE_ERROR);
        !           317:     }
        !           318:
        !           319:     /* Validate the signature via the ACPI table list */
        !           320:
        !           321:     TableData = AcpiDmGetTableData (Signature);
        !           322:     if (!TableData)
        !           323:     {
        !           324:         DtFatal (ASL_MSG_UNKNOWN_TABLE, *FieldList, Signature);
        !           325:         return (AE_ERROR);
        !           326:     }
        !           327:
        !           328:     /*
        !           329:      * All other tables must use the common ACPI table header. Insert the
        !           330:      * current iASL IDs (name, version), and compile the header now.
        !           331:      */
        !           332:     DtInsertCompilerIds (*FieldList);
        !           333:
        !           334:     Status = DtCompileTable (FieldList, AcpiDmTableInfoHeader,
        !           335:                 &Gbl_RootTable, TRUE);
        !           336:     if (ACPI_FAILURE (Status))
        !           337:     {
        !           338:         return (Status);
        !           339:     }
        !           340:
        !           341:     DtPushSubtable (Gbl_RootTable);
        !           342:
        !           343:     /* Dispatch to per-table compile */
        !           344:
        !           345:     if (TableData->CmTableHandler)
        !           346:     {
        !           347:         /* Complex table, has a handler */
        !           348:
        !           349:         Status = TableData->CmTableHandler ((void **) FieldList);
        !           350:         if (ACPI_FAILURE (Status))
        !           351:         {
        !           352:             return (Status);
        !           353:         }
        !           354:     }
        !           355:     else if (TableData->TableInfo)
        !           356:     {
        !           357:         /* Simple table, just walk the info table */
        !           358:
        !           359:         Subtable = NULL;
        !           360:         Status = DtCompileTable (FieldList, TableData->TableInfo,
        !           361:                     &Subtable, TRUE);
        !           362:         if (ACPI_FAILURE (Status))
        !           363:         {
        !           364:             return (Status);
        !           365:         }
        !           366:
        !           367:         DtInsertSubtable (Gbl_RootTable, Subtable);
        !           368:         DtPopSubtable ();
        !           369:     }
        !           370:     else
        !           371:     {
        !           372:         DtFatal (ASL_MSG_COMPILER_INTERNAL, *FieldList,
        !           373:             "Missing table dispatch info");
        !           374:         return (AE_ERROR);
        !           375:     }
        !           376:
        !           377:     /* Set the final table length and then the checksum */
        !           378:
        !           379:     DtSetTableLength ();
        !           380:     AcpiTableHeader = ACPI_CAST_PTR (
        !           381:         ACPI_TABLE_HEADER, Gbl_RootTable->Buffer);
        !           382:     DtSetTableChecksum (&AcpiTableHeader->Checksum);
        !           383:
        !           384:     return (AE_OK);
        !           385: }
        !           386:
        !           387:
        !           388: /******************************************************************************
        !           389:  *
        !           390:  * FUNCTION:    DtCompileTable
        !           391:  *
        !           392:  * PARAMETERS:  Field               - Current field list pointer
        !           393:  *              Info                - Info table for this ACPI table
        !           394:  *              RetSubtable         - Compile result of table
        !           395:  *              Required            - If this subtable must exist
        !           396:  *
        !           397:  * RETURN:      Status
        !           398:  *
        !           399:  * DESCRIPTION: Compile a subtable
        !           400:  *
        !           401:  *****************************************************************************/
        !           402:
        !           403: ACPI_STATUS
        !           404: DtCompileTable (
        !           405:     DT_FIELD                **Field,
        !           406:     ACPI_DMTABLE_INFO       *Info,
        !           407:     DT_SUBTABLE             **RetSubtable,
        !           408:     BOOLEAN                 Required)
        !           409: {
        !           410:     DT_FIELD                *LocalField;
        !           411:     UINT32                  Length;
        !           412:     DT_SUBTABLE             *Subtable;
        !           413:     DT_SUBTABLE             *InlineSubtable;
        !           414:     UINT32                  FieldLength = 0;
        !           415:     UINT8                   FieldType;
        !           416:     UINT8                   *Buffer;
        !           417:     UINT8                   *FlagBuffer = NULL;
        !           418:     ACPI_STATUS             Status;
        !           419:
        !           420:
        !           421:     if (!Field || !*Field)
        !           422:     {
        !           423:         return (AE_BAD_PARAMETER);
        !           424:     }
        !           425:
        !           426:     Length = DtGetSubtableLength (*Field, Info);
        !           427:     Subtable = UtLocalCalloc (sizeof (DT_SUBTABLE));
        !           428:
        !           429:     if (Length > 0)
        !           430:     {
        !           431:         Subtable->Buffer = UtLocalCalloc (Length);
        !           432:     }
        !           433:     Subtable->Length = Length;
        !           434:     Subtable->TotalLength = Length;
        !           435:     Buffer = Subtable->Buffer;
        !           436:
        !           437:     LocalField = *Field;
        !           438:
        !           439:     /*
        !           440:      * Main loop walks the info table for this ACPI table or subtable
        !           441:      */
        !           442:     for (; Info->Name; Info++)
        !           443:     {
        !           444:         if (!LocalField)
        !           445:         {
        !           446:             sprintf (MsgBuffer, "Found NULL field - Field name \"%s\" needed",
        !           447:                 Info->Name);
        !           448:             DtFatal (ASL_MSG_COMPILER_INTERNAL, NULL, MsgBuffer);
        !           449:             Status = AE_BAD_DATA;
        !           450:             goto Error;
        !           451:         }
        !           452:
        !           453:         /* Does input field name match what is expected? */
        !           454:
        !           455:         if (ACPI_STRCMP (LocalField->Name, Info->Name))
        !           456:         {
        !           457:             /*
        !           458:              * If Required = TRUE, the subtable must exist.
        !           459:              * If Required = FALSE, the subtable is optional
        !           460:              * (For example, AcpiDmTableInfoDmarScope in DMAR table is
        !           461:              * optional)
        !           462:              */
        !           463:             if (Required)
        !           464:             {
        !           465:                 sprintf (MsgBuffer, "Expected \"%s\"", Info->Name);
        !           466:                 DtNameError (ASL_ERROR, ASL_MSG_INVALID_FIELD_NAME,
        !           467:                     LocalField, MsgBuffer);
        !           468:             }
        !           469:             else
        !           470:             {
        !           471:                 Status = AE_NOT_FOUND;
        !           472:                 goto Error;
        !           473:             }
        !           474:         }
        !           475:
        !           476:         /* Maintain table offsets */
        !           477:
        !           478:         LocalField->TableOffset = Gbl_CurrentTableOffset;
        !           479:         FieldLength = DtGetFieldLength (LocalField, Info);
        !           480:         Gbl_CurrentTableOffset += FieldLength;
        !           481:
        !           482:         FieldType = DtGetFieldType (Info);
        !           483:         Gbl_InputFieldCount++;
        !           484:
        !           485:         switch (FieldType)
        !           486:         {
        !           487:         case DT_FIELD_TYPE_FLAGS_INTEGER:
        !           488:             /*
        !           489:              * Start of the definition of a flags field.
        !           490:              * This master flags integer starts at value zero, in preparation
        !           491:              * to compile and insert the flag fields from the individual bits
        !           492:              */
        !           493:             LocalField = LocalField->Next;
        !           494:             *Field = LocalField;
        !           495:
        !           496:             FlagBuffer = Buffer;
        !           497:             break;
        !           498:
        !           499:         case DT_FIELD_TYPE_FLAG:
        !           500:
        !           501:             /* Individual Flag field, can be multiple bits */
        !           502:
        !           503:             if (FlagBuffer)
        !           504:             {
        !           505:                 DtCompileFlag (FlagBuffer, LocalField, Info);
        !           506:             }
        !           507:             else
        !           508:             {
        !           509:                 /* TBD - this is an internal error */
        !           510:             }
        !           511:
        !           512:             LocalField = LocalField->Next;
        !           513:             *Field = LocalField;
        !           514:             break;
        !           515:
        !           516:         case DT_FIELD_TYPE_INLINE_SUBTABLE:
        !           517:             /*
        !           518:              * Recursion (one level max): compile GAS (Generic Address)
        !           519:              * or Notify in-line subtable
        !           520:              */
        !           521:             LocalField = LocalField->Next;
        !           522:             *Field = LocalField;
        !           523:
        !           524:             if (Info->Opcode == ACPI_DMT_GAS)
        !           525:             {
        !           526:                 Status = DtCompileTable (Field, AcpiDmTableInfoGas,
        !           527:                     &InlineSubtable, TRUE);
        !           528:             }
        !           529:             else
        !           530:             {
        !           531:                 Status = DtCompileTable (Field, AcpiDmTableInfoHestNotify,
        !           532:                     &InlineSubtable, TRUE);
        !           533:             }
        !           534:
        !           535:             if (ACPI_FAILURE (Status))
        !           536:             {
        !           537:                 goto Error;
        !           538:             }
        !           539:
        !           540:             DtSetSubtableLength (InlineSubtable);
        !           541:
        !           542:             ACPI_MEMCPY (Buffer, InlineSubtable->Buffer, FieldLength);
        !           543:             ACPI_FREE (InlineSubtable->Buffer);
        !           544:             ACPI_FREE (InlineSubtable);
        !           545:             LocalField = *Field;
        !           546:             break;
        !           547:
        !           548:         case DT_FIELD_TYPE_LABEL:
        !           549:
        !           550:             DtWriteFieldToListing (Buffer, LocalField, 0);
        !           551:             LocalField = LocalField->Next;
        !           552:             break;
        !           553:
        !           554:         default:
        !           555:
        !           556:             /* Normal case for most field types (Integer, String, etc.) */
        !           557:
        !           558:             DtCompileOneField (Buffer, LocalField,
        !           559:                 FieldLength, FieldType, Info->Flags);
        !           560:
        !           561:             DtWriteFieldToListing (Buffer, LocalField, FieldLength);
        !           562:             LocalField = LocalField->Next;
        !           563:
        !           564:             if (Info->Flags & DT_LENGTH)
        !           565:             {
        !           566:                 /* Field is an Integer that will contain a subtable length */
        !           567:
        !           568:                 Subtable->LengthField = Buffer;
        !           569:                 Subtable->SizeOfLengthField = FieldLength;
        !           570:             }
        !           571:
        !           572:             break;
        !           573:         }
        !           574:
        !           575:         Buffer += FieldLength;
        !           576:     }
        !           577:
        !           578:     *Field = LocalField;
        !           579:     *RetSubtable = Subtable;
        !           580:     return (AE_OK);
        !           581:
        !           582: Error:
        !           583:     ACPI_FREE (Subtable->Buffer);
        !           584:     ACPI_FREE (Subtable);
        !           585:     return (Status);
        !           586: }

CVSweb <webmaster@jp.NetBSD.org>