VirtualBox

Ignore:
Timestamp:
May 12, 2025 12:37:55 PM (11 days ago)
Author:
vboxsync
svn:sync-xref-src-repo-rev:
168810
Message:

VMM/GIC: bugref:10877 GIC ITS, MSI/LPIs work-in-progress.

File:
1 edited

Legend:

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

    r109220 r109226  
    441441    Assert(!(offReg & 3));
    442442    Log4Func(("offReg=%u uValue=%#RX64 cb=%u\n", offReg, uValue, cb));
     443    /** @todo Call gitsSetLpi for GITS_TRANSLATER register offset write. */
    443444    AssertReleaseMsgFailed(("offReg=%#x uValue=%#RX64 [%u-bit]\n", offReg, uValue, cb << 3));
    444445}
     
    705706
    706707
     708static int gitsR3IteRead(PPDMDEVINS pDevIns, GITSDTE uDte, uint32_t uEventId, GITSITE *puIte)
     709{
     710    RTGCPHYS const GCPhysIntrTable = uDte & GITS_BF_DTE_ITT_ADDR_MASK;
     711    RTGCPHYS const GCPhysIte       = GCPhysIntrTable + uEventId * sizeof(GITSITE);
     712    return PDMDevHlpPhysReadMeta(pDevIns, GCPhysIte, (void *)puIte, sizeof(*puIte));
     713}
     714
     715
    707716static int gitsR3IteWrite(PPDMDEVINS pDevIns, GITSDTE uDte, uint32_t uEventId, GITSITE uIte)
    708717{
     
    9981007
    9991008
    1000 /**
    1001  * @interface_method_impl{PDMGICBACKEND,pfnSendMsi}
    1002  */
    1003 DECL_HIDDEN_CALLBACK(int) gitsSendMsi(PVMCC pVM, PCIBDF uBusDevFn, PCMSIMSG pMsi, uint32_t uTagSrc)
    1004 {
    1005     AssertPtrReturn(pMsi, VERR_INVALID_PARAMETER);
    1006     Log4Func(("uBusDevFn=%#RX32 Msi.Addr=%#RX64 Msi.Data=%#RX32\n", uBusDevFn, pMsi->Addr.u64, pMsi->Data.u32));
    1007     RT_NOREF(pVM, uBusDevFn, pMsi, uTagSrc);
    1008     AssertMsgFailed(("uBusDevFn=%#RX32 Msi.Addr=%#RX64 Msi.Data=%#RX32\n", uBusDevFn, pMsi->Addr.u64, pMsi->Data.u32));
    1009     return VERR_NOT_IMPLEMENTED;
    1010 }
     1009DECL_HIDDEN_CALLBACK(int) gitsSetLpi(PPDMDEVINS pDevIns, PGITSDEV pGitsDev, uint32_t uDevId, uint32_t uEventId, bool fAsserted)
     1010{
     1011    /* We support 32-bits of device ID and hence it cannot be out of range (asserted below). */
     1012    Assert(sizeof(uDevId) * 8 >= RT_BF_GET(pGitsDev->uTypeReg.u, GITS_BF_CTRL_REG_TYPER_DEV_BITS) + 1);
     1013
     1014    /** @todo Error recording. */
     1015
     1016    GIC_CRIT_SECT_ENTER(pDevIns);
     1017
     1018    bool const fEnabled = RT_BF_GET(pGitsDev->uCtrlReg, GITS_BF_CTRL_REG_CTLR_ENABLED);
     1019    if (fEnabled)
     1020    {
     1021        /* Read the DTE */
     1022        GITSDTE uDte;
     1023        int rc = gitsR3DteRead(pDevIns, pGitsDev, uDevId, &uDte);
     1024        if (RT_SUCCESS(rc))
     1025        {
     1026            /* Check the DTE is mapped (valid). */
     1027            bool const fValid = RT_BF_GET(uDte, GITS_BF_DTE_VALID);
     1028            if (fValid)
     1029            {
     1030                /* Check that the event ID (which is the index) is within range. */
     1031                uint32_t const cEntries = RT_BIT_32(RT_BF_GET(uDte, GITS_BF_DTE_ITT_ADDR) + 1);
     1032                if (uEventId < cEntries)
     1033                {
     1034                    /* Read the interrupt-translation entry. */
     1035                    GITSITE uIte = 0;
     1036                    rc = gitsR3IteRead(pDevIns, uDte, uEventId, &uIte);
     1037                    if (RT_SUCCESS(rc))
     1038                    {
     1039                        /* Check the interrupt ID is within range. */
     1040                        uint16_t const uIntId = RT_BF_GET(uIte, GITS_BF_ITE_INTID);
     1041                        uint16_t const uIcId  = RT_BF_GET(uIte, GITS_BF_ITE_ICID);
     1042                        bool const fIsLpiValid = gicDistIsLpiValid(pDevIns, uIntId);
     1043                        if (fIsLpiValid)
     1044                        {
     1045                            /* Check the interrupt collection ID is valid. */
     1046                            if (uIcId < RT_ELEMENTS(pGitsDev->aCtes))
     1047                            {
     1048                                Assert(!RT_BF_GET(pGitsDev->uTypeReg.u, GITS_BF_CTRL_REG_TYPER_PTA));
     1049                                PCVMCC         pVM  = PDMDevHlpGetVM(pDevIns);
     1050                                VMCPUID const idCpu = pGitsDev->aCtes[uIcId].idTargetCpu;
     1051
     1052                                /* Check that the target CPU is valid. */
     1053                                if (idCpu < pVM->cCpus)
     1054                                {
     1055                                    /* Set or clear the LPI pending state in the redistributor. */
     1056                                    PVMCPUCC pVCpu = pVM->CTX_SUFF(apCpus)[idCpu];
     1057                                    gicReDistSetLpi(pDevIns, pVCpu, uIntId, fAsserted);
     1058                                }
     1059                            }
     1060                        }
     1061                    }
     1062                }
     1063            }
     1064        }
     1065    }
     1066    GIC_CRIT_SECT_LEAVE(pDevIns);
     1067    return VINF_SUCCESS;
     1068}
     1069
    10111070
    10121071#endif /* !VBOX_DEVICE_STRUCT_TESTCASE */
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