VirtualBox

Changeset 108865 in vbox


Ignore:
Timestamp:
Apr 7, 2025 10:17:36 AM (13 days ago)
Author:
vboxsync
svn:sync-xref-src-repo-rev:
168315
Message:

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

Location:
trunk
Files:
3 edited

Legend:

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

    r108864 r108865  
    5252/** The guest page shift (x86). */
    5353#define GITS_CMD_QUEUE_PAGE_SHIFT                               12
     54
     55/** The GITS command size in bytes.  */
     56#define GITS_CMD_SIZE                                           32
    5457
    5558/** GITS_CTLR: Control register - RW. */
     
    7881RT_BF_ASSERT_COMPILE_CHECKS(GITS_BF_CTRL_REG_CTLR_, UINT32_C(0), UINT32_MAX,
    7982                            (ENABLED, IM_DE, RSVD_3_2, ITS_NUMBER, UMSI_IRQ, RSVD_30_9, QUIESCENT));
     83/** GITS_CTLR: Mask of valid read-write bits. */
     84#define GITS_BF_CTRL_REG_CTLR_RW_MASK                           (UINT32_MAX & ~(  GITS_BF_CTRL_REG_CTLR_IM_DE_MASK      \
     85                                                                                | GITS_BF_CTRL_REG_CTLR_RSVD_3_2_MASK   \
     86                                                                                | GITS_BF_CTRL_REG_CTLR_ITS_NUMBER_MASK \
     87                                                                                | GITS_BF_CTRL_REG_CTLR_RSVD_30_9_MASK  \
     88                                                                                | GITS_BF_CTRL_REG_CTLR_QUIESCENT_MASK))
    8089
    8190/** GITS_IIDR: Implementer and revision register - RO. */
     
    392401} GITSITSTYPE;
    393402
    394 /** GITS command size in bytes.  */
    395 #define GITS_CMD_SIZE                                           32
    396 
    397403/**
    398404 * ITS command.
     
    418424/** Pointer to a const ITS command. */
    419425typedef GITSCMD const *PCGITSCMD;
    420 
     426AssertCompileSize(GITSCMD, GITS_CMD_SIZE);
    421427
    422428#endif /* !VBOX_INCLUDED_gic_its_h */
  • trunk/src/VBox/VMM/VMMAll/GITSAll.cpp

    r108864 r108865  
    6767AssertCompileSize(GITSITE, 8);
    6868
     69/** GITS diagnostic enum description expansion.
     70 * The below construct ensures typos in the input to this macro are caught
     71 * during compile time. */
     72#define GITSDIAG_DESC(a_Name)        RT_CONCAT(kGitsDiag_, a_Name) < kGitsDiag_End ? RT_STR(a_Name) : "Ignored"
     73/** GITS diagnostics description for members in GITSDIAG. */
     74static const char *const g_apszGitsDiagDesc[] =
     75{
     76    GITSDIAG_DESC(None),
     77    GITSDIAG_DESC(CmdQueue_PhysAddr_Invalid),
     78    /* kGitsDiag_End */
     79};
     80AssertCompile(RT_ELEMENTS(g_apszGitsDiagDesc) == kGitsDiag_End);
     81#undef GITSDIAG_DESC
     82
    6983
    7084/*********************************************************************************************************************************
     
    108122}
    109123
     124static void gitsCmdQueueSetError(PGITSDEV pGitsDev, GITSDIAG enmError, bool fStallQueue)
     125{
     126    /* Record the error and stall the queue. */
     127    pGitsDev->uCmdQueueError = enmError;
     128    if (fStallQueue)
     129        pGitsDev->uCmdReadReg |= GITS_BF_CTRL_REG_CREADR_STALLED_MASK;
     130
     131    /* Since we don't support SEIs, so there should be nothing more to do here. */
     132    Assert(!RT_BF_GET(pGitsDev->uTypeReg.u, GITS_BF_CTRL_REG_TYPER_SEIS));
     133}
     134
    110135
    111136DECL_FORCE_INLINE(bool) gitsCmdQueueIsEmptyEx(PCGITSDEV pGitsDev, uint32_t *poffRead, uint32_t *poffWrite)
     
    117142
    118143
    119 DECL_HIDDEN_CALLBACK(bool) gitsCmdQueueIsEmpty(PCGITSDEV pGitsDev)
     144DECL_FORCE_INLINE(bool) gitsCmdQueueIsEmpty(PCGITSDEV pGitsDev)
    120145{
    121146    uint32_t offRead;
     
    125150
    126151
    127 DECL_HIDDEN_CALLBACK(bool) gitsCmdQueueCanProcessRequests(PCGITSDEV pGitsDev)
    128 {
    129     if (     pGitsDev->fEnabled
     152DECL_FORCE_INLINE(bool) gitsCmdQueueCanProcessRequests(PCGITSDEV pGitsDev)
     153{
     154    if (    (pGitsDev->uTypeReg.u    & GITS_BF_CTRL_REG_CTLR_ENABLED_MASK)
    130155        &&  (pGitsDev->uCmdBaseReg.u & GITS_BF_CTRL_REG_CBASER_VALID_MASK)
    131156        && !(pGitsDev->uCmdReadReg   & GITS_BF_CTRL_REG_CREADR_STALLED_MASK))
     
    169194        case GITS_CTRL_REG_CTLR_OFF:
    170195            Assert(cb == 4);
    171             uReg = RT_BF_MAKE(GITS_BF_CTRL_REG_CTLR_ENABLED,   pGitsDev->fEnabled)
    172                  | RT_BF_MAKE(GITS_BF_CTRL_REG_CTLR_QUIESCENT, pGitsDev->fQuiescent);
     196            uReg = pGitsDev->uCtrlReg;
    173197            break;
    174198
     
    193217        case GITS_CTRL_REG_TYPER_OFF + 4:
    194218        {
    195             uint64_t const uVal = RT_BF_MAKE(GITS_BF_CTRL_REG_TYPER_PHYSICAL,  1)      /* Physical LPIs supported. */
    196                               /*| RT_BF_MAKE(GITS_BF_CTRL_REG_TYPER_VIRTUAL,   0) */   /* Virtual LPIs not supported. */
    197                                 | RT_BF_MAKE(GITS_BF_CTRL_REG_TYPER_CCT,       0)      /* Collections in memory not supported. */
    198                                 | RT_BF_MAKE(GITS_BF_CTRL_REG_TYPER_ITT_ENTRY_SIZE, sizeof(GITSITE)) /* ITE size in bytes. */
    199                                 | RT_BF_MAKE(GITS_BF_CTRL_REG_TYPER_ID_BITS,   31)     /* 32-bit event IDs. */
    200                                 | RT_BF_MAKE(GITS_BF_CTRL_REG_TYPER_DEV_BITS,  31)     /* 32-bit device IDs. */
    201                               /*| RT_BF_MAKE(GITS_BF_CTRL_REG_TYPER_SEIS,      0) */   /** @todo SEI support. */
    202                               /*| RT_BF_MAKE(GITS_BF_CTRL_REG_TYPER_PTA,       0) */   /* Target is VCPU ID not address. */
    203                                 | RT_BF_MAKE(GITS_BF_CTRL_REG_TYPER_HCC,       255)    /* Collection count. */
    204                               /*| RT_BF_MAKE(GITS_BF_CTRL_REG_TYPER_CID_BITS,  0) */   /* CIL specifies collection ID size. */
    205                               /*| RT_BF_MAKE(GITS_BF_CTRL_REG_TYPER_CIL,       0) */   /* 16-bit collection IDs. */
    206                               /*| RT_BF_MAKE(GITS_BF_CTRL_REG_TYPER_VMOVP,     0) */   /* VMOVP not supported. */
    207                               /*| RT_BF_MAKE(GITS_BF_CTRL_REG_TYPER_MPAM,      0) */   /* MPAM no supported. */
    208                               /*| RT_BF_MAKE(GITS_BF_CTRL_REG_TYPER_VSGI,      0) */   /* VSGI not supported. */
    209                               /*| RT_BF_MAKE(GITS_BF_CTRL_REG_TYPER_VMAPP,     0) */   /* VMAPP not supported. */
    210                               /*| RT_BF_MAKE(GITS_BF_CTRL_REG_TYPER_SVPET,     0) */   /* SVPET not supported. */
    211                               /*| RT_BF_MAKE(GITS_BF_CTRL_REG_TYPER_NID,       0) */   /* NID (doorbell) not supported. */
    212                               /*| RT_BF_MAKE(GITS_BF_CTRL_REG_TYPER_UMSI,      0) */   /** @todo Reporting receipt of unmapped MSIs. */
    213                               /*| RT_BF_MAKE(GITS_BF_CTRL_REG_TYPER_UMSI_IRQ,  0) */   /** @todo Generating interrupt on unmapped MSI. */
    214                                 | RT_BF_MAKE(GITS_BF_CTRL_REG_TYPER_INV,       1);     /* ITS caches invalidated when clearing
    215                                                                                           GITS_CTLR.Enabled and GITS_BASER<n>.Valid. */
    216             uReg = uVal >> ((offReg & 7) << 3 /* to bits */);
     219            uReg = pGitsDev->uTypeReg.u >> ((offReg & 7) << 3 /* to bits */);
    217220            break;
    218221        }
     
    289292        case GITS_CTRL_REG_CTLR_OFF:
    290293            Assert(cb == 4);
    291             pGitsDev->fEnabled = RT_BF_GET(uValue, GITS_BF_CTRL_REG_CTLR_ENABLED);
     294            Assert(!(pGitsDev->uTypeReg.u & GITS_BF_CTRL_REG_TYPER_UMSI_IRQ_MASK));
     295            pGitsDev->uCtrlReg = uValue & GITS_BF_CTRL_REG_CTLR_RW_MASK;
    292296            gitsCmdQueueThreadWakeUpIfNeeded(pDevIns, pGitsDev);
    293297            break;
     
    340344{
    341345    Log4Func(("\n"));
    342     pGitsDev->fEnabled           = false;
    343     pGitsDev->fUnmappedMsiReport = false;
    344     pGitsDev->fQuiescent         = true;
     346
     347    pGitsDev->uCtrlReg   = RT_BF_MAKE(GITS_BF_CTRL_REG_CTLR_QUIESCENT, 1);
     348    pGitsDev->uTypeReg.u = RT_BF_MAKE(GITS_BF_CTRL_REG_TYPER_PHYSICAL,  1)     /* Physical LPIs supported. */
     349                       /*| RT_BF_MAKE(GITS_BF_CTRL_REG_TYPER_VIRTUAL,   0) */  /* Virtual LPIs not supported. */
     350                         | RT_BF_MAKE(GITS_BF_CTRL_REG_TYPER_CCT,       0)     /* Collections in memory not supported. */
     351                         | RT_BF_MAKE(GITS_BF_CTRL_REG_TYPER_ITT_ENTRY_SIZE, sizeof(GITSITE)) /* ITE size in bytes. */
     352                         | RT_BF_MAKE(GITS_BF_CTRL_REG_TYPER_ID_BITS,   31)    /* 32-bit event IDs. */
     353                         | RT_BF_MAKE(GITS_BF_CTRL_REG_TYPER_DEV_BITS,  31)    /* 32-bit device IDs. */
     354                       /*| RT_BF_MAKE(GITS_BF_CTRL_REG_TYPER_SEIS,      0) */  /* Locally generated errors not recommended. */
     355                       /*| RT_BF_MAKE(GITS_BF_CTRL_REG_TYPER_PTA,       0) */  /* Target is VCPU ID not address. */
     356                         | RT_BF_MAKE(GITS_BF_CTRL_REG_TYPER_HCC,       255)   /* Collection count. */
     357                       /*| RT_BF_MAKE(GITS_BF_CTRL_REG_TYPER_CID_BITS,  0) */  /* CIL specifies collection ID size. */
     358                       /*| RT_BF_MAKE(GITS_BF_CTRL_REG_TYPER_CIL,       0) */  /* 16-bit collection IDs. */
     359                       /*| RT_BF_MAKE(GITS_BF_CTRL_REG_TYPER_VMOVP,     0) */  /* VMOVP not supported. */
     360                       /*| RT_BF_MAKE(GITS_BF_CTRL_REG_TYPER_MPAM,      0) */  /* MPAM no supported. */
     361                       /*| RT_BF_MAKE(GITS_BF_CTRL_REG_TYPER_VSGI,      0) */  /* VSGI not supported. */
     362                       /*| RT_BF_MAKE(GITS_BF_CTRL_REG_TYPER_VMAPP,     0) */  /* VMAPP not supported. */
     363                       /*| RT_BF_MAKE(GITS_BF_CTRL_REG_TYPER_SVPET,     0) */  /* SVPET not supported. */
     364                       /*| RT_BF_MAKE(GITS_BF_CTRL_REG_TYPER_NID,       0) */  /* NID (doorbell) not supported. */
     365                       /*| RT_BF_MAKE(GITS_BF_CTRL_REG_TYPER_UMSI,      0) */  /** @todo Reporting receipt of unmapped MSIs. */
     366                       /*| RT_BF_MAKE(GITS_BF_CTRL_REG_TYPER_UMSI_IRQ,  0) */  /** @todo Generating interrupt on unmapped MSI. */
     367                         | RT_BF_MAKE(GITS_BF_CTRL_REG_TYPER_INV,       1);    /* ITS caches invalidated when clearing
     368                                                                                  GITS_CTLR.Enabled and GITS_BASER<n>.Valid. */
    345369    RT_ZERO(pGitsDev->aItsTableRegs);
    346370    pGitsDev->uCmdBaseReg.u      = 0;
     
    356380
    357381    pHlp->pfnPrintf(pHlp, "GIC ITS:\n");
    358     pHlp->pfnPrintf(pHlp, "  uArchRev           = %u\n",      pGitsDev->uArchRev);
    359     pHlp->pfnPrintf(pHlp, "  fEnabled           = %RTbool\n", pGitsDev->fEnabled);
    360     pHlp->pfnPrintf(pHlp, "  fUnmappedMsiReport = %RTbool\n", pGitsDev->fUnmappedMsiReport);
    361     pHlp->pfnPrintf(pHlp, "  fQuiescent         = %RTbool\n", pGitsDev->fQuiescent);
     382
     383    /* Basic info, GITS_CTLR and GITS_TYPER. */
     384    {
     385        GITSDIAG const    enmDiag  = pGitsDev->enmDiag;
     386        const char *const pszDiag  = enmDiag < RT_ELEMENTS(g_apszGitsDiagDesc) ? g_apszGitsDiagDesc[enmDiag] : "(Unknown)";
     387        uint32_t const    uCtrlReg = pGitsDev->uCtrlReg;
     388        pHlp->pfnPrintf(pHlp, "  Error              = %#RX32 (%s)\n", enmDiag, pszDiag);
     389        pHlp->pfnPrintf(pHlp, "  uArchRev           = %u\n",      pGitsDev->uArchRev);
     390        pHlp->pfnPrintf(pHlp, "  uCtrlReg           = %#RX32\n",  uCtrlReg);
     391        pHlp->pfnPrintf(pHlp, "    Enabled            = %RTbool\n", RT_BF_GET(uCtrlReg, GITS_BF_CTRL_REG_CTLR_ENABLED));
     392        pHlp->pfnPrintf(pHlp, "    UMSI IRQ           = %RTbool\n", RT_BF_GET(uCtrlReg, GITS_BF_CTRL_REG_CTLR_UMSI_IRQ));
     393        pHlp->pfnPrintf(pHlp, "    Quiescent          = %RTbool\n", RT_BF_GET(uCtrlReg, GITS_BF_CTRL_REG_CTLR_QUIESCENT));
     394    }
    362395
    363396    /* GITS_BASER<n>. */
     
    420453DECL_HIDDEN_CALLBACK(int) gitsR3CmdQueueProcess(PPDMDEVINS pDevIns, PGITSDEV pGitsDev, void *pvBuf, uint32_t cbBuf)
    421454{
     455    /* Hold the critical section as we could be accessing the device state simultaneously with MMIO accesses. */
    422456    int const rcLock = PDMDevHlpCritSectEnter(pDevIns, pDevIns->pCritSectRoR3, VINF_SUCCESS);
    423457    PDM_CRITSECT_RELEASE_ASSERT_RC_DEV(pDevIns, pDevIns->pCritSectRoR3, rcLock);
     
    434468            AssertRelease(cbCmdQueue <= cbBuf); /** @todo Paranoia; make this a debug assert later. */
    435469
    436 #if 0
    437470            /*
    438              * Allocate space for the command-queue if we haven't done so already.
    439              */
    440             if (pGitsDev->pvCmdQueue != NULL)
    441             {
    442                 if (pGitsDev->cbCmdQueue <= cbCmdQueue)
    443                 {   /* Already allocated sufficient space. */   }
    444                 else
    445                 {
    446                     /* Free old allocation and allocate a new one. */
    447                     RTMemFree(pGitsDev->pvCmdQueue);
    448                     pGitsDev->cbCmdQueue = cbCmdQueue;
    449                     pGitsDev->pvCmdQueue = RTMemAllocZ(cbCmdQueue);
    450                     if (pGitsDev->pvCmdQueue)
    451                     { /* likely */ }
    452                     else
    453                         return VERR_NO_MEMORY;
    454                 }
    455             }
    456             else
    457             {
    458                 /* Allocate one. */
    459                 pGitsDev->cbCmdQueue = cbCmdQueue;
    460                 pGitsDev->pvCmdQueue = RTMemAllocZ(cbCmdQueue);
    461                 if (pGitsDev->pvCmdQueue)
    462                 { /* likely */ }
    463                 else
    464                     return VERR_NO_MEMORY;
    465             }
    466 #endif
    467 
    468             /*
    469              * Read all the commands into the command queue.
     471             * Read all the commands from guest memory into our command queue buffer.
    470472             */
    471473            RTGCPHYS const GCPhysCmds = pGitsDev->uCmdBaseReg.u & GITS_BF_CTRL_REG_CBASER_PHYS_ADDR_MASK;
    472474
    473             /* Leave the critical section before reading (a potentially large amount of) commands. */
     475            /* Temporarily leave the critical section while reading (a potentially large number of) commands from guest memory. */
    474476            PDMDevHlpCritSectLeave(pDevIns, pDevIns->pCritSectRoR3);
    475477
     
    478480            if (offWrite > offRead)
    479481            {
    480                 /* The commands have not wrapped around, read them in one go. */
     482                /* The write offset has not wrapped around, read them in one go. */
    481483                cbCmds = offWrite - offRead;
    482484                Assert(cbCmds <= cbBuf);
     
    485487            else
    486488            {
    487                 /* The commands have wrapped around, read forward and wrapped-around. */
     489                /* The write offset has wrapped around, read till end of buffer followed by wrapped-around data. */
    488490                uint32_t const cbForward = cbCmdQueue - offRead;
    489491                uint32_t const cbWrapped = offWrite;
     
    506508            if (RT_SUCCESS(rc))
    507509            {
    508 
    509510                uint32_t const cCmds = cbCmds / GITS_CMD_SIZE;
    510511                for (uint32_t idxCmd = 0; idxCmd < cCmds; idxCmd++)
     
    519520
    520521            /* Failed to read command queue from the physical address specified by the guest, stall queue and retry later. */
    521 
    522 
    523             /** @todo Stall the command queue. */
     522            gitsCmdQueueSetError(pGitsDev, kGitsDiag_CmdQueue_PhysAddr_Invalid, true /* fStall */);
    524523            return VINF_TRY_AGAIN;
    525524        }
  • trunk/src/VBox/VMM/include/GITSInternal.h

    r108864 r108865  
    4343 */
    4444
     45/**
     46 * GITS error diagnostics.
     47 * Sorted alphabetically so it's easier to add and locate items, no other reason.
     48 *
     49 * @note Members of this enum are used as array indices, so no gaps in enum
     50 *       values are not allowed. Update g_apszItsDiagDesc when you modify
     51 *       fields in this enum.
     52 */
     53typedef enum GITSDIAG
     54{
     55    /* No error, this must be zero! */
     56    kGitsDiag_None = 0,
     57
     58    /* Command queue errors. */
     59    kGitsDiag_CmdQueue_PhysAddr_Invalid,
     60
     61    /* Member for determining array index limit. */
     62    kGitsDiag_End,
     63
     64    /* Usual 32-bit hack. */
     65    kGitsDiag_32Bit_Hack = 0x7fffffff
     66} GITSDIAG;
     67AssertCompileSize(GITSDIAG, 4);
     68
    4569#if 0
    4670/**
     
    80104    /** @name Control registers.
    81105     * @{ */
    82     /** Whether the ITS is enabled. */
    83     bool                    fEnabled;
    84     /** Whether unmapped MSI reporting interrupt is enabled. */
    85     bool                    fUnmappedMsiReport;
    86     /** Whether the ITS is quiescent and can be powered down. */
    87     bool                    fQuiescent;
    88     /** Padding. */
    89     bool                    fPadding0;
    90     /** The ITS table descriptor registers. */
     106    /** The ITS control register (GITS_CTLR). */
     107    uint32_t                uCtrlReg;
     108    /** Implmentation-specific error diagnostic. */
     109    GITSDIAG                enmDiag;
     110    /** The ITS type register (GITS_TYPER). */
     111    RTUINT64U               uTypeReg;
     112    /** The ITS table descriptor registers (GITS_BASER<n>). */
    91113    RTUINT64U               aItsTableRegs[8];
    92     /** The ITS command queue base registers. */
     114    /** The ITS command queue base registers (GITS_CBASER). */
    93115    RTUINT64U               uCmdBaseReg;
    94     /** The ITS command read register. */
     116    /** The ITS command read register (GITS_CREADR). */
    95117    uint32_t                uCmdReadReg;
    96     /** The ITS command write register. */
     118    /** The ITS command write register (GITS_CWRITER). */
    97119    uint32_t                uCmdWriteReg;
    98120    /** @} */
     
    102124    /** @} */
    103125
    104     /** @name Command queue thread.
     126    /** @name Command queue.
    105127     * @{ */
    106128    /** The command-queue thread. */
     
    108130    /** The event semaphore the command-queue thread waits on. */
    109131    SUPSEMEVENT             hEvtCmdQueue;
     132    /** Errors while processing command-queue. */
     133    uint32_t                uCmdQueueError;
     134    /** Padding. */
     135    uint32_t                uPadding0;
    110136    /** @} */
    111137
     
    123149typedef GITSDEV const *PCGITSDEV;
    124150AssertCompileSizeAlignment(GITSDEV, 8);
     151AssertCompileMemberAlignment(GITSDEV, aItsTableRegs, 8);
     152AssertCompileMemberAlignment(GITSDEV, uCmdReadReg, 4);
     153AssertCompileMemberAlignment(GITSDEV, uCmdWriteReg, 4);
     154AssertCompileMemberAlignment(GITSDEV, hEvtCmdQueue, 8);
    125155AssertCompileMemberAlignment(GITSDEV, uArchRev, 8);
    126156
     
    135165DECL_HIDDEN_CALLBACK(void)         gitsR3DbgInfo(PCGITSDEV pGitsDev, PCDBGFINFOHLP pHlp, const char *pszArgs);
    136166DECL_HIDDEN_CALLBACK(int)          gitsR3CmdQueueProcess(PPDMDEVINS pDevIns, PGITSDEV pGitsDev, void *pvBuf, uint32_t cbBuf);
    137 DECL_HIDDEN_CALLBACK(bool)         gitsR3CmdQueueCanProcessRequests(PCGITSDEV pGitsDev);
    138 DECL_HIDDEN_CALLBACK(bool)         gitsR3CmdQueueIsEmpty(PCGITSDEV pGitsDev);
    139167#endif
    140168
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