VirtualBox

Changeset 26614 in vbox


Ignore:
Timestamp:
Feb 17, 2010 3:03:18 PM (15 years ago)
Author:
vboxsync
Message:

CPU hotplug: Replace container objects with noop's if the attached CPU can't never show up in the VM

Location:
trunk/src/VBox/Devices/PC
Files:
2 edited

Legend:

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

    r26185 r26614  
    137137    return 0;
    138138}
     139
     140/**
     141 * Patch the CPU hot-plug SSDT version to
     142 * only contain the ACPI containers which may have a CPU
     143 */
     144static int patchAmlCpuHotPlug(PPDMDEVINS pDevIns, uint8_t* pAml, size_t uAmlLen)
     145{
     146    uint16_t cNumCpus;
     147    int rc;
     148    uint32_t idxAml = 0;
     149
     150    rc = CFGMR3QueryU16Def(pDevIns->pCfg, "NumCPUs", &cNumCpus, 1);
     151
     152    if (RT_FAILURE(rc))
     153        return rc;
     154
     155    /**
     156     * Now search AML for:
     157     *  AML_DEVICE_OP               (UINT16) 0x5b82
     158     * and replace whole block with
     159     *  AML_NOOP_OP                 (UINT16) 0xa3
     160     * for VCPU not configured
     161     */
     162    while (idxAml < uAmlLen - 7)
     163    {
     164        /*
     165         * AML_DEVICE_OP
     166         *
     167         * DefDevice    := DeviceOp PkgLength NameString ObjectList
     168         * DeviceOp     := ExtOpPrefix 0x82
     169         */
     170        if ((pAml[idxAml] == 0x5b) && (pAml[idxAml+1] == 0x82))
     171        {
     172            /* Check if the enclosed CPU device is configured. */
     173            uint8_t *pbAmlPkgLength = &pAml[idxAml+2];
     174            uint32_t cBytes = 0;
     175            uint32_t cLengthBytesFollow = pbAmlPkgLength[0] >> 6;
     176
     177            if (cLengthBytesFollow == 0)
     178            {
     179                /* Simple package length */
     180                cBytes = pbAmlPkgLength[0];
     181            }
     182            else
     183            {
     184                unsigned idxLengthByte = 1;
     185
     186                cBytes = pbAmlPkgLength[0] & 0xF;
     187
     188                while (idxLengthByte <= cLengthBytesFollow)
     189                {
     190                    cBytes |= pbAmlPkgLength[idxLengthByte] << (4*idxLengthByte);
     191                    idxLengthByte++;
     192                }
     193            }
     194
     195            uint8_t *pbAmlDevName = &pbAmlPkgLength[cLengthBytesFollow+1];
     196            uint8_t *pbAmlCpu     = &pbAmlDevName[4];
     197            bool fCpuConfigured = false;
     198            bool fCpuFound      = false;
     199
     200            if ((pbAmlDevName[0] != 'S') || (pbAmlDevName[1] != 'C') || (pbAmlDevName[2] != 'K'))
     201            {
     202                /* false alarm, not named starting SCK */
     203                idxAml++;
     204                continue;
     205            }
     206
     207            for (uint32_t idxAmlCpu = 0; idxAmlCpu < cBytes - 7; idxAmlCpu++)
     208            {
     209                /*
     210                 * AML_PROCESSOR_OP
     211                 *
     212                 * DefProcessor := ProcessorOp PkgLength NameString ProcID
     213                                     PblkAddr PblkLen ObjectList
     214                 * ProcessorOp  := ExtOpPrefix 0x83
     215                 * ProcID       := ByteData
     216                 * PblkAddr     := DwordData
     217                 * PblkLen      := ByteData
     218                 */
     219                if ((pbAmlCpu[idxAmlCpu] == 0x5b) && (pbAmlCpu[idxAmlCpu+1] == 0x83))
     220                {
     221                    if ((pbAmlCpu[idxAmlCpu+4] != 'C') || (pbAmlCpu[idxAmlCpu+5] != 'P'))
     222                        /* false alarm, not named starting CP */
     223                        continue;
     224
     225                    fCpuFound = true;
     226
     227                    /* Processor ID */
     228                    if (pbAmlCpu[idxAmlCpu+8] < cNumCpus)
     229                    {
     230                        LogFlow(("CPU %d is configured\n", pbAmlCpu[idxAmlCpu+8]));
     231                        fCpuConfigured = true;
     232                        break;
     233                    }
     234                    else
     235                    {
     236                        LogFlow(("CPU %d is not configured\n", pbAmlCpu[idxAmlCpu+8]));
     237                        fCpuConfigured = false;
     238                        break;
     239                    }
     240                }
     241            }
     242
     243            Assert(fCpuFound);
     244
     245            if (!fCpuConfigured)
     246            {
     247                /* Will fill unwanted CPU block with NOOPs */
     248                /*
     249                 * See 18.2.4 Package Length Encoding in ACPI spec
     250                 * for full format
     251                 */
     252
     253                /* including AML_DEVICE_OP itself */
     254                for (uint32_t j = 0; j < cBytes + 2; j++)
     255                    pAml[idxAml+j] = 0xa3;
     256            }
     257
     258            idxAml++;
     259        }
     260        else
     261            idxAml++;
     262    }
     263
     264    /* now recompute checksum, whole file byte sum must be 0 */
     265    pAml[9] = 0;
     266    uint8_t         aSum = 0;
     267    for (uint32_t i = 0; i < uAmlLen; i++)
     268      aSum = aSum + (uint8_t)pAml[i];
     269    pAml[9] = (uint8_t) (0 - aSum);
     270
     271    return 0;
     272}
    139273#endif
    140274
     
    290424        pbAmlCodeSsdt = (uint8_t *)RTMemAllocZ(cbAmlCodeSsdt);
    291425        if (pbAmlCodeSsdt)
     426        {
    292427            memcpy(pbAmlCodeSsdt, pbAmlCode, cbAmlCodeSsdt);
     428
     429            if (fCpuHotPlug)
     430                patchAmlCpuHotPlug(pDevIns, pbAmlCodeSsdt, cbAmlCodeSsdt);
     431            else
     432                patchAml(pDevIns, pbAmlCodeSsdt, cbAmlCodeSsdt);
     433        }
    293434        else
    294435            rc = VERR_NO_MEMORY;
     
    300441    if (RT_SUCCESS(rc))
    301442    {
    302         patchAml(pDevIns, pbAmlCodeSsdt, cbAmlCodeSsdt);
    303443        *ppPtr = pbAmlCodeSsdt;
    304444        *puSsdtLen = cbAmlCodeSsdt;
  • trunk/src/VBox/Devices/PC/DevACPI.cpp

    r26594 r26614  
    22422242        /* Disable the CPU */
    22432243        VMCPUSET_DEL(&s->CpuSetAttached, iLUN);
     2244        s->u32CpuEventType = CPU_EVENT_TYPE_REMOVE;
     2245        s->u32CpuEvent     = iLUN;
    22442246        /* Notify the guest */
    22452247        update_gpe0(s, s->gpe0_sts | 0x2, s->gpe0_en);
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