VirtualBox

Changeset 108230 in vbox for trunk/src/VBox


Ignore:
Timestamp:
Feb 14, 2025 8:49:02 PM (3 months ago)
Author:
vboxsync
svn:sync-xref-src-repo-rev:
167551
Message:

Runtime/RTAcpi*: Updates and fixes, RTIasl can now mostly generate identical AML code for vbox.dsl, apart from a single optimization where iasl can fold certain operations on constants into an integer, like ShiftLeft(One,1) for instance, bugref:10733

Location:
trunk/src/VBox/Runtime
Files:
5 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/VBox/Runtime/common/acpi/acpi-ast.cpp

    r108221 r108230  
    6969*********************************************************************************************************************************/
    7070
    71 DECLHIDDEN(PRTACPIASTNODE) rtAcpiAstNodeAlloc(RTACPIASTNODEOP enmOp, uint32_t fFlags, uint8_t cArgs)
     71DECLHIDDEN(PRTACPIASTNODE) rtAcpiAstNodeAlloc(PCRTACPINSROOT pNs, RTACPIASTNODEOP enmOp, uint32_t fFlags, uint8_t cArgs)
    7272{
    7373    PRTACPIASTNODE pAstNd = (PRTACPIASTNODE)RTMemAllocZ(RT_UOFFSETOF_DYN(RTACPIASTNODE, aArgs[cArgs]));
    7474    if (pAstNd)
    7575    {
    76         pAstNd->enmOp  = enmOp;
    77         pAstNd->fFlags = fFlags;
    78         pAstNd->cArgs  = cArgs;
     76        pAstNd->pNsEntry = rtAcpiNsGetCurrent(pNs);
     77        pAstNd->enmOp    = enmOp;
     78        pAstNd->fFlags   = fFlags;
     79        pAstNd->cArgs    = cArgs;
    7980        RTListInit(&pAstNd->LstScopeNodes);
    8081    }
     
    179180
    180181        *pu64 = pNsEntry->offBits;
     182        return VINF_SUCCESS;
    181183    }
    182184
     
    203205{
    204206    int rc = VINF_SUCCESS;
     207    char szNameString[_1K];
    205208
    206209    switch (pAstNd->enmOp)
     
    208211        case kAcpiAstNodeOp_Identifier:
    209212        {
    210             rc = RTAcpiTblNameStringAppend(hAcpiTbl, pAstNd->pszIde);
     213            rc = rtAcpiNsAbsoluteNameStringToRelative(pNsRoot, pAstNd->pNsEntry, pAstNd->pszIde, &szNameString[0], sizeof(szNameString));
     214            AssertRC(rc);
     215
     216            rc = RTAcpiTblNameStringAppend(hAcpiTbl, szNameString);
    211217            if (RT_SUCCESS(rc))
    212218            {
     
    232238                            && pAstNd->aArgs[0].enmType == kAcpiAstArgType_NameString,
    233239                            rc = VERR_INTERNAL_ERROR);
    234             rc = RTAcpiTblScopeStart(hAcpiTbl, pAstNd->aArgs[0].u.pszNameString);
     240            rc = rtAcpiNsCompressNameString(pNsRoot, pAstNd->pNsEntry, pAstNd->aArgs[0].u.pszNameString,
     241                                            &szNameString[0], sizeof(szNameString));
     242            AssertRC(rc);
     243
     244            rc = RTAcpiTblScopeStart(hAcpiTbl, szNameString);
    235245            if (RT_SUCCESS(rc))
    236246            {
     
    272282                            && pAstNd->aArgs[3].enmType == kAcpiAstArgType_U8,
    273283                            rc = VERR_INTERNAL_ERROR);
    274             rc = RTAcpiTblMethodStart(hAcpiTbl, pAstNd->aArgs[0].u.pszNameString,
     284            rc = rtAcpiNsCompressNameString(pNsRoot, pAstNd->pNsEntry, pAstNd->aArgs[0].u.pszNameString,
     285                                            &szNameString[0], sizeof(szNameString));
     286            AssertRC(rc);
     287
     288            rc = RTAcpiTblMethodStart(hAcpiTbl, szNameString,
    275289                                      pAstNd->aArgs[1].u.u8,
    276290                                      pAstNd->aArgs[2].u.f ? RTACPI_METHOD_F_SERIALIZED : RTACPI_METHOD_F_NOT_SERIALIZED,
     
    466480                            && pAstNd->aArgs[3].enmType == kAcpiAstArgType_FieldUpdate,
    467481                            rc = VERR_INTERNAL_ERROR);
    468 
    469             rc = RTAcpiTblFieldAppend(hAcpiTbl, pAstNd->aArgs[0].u.pszNameString, pAstNd->aArgs[1].u.enmFieldAcc,
     482            rc = rtAcpiNsAbsoluteNameStringToRelative(pNsRoot, pAstNd->pNsEntry, pAstNd->aArgs[0].u.pszNameString, &szNameString[0], sizeof(szNameString));
     483            AssertRC(rc);
     484
     485            rc = RTAcpiTblFieldAppend(hAcpiTbl, szNameString, pAstNd->aArgs[1].u.enmFieldAcc,
    470486                                      pAstNd->aArgs[2].u.f, pAstNd->aArgs[3].u.enmFieldUpdate, pAstNd->Fields.paFields,
    471487                                      pAstNd->Fields.cFields);
     
    811827            {
    812828                /* Try to resolve to an integer. */
    813                 uint64_t offBits = 0;
    814                 rc = rtAcpiAstNodeEvaluateToInteger(pAstNd->aArgs[1].u.pAstNd, pNsRoot, &offBits);
    815                 if (RT_SUCCESS(rc))
    816                     rc = RTAcpiTblIntegerAppend(hAcpiTbl, pAstNd->enmOp == kAcpiAstNodeOp_CreateBitField ? offBits : offBits / 8);
     829                uint64_t off = 0;
     830                if (pAstNd->aArgs[1].u.pAstNd->enmOp == kAcpiAstNodeOp_Number)
     831                    off = pAstNd->aArgs[1].u.pAstNd->u64;
     832                else
     833                {
     834                    rc = rtAcpiAstNodeEvaluateToInteger(pAstNd->aArgs[1].u.pAstNd, pNsRoot, &off);
     835                    off = pAstNd->enmOp == kAcpiAstNodeOp_CreateBitField ? off : off / 8;
     836                }
     837                if (RT_SUCCESS(rc))
     838                    rc = RTAcpiTblIntegerAppend(hAcpiTbl, off);
    817839                else
    818840                    rc = rtAcpiAstDumpToTbl(pAstNd->aArgs[1].u.pAstNd, pNsRoot, hAcpiTbl);
  • trunk/src/VBox/Runtime/common/acpi/acpi-compiler.cpp

    r108221 r108230  
    11891189
    11901190
    1191 static int rtAcpiTblParseFieldUnitList(PRTACPIASLCU pThis, PRTACPIASTNODE pAstNd)
     1191static int rtAcpiTblParseFieldUnitList(PRTACPIASLCU pThis, const char *pszFieldName, PRTACPIASTNODE pAstNd)
    11921192{
    11931193    RTACPIFIELDENTRY aFieldEntries[128]; RT_ZERO(aFieldEntries); /** @todo Allow dynamic allocation? */
    11941194    uint32_t cFields = 0;
    11951195
     1196    uint32_t offBits = 0;
    11961197    for (;;)
    11971198    {
     
    12161217            RTACPIASL_PARSE_NATURAL(offBytes);
    12171218            aFieldEntries[cFields].pszName = NULL;
    1218             aFieldEntries[cFields].cBits   = offBytes * 8;
     1219            aFieldEntries[cFields].cBits   = (offBytes * 8) - offBits;
    12191220            RTACPIASL_PARSE_PUNCTUATOR(RTACPIASLTERMINAL_PUNCTUATOR_CLOSE_BRACKET, ')');
    12201221        }
     
    12271228            aFieldEntries[cFields].pszName = pszName;
    12281229            aFieldEntries[cFields].cBits   = cBits;
     1230
     1231            rc = rtAcpiNsAddEntryRsrcField(pThis->pNs, pszName, offBits, cBits);
     1232            if (RT_FAILURE(rc))
     1233                return RTErrInfoSetF(pThis->pErrInfo, rc, "Failed to add '%s.%s' to namespace", pszFieldName, pszName);
     1234
    12291235        }
    12301236
     1237        offBits += aFieldEntries[cFields].cBits;
    12311238        cFields++;
    12321239
     
    13371344    /* Parse the field unit list. */
    13381345    RTACPIASL_PARSE_PUNCTUATOR(RTACPIASLTERMINAL_PUNCTUATOR_OPEN_CURLY_BRACKET, '{');
    1339     return rtAcpiTblParseFieldUnitList(pThis, pAstNd);
     1346    return rtAcpiTblParseFieldUnitList(pThis, pszNameString, pAstNd);
    13401347}
    13411348
     
    15311538        static const RTACPIRSRCNSENTRY s_aRsrcNs[] =
    15321539        {
    1533             { NULL, 0,  0 }
     1540            { "_INT", 1 * 8, 16 },
     1541            { NULL,       0,  0 }
    15341542        };
    15351543        rc = rtAcpiTblParseResourceNsCreateEntries(pThis, hAcpiRes, pAstNd, "IRQNoFlags", pszName, &s_aRsrcNs[0]);
     
    16741682    {
    16751683        case RTACPIASLTERMINAL_KEYWORD_TRANSFER_8:    enmTransferType = kAcpiResDmaTransferType_8Bit;       break;
    1676         case RTACPIASLTERMINAL_KEYWORD_TRANSFER_16:   enmTransferType = kAcpiResDmaTransferType_8Bit_16Bit; break;
    1677         case RTACPIASLTERMINAL_KEYWORD_TRANSFER_8_16: enmTransferType = kAcpiResDmaTransferType_16Bit;      break;
     1684        case RTACPIASLTERMINAL_KEYWORD_TRANSFER_16:   enmTransferType = kAcpiResDmaTransferType_16Bit;      break;
     1685        case RTACPIASLTERMINAL_KEYWORD_TRANSFER_8_16: enmTransferType = kAcpiResDmaTransferType_8Bit_16Bit; break;
    16781686        default:
    16791687            AssertReleaseFailed();
     
    19081916            { "_TTP",  5 * 8 + 5,  1 },
    19091917            { "_GRA",  6 * 8,     32 },
    1910             { "_MIN", 12 * 8,     32 },
    1911             { "_MAX", 16 * 8,     32 },
    1912             { "_TRA", 24 * 8,     32 },
    1913             { "_LEN", 32 * 8,     32 },
     1918            { "_MIN", 10 * 8,     32 },
     1919            { "_MAX", 14 * 8,     32 },
     1920            { "_TRA", 18 * 8,     32 },
     1921            { "_LEN", 22 * 8,     32 },
    19141922            { NULL,        0,      0 }
    19151923        };
     
    24002408    /* kAcpiAstNodeOp_StringLiteral           */  RTACPI_ASL_KEYWORD_DEFINE_INVALID,
    24012409    /* kAcpiAstNodeOp_Number                  */  RTACPI_ASL_KEYWORD_DEFINE_INVALID,
    2402     /* kAcpiAstNodeOp_Scope                   */  RTACPI_ASL_KEYWORD_DEFINE_1REQ_0OPT("Scope",                  RTACPI_AST_NODE_F_NEW_SCOPE | RTACPI_AST_NODE_F_NS_ENTRY,   kAcpiAstArgType_NameString),
     2410    /* kAcpiAstNodeOp_Scope                   */  RTACPI_ASL_KEYWORD_DEFINE_1REQ_0OPT("Scope",                  RTACPI_AST_NODE_F_NEW_SCOPE | RTACPI_AST_NODE_F_NS_SWITCH,  kAcpiAstArgType_NameString),
    24032411    /* kAcpiAstNodeOp_Processor               */  {
    24042412                                                      "Processor", NULL, 2, 2, RTACPI_AST_NODE_F_NEW_SCOPE | RTACPI_AST_NODE_F_NS_ENTRY,
     
    24172425                                                  },
    24182426    /* kAcpiAstNodeOp_External                */  RTACPI_ASL_KEYWORD_DEFINE_INVALID, /* Special handling. */
    2419     /* kAcpiAstNodeOp_Method                  */  RTACPI_ASL_KEYWORD_DEFINE_HANDLER(  "Method",                 rtAcpiTblAslParseMethod,   1, 3, RTACPI_AST_NODE_F_NEW_SCOPE),
     2427    /* kAcpiAstNodeOp_Method                  */  RTACPI_ASL_KEYWORD_DEFINE_HANDLER(  "Method",                 rtAcpiTblAslParseMethod,   1, 3, RTACPI_AST_NODE_F_NEW_SCOPE | RTACPI_AST_NODE_F_NS_ENTRY),
    24202428    /* kAcpiAstNodeOp_Device                  */  RTACPI_ASL_KEYWORD_DEFINE_1REQ_0OPT("Device",                 RTACPI_AST_NODE_F_NEW_SCOPE | RTACPI_AST_NODE_F_NS_ENTRY,   kAcpiAstArgType_NameString),
    24212429    /* kAcpiAstNodeOp_If                      */  RTACPI_ASL_KEYWORD_DEFINE_1REQ_0OPT("If",                     RTACPI_AST_NODE_F_NEW_SCOPE,                                kAcpiAstArgType_AstNode),
     
    26132621
    26142622    PCRTACPIASLKEYWORD pAslKeyword = &g_aAslOps[enmOp];
    2615     PRTACPIASTNODE pAstNd = rtAcpiAstNodeAlloc(enmOp, pAslKeyword->fFlags, pAslKeyword->cArgsReq + pAslKeyword->cArgsOpt);
     2623    PRTACPIASTNODE pAstNd = rtAcpiAstNodeAlloc(pThis->pNs, enmOp, pAslKeyword->fFlags, pAslKeyword->cArgsReq + pAslKeyword->cArgsOpt);
    26162624    if (!pAstNd)
    26172625        return RTErrInfoSetF(pThis->pErrInfo, VERR_NO_MEMORY, "Failed to allocate ACPI AST node when processing keyword '%s'", pAslKeyword->pszOpc);
     
    26362644            if (RT_FAILURE(rc))
    26372645                return rc;
    2638 
    2639             if (i == 0 && (pAslKeyword->fFlags & RTACPI_AST_NODE_F_NS_ENTRY))
    2640             {
    2641                 /*
    2642                  * Create a new namespace entry, we currently assume that the first argument is a namestring
    2643                  * which gives the path.
    2644                  */
    2645                 AssertReturn(pAstNd->aArgs[0].enmType == kAcpiAstArgType_NameString, VERR_NOT_SUPPORTED);
    2646 
    2647                 rc = rtAcpiNsAddEntryAstNode(pThis->pNs, pAstNd->aArgs[0].u.pszNameString, pAstNd, true /*fSwitchTo*/);
    2648                 if (RT_FAILURE(rc))
    2649                     return rc;
    2650             }
    26512646
    26522647            /* There must be a "," between required arguments, not counting the last required argument because it can be closed with ")". */
     
    26982693        /* Now there must be a closing ) */
    26992694        RTACPIASL_PARSE_PUNCTUATOR(RTACPIASLTERMINAL_PUNCTUATOR_CLOSE_BRACKET, ')');
     2695
     2696        if (pAslKeyword->fFlags & RTACPI_AST_NODE_F_NS_ENTRY)
     2697        {
     2698            /*
     2699             * Create a new namespace entry, we currently assume that the first argument is a namestring
     2700             * which gives the path.
     2701             */
     2702            AssertReturn(pAstNd->aArgs[0].enmType == kAcpiAstArgType_NameString, VERR_NOT_SUPPORTED);
     2703
     2704            rc = rtAcpiNsAddEntryAstNode(pThis->pNs, pAstNd->aArgs[0].u.pszNameString, pAstNd, RT_BOOL(pAslKeyword->fFlags & RTACPI_AST_NODE_F_NEW_SCOPE) /*fSwitchTo*/);
     2705            if (RT_FAILURE(rc))
     2706                return rc;
     2707        }
     2708        else if (pAslKeyword->fFlags & RTACPI_AST_NODE_F_NS_SWITCH)
     2709        {
     2710            AssertReturn(pAstNd->aArgs[0].enmType == kAcpiAstArgType_NameString, VERR_NOT_SUPPORTED);
     2711            Assert(pAslKeyword->fFlags & RTACPI_AST_NODE_F_NEW_SCOPE);
     2712
     2713            rc = rtAcpiNsSwitchTo(pThis->pNs, pAstNd->aArgs[0].u.pszNameString);
     2714            if (RT_FAILURE(rc))
     2715                return rc;
     2716        }
     2717
    27002718    }
    27012719
     
    27072725        if (RT_SUCCESS(rc))
    27082726            RTACPIASL_PARSE_PUNCTUATOR(RTACPIASLTERMINAL_PUNCTUATOR_CLOSE_CURLY_BRACKET, '}');
    2709     }
    2710 
    2711     if (pAslKeyword->fFlags & RTACPI_AST_NODE_F_NS_ENTRY)
    2712         rtAcpiNsPop(pThis->pNs);
     2727
     2728        if (pAslKeyword->fFlags & (RTACPI_AST_NODE_F_NS_ENTRY | RTACPI_AST_NODE_F_NS_SWITCH))
     2729            rtAcpiNsPop(pThis->pNs);
     2730    }
    27132731
    27142732    return rc;
     
    27612779    }
    27622780
    2763     PRTACPIASTNODE pAstNd = rtAcpiAstNodeAlloc(kAcpiAstNodeOp_Identifier, RTACPI_AST_NODE_F_DEFAULT, cArgs);
     2781    PRTACPIASTNODE pAstNd = rtAcpiAstNodeAlloc(pThis->pNs, kAcpiAstNodeOp_Identifier, RTACPI_AST_NODE_F_DEFAULT, cArgs);
    27642782    if (!pAstNd)
    27652783        return RTErrInfoSetF(pThis->pErrInfo, VERR_NO_MEMORY, "Failed to allocate ACPI AST node when processing identifier '%s'", pszIde);
     
    28262844    else if (pTok->enmType == RTSCRIPTLEXTOKTYPE_STRINGLIT)
    28272845    {
    2828         pAstNd = rtAcpiAstNodeAlloc(kAcpiAstNodeOp_StringLiteral, RTACPI_AST_NODE_F_DEFAULT, 0);
     2846        pAstNd = rtAcpiAstNodeAlloc(pThis->pNs, kAcpiAstNodeOp_StringLiteral, RTACPI_AST_NODE_F_DEFAULT, 0);
    28292847        if (!pAstNd)
    28302848            return RTErrInfoSetF(pThis->pErrInfo, VERR_NO_MEMORY, "Failed to allocate ACPI AST node when processing identifier '%s'",
     
    28372855    {
    28382856        Assert(pTok->Type.Number.enmType == RTSCRIPTLEXTOKNUMTYPE_NATURAL);
    2839         pAstNd = rtAcpiAstNodeAlloc(kAcpiAstNodeOp_Number, RTACPI_AST_NODE_F_DEFAULT, 0);
     2857        pAstNd = rtAcpiAstNodeAlloc(pThis->pNs, kAcpiAstNodeOp_Number, RTACPI_AST_NODE_F_DEFAULT, 0);
    28402858        if (!pAstNd)
    28412859            return RTErrInfoSetF(pThis->pErrInfo, VERR_NO_MEMORY, "Failed to allocate ACPI AST node when processing number '%#RX64'",
  • trunk/src/VBox/Runtime/common/acpi/acpi-ns.cpp

    r108221 r108230  
    4141#define LOG_GROUP RTLOGGROUP_ACPI
    4242#include <iprt/assert.h>
    43 #include <iprt/errcore.h>
     43#include <iprt/err.h>
    4444#include <iprt/list.h>
    4545#include <iprt/mem.h>
     
    7777    }
    7878    RTMemFree(pNsEntry);
     79}
     80
     81
     82static PRTACPINSENTRY rtAcpiNsLookupWorkerSingleNameSeg(PCRTACPINSENTRY pNsEntry, const char *pszNameSeg)
     83{
     84    do
     85    {
     86        PRTACPINSENTRY pIt;
     87        RTListForEach(&pNsEntry->LstNsEntries, pIt, RTACPINSENTRY, NdNs)
     88        {
     89            if (!memcmp(&pIt->achNameSeg[0], pszNameSeg, sizeof(pIt->achNameSeg)))
     90                return pIt;
     91        }
     92
     93        pNsEntry = pNsEntry->pParent;
     94    } while (pNsEntry);
     95
     96    return NULL;
    7997}
    8098
     
    117135    }
    118136    else
     137    {
    119138        pNsEntry = pNsRoot->aNsStack[pNsRoot->idxNsStack];
     139
     140        /* For single name segments there is a special search rule which searches recursively upwards in the namespace. */
     141        if (pszNameString[4] == '\0')
     142        {
     143            if (fExcludeLast)
     144            {
     145                AssertPtr(ppszNameSegLast);
     146                *ppszNameSegLast = pszNameString;
     147                return pNsEntry;
     148            }
     149            else
     150                return rtAcpiNsLookupWorkerSingleNameSeg(pNsEntry, pszNameString);
     151        }
     152    }
    120153
    121154    /* This ASSUMES the namestring has always full 4 character name segments and is well formed. */
     
    157190
    158191/**
     192 * Looks up a name string under the specified entry.
     193 *
     194 * @returns Pointer to the namespace entry or NULL if not found.
     195 * @param   pNsEntry            The namespace entry to start searching at.
     196 * @param   pszNameString       The name string to look for.
     197 */
     198static PCRTACPINSENTRY rtAcpiNsLookupSubTree(PCRTACPINSENTRY pNsEntry, const char *pszNameString)
     199{
     200    /* This ASSUMES the namestring has always full 4 character name segments and is well formed. */
     201    do
     202    {
     203        Assert(pszNameString[0] != '\0' && pszNameString[1] != '\0' && pszNameString[2] != '\0' && pszNameString[3] != '\0');
     204
     205        PCRTACPINSENTRY pIt;
     206        bool fFound = false;
     207        RTListForEach(&pNsEntry->LstNsEntries, pIt, RTACPINSENTRY, NdNs)
     208        {
     209            if (!memcmp(&pIt->achNameSeg[0], pszNameString, sizeof(pIt->achNameSeg)))
     210            {
     211                pNsEntry = pIt;
     212                fFound = true;
     213                break;
     214            }
     215        }
     216
     217        /* The name path is invalid. */
     218        if (!fFound)
     219            return NULL;
     220
     221        pszNameString += 4;
     222    } while (*pszNameString++ == '.');
     223
     224    return pNsEntry;
     225}
     226
     227
     228/**
    159229 * Adds a new entry in the given namespace under the given path.
    160230 *
     
    163233 * @param   pszNameString       The namestring to add.
    164234 * @param   fSwitchTo           Flag whether to switch to the new entry.
     235 * @param   fIgnoreExisting     Flag whether to ignore any existing entry in the namespace parents.
    165236 * @param   ppNsEntry           Where to store the pointer to the created entry on success.
    166237 */
    167 static int rtAcpiNsAddEntryWorker(PRTACPINSROOT pNsRoot, const char *pszNameString, bool fSwitchTo, PRTACPINSENTRY *ppNsEntry)
     238static int rtAcpiNsAddEntryWorker(PRTACPINSROOT pNsRoot, const char *pszNameString, bool fSwitchTo, bool fIgnoreExisting, PRTACPINSENTRY *ppNsEntry)
    168239{
    169240    AssertReturn(   !fSwitchTo
    170241                 || pNsRoot->idxNsStack < RT_ELEMENTS(pNsRoot->aNsStack),
    171242                 VERR_INVALID_STATE);
     243
     244    /* Does it exist already? */
     245    if (!fIgnoreExisting)
     246    {
     247        PRTACPINSENTRY pNsEntry = rtAcpiNsLookupWorker(pNsRoot, pszNameString, false /*fExcludeLast*/, NULL);
     248        if (pNsEntry)
     249        {
     250            *ppNsEntry = pNsEntry;
     251            if (fSwitchTo)
     252                pNsRoot->aNsStack[++pNsRoot->idxNsStack] = pNsEntry;
     253            return VERR_ALREADY_EXISTS;
     254        }
     255    }
    172256
    173257    int rc;
     
    209293        pNsRoot->idxNsStack        = 0;
    210294        pNsRoot->aNsStack[pNsRoot->idxNsStack] = &pNsRoot->RootEntry;
     295        /* Create the default scopes. */
     296        int rc = rtAcpiNsAddEntryAstNode(pNsRoot, "\\_SB_", NULL /*pAstNd*/, false /*fSwitchTo*/);
     297        if (RT_SUCCESS(rc))
     298            rc = rtAcpiNsAddEntryAstNode(pNsRoot, "\\_PR_", NULL /*pAstNd*/, false /*fSwitchTo*/);
     299        if (RT_SUCCESS(rc))
     300            rc = rtAcpiNsAddEntryAstNode(pNsRoot, "\\_GPE", NULL /*pAstNd*/, false /*fSwitchTo*/);
     301        if (RT_SUCCESS(rc))
     302            rc = rtAcpiNsAddEntryAstNode(pNsRoot, "\\_SI_", NULL /*pAstNd*/, false /*fSwitchTo*/);
     303        if (RT_SUCCESS(rc))
     304            rc = rtAcpiNsAddEntryAstNode(pNsRoot, "\\_TZ_", NULL /*pAstNd*/, false /*fSwitchTo*/);
     305        Assert(RT_SUCCESS(rc) || rc == VERR_NO_MEMORY);
     306        if (RT_FAILURE(rc))
     307        {
     308            RTMemFree(pNsRoot);
     309            pNsRoot = NULL;
     310        }
    211311    }
    212312    return pNsRoot;
     
    226326
    227327
     328DECLHIDDEN(int) rtAcpiNsSwitchTo(PRTACPINSROOT pNsRoot, const char *pszNameString)
     329{
     330    PRTACPINSENTRY pNsEntry = rtAcpiNsLookup(pNsRoot, pszNameString);
     331    if (!pNsEntry)
     332        return VERR_NOT_FOUND;
     333
     334    pNsRoot->aNsStack[++pNsRoot->idxNsStack] = pNsEntry;
     335    return VINF_SUCCESS;
     336}
     337
     338
    228339DECLHIDDEN(int) rtAcpiNsAddEntryAstNode(PRTACPINSROOT pNsRoot, const char *pszNameString, PCRTACPIASTNODE pAstNd, bool fSwitchTo)
    229340{
    230341    PRTACPINSENTRY pNsEntry = NULL;
    231     int rc = rtAcpiNsAddEntryWorker(pNsRoot, pszNameString, fSwitchTo, &pNsEntry);
     342    int rc = rtAcpiNsAddEntryWorker(pNsRoot, pszNameString, fSwitchTo, false /*fIgnoreExisting*/, &pNsEntry);
     343    if (rc == VERR_ALREADY_EXISTS)
     344        rc = VINF_SUCCESS;
    232345    if (RT_SUCCESS(rc))
    233346    {
     
    243356{
    244357    PRTACPINSENTRY pNsEntry = NULL;
    245     int rc = rtAcpiNsAddEntryWorker(pNsRoot, pszNameString, false /*fSwitchTo*/, &pNsEntry);
     358    int rc = rtAcpiNsAddEntryWorker(pNsRoot, pszNameString, false /*fSwitchTo*/, true /*fIgnoreExisting*/, &pNsEntry);
    246359    if (RT_SUCCESS(rc))
    247360    {
     
    259372{
    260373    PRTACPINSENTRY pNsEntry = NULL;
    261     int rc = rtAcpiNsAddEntryWorker(pNsRoot, pszNameString, false /*fSwitchTo*/, &pNsEntry);
     374    int rc = rtAcpiNsAddEntryWorker(pNsRoot, pszNameString, false /*fSwitchTo*/, false /*fIgnoreExisting*/, &pNsEntry);
    262375    if (RT_SUCCESS(rc))
    263376    {
     
    350463
    351464
     465DECLHIDDEN(int) rtAcpiNsCompressNameString(PCRTACPINSROOT pNsRoot, PCRTACPINSENTRY pNsEntry, const char *pszNameString, char *pszNameStringComp, size_t cchNameStringComp)
     466{
     467    size_t cchNameString = strlen(pszNameString);
     468    if (cchNameString > cchNameStringComp)
     469        return VERR_BUFFER_OVERFLOW;
     470
     471    if (   *pszNameString != '\\'
     472        || pNsEntry != rtAcpiNsGetCurrent(pNsRoot))
     473    {
     474        memcpy(pszNameStringComp, pszNameString, cchNameString + 1);
     475        return VINF_SUCCESS;
     476    }
     477
     478    /* Try to remove as many components as possible. */
     479    uint32_t cEntries = 0;
     480    PCRTACPINSENTRY aNsEntries[255]; /* Maximum amount of name segments possible. */
     481    do
     482    {
     483        aNsEntries[cEntries++] = pNsEntry;
     484        pNsEntry = pNsEntry->pParent;
     485    } while (pNsEntry);
     486
     487    Assert(cEntries > 0); /* Should have at least the root entry. */
     488
     489    /* Remove the \ specifier. */
     490    pszNameString++;
     491    cchNameString--;
     492    uint32_t idxEntry = 1;
     493    while (idxEntry < cEntries)
     494    {
     495        pNsEntry = aNsEntries[idxEntry++];
     496        if (memcmp(pszNameString, &pNsEntry->achNameSeg[0], sizeof(pNsEntry->achNameSeg)))
     497            break;
     498
     499        Assert(pszNameString[4] == '.');
     500        pszNameString += 5;
     501        cchNameString -= 5;
     502    }
     503
     504    /* The remaining string is what we end up with. */
     505    memcpy(pszNameStringComp, pszNameString, cchNameString + 1);
     506    return VINF_SUCCESS;
     507}
     508
     509
     510DECLHIDDEN(int) rtAcpiNsAbsoluteNameStringToRelative(PRTACPINSROOT pNsRoot, PCRTACPINSENTRY pNsEntrySrc, const char *pszNameStringDst, char *pszNameStringRel, size_t cchNameStringRel)
     511{
     512    size_t cchNameStringDst = strlen(pszNameStringDst);
     513    if (cchNameStringDst > cchNameStringRel)
     514        return VERR_BUFFER_OVERFLOW;
     515
     516    /* Init with the default. */
     517    memcpy(pszNameStringRel, pszNameStringDst, cchNameStringDst + 1);
     518    if (*pszNameStringDst != '\\')
     519        return VINF_SUCCESS;
     520
     521    PCRTACPINSENTRY pNsDst = rtAcpiNsLookup(pNsRoot, pszNameStringDst);
     522    AssertReturn(pNsDst, VERR_NOT_FOUND);
     523
     524    uint32_t cEntriesSrc = 0;
     525    PCRTACPINSENTRY aNsEntriesSrc[255]; /* Maximum amount of name segments possible. */
     526    do
     527    {
     528        aNsEntriesSrc[cEntriesSrc++] = pNsEntrySrc;
     529        pNsEntrySrc = pNsEntrySrc->pParent;
     530    } while (pNsEntrySrc);
     531
     532    uint32_t cEntriesDst = 0;
     533    PCRTACPINSENTRY aNsEntriesDst[255]; /* Maximum amount of name segments possible. */
     534    do
     535    {
     536        aNsEntriesDst[cEntriesDst++] = pNsDst;
     537        pNsDst = pNsDst->pParent;
     538    } while (pNsDst);
     539
     540    Assert(cEntriesSrc > 0 && cEntriesDst > 0); /* Should have at least the root entry. */
     541    uint32_t idxEntrySrc = cEntriesSrc;
     542    idxEntrySrc--;
     543    cEntriesDst--;
     544    Assert(aNsEntriesSrc[idxEntrySrc] == aNsEntriesDst[cEntriesDst]);
     545
     546    /* Remove the \ specifier. */
     547    size_t cchNameStringNew = cchNameStringDst;
     548    pszNameStringDst++;
     549    cchNameStringNew--;
     550
     551    /* Find the first different path entry. */
     552    while (   idxEntrySrc
     553           && cEntriesDst)
     554    {
     555        if (   aNsEntriesSrc[--idxEntrySrc] != aNsEntriesDst[--cEntriesDst]
     556            || pszNameStringDst[4] == '\0')
     557            break;
     558
     559        Assert(pszNameStringDst[4] == '.');
     560        pszNameStringDst += 5;
     561        cchNameStringNew -= 5;
     562    }
     563
     564    /*
     565     * Calculate how many parent prefixes we need to add.
     566     * If the remaining name path is just a segment it must be a
     567     * direct parent of the source and can be written as a simple name segment
     568     * due to the default search rules.
     569     */
     570    uint32_t cParentPrefixes =   (   rtAcpiNsLookupSubTree(aNsEntriesSrc[idxEntrySrc], pszNameStringDst)
     571                                  || pszNameStringDst[4] == '\0')
     572                               ? 0
     573                               : idxEntrySrc + 1;
     574    /* Only overwrite with our result if it is shorter. */
     575    if (cParentPrefixes + cchNameStringNew < cchNameStringDst)
     576    {
     577        for (uint32_t i = 0; i < cParentPrefixes; i++)
     578            pszNameStringRel[i] = '^';
     579        memcpy(&pszNameStringRel[cParentPrefixes], pszNameStringDst, cchNameStringNew + 1);
     580    }
     581    return VINF_SUCCESS;
     582}
     583
     584
    352585DECLHIDDEN(int) rtAcpiNsPop(PRTACPINSROOT pNsRoot)
    353586{
     
    358591
    359592
    360 DECLHIDDEN(PCRTACPINSENTRY) rtAcpiNsLookup(PRTACPINSROOT pNsRoot, const char *pszNameString)
     593DECLHIDDEN(PRTACPINSENTRY) rtAcpiNsLookup(PRTACPINSROOT pNsRoot, const char *pszNameString)
    361594{
    362595    return rtAcpiNsLookupWorker(pNsRoot, pszNameString, false /*fExcludeLast*/, NULL /*ppszNameSegLast*/);
    363596}
     597
     598
     599DECLHIDDEN(PCRTACPINSENTRY) rtAcpiNsGetCurrent(PCRTACPINSROOT pNsRoot)
     600{
     601    return pNsRoot->aNsStack[pNsRoot->idxNsStack];
     602}
  • trunk/src/VBox/Runtime/common/acpi/acpi.cpp

    r108221 r108230  
    11911191        case kAcpiStmt_SizeOf:     bOp = ACPI_AML_BYTE_CODE_OP_SIZE_OF;     break;
    11921192        case kAcpiStmt_Increment:  bOp = ACPI_AML_BYTE_CODE_OP_INCREMENT;   break;
    1193         case kAcpiStmt_Decrement:  bOp = ACPI_AML_BYTE_CODE_OP_INCREMENT;   break;
     1193        case kAcpiStmt_Decrement:  bOp = ACPI_AML_BYTE_CODE_OP_DECREMENT;   break;
    11941194        case kAcpiStmt_CondRefOf:  bOp = ACPI_AML_BYTE_CODE_EXT_OP_COND_REF_OF; fExtOp = true; break;
    11951195        case kAcpiStmt_LNot:       bOp = ACPI_AML_BYTE_CODE_OP_LNOT;        break;
     
    13491349
    13501350
    1351 DECLINLINE(uint8_t) rtAcpiTblHexCharToByte(char ch)
     1351DECLINLINE(uint32_t) rtAcpiTblHexCharToByte(char ch)
    13521352{
    13531353    ch = RT_C_TO_LOWER(ch);
    1354     return RT_C_IS_DIGIT(ch) ? ch - '0' : ch - 'a';
     1354    return RT_C_IS_DIGIT(ch) ? ch - '0' : 10 + ch - 'a';
    13551355}
    13561356
     
    13711371                 VERR_INVALID_PARAMETER);
    13721372
    1373     uint8_t bMfgCode0 = pszEisaId[0] - 0x40;
    1374     uint8_t bMfgCode1 = pszEisaId[1] - 0x40;
    1375     uint8_t bMfgCode2 = pszEisaId[2] - 0x40;
    1376 
    1377     uint8_t abDword[4] = { 0 };
    1378     abDword[0] = (bMfgCode0 << 2) | (bMfgCode1 >> 3);
    1379     abDword[1] = (bMfgCode1 << 5) | bMfgCode2;
    1380     abDword[2] = (rtAcpiTblHexCharToByte(pszEisaId[3]) << 4) | rtAcpiTblHexCharToByte(pszEisaId[4]);
    1381     abDword[3] = (rtAcpiTblHexCharToByte(pszEisaId[5]) << 4) | rtAcpiTblHexCharToByte(pszEisaId[6]);
    1382     rtAcpiTblAppendByte(pThis, ACPI_AML_BYTE_CODE_PREFIX_DWORD);
    1383     rtAcpiTblAppendData(pThis, &abDword[0], sizeof(abDword));
    1384     return pThis->rcErr;
     1373    uint32_t bMfgCode0 = (pszEisaId[0] - 0x40) & 0x1f;
     1374    uint32_t bMfgCode1 = (pszEisaId[1] - 0x40) & 0x1f;
     1375    uint32_t bMfgCode2 = (pszEisaId[2] - 0x40) & 0x1f;
     1376
     1377    uint32_t u32 =   ((bMfgCode0 << 2) | ((bMfgCode1 >> 3) & 0x3))
     1378                   | (((bMfgCode1 & 0x7) << 5) | bMfgCode2) << 8
     1379                   | ((rtAcpiTblHexCharToByte(pszEisaId[3]) << 4) | rtAcpiTblHexCharToByte(pszEisaId[4])) << 16
     1380                   | ((rtAcpiTblHexCharToByte(pszEisaId[5]) << 4) | rtAcpiTblHexCharToByte(pszEisaId[6])) << 24;
     1381    return RTAcpiTblIntegerAppend(hAcpiTbl, u32);
    13851382}
    13861383
     
    17691766
    17701767    *pb++ = ACPI_RSRCS_TAG_END;
    1771 #if 1
     1768#if 0
    17721769    /*
    17731770     * Generate checksum, we could just write 0 here which will be treated as checksum operation succeeded,
     
    22682265
    22692266    bool fDefaultCfg = fEdgeTriggered && !fActiveLow && !fShared && !fWakeCapable;
    2270     uint8_t *pb = rtAcpiResBufEnsureSpace(pThis, 2 + (fDefaultCfg ? 0 : 1));
     2267    uint8_t *pb = rtAcpiResBufEnsureSpace(pThis, 3 + (fDefaultCfg ? 0 : 1));
    22712268    if (!pb)
    22722269        return VERR_NO_MEMORY;
  • trunk/src/VBox/Runtime/include/internal/acpi.h

    r108222 r108230  
    5050/** Pointer to a const ACPI AST node. */
    5151typedef const struct RTACPIASTNODE *PCRTACPIASTNODE;
     52/** Pointer to an ACPI namespace entry. */
     53typedef struct RTACPINSENTRY *PRTACPINSENTRY;
     54
     55
     56/**
     57 * External declaration.
     58 */
     59typedef struct RTACPIASLEXTERNAL
     60{
     61    /** List node for the list of externals. */
     62    RTLISTNODE              NdExternal;
     63    /** The object type. */
     64    RTACPIOBJTYPE           enmObjType;
     65    /** For methods this will hold the argument count. */
     66    uint32_t                cArgs;
     67    /** The name as parsed from the source file. */
     68    const char              *pszName;
     69    /** Size of the full name path in characters excluding the terminating zero. */
     70    size_t                  cchNamePath;
     71    /** The name path - variable in size. */
     72    char                    szNamePath[1];
     73} RTACPIASLEXTERNAL;
     74/** Pointer to an external declaration. */
     75typedef RTACPIASLEXTERNAL *PRTACPIASLEXTERNAL;
     76/** Pointer to a const external declaration. */
     77typedef const RTACPIASLEXTERNAL *PCRTACPIASLEXTERNAL;
     78
     79
     80/**
     81 * An ACPI namespace entry.
     82 */
     83typedef struct RTACPINSENTRY
     84{
     85    /** Node for the namespace list. */
     86    RTLISTNODE              NdNs;
     87    /** Pointer to the parent in the namespace, NULL if this is the root. */
     88    PRTACPINSENTRY          pParent;
     89    /** The name segment identifying the entry. */
     90    char                    achNameSeg[4];
     91    /** Flag whether this points to an AST node or an external. */
     92    bool                    fAstNd;
     93    /** Type dependent data. */
     94    union
     95    {
     96        /** The AST node associated with this namespace entry. */
     97        PCRTACPIASTNODE     pAstNd;
     98        /** Pointer to the external declaration. */
     99        PCRTACPIASLEXTERNAL pExternal;
     100    };
     101    /** Bit offset for resource fields. */
     102    uint32_t                offBits;
     103    /** Bit count for resource fields. */
     104    uint32_t                cBits;
     105    /** List of namespace entries below this entry. */
     106    RTLISTANCHOR            LstNsEntries;
     107} RTACPINSENTRY;
     108/** Pointer to a const ACPI namespace entry. */
     109typedef const RTACPINSENTRY *PCRTACPINSENTRY;
     110
    52111
    53112/**
     
    199258    /** List node. */
    200259    RTLISTNODE              NdAst;
     260    /** The owning namespace entry. */
     261    PCRTACPINSENTRY         pNsEntry;
    201262    /** The AML op defining the node. */
    202263    RTACPIASTNODEOP         enmOp;
     
    238299/** The AST node has an associated namespace entry. */
    239300#define RTACPI_AST_NODE_F_NS_ENTRY      RT_BIT_32(1)
    240 
    241 
    242 /**
    243  * External declaration.
    244  */
    245 typedef struct RTACPIASLEXTERNAL
    246 {
    247     /** List node for the list of externals. */
    248     RTLISTNODE              NdExternal;
    249     /** The object type. */
    250     RTACPIOBJTYPE           enmObjType;
    251     /** For methods this will hold the argument count. */
    252     uint32_t                cArgs;
    253     /** The name as parsed from the source file. */
    254     const char              *pszName;
    255     /** Size of the full name path in characters excluding the terminating zero. */
    256     size_t                  cchNamePath;
    257     /** The name path - variable in size. */
    258     char                    szNamePath[1];
    259 } RTACPIASLEXTERNAL;
    260 /** Pointer to an external declaration. */
    261 typedef RTACPIASLEXTERNAL *PRTACPIASLEXTERNAL;
    262 /** Pointer to a const external declaration. */
    263 typedef const RTACPIASLEXTERNAL *PCRTACPIASLEXTERNAL;
    264 
    265 
    266 
    267 /** Pointer to an ACPI namespace entry. */
    268 typedef struct RTACPINSENTRY *PRTACPINSENTRY;
    269 
    270 
    271 /**
    272  * An ACPI namespace entry.
    273  */
    274 typedef struct RTACPINSENTRY
    275 {
    276     /** Node for the namespace list. */
    277     RTLISTNODE              NdNs;
    278     /** Pointer to the parent in the namespace, NULL if this is the root. */
    279     PRTACPINSENTRY          pParent;
    280     /** The name segment identifying the entry. */
    281     char                    achNameSeg[4];
    282     /** Flag whether this points to an AST node or an external. */
    283     bool                    fAstNd;
    284     /** Type dependent data. */
    285     union
    286     {
    287         /** The AST node associated with this namespace entry. */
    288         PCRTACPIASTNODE     pAstNd;
    289         /** Pointer to the external declaration. */
    290         PCRTACPIASLEXTERNAL pExternal;
    291     };
    292     /** Bit offset for resource fields. */
    293     uint32_t                offBits;
    294     /** Bit count for resource fields. */
    295     uint32_t                cBits;
    296     /** List of namespace entries below this entry. */
    297     RTLISTANCHOR            LstNsEntries;
    298 } RTACPINSENTRY;
    299 /** Pointer to a const ACPI namespace entry. */
    300 typedef const RTACPINSENTRY *PCRTACPINSENTRY;
     301/** The AST node switches the namespace (only Scope). */
     302#define RTACPI_AST_NODE_F_NS_SWITCH     RT_BIT_32(2)
    301303
    302304
     
    324326 *
    325327 * @returns Pointer to the new ACPI AST node or NULL if out of memory.
     328 * @param   pNs                 The namespace this AST node will be part of.
    326329 * @param   enmOp               The operation of the AST node.
    327330 * @param   fFlags              Flags for this node.
    328331 * @param   cArgs               Number of arguments to allocate.
    329332 */
    330 DECLHIDDEN(PRTACPIASTNODE) rtAcpiAstNodeAlloc(RTACPIASTNODEOP enmOp, uint32_t fFlags, uint8_t cArgs);
     333DECLHIDDEN(PRTACPIASTNODE) rtAcpiAstNodeAlloc(PCRTACPINSROOT pNs, RTACPIASTNODEOP enmOp, uint32_t fFlags, uint8_t cArgs);
    331334
    332335
     
    367370 */
    368371DECLHIDDEN(void) rtAcpiNsDestroy(PRTACPINSROOT pNsRoot);
     372
     373
     374/**
     375 * Switches to the given existing namespace.
     376 *
     377 * @returns IPRT status code.
     378 * @param   pNsRoot             The namespace root.
     379 * @param   pszNameString       The namespace to switch to.
     380 */
     381DECLHIDDEN(int) rtAcpiNsSwitchTo(PRTACPINSROOT pNsRoot, const char *pszNameString);
    369382
    370383
     
    420433
    421434/**
     435 * Tries to compress the given name string to a shorter representation.
     436 *
     437 * @returns IPRT status code.
     438 * @param   pNsRoot             The namespace root.
     439 * @param   pNsEntry            The namespace entry the namestring belongs to.
     440 * @param   pszNameString       The name string to try to compress.
     441 * @param   pszNameStringComp   Where to store the result.
     442 * @param   cchNameStringComp   Size of the buffer in characters.
     443 *
     444 * @note This will only try to compress absolute name paths by converting it to a relative one
     445 *       (\SEG1 -> SEG1 for example if the current scope is \) Otherwise the string is just copied as is.
     446 */
     447DECLHIDDEN(int) rtAcpiNsCompressNameString(PCRTACPINSROOT pNsRoot, PCRTACPINSENTRY pNsEntry, const char *pszNameString, char *pszNameStringComp, size_t cchNameStringComp);
     448
     449
     450/**
     451 * Tries to convert an absolute namestring to a relative one from the given namespace.
     452 *
     453 * @returns IPRT status code.
     454 * @param   pNsRoot             The namespace root.
     455 * @param   pNsEntrySrc         The source namespace.
     456 * @param   pszNameStringDst    The destination name string to try to convert.
     457 * @param   pszNameStringRel    Where to store the result.
     458 * @param   cchNameStringRel    Size of the buffer in characters.
     459 *
     460 * @note This will only try to resolve absolute name paths. Others are just copied as is.
     461 */
     462DECLHIDDEN(int) rtAcpiNsAbsoluteNameStringToRelative(PRTACPINSROOT pNsRoot, PCRTACPINSENTRY pNsEntrySrc,
     463                                                     const char *pszNameStringDst,
     464                                                     char *pszNameStringRel, size_t cchNameStringRel);
     465
     466
     467/**
    422468 * Pops the current name space entry from the stack and returns to the previous one.
    423469 *
     
    435481 * @param   pszNameString       The ACPI NameString (either segment or path) to lookup.
    436482 */
    437 DECLHIDDEN(PCRTACPINSENTRY) rtAcpiNsLookup(PRTACPINSROOT pNsRoot, const char *pszNameString);
     483DECLHIDDEN(PRTACPINSENTRY) rtAcpiNsLookup(PRTACPINSROOT pNsRoot, const char *pszNameString);
     484
     485
     486/**
     487 * Returns the current namespace entry being active.
     488 *
     489 * @returns Pointer to the current namespace entry.
     490 * @param   pNsRoot             The namespace root.
     491 */
     492DECLHIDDEN(PCRTACPINSENTRY) rtAcpiNsGetCurrent(PCRTACPINSROOT pNsRoot);
    438493
    439494
Note: See TracChangeset for help on using the changeset viewer.

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