VirtualBox

Ignore:
Timestamp:
Jun 10, 2009 2:27:05 PM (16 years ago)
Author:
vboxsync
svn:sync-xref-src-repo-rev:
48435
Message:

ACPI: dynamic ACPI tables patching for CPU count support

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/VBox/Devices/PC/ACPI/VBoxAcpi.cpp

    r20413 r20464  
    4040
    4141#ifdef VBOX_WITH_DYNAMIC_DSDT
     42
    4243static int prepareDynamicDsdt(PPDMDEVINS pDevIns, 
    4344                              void*      *ppPtr,
    4445                              size_t     *puDsdtLen)
    4546{
    46     //LogRel(("file is %s\n", g_abVboxDslSource));
     47    ACPI_STATUS Status = AdInitialize();
     48    if (ACPI_FAILURE (Status))
     49    {
     50        AssertFailed();
     51        return VERR_INVALID_PARAMETER;
     52    }
     53
     54    Status = CmDoCompile();
     55    AcpiTerminate();
     56
     57    if (Gbl_ExceptionCount[ASL_ERROR] > 0)
     58    {
     59        AssertFailed();
     60        return VERR_INVALID_PARAMETER;
     61    }
     62
     63    LogRel(("OK file is %s\n", g_abVboxDslSource));
    4764    *ppPtr = NULL;
    4865    *puDsdtLen = 0;
     
    5572    return 0;
    5673}
     74
     75#else
     76static int patchAml(PPDMDEVINS pDevIns, uint8_t* pAml, size_t uAmlLen)
     77{
     78    uint16_t cNumCpus;
     79    int rc;
     80   
     81    rc = CFGMR3QueryU16Def(pDevIns->pCfgHandle, "NumCPUs", &cNumCpus, 1);
     82   
     83    if (RT_FAILURE(rc))
     84        return rc;
     85   
     86    /**
     87     * Now search AML for:
     88     *  AML_PROCESSOR_OP            (UINT16) 0x5b83
     89     * and replace whole block with
     90     *  AML_NOOP_OP                 (UINT16) 0xa3
     91     * for VCPU not configured
     92     */
     93    uint16_t cAcpiCpus = 0;
     94    for (uint32_t i = 0; i < uAmlLen - 5; i++)
     95    {
     96        /*
     97         * AML_PROCESSOR_OP
     98         *
     99         * DefProcessor := ProcessorOp PkgLength NameString ProcID
     100                             PblkAddr PblkLen ObjectList
     101         * ProcessorOp  := ExtOpPrefix 0x83
     102         * ProcID       := ByteData
     103         * PblkAddr     := DwordData
     104         * PblkLen      := ByteData
     105         */
     106        if ((pAml[i] == 0x5b) && (pAml[i+1] == 0x83))
     107        {
     108            if ((pAml[i+3] != 'C') || (pAml[i+4] != 'P'))
     109                /* false alarm, not named starting CP */
     110                continue;
     111           
     112            /* Maybe use ProcID instead? */
     113            cAcpiCpus++;
     114            if (cAcpiCpus <= cNumCpus)
     115                continue;
     116
     117            /* Will fill unwanted CPU block with NOOPs */
     118            /*
     119             * See 18.2.4 Package Length Encoding in ACPI spec
     120             * for full format
     121             */
     122            uint32_t cBytes = pAml[i + 2];
     123            AssertReleaseMsg((cBytes >> 6) == 0,
     124                             ("So far, we only understand simple package length"));
     125               
     126            /* including AML_PROCESSOR_OP itself */
     127            for (uint32_t j = 0; j < cBytes + 2; j++)
     128                pAml[i+j] = 0xa3;
     129
     130            /* Can increase i by cBytes + 1, but not really worth it */
     131        }
     132    }
     133
     134       
     135    /* now recompute checksum, whole file byte sum must be 0 */
     136    pAml[9] = 0;
     137    signed char         Sum;
     138    for (uint32_t i = 0; i < uAmlLen; i++)
     139         Sum = (signed char) (Sum + pAml[i]);
     140    pAml[9] = (uint8_t) (0 - Sum);
     141
     142    return 0;
     143}
    57144#endif
    58145
     
    63150    return prepareDynamicDsdt(pDevIns, ppPtr, puDsdtLen);
    64151#else
    65     *ppPtr = AmlCode;
     152    int rc;
     153   
     154    rc = patchAml(pDevIns, &AmlCode[0], sizeof(AmlCode));
     155    if (RT_FAILURE(rc))
     156        return rc;
     157
     158    *ppPtr = &AmlCode[0];
    66159    *puDsdtLen = sizeof(AmlCode);
     160
    67161    return 0;
    68162#endif
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