VirtualBox

Changeset 109144 in vbox for trunk/src/VBox/VMM/VMMAll


Ignore:
Timestamp:
May 5, 2025 8:57:30 AM (4 days ago)
Author:
vboxsync
svn:sync-xref-src-repo-rev:
168698
Message:

VMM/GIC: bugref:10877 GITS command-queue, work-in-progress.

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/VBox/VMM/VMMAll/GITSAll.cpp

    r109135 r109144  
    152152    static uint64_t const s_auPhysAddrLoMasks[] =
    153153    {
    154         UINT64_C(0x0000fffffffff000), /* 4K bits[47:12] */
    155         UINT64_C(0x0000ffffffffe000), /* 16K bits[47:13] */
     154        UINT64_C(0x0000fffffffff000), /*  4K bits[47:12] */
     155        UINT64_C(0x0000ffffffffc000), /* 16K bits[47:14] */
    156156        UINT64_C(0x0000ffffffff0000), /* 64K bits[47:16] */
    157157        UINT64_C(0x0000ffffffff0000)  /* 64K bits[47:16] */
     
    161161    static uint64_t const s_auPhysAddrHiMasks[] =
    162162    {
    163         UINT64_C(0x0),                /* 4K bits[51:48] = 0 */
     163        UINT64_C(0x0),                /*  4K bits[51:48] = 0 */
    164164        UINT64_C(0x0),                /* 16K bits[51:48] = 0 */
    165165        UINT64_C(0x000000000000f000), /* 64K bits[51:48] = bits[15:12] */
     
    293293
    294294        case GITS_CTRL_REG_CREADR_OFF + 4:
     295            uReg = 0;   /* Upper 32-bits are reserved, MBZ. */
     296            break;
     297
     298        case GITS_CTRL_REG_CWRITER_OFF:
     299            uReg = pGitsDev->uCmdWriteReg;
     300            break;
     301
     302        case GITS_CTRL_REG_CWRITER_OFF + 4:
    295303            uReg = 0;   /* Upper 32-bits are reserved, MBZ. */
    296304            break;
     
    558566
    559567
    560 static int gitsR3WriteDeviceTableEntry(PPDMDEVINS pDevIns, RTGCPHYS GCPhysDevTable, uint32_t uDevId, uint64_t uDte)
    561 {
    562     RTGCPHYS const offDte = GITS_DTE_SIZE * uDevId;
    563     int rc = PDMDevHlpPhysWriteMeta(pDevIns, GCPhysDevTable + offDte, (const void *)uDte, sizeof(uDte));
     568static int gitsR3WriteDeviceTableEntry(PPDMDEVINS pDevIns, PGITSDEV pGitsDev, uint32_t uDevId, uint64_t uDte)
     569{
     570    uint64_t const uBaseReg       = pGitsDev->aItsTableRegs[0].u;
     571    bool const     fIndirect      = RT_BF_GET(uBaseReg, GITS_BF_CTRL_REG_BASER_INDIRECT);
     572    RTGCPHYS       GCPhysDevTable = gitsGetBaseRegPhysAddr(uBaseReg);
     573    RTGCPHYS const offDte         = GITS_DTE_SIZE * uDevId;
     574
     575    /* Determine the physical address of the device table. */
     576    if (fIndirect)
     577    {
     578        /* Read the the level 1 table device-table entry. */
     579        uint64_t       uLevel1Dte = 0;
     580        int const rc = PDMDevHlpPhysReadMeta(pDevIns, GCPhysDevTable + offDte, &uLevel1Dte, sizeof(uLevel1Dte));
     581        if (RT_SUCCESS(rc))
     582        {
     583            static uint32_t const s_auPageSizes[] = { _4K, _16K, _64K, _64K };
     584            static uint64_t const s_auPhysAddrMasks[] =
     585            {
     586                UINT64_C(0x000ffffffffff000), /*  4K bits[51:12] */
     587                UINT64_C(0x000fffffffffc000), /* 16K bits[51:14] */
     588                UINT64_C(0x000fffffffff0000), /* 64K bits[51:16] */
     589                UINT64_C(0x000fffffffff0000)  /* 64K bits[51:16] */
     590            };
     591
     592            /* Get size of level 2 table from the level 1 entry. */
     593            uint8_t const idxPageSize = RT_BF_GET(uLevel1Dte, GITS_BF_CTRL_REG_BASER_PAGESIZE);
     594            Assert(idxPageSize < RT_ELEMENTS(s_auPageSizes));
     595            uint32_t const cbPage = s_auPageSizes[idxPageSize];
     596            AssertMsg(offDte < cbPage, ("cbPage=%RU64 offDte=%RU64\n", cbPage, offDte)); NOREF(cbPage);
     597
     598            /* Get the physical address of the device-table and offset to the ITE from the level 1 entry. */
     599            GCPhysDevTable = uLevel1Dte & s_auPhysAddrMasks[idxPageSize];
     600            AssertCompile(GITS_DTE_SIZE == GITS_ITE_INDIRECT_LVL1_SIZE);
     601        }
     602    }
     603
     604    /* Write the device-table entry to its table in memory. */
     605    int const rc = PDMDevHlpPhysWriteMeta(pDevIns, GCPhysDevTable + offDte, (const void *)uDte, sizeof(uDte));
    564606    AssertRC(rc);
    565607    return rc;
     
    639681                            /* Map interrupt collection with a target CPU ID. */
    640682                            uint64_t const uDw2 = pCmd->au64[2].u;
    641                             uint8_t  const fValid            = RT_BF_GET(uDw2, GITS_BF_CMD_MAPC_DW2_VALID);
    642                             uint16_t const uTargetCpuId      = RT_BF_GET(uDw2, GITS_BF_CMD_MAPC_DW2_RDBASE);
    643                             uint16_t const uIntrCollectionId = RT_BF_GET(uDw2, GITS_BF_CMD_MAPC_DW2_IC_ID);
    644 
    645                             if (RT_LIKELY(uIntrCollectionId < RT_ELEMENTS(pGitsDev->auCtes)))
     683                            uint8_t  const fValid       = RT_BF_GET(uDw2, GITS_BF_CMD_MAPC_DW2_VALID);
     684                            uint16_t const uTargetCpuId = RT_BF_GET(uDw2, GITS_BF_CMD_MAPC_DW2_RDBASE);
     685                            uint16_t const uIcId        = RT_BF_GET(uDw2, GITS_BF_CMD_MAPC_DW2_IC_ID);
     686
     687                            if (RT_LIKELY(uIcId < RT_ELEMENTS(pGitsDev->auCtes)))
    646688                            {
    647689                                GIC_CRIT_SECT_ENTER(pDevIns);
    648690                                Assert(!RT_BF_GET(pGitsDev->uTypeReg.u, GITS_BF_CTRL_REG_TYPER_PTA));
    649                                 pGitsDev->auCtes[uIntrCollectionId] = RT_BF_MAKE(GITS_BF_CTE_VALID,  fValid)
    650                                                                     | RT_BF_MAKE(GITS_BF_CTE_RDBASE, uTargetCpuId);
     691                                pGitsDev->auCtes[uIcId] = RT_BF_MAKE(GITS_BF_CTE_VALID,  fValid)
     692                                                        | RT_BF_MAKE(GITS_BF_CTE_RDBASE, uTargetCpuId);
    651693                                GIC_CRIT_SECT_LEAVE(pDevIns);
    652694                            }
     
    664706                            uint8_t const  cDevIdBits = RT_BF_GET(pCmd->au64[1].u, GITS_BF_CMD_MAPD_DW1_SIZE);
    665707                            bool const     fValid     = RT_BF_GET(pCmd->au64[2].u, GITS_BF_CMD_MAPD_DW2_VALID);
    666                             RTGCPHYS const GCPhysItt = RT_BF_GET(pCmd->au64[2].u, GITS_BF_CMD_MAPD_DW2_ITT_ADDR);
     708                            uint64_t const u64IttAddr = RT_BF_GET(pCmd->au64[2].u, GITS_BF_CMD_MAPD_DW2_ITT_ADDR);
    667709                            if (fValid)
    668710                            {
     
    675717                                {
    676718                                    uint64_t const uDte = RT_BF_MAKE(GITS_BF_DTE_VALID,     1)
    677                                                         | RT_BF_MAKE(GITS_BF_DTE_ITT_ADDR,  GCPhysItt)
    678                                                         | RT_BF_MAKE(GITS_BF_DTE_ITT_RANGE, cDevIdBits);
     719                                                        | RT_BF_MAKE(GITS_BF_DTE_ITT_RANGE, cDevIdBits)
     720                                                        | RT_BF_MAKE(GITS_BF_DTE_ITT_ADDR,  u64IttAddr);
    679721                                    AssertCompile(sizeof(uDte) == GITS_DTE_SIZE);
    680                                     rc = gitsR3WriteDeviceTableEntry(pDevIns, GCPhysItt, uDevId, uDte);
     722                                    rc = gitsR3WriteDeviceTableEntry(pDevIns, pGitsDev, uDevId, uDte);
    681723                                    AssertRC(rc);
     724                                    /** @todo Add Device ID to internal cache. */
    682725                                }
    683726                                else
     
    688731                            {
    689732                                uint64_t const uDte = 0;
    690                                 rc = gitsR3WriteDeviceTableEntry(pDevIns, GCPhysItt, uDevId, uDte);
     733                                rc = gitsR3WriteDeviceTableEntry(pDevIns, pGitsDev, uDevId, uDte);
     734                                /** @todo Remove Device ID from internal cache. */
    691735                            }
    692736                            STAM_COUNTER_INC(&pGitsDev->StatCmdMapd);
     
    694738                        }
    695739
     740                        case GITS_CMD_ID_MAPTI:
     741                        {
     742                            ///* Map device ID and event ID to corresponding ITE. */
     743                            //uint32_t const uDevId   = RT_BF_GET(pCmd->au64[0].u, GITS_BF_CMD_MAPTI_DW0_DEV_ID);
     744                            //uint32_t const uEventId = RT_BF_GET(pCmd->au64[1].u, GITS_BF_CMD_MAPTI_DW1_EVENT_ID);
     745                            //uint32_t const uIntId   = RT_BF_GET(pCmd->au64[1].u, GITS_BF_CMD_MAPTI_DW1_PHYS_INTID);
     746                            //uint16_t const uIcId    = RT_BF_GET(pCmd->au64[2].u, GITS_BF_CMD_MAPTI_DW2_IC_ID);
     747                            //
     748                            ///* We support 32-bits of device ID and hence it cannot be out of range (asserted below). */
     749                            //Assert(sizeof(uDevId) * 8 >= RT_BF_GET(pGitsDev->uTypeReg.u, GITS_BF_CTRL_REG_TYPER_DEV_BITS) + 1);
     750                            break;
     751                        }
     752
     753                        case GITS_CMD_ID_INV:
     754                        {
     755                            uint64_t const uReg = pGitsDev->aItsTableRegs[0].u;
     756                            AssertMsgFailed(("aItsTableRegs[0].u=%#RX64 (%#RGp %#RGp) Valid=%RTbool\n", uReg,
     757                                             uReg & GITS_BF_CTRL_REG_BASER_PHYS_ADDR_MASK, gitsGetBaseRegPhysAddr(uReg),
     758                                             RT_BOOL(RT_BF_GET(uReg, GITS_BF_CTRL_REG_BASER_VALID))));
     759                            break;
     760                        }
     761
    696762                        case GITS_CMD_ID_SYNC:
    697763                            /* Nothing to do since all previous commands have committed their changes to device state. */
     
    702768                        {
    703769                            /* Reading the table is likely to take the same time as reading just one entry. */
    704                             uint64_t const uDw2 = pCmd->au64[2].u;
    705                             uint16_t const uIntrCollectionId = RT_BF_GET(uDw2, GITS_BF_CMD_INVALL_DW2_IC_ID);
    706                             if (RT_LIKELY(uIntrCollectionId < RT_ELEMENTS(pGitsDev->auCtes)))
     770                            uint64_t const uDw2  = pCmd->au64[2].u;
     771                            uint16_t const uIcId = RT_BF_GET(uDw2, GITS_BF_CMD_INVALL_DW2_IC_ID);
     772                            if (RT_LIKELY(uIcId < RT_ELEMENTS(pGitsDev->auCtes)))
    707773                                gicDistReadLpiConfigTableFromMem(pDevIns);
    708774                            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