VirtualBox

Changeset 108088 in vbox


Ignore:
Timestamp:
Feb 6, 2025 8:48:47 AM (2 weeks ago)
Author:
vboxsync
svn:sync-xref-src-repo-rev:
167382
Message:

Runtime/RTAcpi*: Updates to the ASL -> AML compiler, it is now possible to produce a valid AML table from the pre processed vbox-cpuhotplug.dsl SSDT, bugref:10733

Location:
trunk
Files:
5 edited

Legend:

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

    r108087 r108088  
    478478    kAcpiStmt_Index,
    479479    /** DerefOf(ObjReference) statement. */
    480     kAcpiStmt_DerefOf
     480    kAcpiStmt_DerefOf,
     481    /** Store(SuperName, TermArg => Integer) statement. */
     482    kAcpiStmt_Notify
    481483} RTACPISTMT;
    482484
     
    769771    kAcpiObjType_ThermalZone,
    770772    /** Buffer field object - BuffFieldObj */
    771     kAcpiObjType_BuffField
     773    kAcpiObjType_BuffField,
     774    /** Processor object - ProcessorObj */
     775    kAcpiObjType_Processor,
    772776} RTACPIOBJTYPE;
    773777
  • trunk/src/VBox/Runtime/common/acpi/acpi-ast.cpp

    r108087 r108088  
    390390            rc = RTAcpiTblStmtSimpleAppend(hAcpiTbl, kAcpiStmt_Return);
    391391            if (RT_SUCCESS(rc))
    392                 rc = rtAcpiAstDumpToTbl(pAstNd->aArgs[0].u.pAstNd, hAcpiTbl);
     392            {
     393                if (pAstNd->aArgs[0].u.pAstNd)
     394                    rc = rtAcpiAstDumpToTbl(pAstNd->aArgs[0].u.pAstNd, hAcpiTbl);
     395                else
     396                    rc = RTAcpiTblNullNameAppend(hAcpiTbl);
     397            }
    393398            break;
    394399        }
     
    596601        }
    597602        case kAcpiAstNodeOp_Store:
     603        case kAcpiAstNodeOp_Notify:
    598604        {
    599605            AssertBreakStmt(   pAstNd->cArgs == 2
     
    601607                            && pAstNd->aArgs[1].enmType == kAcpiAstArgType_AstNode,
    602608                            rc = VERR_INTERNAL_ERROR);
    603             rc = RTAcpiTblStmtSimpleAppend(hAcpiTbl, kAcpiStmt_Store);
     609            rc = RTAcpiTblStmtSimpleAppend(hAcpiTbl,
     610                                             pAstNd->enmOp == kAcpiAstNodeOp_Store
     611                                           ? kAcpiStmt_Store
     612                                           : kAcpiStmt_Notify);
    604613            if (RT_SUCCESS(rc))
    605614                rc = rtAcpiAstDumpToTbl(pAstNd->aArgs[0].u.pAstNd, hAcpiTbl);
  • trunk/src/VBox/Runtime/common/acpi/acpi-compiler.cpp

    r108087 r108088  
    9090    RTACPIASLTERMINAL_KEYWORD_THERMAL_ZONE_OBJ,
    9191    RTACPIASLTERMINAL_KEYWORD_BUFF_FIELD_OBJ,
     92    RTACPIASLTERMINAL_KEYWORD_PROCESSOR_OBJ,
    9293    RTACPIASLTERMINAL_KEYWORD_SERIALIZED,
    9394    RTACPIASLTERMINAL_KEYWORD_NOT_SERIALIZED,
     
    288289    { RT_STR_TUPLE("XOR"),                      RTSCRIPTLEXTOKTYPE_KEYWORD,    true,  kAcpiAstNodeOp_Xor                               },
    289290    { RT_STR_TUPLE("NOT"),                      RTSCRIPTLEXTOKTYPE_KEYWORD,    true,  kAcpiAstNodeOp_Not                               },
     291    { RT_STR_TUPLE("NOTIFY"),                   RTSCRIPTLEXTOKTYPE_KEYWORD,    true,  kAcpiAstNodeOp_Notify                            },
    290292
    291293    /* Keywords not in the operation parser table. */
     
    305307    { RT_STR_TUPLE("THERMALZONEOBJ"),           RTSCRIPTLEXTOKTYPE_KEYWORD,    true,  RTACPIASLTERMINAL_KEYWORD_THERMAL_ZONE_OBJ       },
    306308    { RT_STR_TUPLE("BUFFFIELDOBJ"),             RTSCRIPTLEXTOKTYPE_KEYWORD,    true,  RTACPIASLTERMINAL_KEYWORD_BUFF_FIELD_OBJ         },
     309    { RT_STR_TUPLE("PROCESSOROBJ"),             RTSCRIPTLEXTOKTYPE_KEYWORD,    true,  RTACPIASLTERMINAL_KEYWORD_PROCESSOR_OBJ          },
    307310
    308311    { RT_STR_TUPLE("SERIALIZED"),               RTSCRIPTLEXTOKTYPE_KEYWORD,    true,  RTACPIASLTERMINAL_KEYWORD_SERIALIZED             },
     
    489492        if (ch != '.')
    490493            break;
     494        aszIde[idx++] = '.';
     495        RTScriptLexConsumeCh(hScriptLex);
    491496    }
    492497
     
    760765    RTACPIASLTERMINAL_KEYWORD_THERMAL_ZONE_OBJ,
    761766    RTACPIASLTERMINAL_KEYWORD_BUFF_FIELD_OBJ,
     767    RTACPIASLTERMINAL_KEYWORD_PROCESSOR_OBJ,
    762768    RTACPIASLTERMINAL_INVALID
    763769};
     
    873879                case RTACPIASLTERMINAL_KEYWORD_THERMAL_ZONE_OBJ: pAstNd->aArgs[1].u.enmObjType = kAcpiObjType_ThermalZone; break;
    874880                case RTACPIASLTERMINAL_KEYWORD_BUFF_FIELD_OBJ:   pAstNd->aArgs[1].u.enmObjType = kAcpiObjType_BuffField; break;
     881                case RTACPIASLTERMINAL_KEYWORD_PROCESSOR_OBJ:    pAstNd->aArgs[1].u.enmObjType = kAcpiObjType_Processor; break;
    875882                default:
    876883                    AssertFailedReturn(VERR_INTERNAL_ERROR);
     
    12361243
    12371244    RTACPIASL_PARSE_PUNCTUATOR(RTACPIASLTERMINAL_PUNCTUATOR_CLOSE_CURLY_BRACKET, '}');
     1245    return VINF_SUCCESS;
     1246}
     1247
     1248
     1249static DECLCALLBACK(int) rtAcpiTblAslParseReturn(PRTACPIASLCU pThis, PCRTACPIASLKEYWORD pKeyword, PRTACPIASTNODE pAstNd)
     1250{
     1251    RT_NOREF(pKeyword);
     1252
     1253    pAstNd->aArgs[0].enmType = kAcpiAstArgType_AstNode;
     1254    pAstNd->aArgs[0].u.pAstNd = NULL;
     1255
     1256    /*
     1257     * Return has three valid forms:
     1258     *    Return
     1259     *    Return ()
     1260     *    Return (TermArg)
     1261     */
     1262    if (rtAcpiAslLexerIsPunctuator(pThis, RTACPIASLTERMINAL_PUNCTUATOR_OPEN_BRACKET))
     1263    {
     1264        RTACPIASL_SKIP_CURRENT_TOKEN(); /* Skip the "(" */
     1265
     1266        if (!rtAcpiAslLexerIsPunctuator(pThis, RTACPIASLTERMINAL_PUNCTUATOR_CLOSE_BRACKET))
     1267        {
     1268            PRTACPIASTNODE pAstNdSize = NULL;
     1269            int rc = rtAcpiTblAslParseTermArg(pThis, &pAstNdSize);
     1270            if (RT_FAILURE(rc))
     1271                return rc;
     1272            pAstNd->aArgs[0].u.pAstNd = pAstNdSize;
     1273        }
     1274        RTACPIASL_PARSE_PUNCTUATOR(RTACPIASLTERMINAL_PUNCTUATOR_CLOSE_BRACKET, ')');
     1275    }
     1276
    12381277    return VINF_SUCCESS;
    12391278}
     
    14151454    /* kAcpiAstNodeOp_One               */  RTACPI_ASL_KEYWORD_DEFINE_0REQ_0OPT("One",              RTACPI_AST_NODE_F_DEFAULT),
    14161455    /* kAcpiAstNodeOp_Ones              */  RTACPI_ASL_KEYWORD_DEFINE_0REQ_0OPT("Ones",             RTACPI_AST_NODE_F_DEFAULT),
    1417     /* kAcpiAstNodeOp_Return            */  RTACPI_ASL_KEYWORD_DEFINE_1REQ_0OPT("Return",           RTACPI_AST_NODE_F_DEFAULT,   kAcpiAstArgType_AstNode),
     1456    /* kAcpiAstNodeOp_Return            */  RTACPI_ASL_KEYWORD_DEFINE_HANDLER(  "Return",           rtAcpiTblAslParseReturn,  0, 1, RTACPI_AST_NODE_F_DEFAULT),
    14181457    /* kAcpiAstNodeOp_Unicode           */  RTACPI_ASL_KEYWORD_DEFINE_1REQ_0OPT("Unicode",          RTACPI_AST_NODE_F_DEFAULT,   kAcpiAstArgType_AstNode), /* Actually only String allowed here */
    14191458    /* kAcpiAstNodeOp_OperationRegion   */  RTACPI_ASL_KEYWORD_DEFINE_4REQ_0OPT("OperationRegion",  RTACPI_AST_NODE_F_DEFAULT,   kAcpiAstArgType_NameString, kAcpiAstArgType_RegionSpace, kAcpiAstArgType_AstNode, kAcpiAstArgType_AstNode),
     
    14521491    /* kAcpiAstNodeOp_Xor               */  RTACPI_ASL_KEYWORD_DEFINE_2REQ_1OPT("Xor",              RTACPI_AST_NODE_F_DEFAULT,    kAcpiAstArgType_AstNode, kAcpiAstArgType_AstNode, kAcpiAstArgType_AstNode),
    14531492    /* kAcpiAstNodeOp_Not               */  RTACPI_ASL_KEYWORD_DEFINE_1REQ_1OPT("Not",              RTACPI_AST_NODE_F_DEFAULT,    kAcpiAstArgType_AstNode, kAcpiAstArgType_AstNode),
     1493    /* kAcpiAstNodeOp_Notify            */  RTACPI_ASL_KEYWORD_DEFINE_2REQ_0OPT("Notify",           RTACPI_AST_NODE_F_DEFAULT,    kAcpiAstArgType_AstNode, kAcpiAstArgType_AstNode),
    14541494
    14551495};
  • trunk/src/VBox/Runtime/common/acpi/acpi.cpp

    r108087 r108088  
    6969typedef struct RTACPITBLSTACKELEM
    7070{
    71     /** Pointer to the table buffer memory where the PkgLength object starts. */
    72     uint8_t                     *pbPkgLength;
     71    /** Offset into the table buffer memory where the PkgLength object starts. */
     72    uint32_t                    offPkgLength;
    7373    /** Current size of the package in bytes, without the PkgLength object. */
    7474    uint32_t                    cbPkg;
     
    200200    pThis->pbTblBuf = pbNew;
    201201    pThis->cbTblBuf = cbNew;
     202    pThis->pHdr     = (PACPITBLHDR)pbNew;
    202203
    203204    uint8_t *pb = &pThis->pbTblBuf[pThis->offTblBuf];
     
    214215 * @param pThis                 The ACPI table instance.
    215216 * @param bOp                   The opcode byte the package starts with (for verification purposes when finalizing the package).
    216  * @param pbPkgBuf              The Start of the package buffer.
    217  */
    218 static int rtAcpiTblPkgAppendEx(PRTACPITBLINT pThis, uint8_t bOp, uint8_t *pbPkgBuf)
     217 * @param offPkgBuf             Offset of the start of the package buffer.
     218 */
     219static int rtAcpiTblPkgAppendEx(PRTACPITBLINT pThis, uint8_t bOp, uint32_t offPkgBuf)
    219220{
    220221    /* Get a new stack element. */
     
    234235
    235236    PRTACPITBLSTACKELEM pStackElem = &pThis->paPkgStack[++pThis->idxPkgStackElem];
    236     pStackElem->pbPkgLength = pbPkgBuf;
    237     pStackElem->cbPkg       = 0;
    238     pStackElem->bOp         = bOp;
     237    pStackElem->offPkgLength = offPkgBuf;
     238    pStackElem->cbPkg        = 0;
     239    pStackElem->bOp          = bOp;
    239240    return VINF_SUCCESS;
    240241}
     
    268269     */
    269270    rtAcpiTblUpdatePkgLength(pThis, sizeof(bOp));
    270     return rtAcpiTblPkgAppendEx(pThis, bOp, pbPkg + 1);
     271    return rtAcpiTblPkgAppendEx(pThis, bOp, (pbPkg + 1) - pThis->pbTblBuf);
    271272}
    272273
     
    302303     */
    303304    rtAcpiTblUpdatePkgLength(pThis, sizeof(uint8_t) + sizeof(bOp));
    304     return rtAcpiTblPkgAppendEx(pThis, bOp, pbPkg + 2);
     305    return rtAcpiTblPkgAppendEx(pThis, bOp, (pbPkg + 2) - pThis->pbTblBuf);
    305306}
    306307
     
    329330     * Note! PkgLength will also include its own length.
    330331     */
    331     uint8_t  *pbPkgLength = pPkgElem->pbPkgLength;
     332    uint8_t  *pbPkgLength = &pThis->pbTblBuf[pPkgElem->offPkgLength];
    332333    uint32_t cbThisPkg    = pPkgElem->cbPkg;
    333334    if (cbThisPkg + 1 <= 63)
     
    436437
    437438/**
     439 * Appends the given name segment to the destination padding the segment with '_' if the
     440 * name segment is shorter than 4 characters.
     441 *
     442 * @returns Pointer to the character after the given name segment.
     443 * @param   pbDst               Where to store the name segment.
     444 * @param   pachNameSeg         The name segment to append.
     445 */
     446DECLINLINE(const char *) rtAcpiTblAppendNameSeg(uint8_t *pbDst, const char *pachNameSeg)
     447{
     448    Assert(pachNameSeg[0] != '.' && pachNameSeg[0] != '\0');
     449
     450    uint8_t cch = 1;
     451    pbDst[0] = pachNameSeg[0];
     452
     453    for (uint8_t i = 1; i < 4; i++)
     454    {
     455        if (   pachNameSeg[cch] != '.'
     456            && pachNameSeg[cch] != '\0')
     457        {
     458            pbDst[i] = pachNameSeg[cch];
     459            cch++;
     460        }
     461        else
     462            pbDst[i] = '_';
     463    }
     464
     465    return &pachNameSeg[cch];
     466}
     467
     468
     469/**
    438470 * Appends the given namestring to the ACPI table, updating the package length of the current package
    439471 * and padding the name with _ if too short.
    440472 *
    441473 * @param pThis                 The ACPI table instance.
    442  * @param pszName               The name to append, maximum is 4 bytes (or 5 if \\ is the first character).
    443  *
    444  * @todo This is completely wrong with how name strings are working.
    445  */
    446 DECLINLINE(void) rtAcpiTblAppendNameString(PRTACPITBLINT pThis, const char *pszName)
    447 {
    448     uint32_t cbName = *pszName == '\\' ? 5 : 4;
    449     uint8_t *pb = rtAcpiTblBufEnsureSpace(pThis, cbName);
     474 * @param pszName               The name string to append.
     475 */
     476static void rtAcpiTblAppendNameString(PRTACPITBLINT pThis, const char *pszName)
     477{
     478    if (*pszName == '\\')
     479    {
     480        /* Root prefix. */
     481        rtAcpiTblAppendByte(pThis, '\\');
     482        pszName++;
     483    }
     484    else if (*pszName == '^')
     485    {
     486        /* PrefixPath */
     487        do
     488        {
     489            rtAcpiTblAppendByte(pThis, '^');
     490            pszName++;
     491        }
     492        while (*pszName == '^');
     493    }
     494
     495    /*
     496     * We need to count the number of segments to decide whether a
     497     * NameSeg, DualNamePath or MultiNamePath is needed.
     498     */
     499    uint8_t cSegments = 1;
     500    const char *pszTmp = pszName;
     501    while (*pszTmp != '\0')
     502    {
     503        if (*pszTmp++ == '.')
     504            cSegments++;
     505    }
     506
     507    size_t cbReq = cSegments * 4 * sizeof(uint8_t);
     508    if (cSegments == 2)
     509        cbReq++; /* DualName Prefix */
     510    else if (cSegments != 1)
     511        cbReq += 2; /* MultiName prefix + segment count */
     512    uint8_t *pb = rtAcpiTblBufEnsureSpace(pThis, cbReq);
    450513    if (pb)
    451514    {
    452         rtAcpiTblCopyStringPadWith(pb, cbName, pszName, '_');
    453         rtAcpiTblUpdatePkgLength(pThis, cbName);
     515        if (cSegments == 1)
     516        {
     517            rtAcpiTblAppendNameSeg(pb, pszName);
     518            rtAcpiTblUpdatePkgLength(pThis, 4);
     519        }
     520        else if (cSegments == 2)
     521        {
     522            *pb++ = ACPI_AML_BYTE_CODE_PREFIX_DUAL_NAME;
     523            pszName = rtAcpiTblAppendNameSeg(pb, pszName);
     524            pb += 4;
     525            Assert(*pszName == '.');
     526            pszName++;
     527            pszName = rtAcpiTblAppendNameSeg(pb, pszName);
     528            Assert(*pszName == '\0'); RT_NOREF(pszName);
     529            rtAcpiTblUpdatePkgLength(pThis, 1 + 8);
     530        }
     531        else
     532        {
     533            *pb++ = ACPI_AML_BYTE_CODE_PREFIX_MULTI_NAME;
     534            *pb++ = cSegments;
     535            for (uint8_t i = 0; i < cSegments; i++)
     536            {
     537                pszName = rtAcpiTblAppendNameSeg(pb, pszName);
     538                Assert(*pszName == '.' || *pszName == '\0');
     539                pb += 4;
     540                pszName++;
     541            }
     542            rtAcpiTblUpdatePkgLength(pThis, 2 + cSegments * 4);
     543        }
    454544    }
    455545}
     
    587677
    588678                PRTACPITBLSTACKELEM pStackElem = &pThis->paPkgStack[pThis->idxPkgStackElem];
    589                 pStackElem->pbPkgLength        = pThis->pbTblBuf; /* Starts with the header. */
     679                pStackElem->offPkgLength       = 0; /* Starts with the header. */
    590680                pStackElem->cbPkg              = sizeof(*pThis->pHdr);
    591681                pStackElem->bOp                = UINT8_MAX;
     
    10041094        case kAcpiStmt_Index:      bOp = ACPI_AML_BYTE_CODE_OP_INDEX;       break;
    10051095        case kAcpiStmt_DerefOf:    bOp = ACPI_AML_BYTE_CODE_OP_DEREF_OF;    break;
     1096        case kAcpiStmt_Notify:     bOp = ACPI_AML_BYTE_CODE_OP_NOTIFY;      break;
    10061097        default:
    10071098            AssertFailedReturn(VERR_INVALID_PARAMETER);
     
    12471338        case kAcpiObjType_ThermalZone: bObjType = ACPI_AML_OBJECT_TYPE_THERMAL_ZONE; break;
    12481339        case kAcpiObjType_BuffField:   bObjType = ACPI_AML_OBJECT_TYPE_BUFFER_FIELD; break;
     1340        case kAcpiObjType_Processor:   bObjType = ACPI_AML_OBJECT_TYPE_PROCESSOR; break;
    12491341        default:
    12501342            pThis->rcErr = VERR_INVALID_PARAMETER;
  • trunk/src/VBox/Runtime/include/internal/acpi.h

    r108087 r108088  
    165165    kAcpiAstNodeOp_Xor,
    166166    kAcpiAstNodeOp_Not,
     167    kAcpiAstNodeOp_Notify,
    167168    kAcpiAstNodeOp_32Bit_Hack = 0x7fffffff
    168169} RTACPIASTNODEOP;
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