VirtualBox

Changeset 108029 in vbox


Ignore:
Timestamp:
Feb 3, 2025 3:58:01 PM (3 weeks ago)
Author:
vboxsync
svn:sync-xref-src-repo-rev:
167302
Message:

Runtime/RTAcpi: Some more work on the ASL -> AML compiler, can process our vbox-standard.dsl now, bugref:10733

Location:
trunk
Files:
1 added
6 edited

Legend:

Unmodified
Added
Removed
  • trunk/include/iprt/acpi.h

    r107952 r108029  
    277277 */
    278278RTDECL(int) RTAcpiTblDeviceFinalize(RTACPITBL hAcpiTbl);
     279
     280
     281/**
     282 * Starts a new processor object for the given ACPI table in the current scope.
     283 *
     284 * @returns IPRT status code.
     285 * @param   hAcpiTbl            The ACPI table handle.
     286 * @param   pszName             Name of the device object, must be <= 4 characters long.
     287 * @param   bProcId             The processor ID.
     288 * @param   u32PBlkAddr         Address of the processor register block.
     289 * @param   cbPBlk              Size of the processor register block in bytes.
     290 */
     291RTDECL(int) RTAcpiTblProcessorStart(RTACPITBL hAcpiTbl, const char *pszName, uint8_t bProcId, uint32_t u32PBlkAddr,
     292                                    uint8_t cbPBlk);
     293
     294
     295/**
     296 * Starts a new processor object for the given ACPI table in the current scope.
     297 *
     298 * @returns IPRT status code.
     299 * @param   hAcpiTbl            The ACPI table handle.
     300 * @param   bProcId             The processor ID.
     301 * @param   u32PBlkAddr         Address of the processor register block.
     302 * @param   cbPBlk              Size of the processor register block in bytes.
     303 * @param   pszNameFmt          The name of the device as a format string.
     304 * @param   ...                 The format arguments.
     305 */
     306RTDECL(int) RTAcpiTblProcessorStartF(RTACPITBL hAcpiTbl, uint8_t bProcId, uint32_t u32PBlkAddr, uint8_t cbPBlk,
     307                                     const char *pszNameFmt, ...) RT_IPRT_FORMAT_ATTR(5, 6);
     308
     309
     310/**
     311 * Starts a new processor object for the given ACPI table in the current scope.
     312 *
     313 * @returns IPRT status code.
     314 * @param   hAcpiTbl            The ACPI table handle.
     315 * @param   bProcId             The processor ID.
     316 * @param   u32PBlkAddr         Address of the processor register block.
     317 * @param   cbPBlk              Size of the processor register block in bytes.
     318 * @param   pszNameFmt          The name of the device as a format string.
     319 * @param   va                  The format arguments.
     320 */
     321RTDECL(int) RTAcpiTblProcessorStartV(RTACPITBL hAcpiTbl, uint8_t bProcId, uint32_t u32PBlkAddr, uint8_t cbPBlk,
     322                                     const char *pszNameFmt, va_list va) RT_IPRT_FORMAT_ATTR(5, 0);
     323
     324
     325/**
     326 * Finalizes the current scope object, nothing can be added to the scope afterwards.
     327 *
     328 * @returns IPRT status code.
     329 * @param   hAcpiTbl            The ACPI table handle.
     330 */
     331RTDECL(int) RTAcpiTblProcessorFinalize(RTACPITBL hAcpiTbl);
    279332
    280333
  • trunk/include/iprt/mangling.h

    r108014 r108029  
    421421# define RTAcpiTblPackageStart                          RT_MANGLER(RTAcpiTblPackageStart)
    422422# define RTAcpiTblPackageFinalize                       RT_MANGLER(RTAcpiTblPackageFinalize)
     423# define RTAcpiTblProcessorStart                        RT_MANGLER(RTAcpiTblProcessorStart)
     424# define RTAcpiTblProcessorStartF                       RT_MANGLER(RTAcpiTblProcessorStartF)
     425# define RTAcpiTblProcessorStartV                       RT_MANGLER(RTAcpiTblProcessorStartV)
     426# define RTAcpiTblProcessorFinalize                     RT_MANGLER(RTAcpiTblProcessorFinalize)
    423427# define RTAcpiTblResourceAppend                        RT_MANGLER(RTAcpiTblResourceAppend)
    424428# define RTAcpiTblScopeFinalize                         RT_MANGLER(RTAcpiTblScopeFinalize)
  • trunk/src/VBox/Runtime/Makefile.kmk

    r108015 r108029  
    396396RuntimeBaseR3_SOURCES      := \
    397397        common/acpi/acpi.cpp \
     398        common/acpi/acpi-ast.cpp \
    398399        common/acpi/acpi-compiler.cpp \
    399400        common/acpi/acpi-decompiler.cpp \
  • trunk/src/VBox/Runtime/common/acpi/acpi-compiler.cpp

    r108021 r108029  
    7373{
    7474    RTACPIASLTERMINAL_INVALID = 0,
     75
     76    /** Keyword terminals, must come first as they are used for indexing into a table later on. */
    7577    RTACPIASLTERMINAL_KEYWORD_DEFINITION_BLOCK,
    7678    RTACPIASLTERMINAL_KEYWORD_SCOPE,
     
    99101    /** Error information. */
    100102    PRTERRINFO              pErrInfo;
     103    /** List of AST nodes for the DefinitionBlock() scope. */
     104    RTLISTANCHOR            LstStmts;
    101105} RTACPIASLCU;
    102106/** Pointer to an ACPI ASL compilation unit state. */
     
    104108/** Pointer to a constant ACPI ASL compilation unit state. */
    105109typedef const RTACPIASLCU *PCRTACPIASLCU;
     110
     111
     112/**
     113 * ASL keyword encoding entry.
     114 */
     115typedef struct RTACPIASLKEYWORD
     116{
     117    /** Name of the opcode. */
     118    const char               *pszOpc;
     119    /** The opcode AML value. */
     120    uint8_t                  bOpc;
     121    /** Number of arguments required. */
     122    uint8_t                  cArgsReq;
     123    /** Number of optional arguments. */
     124    uint8_t                  cArgsOpt;
     125    /** Flags for the opcode. */
     126    uint32_t                 fFlags;
     127    /** Argument type for the required arguments. */
     128    RTACPIASTARGTYPE         aenmTypes[5];
     129    /** Arguments for optional arguments, including the default value if absent. */
     130    RTACPIASTARG             aArgsOpt[3];
     131} RTACPIASLKEYWORD;
     132/** Pointer to a ASL keyword encoding entry. */
     133typedef RTACPIASLKEYWORD *PRTACPIASLKEYWORD;
     134/** Pointer to a const ASL keyword encoding entry. */
     135typedef const RTACPIASLKEYWORD *PCRTACPIASLKEYWORD;
    106136
    107137
     
    155185{
    156186    { '\"', '\"',  RTSCRIPT_LEX_RULE_CONSUME, RTScriptLexScanStringLiteralC,      NULL},
    157     { '0',  '9',   RTSCRIPT_LEX_RULE_CONSUME, rtAcpiAslLexerParseNumber,          NULL},
    158     { 'A',  'Z',   RTSCRIPT_LEX_RULE_CONSUME, rtAcpiAslLexerParseNameString,      NULL},
    159     { '_',  '_',   RTSCRIPT_LEX_RULE_CONSUME, rtAcpiAslLexerParseNameString,      NULL},
    160     { '^',  '^',   RTSCRIPT_LEX_RULE_CONSUME, rtAcpiAslLexerParseNameString,      NULL},
    161     { '\\',  '\\', RTSCRIPT_LEX_RULE_CONSUME, rtAcpiAslLexerParseNameString,      NULL},
     187    { '0',  '9',   RTSCRIPT_LEX_RULE_DEFAULT, rtAcpiAslLexerParseNumber,          NULL},
     188    { 'A',  'Z',   RTSCRIPT_LEX_RULE_DEFAULT, rtAcpiAslLexerParseNameString,      NULL},
     189    { '_',  '_',   RTSCRIPT_LEX_RULE_DEFAULT, rtAcpiAslLexerParseNameString,      NULL},
     190    { '^',  '^',   RTSCRIPT_LEX_RULE_DEFAULT, rtAcpiAslLexerParseNameString,      NULL},
     191    { '\\',  '\\', RTSCRIPT_LEX_RULE_DEFAULT, rtAcpiAslLexerParseNameString,      NULL},
    162192
    163193    { '\0', '\0',  RTSCRIPT_LEX_RULE_DEFAULT, NULL,                               NULL}
     
    249279    char aszIde[513]; RT_ZERO(aszIde);
    250280    unsigned idx = 0;
    251     aszIde[idx++] = ch;
    252281
    253282    if (ch == '^') /* PrefixPath */
    254283    {
     284        aszIde[idx++] = '^';
     285        RTScriptLexConsumeCh(hScriptLex);
     286
    255287        ch = RTScriptLexGetCh(hScriptLex);
    256288        while (   idx < sizeof(aszIde) - 1
     
    264296        if (idx == sizeof(aszIde) - 1)
    265297            return RTScriptLexProduceTokError(hScriptLex, pTok, VERR_BUFFER_OVERFLOW, "Lexer: PrefixPath exceeds the allowed length");
     298    }
     299    else if (ch == '\\')
     300    {
     301        aszIde[idx++] = '\\';
     302        RTScriptLexConsumeCh(hScriptLex);
    266303    }
    267304
     
    310347
    311348
     349#if 0
     350DECLINLINE(bool) rtAcpiAslLexerIsKeyword(PCRTACPIASLCU pThis, RTACPIASLTERMINAL enmTerm)
     351{
     352    PCRTSCRIPTLEXTOKEN pTok;
     353    int rc = RTScriptLexQueryToken(pThis->hLexSource, &pTok);
     354    if (RT_FAILURE(rc))
     355        return false;
     356
     357    if (   pTok->enmType == RTSCRIPTLEXTOKTYPE_KEYWORD
     358        && pTok->Type.Keyword.pKeyword->u64Val == (uint64_t)enmTerm)
     359        return true;
     360
     361    return false;
     362}
     363#endif
     364
     365
     366DECLINLINE(bool) rtAcpiAslLexerIsPunctuator(PCRTACPIASLCU pThis, RTACPIASLTERMINAL enmTerm)
     367{
     368    PCRTSCRIPTLEXTOKEN pTok;
     369    int rc = RTScriptLexQueryToken(pThis->hLexSource, &pTok);
     370    if (RT_FAILURE(rc))
     371        return false;
     372
     373    if (   pTok->enmType == RTSCRIPTLEXTOKTYPE_PUNCTUATOR
     374        && pTok->Type.Keyword.pKeyword->u64Val == (uint64_t)enmTerm)
     375        return true;
     376
     377    return false;
     378}
     379
     380
    312381static int rtAcpiAslLexerConsumeIfKeyword(PCRTACPIASLCU pThis, RTACPIASLTERMINAL enmTerm, bool *pfConsumed)
    313382{
     
    396465        && pTok->Type.Number.enmType == RTSCRIPTLEXTOKNUMTYPE_NATURAL)
    397466    {
    398         RTScriptLexConsumeToken(pThis->hLexSource);
    399467        *pfConsumed = true;
    400468        *pu64 = pTok->Type.Number.Type.u64;
     469        RTScriptLexConsumeToken(pThis->hLexSource);
    401470        return VINF_SUCCESS;
    402471    }
     
    477546    } while(0)
    478547
    479 static int rtAcpiTblAslParseInner(PRTACPIASLCU pThis);
    480 
    481 static int rtAcpiTblAslParseTerminal(PRTACPIASLCU pThis, RTACPIASLTERMINAL enmTerminal)
     548#define RTACPIASL_SKIP_CURRENT_TOKEN() \
     549    RTScriptLexConsumeToken(pThis->hLexSource);
     550
     551
     552static int rtAcpiTblAslParseInner(PRTACPIASLCU pThis, PRTLISTANCHOR pLstStmts);
     553
     554/**
     555 * Keyword encoding table, indexed by RTACPIASLTERMINAL_XXX.
     556 */
     557static const RTACPIASLKEYWORD g_aAslKeywords[] =
     558{
     559    /* RTACPIASLTERMINAL_INVALID */     {
     560                                            NULL, 0, 0, 0, RTACPI_AST_NODE_F_DEFAULT,
     561                                            {   kAcpiAstArgType_Invalid,
     562                                                kAcpiAstArgType_Invalid,
     563                                                kAcpiAstArgType_Invalid,
     564                                                kAcpiAstArgType_Invalid,
     565                                                kAcpiAstArgType_Invalid},
     566                                            {
     567                                                { kAcpiAstArgType_Invalid, { 0 } },
     568                                                { kAcpiAstArgType_Invalid, { 0 } },
     569                                                { kAcpiAstArgType_Invalid, { 0 } }
     570                                            }
     571                                        },
     572    /* RTACPIASLTERMINAL_DEFINITION_BLOCK */ {
     573                                            NULL, 0, 0, 0, RTACPI_AST_NODE_F_DEFAULT,
     574                                            {   kAcpiAstArgType_Invalid,
     575                                                kAcpiAstArgType_Invalid,
     576                                                kAcpiAstArgType_Invalid,
     577                                                kAcpiAstArgType_Invalid,
     578                                                kAcpiAstArgType_Invalid},
     579                                            {
     580                                                { kAcpiAstArgType_Invalid, { 0 } },
     581                                                { kAcpiAstArgType_Invalid, { 0 } },
     582                                                { kAcpiAstArgType_Invalid, { 0 } }
     583                                            }
     584                                        },
     585    /* RTACPIASLTERMINAL_SCOPE   */     {
     586                                            "Scope", ACPI_AML_BYTE_CODE_OP_SCOPE, 1, 0, RTACPI_AST_NODE_F_NEW_SCOPE,
     587                                            {    kAcpiAstArgType_NameString,
     588                                                 kAcpiAstArgType_Invalid,
     589                                                 kAcpiAstArgType_Invalid,
     590                                                 kAcpiAstArgType_Invalid,
     591                                                 kAcpiAstArgType_Invalid
     592                                            },
     593                                            {
     594                                                { kAcpiAstArgType_Invalid, { 0 } },
     595                                                { kAcpiAstArgType_Invalid, { 0 } },
     596                                                { kAcpiAstArgType_Invalid, { 0 } }
     597                                            }
     598                                        },
     599    /* RTACPIASLTERMINAL_PROCESSOR */   {
     600                                            "Processor", ACPI_AML_BYTE_CODE_EXT_OP_PROCESSOR, 2, 2, RTACPI_AST_NODE_F_NEW_SCOPE | RTACPI_AST_NODE_F_EXT_OPC,
     601                                            {    kAcpiAstArgType_NameString,
     602                                                 kAcpiAstArgType_U8,
     603                                                 kAcpiAstArgType_Invalid,
     604                                                 kAcpiAstArgType_Invalid,
     605                                                 kAcpiAstArgType_Invalid
     606                                            },
     607                                            {
     608                                                { kAcpiAstArgType_U32,     { 0 } },
     609                                                { kAcpiAstArgType_U8,      { 0 } },
     610                                                { kAcpiAstArgType_Invalid, { 0 } }
     611                                            }
     612                                        },
     613};
     614
     615static int rtAcpiTblAslParseArgument(PRTACPIASLCU pThis, const char *pszKeyword, uint8_t iArg, RTACPIASTARGTYPE enmArgType, PRTACPIASTARG pArg)
     616{
     617    switch (enmArgType)
     618    {
     619        case kAcpiAstArgType_AstNode:
     620        {
     621            //rtAcpiTblAslParseTerminal(pThis, RTACPIASLTERMINAL enmTerminal, PRTACPIASTNODE *ppAstNd)
     622            break;
     623        }
     624        case kAcpiAstArgType_NameString:
     625        {
     626            RTACPIASL_PARSE_NAME_STRING(pszNameString);
     627            pArg->enmType         = kAcpiAstArgType_NameString;
     628            pArg->u.pszNameString = pszNameString;
     629            break;
     630        }
     631        case kAcpiAstArgType_U8:
     632        {
     633            RTACPIASL_PARSE_NATURAL(u64);
     634            if (u64 > UINT8_MAX)
     635                return RTErrInfoSetF(pThis->pErrInfo, VERR_INVALID_PARAMETER,
     636                                     "Value for byte parameter %u is out of range (%#RX64) while processing keyword '%s'",
     637                                     iArg, u64, pszKeyword);
     638
     639            pArg->enmType = kAcpiAstArgType_U8;
     640            pArg->u.u8    = (uint8_t)u64;
     641            break;
     642        }
     643        case kAcpiAstArgType_U16:
     644        {
     645            RTACPIASL_PARSE_NATURAL(u64);
     646            if (u64 > UINT16_MAX)
     647                return RTErrInfoSetF(pThis->pErrInfo, VERR_INVALID_PARAMETER,
     648                                     "Value for word parameter %u is out of range (%#RX64) while processing keyword '%s'",
     649                                     iArg, u64, pszKeyword);
     650
     651            pArg->enmType = kAcpiAstArgType_U16;
     652            pArg->u.u16   = (uint16_t)u64;
     653            break;
     654        }
     655        case kAcpiAstArgType_U32:
     656        {
     657            RTACPIASL_PARSE_NATURAL(u64);
     658            if (u64 > UINT32_MAX)
     659                return RTErrInfoSetF(pThis->pErrInfo, VERR_INVALID_PARAMETER,
     660                                     "Value for 32-bit parameter %u is out of range (%#RX64) while processing keyword '%s'",
     661                                     iArg, u64, pszKeyword);
     662
     663            pArg->enmType = kAcpiAstArgType_U32;
     664            pArg->u.u32   = (uint32_t)u64;
     665            break;
     666        }
     667        case kAcpiAstArgType_U64:
     668        {
     669            RTACPIASL_PARSE_NATURAL(u64);
     670            pArg->enmType = kAcpiAstArgType_U64;
     671            pArg->u.u64   = u64;
     672            break;
     673        }
     674        default:
     675            AssertReleaseFailed();
     676    }
     677
     678    return VINF_SUCCESS;
     679}
     680
     681
     682static int rtAcpiTblAslParseTerminal(PRTACPIASLCU pThis, RTACPIASLTERMINAL enmTerminal, PRTACPIASTNODE *ppAstNd)
    482683{
    483684    int rc = VINF_SUCCESS;
    484685
    485     switch (enmTerminal)
    486     {
    487         case RTACPIASLTERMINAL_KEYWORD_SCOPE:
    488         {
    489             RTACPIASL_PARSE_PUNCTUATOR(RTACPIASLTERMINAL_PUNCTUATOR_OPEN_BRACKET, '(');
    490             RTACPIASL_PARSE_NAME_STRING(pszName);
    491             RT_NOREF(pszName);
    492             RTACPIASL_PARSE_PUNCTUATOR(RTACPIASLTERMINAL_PUNCTUATOR_CLOSE_BRACKET, ')');
    493             RTACPIASL_PARSE_PUNCTUATOR(RTACPIASLTERMINAL_PUNCTUATOR_OPEN_CURLY_BRACKET, '{');
    494             rc = rtAcpiTblAslParseInner(pThis);
     686    AssertReturn(enmTerminal > RTACPIASLTERMINAL_INVALID && enmTerminal < RT_ELEMENTS(g_aAslKeywords), VERR_INTERNAL_ERROR);
     687
     688    *ppAstNd = NULL;
     689
     690    PCRTACPIASLKEYWORD pAslKeyword = &g_aAslKeywords[enmTerminal];
     691    PRTACPIASTNODE pAstNd = rtAcpiAstNodeAlloc(pAslKeyword->bOpc, pAslKeyword->fFlags, pAslKeyword->cArgsReq + pAslKeyword->cArgsOpt);
     692    if (!pAstNd)
     693        return RTErrInfoSetF(pThis->pErrInfo, VERR_NO_MEMORY, "Failed to allocate ACPI AST node when processing keyword '%s'", pAslKeyword->pszOpc);
     694
     695    *ppAstNd = pAstNd;
     696
     697    if (pAslKeyword->cArgsReq || pAslKeyword->cArgsOpt)
     698    {
     699        RTACPIASL_PARSE_PUNCTUATOR(RTACPIASLTERMINAL_PUNCTUATOR_OPEN_BRACKET, '(');
     700
     701        /* Process any required arguments. */
     702        for (uint32_t i = 0; i < pAslKeyword->cArgsReq; i++)
     703        {
     704            rc = rtAcpiTblAslParseArgument(pThis, pAslKeyword->pszOpc, i, pAslKeyword->aenmTypes[i], &pAstNd->aArgs[i]);
     705            if (RT_FAILURE(rc))
     706                return rc;
     707
     708            /* There must be a "," between required arguments, not counting the last required argument because it can be closed with ")". */
     709            if (i < pAslKeyword->cArgsReq - 1)
     710                RTACPIASL_PARSE_PUNCTUATOR(RTACPIASLTERMINAL_PUNCTUATOR_COMMA, ',');
     711        }
     712
     713        /* Process any optional arguments, this is a bit ugly. */
     714        uint8_t iArg = 0;
     715        while (iArg < pAslKeyword->cArgsOpt)
     716        {
     717            if (rtAcpiAslLexerIsPunctuator(pThis, RTACPIASLTERMINAL_PUNCTUATOR_CLOSE_BRACKET))
     718                break; /* The end of the argument list was reached. */
     719
     720            /*
     721             * It is possible to have empty arguments in the list by having nothing to parse between the "," or something like ",)"
     722             * (like "Method(NAM, 0,,)" for example).
     723             */
     724            if (rtAcpiAslLexerIsPunctuator(pThis, RTACPIASLTERMINAL_PUNCTUATOR_COMMA))
     725            {
     726                RTACPIASL_SKIP_CURRENT_TOKEN(); /* Skip "," */
     727
     728                /*
     729                 * If the next token is also a "," there is a hole in the argument list and we have to fill in the default,
     730                 * if it is ")" we reached the end.
     731                 */
     732                if (rtAcpiAslLexerIsPunctuator(pThis, RTACPIASLTERMINAL_PUNCTUATOR_CLOSE_BRACKET))
     733                    break;
     734                else if (rtAcpiAslLexerIsPunctuator(pThis, RTACPIASLTERMINAL_PUNCTUATOR_COMMA))
     735                {
     736                    pAstNd->aArgs[pAslKeyword->cArgsReq + iArg] = pAslKeyword->aArgsOpt[iArg];
     737                    iArg++;
     738                    continue; /* Continue with the next argument. */
     739                }
     740
     741                /* So there is an argument we need to parse. */
     742                rc = rtAcpiTblAslParseArgument(pThis, pAslKeyword->pszOpc, iArg, pAslKeyword->aArgsOpt[iArg].enmType, &pAstNd->aArgs[pAslKeyword->cArgsReq + iArg]);
     743                if (RT_FAILURE(rc))
     744                    return rc;
     745
     746                iArg++;
     747            }
     748        }
     749
     750        /* Fill remaining optional arguments with the defaults. */
     751        for (; iArg < pAslKeyword->cArgsOpt; iArg++)
     752            pAstNd->aArgs[pAslKeyword->cArgsReq + iArg] = pAslKeyword->aArgsOpt[iArg];
     753
     754        /* Now there must be a closing ) */
     755        RTACPIASL_PARSE_PUNCTUATOR(RTACPIASLTERMINAL_PUNCTUATOR_CLOSE_BRACKET, ')');
     756    }
     757
     758    /* For keywords opening a new scope do the parsing now. */
     759    if (pAslKeyword->fFlags & RTACPI_AST_NODE_F_NEW_SCOPE)
     760    {
     761        RTACPIASL_PARSE_PUNCTUATOR(RTACPIASLTERMINAL_PUNCTUATOR_OPEN_CURLY_BRACKET, '{');
     762        rc = rtAcpiTblAslParseInner(pThis, &pAstNd->LstScopeNodes);
     763        if (RT_SUCCESS(rc))
    495764            RTACPIASL_PARSE_PUNCTUATOR(RTACPIASLTERMINAL_PUNCTUATOR_CLOSE_CURLY_BRACKET, '}');
    496             break;
    497         }
    498         case RTACPIASLTERMINAL_KEYWORD_PROCESSOR:
    499         {
    500             RTACPIASL_PARSE_PUNCTUATOR(RTACPIASLTERMINAL_PUNCTUATOR_OPEN_BRACKET, '(');
    501             RTACPIASL_PARSE_NAME_STRING(pszName);
    502             RT_NOREF(pszName);
    503             RTACPIASL_PARSE_PUNCTUATOR(RTACPIASLTERMINAL_PUNCTUATOR_COMMA, ',');
    504             AssertFailed();
    505             RTACPIASL_PARSE_PUNCTUATOR(RTACPIASLTERMINAL_PUNCTUATOR_CLOSE_BRACKET, ')');
    506             RTACPIASL_PARSE_PUNCTUATOR(RTACPIASLTERMINAL_PUNCTUATOR_OPEN_CURLY_BRACKET, '{');
    507             rc = rtAcpiTblAslParseInner(pThis);
    508             RTACPIASL_PARSE_PUNCTUATOR(RTACPIASLTERMINAL_PUNCTUATOR_CLOSE_CURLY_BRACKET, '}');
    509             break;
    510         }
    511         default:
    512             rc = RTErrInfoSetF(pThis->pErrInfo, VERR_INVALID_PARAMETER, "Parser: Unexpected keyword encountered");
    513             break;
    514765    }
    515766
     
    518769
    519770
    520 static int rtAcpiTblAslParseInner(PRTACPIASLCU pThis)
     771static int rtAcpiTblAslParseInner(PRTACPIASLCU pThis, PRTLISTANCHOR pLstStmts)
    521772{
    522773    for (;;)
     
    537788
    538789        RTACPIASLTERMINAL enmKeyword = (RTACPIASLTERMINAL)pTok->Type.Keyword.pKeyword->u64Val;
    539         RTScriptLexConsumeToken(pThis->hLexSource);
    540 
    541         rc = rtAcpiTblAslParseTerminal(pThis, enmKeyword);
     790        RTScriptLexConsumeToken(pThis->hLexSource); /* This must come here as rtAcpiTblAslParseTerminal() will continue parsing. */
     791
     792        PRTACPIASTNODE pAstNd = NULL;
     793        rc = rtAcpiTblAslParseTerminal(pThis, enmKeyword, &pAstNd);
    542794        if (RT_FAILURE(rc))
     795        {
     796            if (pAstNd)
     797                rtAcpiAstNodeFree(pAstNd);
    543798            return rc;
     799        }
     800
     801        RTListAppend(pLstStmts, &pAstNd->NdAst);
    544802    }
    545803}
     
    596854    {
    597855        RTACPIASL_PARSE_PUNCTUATOR(RTACPIASLTERMINAL_PUNCTUATOR_OPEN_CURLY_BRACKET, '{');
    598         rc = rtAcpiTblAslParseInner(pThis);
     856        rc = rtAcpiTblAslParseInner(pThis, &pThis->LstStmts);
    599857        if (RT_SUCCESS(rc))
    600858        {
     
    603861        }
    604862    }
     863    else
     864        rc = RTErrInfoSetF(pThis->pErrInfo, rc, "Call to RTAcpiTblCreate() failed");
    605865
    606866    return rc;
     
    616876        pThis->hVfsIosIn  = hVfsIosIn;
    617877        pThis->pErrInfo   = pErrInfo;
     878        RTListInit(&pThis->LstStmts);
    618879
    619880        rc = RTScriptLexCreateFromReader(&pThis->hLexSource, rtAcpiAslLexerRead,
     
    627888            {
    628889                /* 2. - Optimize AST (constant folding, etc). */
     890                /** @todo */
     891
    629892                /* 3. - Traverse AST and output table. */
    630                 RT_NOREF(hVfsIosOut);
     893                PRTACPIASTNODE pIt;
     894                RTListForEach(&pThis->LstStmts, pIt, RTACPIASTNODE, NdAst)
     895                {
     896                    rc = rtAcpiAstDumpToTbl(pIt, pThis->hAcpiTbl);
     897                    if (RT_FAILURE(rc))
     898                        break;
     899                }
     900
     901                /* Finalize and write to the VFS I/O stream. */
     902                if (RT_SUCCESS(rc))
     903                {
     904                    rc = RTAcpiTblFinalize(pThis->hAcpiTbl);
     905                    if (RT_SUCCESS(rc))
     906                    {
     907                        rc = RTAcpiTblDumpToVfsIoStrm(pThis->hAcpiTbl, RTACPITBLTYPE_AML, hVfsIosOut);
     908                        if (RT_FAILURE(rc))
     909                            rc = RTErrInfoSetF(pErrInfo, rc, "Writing the ACPI table failed with %Rrc", rc);
     910                    }
     911                    else
     912                        rc = RTErrInfoSetF(pErrInfo, rc, "Finalizing the ACPI table failed with %Rrc", rc);
     913                }
     914                else
     915                    rc = RTErrInfoSetF(pErrInfo, rc, "Dumping AST to ACPI table failed with %Rrc", rc);
    631916            }
    632917
    633             /** @todo Destroy AST. */
    634918            RTScriptLexDestroy(pThis->hLexSource);
    635919        }
     
    637921            rc = RTErrInfoSetF(pErrInfo, rc, "Creating the ASL lexer failed with %Rrc", rc);
    638922
     923        /* Destroy the AST nodes. */
     924        PRTACPIASTNODE pIt, pItNext;
     925        RTListForEachSafe(&pThis->LstStmts, pIt, pItNext, RTACPIASTNODE, NdAst)
     926        {
     927            RTListNodeRemove(&pIt->NdAst);
     928            rtAcpiAstNodeFree(pIt);
     929        }
     930
    639931        RTMemFree(pThis);
    640932    }
  • trunk/src/VBox/Runtime/common/acpi/acpi.cpp

    r108015 r108029  
    397397
    398398/**
     399 * Appends the given double word to the ACPI table, updating the package length of the current package.
     400 *
     401 * @param pThis                 The ACPI table instance.
     402 * @param u32                   The data to append.
     403 */
     404DECLINLINE(void) rtAcpiTblAppendDword(PRTACPITBLINT pThis, uint32_t u32)
     405{
     406    uint8_t *pb = rtAcpiTblBufEnsureSpace(pThis, sizeof(u32));
     407    if (pb)
     408    {
     409        pb[0] = (uint8_t)u32;
     410        pb[1] = (uint8_t)(u32 >>  8);
     411        pb[2] = (uint8_t)(u32 >> 16);
     412        pb[3] = (uint8_t)(u32 >> 24);
     413        rtAcpiTblUpdatePkgLength(pThis, sizeof(u32));
     414    }
     415}
     416
     417
     418/**
    399419 * Appends the given date to the ACPI table, updating the package length of the current package.
    400420 *
     
    696716RTDECL(int) RTAcpiTblDeviceStartV(RTACPITBL hAcpiTbl, const char *pszNameFmt, va_list va)
    697717{
    698     char szName[5];
     718    char szName[128];
    699719    ssize_t cch = RTStrPrintf2V(&szName[0], sizeof(szName), pszNameFmt, va);
    700720    if (cch <= 0)
     
    711731
    712732    return rtAcpiTblPkgFinish(pThis, ACPI_AML_BYTE_CODE_EXT_OP_DEVICE);
     733}
     734
     735
     736RTDECL(int) RTAcpiTblProcessorStart(RTACPITBL hAcpiTbl, const char *pszName, uint8_t bProcId, uint32_t u32PBlkAddr,
     737                                    uint8_t cbPBlk)
     738{
     739    PRTACPITBLINT pThis = hAcpiTbl;
     740    AssertPtrReturn(pThis, VERR_INVALID_HANDLE);
     741
     742    rtAcpiTblPkgStartExt(pThis, ACPI_AML_BYTE_CODE_EXT_OP_PROCESSOR);
     743    rtAcpiTblAppendNameString(pThis, pszName);
     744    rtAcpiTblAppendByte(pThis, bProcId);
     745    rtAcpiTblAppendDword(pThis, u32PBlkAddr);
     746    rtAcpiTblAppendByte(pThis, cbPBlk);
     747    return pThis->rcErr;
     748}
     749
     750
     751RTDECL(int) RTAcpiTblProcessorStartF(RTACPITBL hAcpiTbl, uint8_t bProcId, uint32_t u32PBlkAddr, uint8_t cbPBlk,
     752                                     const char *pszNameFmt, ...)
     753{
     754    va_list va;
     755    va_start(va, pszNameFmt);
     756    int rc = RTAcpiTblProcessorStartV(hAcpiTbl, bProcId, u32PBlkAddr, cbPBlk, pszNameFmt, va);
     757    va_end(va);
     758    return rc;
     759}
     760
     761
     762RTDECL(int) RTAcpiTblProcessorStartV(RTACPITBL hAcpiTbl, uint8_t bProcId, uint32_t u32PBlkAddr, uint8_t cbPBlk,
     763                                     const char *pszNameFmt, va_list va)
     764{
     765    char szName[128];
     766    ssize_t cch = RTStrPrintf2V(&szName[0], sizeof(szName), pszNameFmt, va);
     767    if (cch <= 0)
     768        return VERR_BUFFER_OVERFLOW;
     769
     770    return RTAcpiTblProcessorStart(hAcpiTbl, &szName[0], bProcId, u32PBlkAddr, cbPBlk);
     771}
     772
     773
     774RTDECL(int) RTAcpiTblProcessorFinalize(RTACPITBL hAcpiTbl)
     775{
     776    PRTACPITBLINT pThis = hAcpiTbl;
     777    AssertPtrReturn(pThis, VERR_INVALID_HANDLE);
     778
     779    return rtAcpiTblPkgFinish(pThis, ACPI_AML_BYTE_CODE_EXT_OP_PROCESSOR);
    713780}
    714781
  • trunk/src/VBox/Runtime/include/internal/acpi.h

    r108015 r108029  
    4242
    4343#include <iprt/acpi.h>
     44#include <iprt/list.h>
    4445
    4546RT_C_DECLS_BEGIN
     47
     48/** Pointer to an ACPI AST node. */
     49typedef struct RTACPIASTNODE *PRTACPIASTNODE;
     50/** Pointer to a const ACPI AST node. */
     51typedef const struct RTACPIASTNODE *PCRTACPIASTNODE;
     52
     53/**
     54 * AST node argument type.
     55 */
     56typedef enum RTACPIASTARGTYPE
     57{
     58    kAcpiAstArgType_Invalid = 0,
     59    kAcpiAstArgType_AstNode,
     60    kAcpiAstArgType_NameString,
     61    kAcpiAstArgType_U8,
     62    kAcpiAstArgType_U16,
     63    kAcpiAstArgType_U32,
     64    kAcpiAstArgType_U64,
     65    kAcpiAstArgType_32Bit_Hack = 0x7fffffff
     66} RTACPIASTARGTYPE;
     67
     68
     69/**
     70 * An AST node argument
     71 */
     72typedef struct RTACPIASTARG
     73{
     74    /** Argument type. */
     75    RTACPIASTARGTYPE    enmType;
     76    /** Type dependent data. */
     77    union
     78    {
     79        uintptr_t       uPtrInternal;
     80        PCRTACPIASTNODE pAstNode;
     81        const char      *pszNameString;
     82        uint8_t         u8;
     83        uint16_t        u16;
     84        uint32_t        u32;
     85        uint64_t        u64;
     86    } u;
     87} RTACPIASTARG;
     88/** Pointer to an AST node argument. */
     89typedef RTACPIASTARG *PRTACPIASTARG;
     90/** Pointer to a const AST node argument. */
     91typedef const RTACPIASTARG *PCRTACPIASTARG;
     92
     93
     94/**
     95 * The core ACPI AST node.
     96 */
     97typedef struct RTACPIASTNODE
     98{
     99    /** List node. */
     100    RTLISTNODE          NdAst;
     101    /** The AML opcode defining the node. */
     102    uint8_t             bOpc;
     103    /** Number of "arguments" for the opcode following (for example Scope(), Method(), If(), etc., i.e. anything requiring () after the keyword ). */
     104    uint8_t             cArgs;
     105    /** Padding */
     106    uint8_t             abRsvd[2];
     107    /** Some additional flags. */
     108    uint32_t            fFlags;
     109    /** List of other AST nodes for the opened scope if indicated by the AST flags (RTACPIASTNODE). */
     110    RTLISTANCHOR        LstScopeNodes;
     111    /** The AST node arguments - variable in size. */
     112    RTACPIASTARG        aArgs[1];
     113} RTACPIASTNODE;
     114
     115/** Default flags. */
     116#define RTACPI_AST_NODE_F_DEFAULT       0
     117/** The AST node opens a new scope. */
     118#define RTACPI_AST_NODE_F_NEW_SCOPE     RT_BIT_32(0)
     119/** The AST node opcode is part of the extended prefix opcode map. */
     120#define RTACPI_AST_NODE_F_EXT_OPC       RT_BIT_32(1)
     121
     122
     123/**
     124 * Allocates a new ACPI AST node initialized with the given properties.
     125 *
     126 * @returns Pointer to the new ACPI AST node or NULL if out of memory.
     127 * @param   bOpc                The opcode value for the AST node.
     128 * @param   fFlags              Flags for this node.
     129 * @param   cArgs               Number of arguments to allocate.
     130 */
     131DECLHIDDEN(PRTACPIASTNODE) rtAcpiAstNodeAlloc(uint8_t bOpc, uint32_t fFlags, uint8_t cArgs);
     132
     133
     134/**
     135 * Frees the given AST node and all children nodes linked to this one.
     136 *
     137 * @param   pAstNd              The AST node to free.
     138 */
     139DECLHIDDEN(void) rtAcpiAstNodeFree(PRTACPIASTNODE pAstNd);
     140
     141
     142/**
     143 * Dumps the given AST node and everything it references to the given ACPI table.
     144 *
     145 * @returns IPRT status code.
     146 * @param   pAstNd              The AST node to dump.
     147 * @param   hAcpiTbl            The ACPI table to dump to.
     148 */
     149DECLHIDDEN(int) rtAcpiAstDumpToTbl(PCRTACPIASTNODE pAstNd, RTACPITBL hAcpiTbl);
     150
    46151
    47152/**
     
    57162
    58163/**
    59  * Worker for decompiling ASL bytecode to the AML source language.
     164 * Worker for compiling ASL to the AML bytecode.
    60165 *
    61166 * @returns IPRT status code.
Note: See TracChangeset for help on using the changeset viewer.

© 2024 Oracle Support Privacy / Do Not Sell My Info Terms of Use Trademark Policy Automated Access Etiquette