VirtualBox

Changeset 108871 in vbox


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

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

Location:
trunk
Files:
2 edited

Legend:

Unmodified
Added
Removed
  • trunk/include/VBox/gic-its.h

    r108865 r108871  
    390390
    391391/**
    392  * ITS entry type.
     392 * GITS entry type.
    393393 * In accordance to the ARM GIC spec.
    394394 */
     
    411411    {
    412412        uint8_t         uCmdId;
    413         uint8_t         au8Rsvd[3];
    414         uint32_t        uDeviceId;
    415 
    416         uint32_t        uEventId;
    417         uint32_t        u32Rsvd;
    418 
    419         uint64_t        au64Rsvd[2];
    420     } clear;
     413        uint8_t         auData[31];
     414    } common;
    421415} GITSCMD;
    422416/** Pointer to an ITS command. */
     
    426420AssertCompileSize(GITSCMD, GITS_CMD_SIZE);
    427421
     422/** @name GITS command IDs.
     423 * @{ */
     424#define GITS_CMD_ID_CLEAR                                       0x04
     425#define GITS_CMD_ID_DISCARD                                     0x0f
     426#define GITS_CMD_ID_INT                                         0x03
     427#define GITS_CMD_ID_INV                                         0x0c
     428#define GITS_CMD_ID_INVALL                                      0x0d
     429#define GITS_CMD_ID_INVDB                                       0x2e
     430#define GITS_CMD_ID_MAPC                                        0x09
     431#define GITS_CMD_ID_MAPD                                        0x08
     432#define GITS_CMD_ID_MAPI                                        0x0b
     433#define GITS_CMD_ID_MAPTI                                       0x0a
     434#define GITS_CMD_ID_MOVALL                                      0x0e
     435#define GITS_CMD_ID_MOVI                                        0x01
     436#define GITS_CMD_ID_SYNC                                        0x05
     437#define GITS_CMD_ID_VINVALL                                     0x2d
     438#define GITS_CMD_ID_VMAPI                                       0x2b
     439#define GITS_CMD_ID_VMAPP                                       0x29
     440#define GITS_CMD_ID_VMAPTI                                      0x2a
     441#define GITS_CMD_ID_VMOVI                                       0x21
     442#define GITS_CMD_ID_VMOVP                                       0x22
     443#define GITS_CMD_ID_VSGI                                        0x23
     444#define GITS_CMD_ID_VSYNC                                       0x25
     445/** @} */
     446
     447/** @name GITS command: MAPC.
     448 * @{ */
     449/** MAPC DW0: Command Id. */
     450#define GITS_BF_CMD_MAPC_DW0_CMD_ID_SHIFT                       0
     451#define GITS_BF_CMD_MAPC_DW0_CMD_ID_MASK                        UINT64_C(0x00000000000000ff)
     452/** MAPC DW0: Reserved (bits 63:8). */
     453#define GITS_BF_CMD_MAPC_DW0_RSVD_63_8_SHIFT                    8
     454#define GITS_BF_CMD_MAPC_DW0_RSVD_63_8_MASK                     UINT64_C(0xffffffffffffff00)
     455RT_BF_ASSERT_COMPILE_CHECKS(GITS_BF_CMD_MAPC_DW0_, UINT64_C(0), UINT64_MAX,
     456                            (CMD_ID, RSVD_63_8));
     457
     458/** MAPC DW1: Reserved (bits 63:0). */
     459#define GITS_BF_CMD_MAPC_DW1_RSVD_63_0_MASK                     UINT64_MAX
     460
     461/** MAPC DW2: IC ID - The interrupt collection ID. */
     462#define GITS_BF_CMD_MAPC_DW2_IC_ID_SHIFT                        0
     463#define GITS_BF_CMD_MAPC_DW2_IC_ID_MASK                         UINT64_C(0x000000000000ffff)
     464/** MAPC DW2: RDBase - The target redistributor base address or PE number. */
     465#define GITS_BF_CMD_MAPC_DW2_RDBASE_SHIFT                       16
     466#define GITS_BF_CMD_MAPC_DW2_RDBASE_MASK                        UINT64_C(0x0007ffffffff0000)
     467/** MAPC DW2: Reserved (bits 62:51). */
     468#define GITS_BF_CMD_MAPC_DW2_RSVD_62_51_SHIFT                   51
     469#define GITS_BF_CMD_MAPC_DW2_RSVD_62_51_MASK                    UINT64_C(0x7ff8000000000000)
     470/** MAPC DW2: Valid bit. */
     471#define GITS_BF_CMD_MAPC_DW2_VALID_SHIFT                        63
     472#define GITS_BF_CMD_MAPC_DW2_VALID_MASK                         UINT64_C(0x8000000000000000)
     473RT_BF_ASSERT_COMPILE_CHECKS(GITS_BF_CMD_MAPC_DW2_, UINT64_C(0), UINT64_MAX,
     474                            (IC_ID, RDBASE, RSVD_62_51, VALID));
     475/** @} */
     476
    428477#endif /* !VBOX_INCLUDED_gic_its_h */
    429478
  • 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