VirtualBox

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


Ignore:
Timestamp:
Apr 7, 2025 1:38:57 PM (5 weeks ago)
Author:
vboxsync
svn:sync-xref-src-repo-rev:
168321
Message:

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

File:
1 edited

Legend:

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

    r108867 r108871  
    136136}
    137137
    138 static void gitsCmdQueueSetError(PGITSDEV pGitsDev, GITSDIAG enmError, bool fStallQueue)
    139 {
     138
     139static const char * gitsGetCommandName(uint8_t uCmdId)
     140{
     141    switch (uCmdId)
     142    {
     143        case GITS_CMD_ID_CLEAR:     return "CLEAR";
     144        case GITS_CMD_ID_DISCARD:   return "DISCARD";
     145        case GITS_CMD_ID_INT:       return "INT";
     146        case GITS_CMD_ID_INV:       return "INV";
     147        case GITS_CMD_ID_INVALL:    return "INVALL";
     148        case GITS_CMD_ID_INVDB:     return "INVDB";
     149        case GITS_CMD_ID_MAPC:      return "MAPC";
     150        case GITS_CMD_ID_MAPD:      return "MAPD";
     151        case GITS_CMD_ID_MAPI:      return "MAPI";
     152        case GITS_CMD_ID_MAPTI:     return "MAPTI";
     153        case GITS_CMD_ID_MOVALL:    return "MOVALL";
     154        case GITS_CMD_ID_MOVI:      return "MOVI";
     155        case GITS_CMD_ID_SYNC:      return "SYNC";
     156        case GITS_CMD_ID_VINVALL:   return "VINVALL";
     157        case GITS_CMD_ID_VMAPI:     return "VMAPI";
     158        case GITS_CMD_ID_VMAPP:     return "VMAPP";
     159        case GITS_CMD_ID_VMAPTI:    return "VMAPTI";
     160        case GITS_CMD_ID_VMOVI:     return "VMOVI";
     161        case GITS_CMD_ID_VMOVP:     return "VMOVP";
     162        case GITS_CMD_ID_VSGI:      return "VSGI";
     163        case GITS_CMD_ID_VSYNC:     return "VSYNC";
     164        default:
     165            return "<UNKNOWN>";
     166    }
     167}
     168
     169
     170static void gitsCmdQueueSetError(PPDMDEVINS pDevIns, PGITSDEV pGitsDev, GITSDIAG enmError, bool fStallQueue)
     171{
     172    Assert(GITS_CRIT_SECT_IS_OWNER(pDevIns));
     173    NOREF(pDevIns);
     174
    140175    /* Record the error and stall the queue. */
    141176    pGitsDev->uCmdQueueError = enmError;
     
    484519             * Read all the commands from guest memory into our command queue buffer.
    485520             */
    486             RTGCPHYS const GCPhysCmds = pGitsDev->uCmdBaseReg.u & GITS_BF_CTRL_REG_CBASER_PHYS_ADDR_MASK;
    487 
    488             /* Temporarily leave the critical section while reading (a potentially large number of) commands from guest memory. */
    489             GITS_CRIT_SECT_LEAVE(pDevIns);
    490 
    491521            int      rc;
    492522            uint32_t cbCmds;
     523            RTGCPHYS const GCPhysCmds = pGitsDev->uCmdBaseReg.u & GITS_BF_CTRL_REG_CBASER_PHYS_ADDR_MASK;
     524
     525            /* Leave the critical section while reading (a potentially large number of) commands from guest memory. */
     526            GITS_CRIT_SECT_LEAVE(pDevIns);
     527
    493528            if (offWrite > offRead)
    494529            {
     
    507542                if (   RT_SUCCESS(rc)
    508543                    && cbWrapped > 0)
    509                     rc = PDMDevHlpPhysReadMeta(pDevIns, GCPhysCmds + cbForward,
    510                                                (void *)((uintptr_t)pvBuf + cbForward), cbWrapped);
     544                {
     545                    rc = PDMDevHlpPhysReadMeta(pDevIns, GCPhysCmds + cbForward, (void *)((uintptr_t)pvBuf + cbForward),
     546                                               cbWrapped);
     547                }
    511548                cbCmds = cbForward + cbWrapped;
    512549            }
    513550
    514             /* Re-acquire the critical section as we now need to modify device state. */
     551            /* Indicate to the guest we've fetched all commands. */
    515552            GITS_CRIT_SECT_ENTER(pDevIns);
     553            pGitsDev->uCmdReadReg = RT_BF_SET(pGitsDev->uCmdReadReg, GITS_BF_CTRL_REG_CREADR_OFFSET, offWrite);
    516554
    517555            /*
    518              * Process the commands in the queue.
     556             * Process the commands in the buffer.
    519557             */
    520558            if (RT_SUCCESS(rc))
    521559            {
     560                /* Don't hold the lock while processing commands. */
     561                GITS_CRIT_SECT_LEAVE(pDevIns);
     562
    522563                uint32_t const cCmds = cbCmds / GITS_CMD_SIZE;
    523564                for (uint32_t idxCmd = 0; idxCmd < cCmds; idxCmd++)
    524565                {
    525                     PCGITSCMD pCmd = (PCGITSCMD)((uintptr_t)pvBuf + (idxCmd * sizeof(GITSCMD)));
    526                     AssertReleaseMsgFailed(("Cmd=%#x\n", pCmd->clear.uCmdId));
     566                    PCGITSCMD pCmd = (PCGITSCMD)((uintptr_t)pvBuf + (idxCmd * GITS_CMD_SIZE));
     567                    uint8_t const uCmdId = pCmd->common.uCmdId;
     568                    switch (uCmdId)
     569                    {
     570                        case GITS_CMD_ID_MAPC:
     571                        {
     572                            Assert(!RT_BF_GET(pGitsDev->uTypeReg.u, GITS_BF_CTRL_REG_TYPER_PTA)); /* GITS_TYPER is read-only */
     573                            /** @todo Implementing me. Figure out interrupt collection, HCC etc. */
     574                            //uint64_t const uDw2 = pCmd->au64[2].u;
     575                            //bool const     fValid            = RT_BF_GET(uDw2, GITS_BF_CMD_MAPC_DW2_VALID);
     576                            //uint32_t const uTargetCpuId      = RT_BF_GET(uDw2, GITS_BF_CMD_MAPC_DW2_RDBASE);
     577                            //uint16_t const uIntrCollectionId = RT_BF_GET(uDw2, GITS_BF_CMD_MAPC_DW2_IC_ID);
     578                            break;
     579                        }
     580
     581                        default:
     582                            AssertReleaseMsgFailed(("Cmd=%#x (%s)\n", uCmdId, gitsGetCommandName(uCmdId)));
     583                            break;
     584                    }
    527585                }
    528 
    529                 GITS_CRIT_SECT_LEAVE(pDevIns);
    530586                return VINF_SUCCESS;
    531587            }
    532588
    533589            /* Failed to read command queue from the physical address specified by the guest, stall queue and retry later. */
    534             gitsCmdQueueSetError(pGitsDev, kGitsDiag_CmdQueue_PhysAddr_Invalid, true /* fStall */);
     590            gitsCmdQueueSetError(pDevIns, pGitsDev, kGitsDiag_CmdQueue_PhysAddr_Invalid, true /* fStall */);
     591            GITS_CRIT_SECT_LEAVE(pDevIns);
    535592            return VINF_TRY_AGAIN;
    536593        }
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