VirtualBox

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

File:
1 edited

Legend:

Unmodified
Added
Removed
  • 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;
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