VirtualBox

Changeset 107971 in vbox for trunk/src


Ignore:
Timestamp:
Jan 28, 2025 3:48:44 PM (3 months ago)
Author:
vboxsync
svn:sync-xref-src-repo-rev:
167225
Message:

Runtime/common/misc/acpi-decompiler.cpp: Some updates, can decompile our CPU hotplug SSDT _mostly_ without error, bugref:10733

File:
1 edited

Legend:

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

    r107955 r107971  
    221221
    222222
     223DECLINLINE(int) rtAcpiTblAmlDecodeReadU64(PRTACPITBLAMLDECODE pThis, uint64_t *pu64, PRTERRINFO pErrInfo)
     224{
     225    if (pThis->offTbl <= pThis->cbTbl + sizeof(uint64_t))
     226    { /* probable */ }
     227    else
     228        return RTErrInfoSetF(pErrInfo, VERR_EOF, "AML stream ended prematurely at offset '%#x' trying to read eight bytes", pThis->offTbl);
     229
     230    if (pThis->pacbPkgLeft[pThis->iLvl] < sizeof(uint64_t))
     231        return RTErrInfoSetF(pErrInfo, VERR_INVALID_STATE, "Data overflows current package limitation");
     232
     233    pThis->pacbPkgLeft[pThis->iLvl] -= sizeof(uint64_t);
     234
     235    *pu64 =  pThis->pbTbl[pThis->offTbl++];
     236    *pu64 |= (uint64_t)pThis->pbTbl[pThis->offTbl++] <<  8;
     237    *pu64 |= (uint64_t)pThis->pbTbl[pThis->offTbl++] << 16;
     238    *pu64 |= (uint64_t)pThis->pbTbl[pThis->offTbl++] << 24;
     239    *pu64 |= (uint64_t)pThis->pbTbl[pThis->offTbl++] << 32;
     240    *pu64 |= (uint64_t)pThis->pbTbl[pThis->offTbl++] << 40;
     241    *pu64 |= (uint64_t)pThis->pbTbl[pThis->offTbl++] << 48;
     242    *pu64 |= (uint64_t)pThis->pbTbl[pThis->offTbl++] << 54;
     243    return VINF_SUCCESS;
     244}
     245
     246
    223247static int rtAcpiTblAmlDecodeNameSeg(PRTACPITBLAMLDECODE pThis, char *pszNameString, PRTERRINFO pErrInfo)
    224248{
     
    233257    if (   abNameSeg[0] != '_'
    234258        && !RTLocCIsUpper(abNameSeg[0]))
    235         return RTErrInfoSetF(pErrInfo, VERR_INVALID_PARAMETER, "AML stream contains invalid lead name character '%c'", abNameSeg[0]);
     259        return RTErrInfoSetF(pErrInfo, VERR_INVALID_PARAMETER, "AML stream contains invalid lead name character '%#02RX8'", abNameSeg[0]);
    236260
    237261    for (uint8_t i = 1; i < sizeof(abNameSeg); i++)
     
    240264            && !RTLocCIsUpper(abNameSeg[i])
    241265            && !RTLocCIsDigit(abNameSeg[i]))
    242             return RTErrInfoSetF(pErrInfo, VERR_INVALID_PARAMETER, "AML stream contains invalid name character '%c'", abNameSeg[i]);
     266            return RTErrInfoSetF(pErrInfo, VERR_INVALID_PARAMETER, "AML stream contains invalid name character '%#02RX8", abNameSeg[i]);
    243267    }
    244268
     
    263287    if (   bLeadChar != '_'
    264288        && !RTLocCIsUpper(bLeadChar))
    265         return RTErrInfoSetF(pErrInfo, VERR_INVALID_PARAMETER, "AML stream contains invalid lead name character '%c'", bLeadChar);
     289        return RTErrInfoSetF(pErrInfo, VERR_INVALID_PARAMETER, "AML stream contains invalid lead name character '%#02RX8'", bLeadChar);
    266290
    267291    for (uint8_t i = 1; i < sizeof(abNameSeg); i++)
     
    270294            && !RTLocCIsUpper(abNameSeg[i])
    271295            && !RTLocCIsDigit(abNameSeg[i]))
    272             return RTErrInfoSetF(pErrInfo, VERR_INVALID_PARAMETER, "AML stream contains invalid name character '%c'", abNameSeg[i]);
     296            return RTErrInfoSetF(pErrInfo, VERR_INVALID_PARAMETER, "AML stream contains invalid name character '%#02RX8'", abNameSeg[i]);
    273297    }
    274298
     
    281305
    282306
    283 
    284 static int rtAcpiTblAmlDecodeNameString(PRTACPITBLAMLDECODE pThis, char *pszNameString, size_t cchNameString, size_t *pcbNameString, PRTERRINFO pErrInfo)
     307static int rtAcpiTblAmlDecodeNameStringWithLead(PRTACPITBLAMLDECODE pThis, uint8_t bLeadChar, char *pszNameString, size_t cchNameString, size_t *pcbNameString, PRTERRINFO pErrInfo)
    285308{
    286309    AssertReturn(cchNameString >= 5, VERR_INVALID_PARAMETER); /* One name segment is at least 4 bytes (+ terminator). */
    287310
    288311    /* Check for a root path. */
    289     uint8_t bTmp = 0; /* shut up gcc */
    290     int rc = rtAcpiTblAmlDecodeReadU8(pThis, &bTmp, pErrInfo);
    291     if (RT_FAILURE(rc)) return rc;
    292 
     312    int rc = VINF_SUCCESS;
     313    uint8_t bTmp = bLeadChar;
    293314    size_t idxName = 0;
    294315    if (bTmp == '\\')
     
    313334
    314335            if (idxName == cchNameString - 1)
    315                 rc = RTErrInfoSetF(pErrInfo, VERR_BUFFER_OVERFLOW, "PrefixPath in AML byte stream is too long to fit into a %zu byte buffer",
    316                                    cchNameString - 1);
     336                return RTErrInfoSetF(pErrInfo, VERR_BUFFER_OVERFLOW, "PrefixPath in AML byte stream is too long to fit into a %zu byte buffer",
     337                                     cchNameString - 1);
    317338
    318339            pszNameString[idxName++] = '^';
     
    322343    if (bTmp == ACPI_AML_BYTE_CODE_PREFIX_DUAL_NAME)
    323344    {
    324         if (idxName + 8 <= cchNameString)
     345        if (idxName + 8 < cchNameString)
    325346        {
    326347            rc = rtAcpiTblAmlDecodeNameSeg(pThis, &pszNameString[idxName], pErrInfo);
     
    339360    else if (bTmp == ACPI_AML_BYTE_CODE_PREFIX_MULTI_NAME)
    340361    {
    341         /** @todo */
    342         AssertReleaseFailed();
     362        uint8_t cSegs = 0;
     363        rc = rtAcpiTblAmlDecodeReadU8(pThis, &cSegs, pErrInfo);
     364        if (RT_FAILURE(rc)) return rc;
     365
     366        if (idxName + cSegs * 4 < cchNameString)
     367        {
     368            for (uint8_t i = 0; i < cSegs; i++)
     369            {
     370                rc = rtAcpiTblAmlDecodeNameSeg(pThis, &pszNameString[idxName + i * 4], pErrInfo);
     371                if (RT_FAILURE(rc)) return rc;
     372            }
     373
     374            idxName += cSegs * 4;
     375            pszNameString[idxName] = '\0';
     376        }
     377        else
     378            rc = RTErrInfoSetF(pErrInfo, VERR_BUFFER_OVERFLOW, "MultiNamePrefix string in AML byte stream is too long to fit into a %zu byte buffer",
     379                               cchNameString - 1);
    343380    }
    344381    else if (bTmp == ACPI_AML_BYTE_CODE_PREFIX_NULL_NAME)
     
    346383    else
    347384    {
    348         if (idxName + 4 <= cchNameString)
     385        if (idxName + 4 < cchNameString)
    349386        {
    350387            rc = rtAcpiTblAmlDecodeNameSegWithoutLeadChar(pThis, bTmp, &pszNameString[idxName], pErrInfo);
     
    361398    *pcbNameString = idxName;
    362399    return rc;
     400}
     401
     402
     403static int rtAcpiTblAmlDecodeNameString(PRTACPITBLAMLDECODE pThis, char *pszNameString, size_t cchNameString, size_t *pcbNameString, PRTERRINFO pErrInfo)
     404{
     405    AssertReturn(cchNameString >= 5, VERR_INVALID_PARAMETER); /* One name segment is at least 4 bytes (+ terminator). */
     406
     407    uint8_t bLead = 0; /* shut up gcc */
     408    int rc = rtAcpiTblAmlDecodeReadU8(pThis, &bLead, pErrInfo);
     409    if (RT_FAILURE(rc)) return rc;
     410
     411    return rtAcpiTblAmlDecodeNameStringWithLead( pThis, bLead, pszNameString, cchNameString, pcbNameString, pErrInfo);
    363412}
    364413
     
    377426        ssize_t cch = RTVfsIoStrmPrintf(hVfsIos, "    ");
    378427        if (cch != 4)
    379             return cch < 0 ? -cch : VERR_BUFFER_UNDERFLOW;
     428            return cch < 0 ? (int)cch : VERR_BUFFER_UNDERFLOW;
    380429    }
    381430
     
    465514        pThis->iLvl--;
    466515
    467         if (pThis->pacbPkgLeft[pThis->iLvl] <= cbPkg)
     516        if (pThis->pacbPkgLeft[pThis->iLvl] < cbPkg)
    468517            return RTErrInfoSetF(pErrInfo, VERR_INVALID_STATE, "AML contains invalid package length encoding");
    469518
     
    475524
    476525    return VINF_SUCCESS;
     526}
     527
     528
     529static int rtAcpiTblAmlDecodeIntegerFromPrefix(PRTACPITBLAMLDECODE pThis, uint8_t bPrefix, uint64_t *pu64, size_t cbDecodeMax, size_t *pcbDecoded, PRTERRINFO pErrInfo)
     530{
     531    switch (bPrefix)
     532    {
     533        case ACPI_AML_BYTE_CODE_PREFIX_BYTE:
     534        {
     535            if (!cbDecodeMax)
     536                return RTErrInfoSetF(pErrInfo, VERR_INVALID_STATE, "Not enough data left to decode byte integer in AML stream");
     537
     538            uint8_t bInt = 0;
     539            int rc = rtAcpiTblAmlDecodeReadU8(pThis, &bInt, pErrInfo);
     540            if (RT_FAILURE(rc))
     541                return rc;
     542
     543            *pu64       = bInt;
     544            *pcbDecoded = 2;
     545            break;
     546        }
     547        case ACPI_AML_BYTE_CODE_PREFIX_WORD:
     548        {
     549            if (cbDecodeMax < 2)
     550                return RTErrInfoSetF(pErrInfo, VERR_INVALID_STATE, "Not enough data left to decode word integer in AML stream");
     551
     552            uint16_t u16 = 0;
     553            int rc = rtAcpiTblAmlDecodeReadU16(pThis, &u16, pErrInfo);
     554            if (RT_FAILURE(rc))
     555                return rc;
     556
     557            *pu64       = u16;
     558            *pcbDecoded = 3;
     559            break;
     560        }
     561        case ACPI_AML_BYTE_CODE_PREFIX_DWORD:
     562        {
     563            if (cbDecodeMax < 4)
     564                return RTErrInfoSetF(pErrInfo, VERR_INVALID_STATE, "Not enough data left to decode double word integer in AML stream");
     565
     566            uint32_t u32 = 0;
     567            int rc = rtAcpiTblAmlDecodeReadU32(pThis, &u32, pErrInfo);
     568            if (RT_FAILURE(rc))
     569                return rc;
     570
     571            *pu64       = u32;
     572            *pcbDecoded = 5;
     573            break;
     574        }
     575        case ACPI_AML_BYTE_CODE_PREFIX_QWORD:
     576        {
     577            if (cbDecodeMax < 8)
     578                return RTErrInfoSetF(pErrInfo, VERR_INVALID_STATE, "Not enough data left to decode quad word integer in AML stream");
     579
     580            uint64_t u64 = 0;
     581            int rc = rtAcpiTblAmlDecodeReadU64(pThis, &u64, pErrInfo);
     582            if (RT_FAILURE(rc))
     583                return rc;
     584
     585            *pu64       = u64;
     586            *pcbDecoded = 9;
     587            break;
     588        }
     589        default:
     590            return RTErrInfoSetF(pErrInfo, VERR_INVALID_STATE, "Invalid integer prefix '%#02RX8'", bPrefix);
     591    }
     592
     593    return VINF_SUCCESS;
     594}
     595
     596
     597static int rtAcpiTblAmlDecodeIntegerWorker(PRTACPITBLAMLDECODE pThis, uint64_t *pu64, size_t cbDecodeMax, size_t *pcbDecoded, PRTERRINFO pErrInfo)
     598{
     599    AssertReturn(cbDecodeMax >= 1, VERR_INVALID_PARAMETER);
     600
     601    uint8_t bPrefix = 0; /* shut up gcc */
     602    int rc = rtAcpiTblAmlDecodeReadU8(pThis, &bPrefix, pErrInfo);
     603    if (RT_FAILURE(rc))
     604        return rc;
     605
     606    cbDecodeMax--;
     607    return rtAcpiTblAmlDecodeIntegerFromPrefix(pThis, bPrefix, pu64, cbDecodeMax, pcbDecoded, pErrInfo);
     608}
     609
     610
     611static DECLCALLBACK(int) rtAcpiTblAmlDecodeNameObject(PRTACPITBLAMLDECODE pThis, RTVFSIOSTREAM hVfsIosOut, uint8_t bOp, PRTERRINFO pErrInfo)
     612{
     613    char szName[512];
     614    size_t cbName = 0;
     615
     616    int rc = rtAcpiTblAmlDecodeNameStringWithLead(pThis, bOp, &szName[0], sizeof(szName), &cbName, pErrInfo);
     617    if (RT_FAILURE(rc)) return rc;
     618
     619    return rtAcpiTblAmlDecodeFormat(pThis, hVfsIosOut, "%s", szName);
     620}
     621
     622
     623static DECLCALLBACK(int) rtAcpiTblAmlDecodeString(PRTACPITBLAMLDECODE pThis, RTVFSIOSTREAM hVfsIosOut, uint8_t bOp, PRTERRINFO pErrInfo)
     624{
     625    RT_NOREF(bOp);
     626
     627    char szStr[512];
     628    uint32_t i = 0;
     629    for (;;)
     630    {
     631        uint8_t bTmp = 0; /* shut up gcc */
     632        int rc = rtAcpiTblAmlDecodeReadU8(pThis, &bTmp, pErrInfo);
     633        if (RT_FAILURE(rc))
     634            return rc;
     635
     636        if (bTmp >= 0x1 && bTmp <= 0x7f)
     637            szStr[i++] = (char)bTmp;
     638        else if (bTmp == 0x00)
     639        {
     640            szStr[i++] = '\0';
     641            break;
     642        }
     643        else
     644            return RTErrInfoSetF(pErrInfo, VERR_INVALID_STATE, "Invalid ASCII string character %#x in string", bTmp);
     645
     646        if (i == sizeof(szStr))
     647            return RTErrInfoSetF(pErrInfo, VERR_BUFFER_OVERFLOW, "ASCII string is out of bounds");
     648    }
     649
     650    return rtAcpiTblAmlDecodeFormat(pThis, hVfsIosOut, "\"%s\"", szStr);
     651}
     652
     653
     654static DECLCALLBACK(int) rtAcpiTblAmlDecodeBuffer(PRTACPITBLAMLDECODE pThis, RTVFSIOSTREAM hVfsIosOut, uint8_t bOp, PRTERRINFO pErrInfo)
     655{
     656    RT_NOREF(bOp);
     657
     658    size_t cbPkg = 0;
     659    size_t cbPkgLength = 0;
     660    int rc = rtAcpiTblAmlDecodePkgLength(pThis, &cbPkg, &cbPkgLength, pErrInfo);
     661    if (RT_FAILURE(rc))
     662        return rc;
     663
     664    cbPkg -= cbPkgLength;
     665    uint64_t u64 = 0;
     666    size_t cbInt = 0;
     667    rc = rtAcpiTblAmlDecodeIntegerWorker(pThis, &u64, cbPkg, &cbInt, pErrInfo);
     668    if (RT_FAILURE(rc))
     669        return rc;
     670
     671    cbPkg -= cbInt;
     672
     673    rc = rtAcpiTblAmlDecodeFormat(pThis, hVfsIosOut, "Buffer (%RU64) {", u64);
     674    if (RT_FAILURE(rc))
     675        return rc;
     676
     677    /* Decode remaining bytes. */
     678    while (cbPkg--)
     679    {
     680        uint8_t bTmp = 0;
     681        rc = rtAcpiTblAmlDecodeReadU8(pThis, &bTmp, pErrInfo);
     682        if (RT_FAILURE(rc))
     683            return rc;
     684
     685        rc = rtAcpiTblAmlDecodeFormat(pThis, hVfsIosOut, "%#02RX8%s", bTmp, cbPkg ? "," : "");
     686        if (RT_FAILURE(rc))
     687            return rc;
     688    }
     689
     690    return rtAcpiTblAmlDecodeFormat(pThis, hVfsIosOut, "}");
     691}
     692
     693
     694static DECLCALLBACK(int) rtAcpiTblAmlDecodeInteger(PRTACPITBLAMLDECODE pThis, RTVFSIOSTREAM hVfsIosOut, uint8_t bOp, PRTERRINFO pErrInfo)
     695{
     696    uint64_t u64 = 0;
     697    size_t cbDecoded = 0;
     698    int rc = rtAcpiTblAmlDecodeIntegerFromPrefix(pThis, bOp, &u64, sizeof(uint64_t), &cbDecoded, pErrInfo);
     699    if (RT_FAILURE(rc))
     700        return rc;
     701
     702    return rtAcpiTblAmlDecodeFormat(pThis, hVfsIosOut, "%#RX64", u64);
    477703}
    478704
     
    497723#define RTACPI_AML_OPC_SIMPLE_5(a_pszOpc, a_fFlags, a_enmType0, a_enmType1, a_enmType2, a_enmType3, a_enmType4) \
    498724    { a_pszOpc, a_fFlags, { a_enmType0,              a_enmType1,              a_enmType2,              a_enmType3,              a_enmType4              }, NULL }
     725#define RTACPI_AML_OPC_HANDLER(a_pszOpc, a_pfnHandler) \
     726    { a_pszOpc, 0,        { kAcpiAmlOpcType_Invalid, kAcpiAmlOpcType_Invalid, kAcpiAmlOpcType_Invalid, kAcpiAmlOpcType_Invalid, kAcpiAmlOpcType_Invalid }, a_pfnHandler }
    499727
    500728    /* 0x00 */ RTACPI_AML_OPC_SIMPLE_0("Zero", RTACPI_AML_OPC_F_NONE),
     
    508736    /* 0x08 */ RTACPI_AML_OPC_SIMPLE_2("Name",   0,     kAcpiAmlOpcType_NameString,  kAcpiAmlOpcType_TermArg),
    509737    /* 0x09 */ RTACPI_AML_OPC_INVALID,
    510     /* 0x0a */ RTACPI_AML_OPC_INVALID,
    511     /* 0x0b */ RTACPI_AML_OPC_INVALID,
    512     /* 0x0c */ RTACPI_AML_OPC_INVALID,
    513     /* 0x0d */ RTACPI_AML_OPC_INVALID,
    514     /* 0x0e */ RTACPI_AML_OPC_INVALID,
     738    /* 0x0a */ RTACPI_AML_OPC_HANDLER( "ByteInteger",   rtAcpiTblAmlDecodeInteger),
     739    /* 0x0b */ RTACPI_AML_OPC_HANDLER( "WordInteger",   rtAcpiTblAmlDecodeInteger),
     740    /* 0x0c */ RTACPI_AML_OPC_HANDLER( "DWordInteger",  rtAcpiTblAmlDecodeInteger),
     741    /* 0x0d */ RTACPI_AML_OPC_HANDLER( "StringPrefix",  rtAcpiTblAmlDecodeString),
     742    /* 0x0e */ RTACPI_AML_OPC_HANDLER( "QWordInteger",  rtAcpiTblAmlDecodeInteger),
    515743    /* 0x0f */ RTACPI_AML_OPC_INVALID,
    516744
    517745    /* 0x10 */ RTACPI_AML_OPC_SIMPLE_1("Scope",    RTACPI_AML_OPC_F_HAS_PKG_LENGTH,  kAcpiAmlOpcType_NameString),
    518     /* 0x11 */ RTACPI_AML_OPC_INVALID,
     746    /* 0x11 */ RTACPI_AML_OPC_HANDLER( "Buffer",   rtAcpiTblAmlDecodeBuffer),
    519747    /* 0x12 */ RTACPI_AML_OPC_INVALID,
    520748    /* 0x13 */ RTACPI_AML_OPC_INVALID,
     
    567795
    568796    /* 0x40 */ RTACPI_AML_OPC_INVALID,
    569     /* 0x41 */ RTACPI_AML_OPC_INVALID,
    570     /* 0x42 */ RTACPI_AML_OPC_INVALID,
    571     /* 0x43 */ RTACPI_AML_OPC_INVALID,
    572     /* 0x44 */ RTACPI_AML_OPC_INVALID,
    573     /* 0x45 */ RTACPI_AML_OPC_INVALID,
    574     /* 0x46 */ RTACPI_AML_OPC_INVALID,
    575     /* 0x47 */ RTACPI_AML_OPC_INVALID,
    576     /* 0x48 */ RTACPI_AML_OPC_INVALID,
    577     /* 0x49 */ RTACPI_AML_OPC_INVALID,
    578     /* 0x4a */ RTACPI_AML_OPC_INVALID,
    579     /* 0x4b */ RTACPI_AML_OPC_INVALID,
    580     /* 0x4c */ RTACPI_AML_OPC_INVALID,
    581     /* 0x4d */ RTACPI_AML_OPC_INVALID,
    582     /* 0x4e */ RTACPI_AML_OPC_INVALID,
    583     /* 0x4f */ RTACPI_AML_OPC_INVALID,
    584 
    585     /* 0x50 */ RTACPI_AML_OPC_INVALID,
    586     /* 0x51 */ RTACPI_AML_OPC_INVALID,
    587     /* 0x52 */ RTACPI_AML_OPC_INVALID,
    588     /* 0x53 */ RTACPI_AML_OPC_INVALID,
    589     /* 0x54 */ RTACPI_AML_OPC_INVALID,
    590     /* 0x55 */ RTACPI_AML_OPC_INVALID,
    591     /* 0x56 */ RTACPI_AML_OPC_INVALID,
    592     /* 0x57 */ RTACPI_AML_OPC_INVALID,
    593     /* 0x58 */ RTACPI_AML_OPC_INVALID,
    594     /* 0x59 */ RTACPI_AML_OPC_INVALID,
    595     /* 0x5a */ RTACPI_AML_OPC_INVALID,
     797    /* 0x41 */ RTACPI_AML_OPC_HANDLER("NameChar",         rtAcpiTblAmlDecodeNameObject),
     798    /* 0x42 */ RTACPI_AML_OPC_HANDLER("NameChar",         rtAcpiTblAmlDecodeNameObject),
     799    /* 0x43 */ RTACPI_AML_OPC_HANDLER("NameChar",         rtAcpiTblAmlDecodeNameObject),
     800    /* 0x44 */ RTACPI_AML_OPC_HANDLER("NameChar",         rtAcpiTblAmlDecodeNameObject),
     801    /* 0x45 */ RTACPI_AML_OPC_HANDLER("NameChar",         rtAcpiTblAmlDecodeNameObject),
     802    /* 0x46 */ RTACPI_AML_OPC_HANDLER("NameChar",         rtAcpiTblAmlDecodeNameObject),
     803    /* 0x47 */ RTACPI_AML_OPC_HANDLER("NameChar",         rtAcpiTblAmlDecodeNameObject),
     804    /* 0x48 */ RTACPI_AML_OPC_HANDLER("NameChar",         rtAcpiTblAmlDecodeNameObject),
     805    /* 0x49 */ RTACPI_AML_OPC_HANDLER("NameChar",         rtAcpiTblAmlDecodeNameObject),
     806    /* 0x4a */ RTACPI_AML_OPC_HANDLER("NameChar",         rtAcpiTblAmlDecodeNameObject),
     807    /* 0x4b */ RTACPI_AML_OPC_HANDLER("NameChar",         rtAcpiTblAmlDecodeNameObject),
     808    /* 0x4c */ RTACPI_AML_OPC_HANDLER("NameChar",         rtAcpiTblAmlDecodeNameObject),
     809    /* 0x4d */ RTACPI_AML_OPC_HANDLER("NameChar",         rtAcpiTblAmlDecodeNameObject),
     810    /* 0x4e */ RTACPI_AML_OPC_HANDLER("NameChar",         rtAcpiTblAmlDecodeNameObject),
     811    /* 0x4f */ RTACPI_AML_OPC_HANDLER("NameChar",         rtAcpiTblAmlDecodeNameObject),
     812
     813    /* 0x50 */ RTACPI_AML_OPC_HANDLER("NameChar",         rtAcpiTblAmlDecodeNameObject),
     814    /* 0x51 */ RTACPI_AML_OPC_HANDLER("NameChar",         rtAcpiTblAmlDecodeNameObject),
     815    /* 0x52 */ RTACPI_AML_OPC_HANDLER("NameChar",         rtAcpiTblAmlDecodeNameObject),
     816    /* 0x53 */ RTACPI_AML_OPC_HANDLER("NameChar",         rtAcpiTblAmlDecodeNameObject),
     817    /* 0x54 */ RTACPI_AML_OPC_HANDLER("NameChar",         rtAcpiTblAmlDecodeNameObject),
     818    /* 0x55 */ RTACPI_AML_OPC_HANDLER("NameChar",         rtAcpiTblAmlDecodeNameObject),
     819    /* 0x56 */ RTACPI_AML_OPC_HANDLER("NameChar",         rtAcpiTblAmlDecodeNameObject),
     820    /* 0x57 */ RTACPI_AML_OPC_HANDLER("NameChar",         rtAcpiTblAmlDecodeNameObject),
     821    /* 0x58 */ RTACPI_AML_OPC_HANDLER("NameChar",         rtAcpiTblAmlDecodeNameObject),
     822    /* 0x59 */ RTACPI_AML_OPC_HANDLER("NameChar",         rtAcpiTblAmlDecodeNameObject),
     823    /* 0x5a */ RTACPI_AML_OPC_HANDLER("NameChar",         rtAcpiTblAmlDecodeNameObject),
    596824    /* 0x5b */ RTACPI_AML_OPC_INVALID,
    597     /* 0x5c */ RTACPI_AML_OPC_INVALID,
     825    /* 0x5c */ RTACPI_AML_OPC_HANDLER("RootChar",         rtAcpiTblAmlDecodeNameObject),
    598826    /* 0x5d */ RTACPI_AML_OPC_INVALID,
    599     /* 0x5e */ RTACPI_AML_OPC_INVALID,
    600     /* 0x5f */ RTACPI_AML_OPC_INVALID,
     827    /* 0x5e */ RTACPI_AML_OPC_HANDLER("ParentPrefixChar", rtAcpiTblAmlDecodeNameObject),
     828    /* 0x5f */ RTACPI_AML_OPC_HANDLER("NameChar",         rtAcpiTblAmlDecodeNameObject),
    601829
    602830    /* 0x60 */ RTACPI_AML_OPC_SIMPLE_0("Local0", RTACPI_AML_OPC_F_NONE),
     
    640868    /* 0x84 */ RTACPI_AML_OPC_INVALID,
    641869    /* 0x85 */ RTACPI_AML_OPC_INVALID,
    642     /* 0x86 */ RTACPI_AML_OPC_INVALID,
     870    /* 0x86 */ RTACPI_AML_OPC_SIMPLE_2("Notify",                                0,     kAcpiAmlOpcType_SuperName, kAcpiAmlOpcType_TermArg),
    643871    /* 0x87 */ RTACPI_AML_OPC_INVALID,
    644     /* 0x88 */ RTACPI_AML_OPC_INVALID,
     872    /* 0x88 */ RTACPI_AML_OPC_SIMPLE_3("Index",                                 0,     kAcpiAmlOpcType_TermArg,   kAcpiAmlOpcType_TermArg, kAcpiAmlOpcType_SuperName),
    645873    /* 0x89 */ RTACPI_AML_OPC_INVALID,
    646874    /* 0x8a */ RTACPI_AML_OPC_INVALID,
     
    669897
    670898    /* 0xa0 */ RTACPI_AML_OPC_SIMPLE_1("If",      RTACPI_AML_OPC_F_HAS_PKG_LENGTH,     kAcpiAmlOpcType_TermArg),
    671     /* 0xa1 */ RTACPI_AML_OPC_INVALID,
     899    /* 0xa1 */ RTACPI_AML_OPC_SIMPLE_0("Else",    RTACPI_AML_OPC_F_HAS_PKG_LENGTH),
    672900    /* 0xa2 */ RTACPI_AML_OPC_INVALID,
    673901    /* 0xa3 */ RTACPI_AML_OPC_INVALID,
     
    9131141    /* 0x7f */ RTACPI_AML_OPC_INVALID,
    9141142
    915     /* 0x80 */ RTACPI_AML_OPC_INVALID,
     1143    /* 0x80 */ RTACPI_AML_OPC_SIMPLE_4("OpRegion",                                0, kAcpiAmlOpcType_NameString, kAcpiAmlOpcType_Byte, kAcpiAmlOpcType_TermArg, kAcpiAmlOpcType_TermArg),
    9161144    /* 0x81 */ RTACPI_AML_OPC_INVALID,
    917     /* 0x82 */ RTACPI_AML_OPC_INVALID,
    918     /* 0x83 */ RTACPI_AML_OPC_SIMPLE_4("Processor", RTACPI_AML_OPC_F_HAS_PKG_LENGTH, kAcpiAmlOpcType_NameString, kAcpiAmlOpcType_Byte, kAcpiAmlOpcType_DWord, kAcpiAmlOpcType_Byte),
     1145    /* 0x82 */ RTACPI_AML_OPC_SIMPLE_1("Device",    RTACPI_AML_OPC_F_HAS_PKG_LENGTH, kAcpiAmlOpcType_NameString),
     1146    /* 0x83 */ RTACPI_AML_OPC_SIMPLE_4("Processor", RTACPI_AML_OPC_F_HAS_PKG_LENGTH, kAcpiAmlOpcType_NameString, kAcpiAmlOpcType_Byte, kAcpiAmlOpcType_DWord,   kAcpiAmlOpcType_Byte),
    9191147    /* 0x84 */ RTACPI_AML_OPC_INVALID,
    9201148    /* 0x85 */ RTACPI_AML_OPC_INVALID,
     
    10511279
    10521280
     1281static int rtAcpiTblAmlDecodeSimple(PRTACPITBLAMLDECODE pThis, PCRTACPIAMLOPC pAmlOpc, uint8_t bOpc, RTVFSIOSTREAM hVfsIosOut, PRTERRINFO pErrInfo)
     1282{
     1283    RT_NOREF(bOpc);
     1284
     1285    int rc;
     1286
     1287    /* Decode any package length field first. */
     1288    size_t cbPkg         = 0;
     1289    size_t cbPkgLength   = 0;
     1290    size_t cbPkgConsumed = 0;
     1291    if (pAmlOpc->fFlags & RTACPI_AML_OPC_F_HAS_PKG_LENGTH)
     1292    {
     1293        rc = rtAcpiTblAmlDecodePkgLength(pThis, &cbPkg, &cbPkgLength, pErrInfo);
     1294        if (RT_FAILURE(rc)) return rc;
     1295
     1296        cbPkgConsumed += cbPkgLength;
     1297    }
     1298
     1299    rc = rtAcpiTblAmlDecodeFormat(pThis, hVfsIosOut, "%s", pAmlOpc->pszOpc);
     1300    if (RT_FAILURE(rc)) return rc;
     1301
     1302    /* Any arguments? */
     1303    if (pAmlOpc->aenmTypes[0] != kAcpiAmlOpcType_Invalid)
     1304    {
     1305        pThis->fIndent = false;
     1306
     1307        rc = rtAcpiTblAmlDecodeFormat(pThis, hVfsIosOut, "(");
     1308        if (RT_FAILURE(rc)) return rc;
     1309
     1310        for (uint32_t i = 0; i < RT_ELEMENTS(pAmlOpc->aenmTypes); i++)
     1311        {
     1312            if (pAmlOpc->aenmTypes[i] == kAcpiAmlOpcType_Invalid)
     1313                break; /* End of arguments. */
     1314
     1315            if (i > 0)
     1316            {
     1317                rc = rtAcpiTblAmlDecodeFormat(pThis, hVfsIosOut, ", ");
     1318                if (RT_FAILURE(rc)) return rc;
     1319            }
     1320
     1321            switch (pAmlOpc->aenmTypes[i])
     1322            {
     1323                case kAcpiAmlOpcType_Byte:
     1324                {
     1325                    uint8_t bVal = 0; /* shut up gcc */
     1326                    rc = rtAcpiTblAmlDecodeReadU8(pThis, &bVal, pErrInfo);
     1327                    if (RT_FAILURE(rc)) return rc;
     1328
     1329                    rc = rtAcpiTblAmlDecodeFormat(pThis, hVfsIosOut, "%RU8", bVal);
     1330                    if (RT_FAILURE(rc)) return rc;
     1331
     1332                    cbPkgConsumed++;
     1333                    break;
     1334                }
     1335                case kAcpiAmlOpcType_Word:
     1336                {
     1337                    uint16_t u16Val = 0; /* shut up gcc */
     1338                    rc = rtAcpiTblAmlDecodeReadU16(pThis, &u16Val, pErrInfo);
     1339                    if (RT_FAILURE(rc)) return rc;
     1340
     1341                    rc = rtAcpiTblAmlDecodeFormat(pThis, hVfsIosOut, "%RX16", u16Val);
     1342                    if (RT_FAILURE(rc)) return rc;
     1343
     1344                    cbPkgConsumed += sizeof(uint16_t);
     1345                    break;
     1346                }
     1347                case kAcpiAmlOpcType_DWord:
     1348                {
     1349                    uint32_t u32Val = 0; /* shut up gcc */
     1350                    rc = rtAcpiTblAmlDecodeReadU32(pThis, &u32Val, pErrInfo);
     1351                    if (RT_FAILURE(rc)) return rc;
     1352
     1353                    rc = rtAcpiTblAmlDecodeFormat(pThis, hVfsIosOut, "%RX32", u32Val);
     1354                    if (RT_FAILURE(rc)) return rc;
     1355
     1356                    cbPkgConsumed += sizeof(uint32_t);
     1357                    break;
     1358                }
     1359                case kAcpiAmlOpcType_NameString:
     1360                {
     1361                    char szName[512];
     1362                    size_t cbName = 0;
     1363                    rc = rtAcpiTblAmlDecodeNameString(pThis, &szName[0], sizeof(szName), &cbName, pErrInfo);
     1364                    if (RT_FAILURE(rc)) return rc;
     1365
     1366                    rc = rtAcpiTblAmlDecodeFormat(pThis, hVfsIosOut, "%s", szName);
     1367                    if (RT_FAILURE(rc)) return rc;
     1368
     1369                    cbPkgConsumed += cbName;
     1370                    break;
     1371                }
     1372                case kAcpiAmlOpcType_SuperName:
     1373                case kAcpiAmlOpcType_TermArg:
     1374                {
     1375                    /** @todo SuperName has limited allowed arguments. */
     1376                    size_t offTblOrig = pThis->offTbl;
     1377
     1378                    rc = rtAcpiTblAmlDecodeTerminal(pThis, hVfsIosOut, pErrInfo);
     1379                    if (RT_FAILURE(rc)) return rc;
     1380
     1381                    cbPkgConsumed += pThis->offTbl - offTblOrig;
     1382                    break;
     1383                }
     1384                case kAcpiAmlOpcType_Invalid:
     1385                default:
     1386                    AssertReleaseFailed();
     1387            }
     1388        }
     1389
     1390        rc = rtAcpiTblAmlDecodeFormat(pThis, hVfsIosOut, ")\n");
     1391        if (RT_FAILURE(rc)) return rc;
     1392
     1393        pThis->fIndent = true;
     1394    }
     1395    else if (pThis->fIndent)
     1396    {
     1397        rc = rtAcpiTblAmlDecodeFormat(pThis, hVfsIosOut, "\n");
     1398        if (RT_FAILURE(rc)) return rc;
     1399    }
     1400
     1401    if (pAmlOpc->fFlags & RTACPI_AML_OPC_F_HAS_PKG_LENGTH)
     1402    {
     1403        if (cbPkg < cbPkgConsumed)
     1404            return RTErrInfoSetF(pErrInfo, VERR_BUFFER_OVERFLOW, "Opcode arguments consumed more than the package length indicated (%zu vs %zu)", cbPkg, cbPkgConsumed);
     1405        rc = rtAcpiTblAmlDecodePkgPush(pThis, hVfsIosOut, cbPkg - cbPkgConsumed, pErrInfo);
     1406    }
     1407
     1408    return rc;
     1409}
     1410
    10531411static int rtAcpiTblAmlDecode(PRTACPITBLAMLDECODE pThis, PCRTACPIAMLOPC pAmlOpc, uint8_t bOpc, RTVFSIOSTREAM hVfsIosOut, PRTERRINFO pErrInfo)
    10541412{
    10551413    if (pAmlOpc->pszOpc)
    10561414    {
    1057         int rc;
    1058 
    1059         /* Decode any package length field first. */
    1060         size_t cbPkg         = 0;
    1061         size_t cbPkgLength   = 0;
    1062         size_t cbPkgConsumed = 0;
    1063         if (pAmlOpc->fFlags & RTACPI_AML_OPC_F_HAS_PKG_LENGTH)
    1064         {
    1065             rc = rtAcpiTblAmlDecodePkgLength(pThis, &cbPkg, &cbPkgLength, pErrInfo);
    1066             if (RT_FAILURE(rc)) return rc;
    1067 
    1068             cbPkgConsumed += cbPkgLength;
    1069         }
    1070 
    1071         rc = rtAcpiTblAmlDecodeFormat(pThis, hVfsIosOut, "%s", pAmlOpc->pszOpc);
    1072         if (RT_FAILURE(rc)) return rc;
    1073 
    1074         /* Any arguments? */
    1075         if (pAmlOpc->aenmTypes[0] != kAcpiAmlOpcType_Invalid)
    1076         {
    1077             pThis->fIndent = false;
    1078 
    1079             rc = rtAcpiTblAmlDecodeFormat(pThis, hVfsIosOut, "(");
    1080             if (RT_FAILURE(rc)) return rc;
    1081 
    1082             for (uint32_t i = 0; i < RT_ELEMENTS(pAmlOpc->aenmTypes); i++)
    1083             {
    1084                 if (pAmlOpc->aenmTypes[i] == kAcpiAmlOpcType_Invalid)
    1085                     break; /* End of arguments. */
    1086 
    1087                 if (i > 0)
    1088                 {
    1089                     rc = rtAcpiTblAmlDecodeFormat(pThis, hVfsIosOut, ", ");
    1090                     if (RT_FAILURE(rc)) return rc;
    1091                 }
    1092 
    1093                 switch (pAmlOpc->aenmTypes[i])
    1094                 {
    1095                     case kAcpiAmlOpcType_Byte:
    1096                     {
    1097                         uint8_t bVal = 0; /* shut up gcc */
    1098                         rc = rtAcpiTblAmlDecodeReadU8(pThis, &bVal, pErrInfo);
    1099                         if (RT_FAILURE(rc)) return rc;
    1100 
    1101                         rc = rtAcpiTblAmlDecodeFormat(pThis, hVfsIosOut, "%RU8", bVal);
    1102                         if (RT_FAILURE(rc)) return rc;
    1103 
    1104                         cbPkgConsumed++;
    1105                         break;
    1106                     }
    1107                     case kAcpiAmlOpcType_Word:
    1108                     {
    1109                         uint16_t u16Val = 0; /* shut up gcc */
    1110                         rc = rtAcpiTblAmlDecodeReadU16(pThis, &u16Val, pErrInfo);
    1111                         if (RT_FAILURE(rc)) return rc;
    1112 
    1113                         rc = rtAcpiTblAmlDecodeFormat(pThis, hVfsIosOut, "%RX16", u16Val);
    1114                         if (RT_FAILURE(rc)) return rc;
    1115 
    1116                         cbPkgConsumed += sizeof(uint16_t);
    1117                         break;
    1118                     }
    1119                     case kAcpiAmlOpcType_DWord:
    1120                     {
    1121                         uint32_t u32Val = 0; /* shut up gcc */
    1122                         rc = rtAcpiTblAmlDecodeReadU32(pThis, &u32Val, pErrInfo);
    1123                         if (RT_FAILURE(rc)) return rc;
    1124 
    1125                         rc = rtAcpiTblAmlDecodeFormat(pThis, hVfsIosOut, "%RX32", u32Val);
    1126                         if (RT_FAILURE(rc)) return rc;
    1127 
    1128                         cbPkgConsumed += sizeof(uint32_t);
    1129                         break;
    1130                     }
    1131                     case kAcpiAmlOpcType_NameString:
    1132                     {
    1133                         char szName[512];
    1134                         size_t cbName = 0;
    1135                         rc = rtAcpiTblAmlDecodeNameString(pThis, &szName[0], sizeof(szName), &cbName, pErrInfo);
    1136                         if (RT_FAILURE(rc)) return rc;
    1137 
    1138                         rc = rtAcpiTblAmlDecodeFormat(pThis, hVfsIosOut, "%s", szName);
    1139                         if (RT_FAILURE(rc)) return rc;
    1140 
    1141                         cbPkgConsumed += cbName;
    1142                         break;
    1143                     }
    1144                     case kAcpiAmlOpcType_TermArg:
    1145                     {
    1146                         size_t offTblOrig = pThis->offTbl;
    1147 
    1148                         rc = rtAcpiTblAmlDecodeTerminal(pThis, hVfsIosOut, pErrInfo);
    1149                         if (RT_FAILURE(rc)) return rc;
    1150 
    1151                         cbPkgConsumed += pThis->offTbl - offTblOrig;
    1152                         break;
    1153                     }
    1154                     case kAcpiAmlOpcType_SuperName:
    1155                     {
    1156                         /** @todo SuperName includes more. */
    1157                         char szName[512];
    1158                         size_t cbName = 0;
    1159                         rc = rtAcpiTblAmlDecodeNameString(pThis, &szName[0], sizeof(szName), &cbName, pErrInfo);
    1160                         if (RT_FAILURE(rc)) return rc;
    1161 
    1162                         rc = rtAcpiTblAmlDecodeFormat(pThis, hVfsIosOut, "%s", szName);
    1163                         if (RT_FAILURE(rc)) return rc;
    1164 
    1165                         cbPkgConsumed += cbName;
    1166                         break;
    1167                     }
    1168                     case kAcpiAmlOpcType_Invalid:
    1169                     default:
    1170                         AssertReleaseFailed();
    1171                 }
    1172             }
    1173 
    1174             rc = rtAcpiTblAmlDecodeFormat(pThis, hVfsIosOut, ")\n");
    1175             if (RT_FAILURE(rc)) return rc;
    1176 
    1177             pThis->fIndent = true;
    1178         }
    1179 
    1180         if (pAmlOpc->fFlags & RTACPI_AML_OPC_F_HAS_PKG_LENGTH)
    1181         {
    1182             if (cbPkg < cbPkgConsumed)
    1183                 return RTErrInfoSetF(pErrInfo, VERR_BUFFER_OVERFLOW, "Opcode arguments consumed more than the package length indicated (%zu vs %zu)", cbPkg, cbPkgConsumed);
    1184             rc = rtAcpiTblAmlDecodePkgPush(pThis, hVfsIosOut, cbPkg - cbPkgConsumed, pErrInfo);
    1185         }
    1186 
    1187         return rc;
     1415        if (pAmlOpc->pfnDecode)
     1416            return pAmlOpc->pfnDecode(pThis, hVfsIosOut, bOpc, pErrInfo);
     1417        return rtAcpiTblAmlDecodeSimple(pThis, pAmlOpc, bOpc, hVfsIosOut, pErrInfo);
    11881418    }
    11891419
     
    12871517                            cch = RTVfsIoStrmPrintf(hVfsIosOut, "}\n");
    12881518                            if (cch <= 0)
    1289                                 rc = RTErrInfoSetF(pErrInfo, cch == 0 ? VERR_NO_MEMORY : cch, "Failed to emit closing definition block");
     1519                                rc = RTErrInfoSetF(pErrInfo, cch == 0 ? VERR_NO_MEMORY : (int)cch, "Failed to emit closing definition block");
    12901520                        }
    12911521                    }
    12921522                    else
    1293                         rc = RTErrInfoSetF(pErrInfo, cch == 0 ? VERR_NO_MEMORY : cch, "Failed to emit DefinitionBlock()");
     1523                        rc = RTErrInfoSetF(pErrInfo, cch == 0 ? VERR_NO_MEMORY : (int)cch, "Failed to emit DefinitionBlock()");
    12941524                }
    12951525                else
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