VirtualBox

Changeset 81156 in vbox for trunk/src/VBox/VMM/VMMR3/IOM.cpp


Ignore:
Timestamp:
Oct 8, 2019 2:58:45 PM (5 years ago)
Author:
vboxsync
Message:

IOM,PDMDevHlp: Started implementing new MMIO registration APIs. Splitting up IOM.cpp into I/O port and MMIO source files. bugref:9218

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/VBox/VMM/VMMR3/IOM.cpp

    r81136 r81156  
    138138static DECLCALLBACK(int) iomR3RelocateMMIOCallback(PAVLROGCPHYSNODECORE pNode, void *pvUser);
    139139#endif
    140 #ifdef VBOX_WITH_STATISTICS
    141 static void iomR3IoPortRegStats(PVM pVM, PIOMIOPORTENTRYR3 pRegEntry);
    142 static void iomR3IoPortDeregStats(PVM pVM, PIOMIOPORTENTRYR3 pRegEntry, unsigned uPort);
    143 #endif
    144 static DECLCALLBACK(void) iomR3IOPortInfo(PVM pVM, PCDBGFINFOHLP pHlp, const char *pszArgs);
    145140static DECLCALLBACK(void) iomR3MMIOInfo(PVM pVM, PCDBGFINFOHLP pHlp, const char *pszArgs);
    146141static FNIOMIOPORTIN        iomR3IOPortDummyIn;
     
    148143static FNIOMIOPORTINSTRING  iomR3IOPortDummyInStr;
    149144static FNIOMIOPORTOUTSTRING iomR3IOPortDummyOutStr;
    150 static FNIOMIOPORTNEWIN        iomR3IOPortDummyNewIn;
    151 static FNIOMIOPORTNEWOUT       iomR3IOPortDummyNewOut;
    152 static FNIOMIOPORTNEWINSTRING  iomR3IOPortDummyNewInStr;
    153 static FNIOMIOPORTNEWOUTSTRING iomR3IOPortDummyNewOutStr;
    154145
    155146#ifdef VBOX_WITH_STATISTICS
     
    208199             * Info.
    209200             */
    210             DBGFR3InfoRegisterInternal(pVM, "ioport", "Dumps all IOPort ranges. No arguments.", &iomR3IOPortInfo);
     201            DBGFR3InfoRegisterInternal(pVM, "ioport", "Dumps all IOPort ranges. No arguments.", &iomR3IoPortInfo);
    211202            DBGFR3InfoRegisterInternal(pVM, "mmio", "Dumps all MMIO ranges. No arguments.", &iomR3MMIOInfo);
    212203
     
    452443
    453444
    454 /**
    455  * Worker for PDMDEVHLPR3::pfnIoPortCreateEx.
    456  */
    457 VMMR3_INT_DECL(int)  IOMR3IoPortCreate(PVM pVM, PPDMDEVINS pDevIns, RTIOPORT cPorts, uint32_t fFlags, PPDMPCIDEV pPciDev,
    458                                        uint32_t iPciRegion, PFNIOMIOPORTNEWOUT pfnOut, PFNIOMIOPORTNEWIN pfnIn,
    459                                        PFNIOMIOPORTNEWOUTSTRING pfnOutStr, PFNIOMIOPORTNEWINSTRING pfnInStr, RTR3PTR pvUser,
    460                                        const char *pszDesc, PCIOMIOPORTDESC paExtDescs, PIOMIOPORTHANDLE phIoPorts)
    461 {
    462     /*
    463      * Validate input.
    464      */
    465     AssertPtrReturn(phIoPorts, VERR_INVALID_POINTER);
    466     *phIoPorts = UINT32_MAX;
    467     VM_ASSERT_EMT0_RETURN(pVM, VERR_VM_THREAD_NOT_EMT);
    468     VM_ASSERT_STATE_RETURN(pVM, VMSTATE_CREATING, VERR_VM_INVALID_VM_STATE);
    469 
    470     AssertPtrReturn(pDevIns, VERR_INVALID_POINTER);
    471 
    472     AssertMsgReturn(cPorts > 0 && cPorts <= _8K, ("cPorts=%s\n", cPorts), VERR_OUT_OF_RANGE);
    473     AssertReturn(!(fFlags & ~IOM_IOPORT_F_VALID_MASK), VERR_INVALID_FLAGS);
    474 
    475     AssertReturn(pfnOut || pfnIn || pfnOutStr || pfnInStr, VERR_INVALID_PARAMETER);
    476     AssertPtrNullReturn(pfnOut, VERR_INVALID_POINTER);
    477     AssertPtrNullReturn(pfnIn, VERR_INVALID_POINTER);
    478     AssertPtrNullReturn(pfnOutStr, VERR_INVALID_POINTER);
    479     AssertPtrNullReturn(pfnInStr, VERR_INVALID_POINTER);
    480     AssertPtrReturn(pszDesc, VERR_INVALID_POINTER);
    481     AssertReturn(*pszDesc != '\0', VERR_INVALID_POINTER);
    482     AssertReturn(strlen(pszDesc) < 128, VERR_INVALID_POINTER);
    483     if (paExtDescs)
    484     {
    485         AssertPtrReturn(paExtDescs, VERR_INVALID_POINTER);
    486         for (size_t i = 0;; i++)
    487         {
    488             const char *pszIn  = paExtDescs[i].pszIn;
    489             const char *pszOut = paExtDescs[i].pszIn;
    490             if (!pszIn && !pszOut)
    491                 break;
    492             AssertReturn(i < _8K, VERR_OUT_OF_RANGE);
    493             AssertReturn(!pszIn  || strlen(pszIn)  < 128, VERR_INVALID_POINTER);
    494             AssertReturn(!pszOut || strlen(pszOut) < 128, VERR_INVALID_POINTER);
    495         }
    496     }
    497 
    498     /*
    499      * Ensure that we've got table space for it.
    500      */
    501 #ifndef VBOX_WITH_STATISTICS
    502     uint16_t const idxStats        = UINT16_MAX;
    503 #else
    504     uint32_t const idxStats        = pVM->iom.s.cIoPortStats;
    505     uint32_t const cNewIoPortStats = idxStats + cPorts;
    506     AssertReturn(cNewIoPortStats <= _64K, VERR_IOM_TOO_MANY_IOPORT_REGISTRATIONS);
    507     if (cNewIoPortStats > pVM->iom.s.cIoPortStatsAllocation)
    508     {
    509         int rc = VMMR3CallR0Emt(pVM, pVM->apCpusR3[0], VMMR0_DO_IOM_GROW_IO_PORT_STATS, cNewIoPortStats, NULL);
    510         AssertLogRelRCReturn(rc, rc);
    511         AssertReturn(idxStats == pVM->iom.s.cIoPortStats, VERR_IOM_IOPORT_IPE_1);
    512         AssertReturn(cNewIoPortStats <= pVM->iom.s.cIoPortStatsAllocation, VERR_IOM_IOPORT_IPE_2);
    513     }
    514 #endif
    515 
    516     uint32_t idx = pVM->iom.s.cIoPortRegs;
    517     if (idx >= pVM->iom.s.cIoPortAlloc)
    518     {
    519         int rc = VMMR3CallR0Emt(pVM, pVM->apCpusR3[0], VMMR0_DO_IOM_GROW_IO_PORTS, pVM->iom.s.cIoPortAlloc + 1, NULL);
    520         AssertLogRelRCReturn(rc, rc);
    521         AssertReturn(idx == pVM->iom.s.cIoPortRegs, VERR_IOM_IOPORT_IPE_1);
    522         AssertReturn(idx < pVM->iom.s.cIoPortAlloc, VERR_IOM_IOPORT_IPE_2);
    523     }
    524 
    525     /*
    526      * Enter it.
    527      */
    528     pVM->iom.s.paIoPortRegs[idx].pvUser             = pvUser;
    529     pVM->iom.s.paIoPortRegs[idx].pDevIns            = pDevIns;
    530     pVM->iom.s.paIoPortRegs[idx].pfnOutCallback     = pfnOut    ? pfnOut    : iomR3IOPortDummyNewOut;
    531     pVM->iom.s.paIoPortRegs[idx].pfnInCallback      = pfnIn     ? pfnIn     : iomR3IOPortDummyNewIn;
    532     pVM->iom.s.paIoPortRegs[idx].pfnOutStrCallback  = pfnOutStr ? pfnOutStr : iomR3IOPortDummyNewOutStr;
    533     pVM->iom.s.paIoPortRegs[idx].pfnInStrCallback   = pfnInStr  ? pfnInStr  : iomR3IOPortDummyNewInStr;
    534     pVM->iom.s.paIoPortRegs[idx].pszDesc            = pszDesc;
    535     pVM->iom.s.paIoPortRegs[idx].paExtDescs         = paExtDescs;
    536     pVM->iom.s.paIoPortRegs[idx].pPciDev            = pPciDev;
    537     pVM->iom.s.paIoPortRegs[idx].iPciRegion         = iPciRegion;
    538     pVM->iom.s.paIoPortRegs[idx].cPorts             = cPorts;
    539     pVM->iom.s.paIoPortRegs[idx].uPort              = UINT16_MAX;
    540     pVM->iom.s.paIoPortRegs[idx].idxStats           = (uint16_t)idxStats;
    541     pVM->iom.s.paIoPortRegs[idx].fMapped            = false;
    542     pVM->iom.s.paIoPortRegs[idx].fFlags             = (uint8_t)fFlags;
    543     pVM->iom.s.paIoPortRegs[idx].idxSelf            = idx;
    544 
    545     pVM->iom.s.cIoPortRegs = idx + 1;
    546     *phIoPorts = idx;
    547     return VINF_SUCCESS;
    548 }
    549 
    550 
    551 /**
    552  * Worker for PDMDEVHLPR3::pfnIoPortMap.
    553  */
    554 VMMR3_INT_DECL(int)  IOMR3IoPortMap(PVM pVM, PPDMDEVINS pDevIns, IOMIOPORTHANDLE hIoPorts, RTIOPORT uPort)
    555 {
    556     /*
    557      * Validate input and state.
    558      */
    559     AssertPtrReturn(pDevIns, VERR_INVALID_HANDLE);
    560     AssertReturn(hIoPorts < pVM->iom.s.cIoPortRegs, VERR_IOM_INVALID_IOPORT_HANDLE);
    561     PIOMIOPORTENTRYR3 const pRegEntry = &pVM->iom.s.paIoPortRegs[hIoPorts];
    562     AssertReturn(pRegEntry->pDevIns == pDevIns, VERR_IOM_INVALID_IOPORT_HANDLE);
    563 
    564     RTIOPORT const cPorts = pRegEntry->cPorts;
    565     AssertMsgReturn(cPorts > 0 && cPorts <= _8K, ("cPorts=%s\n", cPorts), VERR_IOM_IOPORT_IPE_1);
    566     AssertReturn((uint32_t)uPort + cPorts <= _64K, VERR_OUT_OF_RANGE);
    567     RTIOPORT const uLastPort = uPort + cPorts - 1;
    568 
    569     /*
    570      * Do the mapping.
    571      */
    572     int rc = VINF_SUCCESS;
    573     IOM_LOCK_EXCL(pVM);
    574 
    575     if (!pRegEntry->fMapped)
    576     {
    577         uint32_t const cEntries = RT_MIN(pVM->iom.s.cIoPortLookupEntries, pVM->iom.s.cIoPortRegs);
    578         Assert(pVM->iom.s.cIoPortLookupEntries == cEntries);
    579 
    580         PIOMIOPORTLOOKUPENTRY paEntries = pVM->iom.s.paIoPortLookup;
    581         PIOMIOPORTLOOKUPENTRY pEntry;
    582         if (cEntries > 0)
    583         {
    584             uint32_t iFirst = 0;
    585             uint32_t iEnd   = cEntries;
    586             uint32_t i      = cEntries / 2;
    587             for (;;)
    588             {
    589                 pEntry = &paEntries[i];
    590                 if (pEntry->uLastPort < uPort)
    591                 {
    592                     i += 1;
    593                     if (i < iEnd)
    594                         iFirst = i;
    595                     else
    596                     {
    597                         /* Insert after the entry we just considered: */
    598                         pEntry += 1;
    599                         if (i < cEntries)
    600                             memmove(pEntry + 1, pEntry, sizeof(*pEntry) * (cEntries - i));
    601                         break;
    602                     }
    603                 }
    604                 else if (pEntry->uFirstPort > uLastPort)
    605                 {
    606                     if (i > iFirst)
    607                         iEnd = i;
    608                     else
    609                     {
    610                         /* Insert at the entry we just considered: */
    611                         if (i < cEntries)
    612                             memmove(pEntry + 1, pEntry, sizeof(*pEntry) * (cEntries - i));
    613                         break;
    614                     }
    615                 }
    616                 else
    617                 {
    618                     /* Oops! We've got a conflict. */
    619                     AssertLogRelMsgFailed(("%u..%u (%s) conflicts with existing mapping %u..%u (%s)\n",
    620                                            uPort, uLastPort, pRegEntry->pszDesc,
    621                                            pEntry->uFirstPort, pEntry->uLastPort, pVM->iom.s.paIoPortRegs[pEntry->idx].pszDesc));
    622                     IOM_UNLOCK_EXCL(pVM);
    623                     return VERR_IOM_IOPORT_RANGE_CONFLICT;
    624                 }
    625 
    626                 i = iFirst + (iEnd - iFirst) / 2;
    627             }
    628         }
    629         else
    630             pEntry = paEntries;
    631 
    632         /*
    633          * Fill in the entry and bump the table size.
    634          */
    635         pEntry->idx        = hIoPorts;
    636         pEntry->uFirstPort = uPort;
    637         pEntry->uLastPort  = uLastPort;
    638         pVM->iom.s.cIoPortLookupEntries = cEntries + 1;
    639 
    640         pRegEntry->uPort   = uPort;
    641         pRegEntry->fMapped = true;
    642 
    643 #ifdef VBOX_WITH_STATISTICS
    644         /* Don't register stats here when we're creating the VM as the
    645            statistics table may still be reallocated. */
    646         if (pVM->enmVMState >= VMSTATE_CREATED)
    647             iomR3IoPortRegStats(pVM, pRegEntry);
    648 #endif
    649 
    650 #ifdef VBOX_STRICT
    651         /*
    652          * Assert table sanity.
    653          */
    654         AssertMsg(paEntries[0].uLastPort >= paEntries[0].uFirstPort, ("%#x %#x\n", paEntries[0].uLastPort, paEntries[0].uFirstPort));
    655         AssertMsg(paEntries[0].idx < pVM->iom.s.cIoPortRegs, ("%#x %#x\n", paEntries[0].idx, pVM->iom.s.cIoPortRegs));
    656 
    657         RTIOPORT uPortPrev = paEntries[0].uLastPort;
    658         for (size_t i = 1; i <= cEntries; i++)
    659         {
    660             AssertMsg(paEntries[i].uLastPort >= paEntries[i].uFirstPort, ("%u: %#x %#x\n", i, paEntries[i].uLastPort, paEntries[i].uFirstPort));
    661             AssertMsg(paEntries[i].idx < pVM->iom.s.cIoPortRegs, ("%u: %#x %#x\n", i, paEntries[i].idx, pVM->iom.s.cIoPortRegs));
    662             AssertMsg(uPortPrev < paEntries[i].uFirstPort, ("%u: %#x %#x\n", i, uPortPrev, paEntries[i].uFirstPort));
    663             uPortPrev = paEntries[i].uLastPort;
    664         }
    665 #endif
    666     }
    667     else
    668     {
    669         AssertFailed();
    670         rc = VERR_IOM_IOPORTS_ALREADY_MAPPED;
    671     }
    672 
    673     IOM_UNLOCK_EXCL(pVM);
    674     return rc;
    675 }
    676 
    677 
    678 /**
    679  * Worker for PDMDEVHLPR3::pfnIoPortUnmap.
    680  */
    681 VMMR3_INT_DECL(int)  IOMR3IoPortUnmap(PVM pVM, PPDMDEVINS pDevIns, IOMIOPORTHANDLE hIoPorts)
    682 {
    683     /*
    684      * Validate input and state.
    685      */
    686     AssertPtrReturn(pDevIns, VERR_INVALID_HANDLE);
    687     AssertReturn(hIoPorts < pVM->iom.s.cIoPortRegs, VERR_IOM_INVALID_IOPORT_HANDLE);
    688     PIOMIOPORTENTRYR3 const pRegEntry = &pVM->iom.s.paIoPortRegs[hIoPorts];
    689     AssertReturn(pRegEntry->pDevIns == pDevIns, VERR_IOM_INVALID_IOPORT_HANDLE);
    690 
    691     /*
    692      * Do the mapping.
    693      */
    694     int rc;
    695     IOM_LOCK_EXCL(pVM);
    696 
    697     if (pRegEntry->fMapped)
    698     {
    699         RTIOPORT const uPort     = pRegEntry->uPort;
    700         RTIOPORT const uLastPort = uPort + pRegEntry->cPorts - 1;
    701         uint32_t const cEntries  = RT_MIN(pVM->iom.s.cIoPortLookupEntries, pVM->iom.s.cIoPortRegs);
    702         Assert(pVM->iom.s.cIoPortLookupEntries == cEntries);
    703         Assert(cEntries > 0);
    704 
    705         PIOMIOPORTLOOKUPENTRY paEntries = pVM->iom.s.paIoPortLookup;
    706         uint32_t iFirst = 0;
    707         uint32_t iEnd   = cEntries;
    708         uint32_t i      = cEntries / 2;
    709         for (;;)
    710         {
    711             PIOMIOPORTLOOKUPENTRY pEntry = &paEntries[i];
    712             if (pEntry->uLastPort < uPort)
    713             {
    714                 i += 1;
    715                 if (i < iEnd)
    716                     iFirst = i;
    717                 else
    718                 {
    719                     rc = VERR_IOM_IOPORT_IPE_1;
    720                     AssertLogRelMsgFailedBreak(("%u..%u (%s) not found!\n", uPort, uLastPort, pRegEntry->pszDesc));
    721                 }
    722             }
    723             else if (pEntry->uFirstPort > uLastPort)
    724             {
    725                 if (i > iFirst)
    726                     iEnd = i;
    727                 else
    728                 {
    729                     rc = VERR_IOM_IOPORT_IPE_1;
    730                     AssertLogRelMsgFailedBreak(("%u..%u (%s) not found!\n", uPort, uLastPort, pRegEntry->pszDesc));
    731                 }
    732             }
    733             else if (pEntry->idx == hIoPorts)
    734             {
    735                 Assert(pEntry->uFirstPort == uPort);
    736                 Assert(pEntry->uLastPort == uLastPort);
    737 #ifdef VBOX_WITH_STATISTICS
    738                 iomR3IoPortDeregStats(pVM, pRegEntry, uPort);
    739 #endif
    740                 if (i + 1 < cEntries)
    741                     memmove(pEntry, pEntry + 1, sizeof(*pEntry) * (cEntries - i - 1));
    742                 pVM->iom.s.cIoPortLookupEntries = cEntries - 1;
    743                 pRegEntry->uPort   = UINT16_MAX;
    744                 pRegEntry->fMapped = false;
    745                 rc = VINF_SUCCESS;
    746                 break;
    747             }
    748             else
    749             {
    750                 AssertLogRelMsgFailed(("Lookig for %u..%u (%s), found %u..%u (%s) instead!\n",
    751                                        uPort, uLastPort, pRegEntry->pszDesc,
    752                                        pEntry->uFirstPort, pEntry->uLastPort, pVM->iom.s.paIoPortRegs[pEntry->idx].pszDesc));
    753                 rc = VERR_IOM_IOPORT_IPE_1;
    754                 break;
    755             }
    756 
    757             i = iFirst + (iEnd - iFirst) / 2;
    758         }
    759 
    760 #ifdef VBOX_STRICT
    761         /*
    762          * Assert table sanity.
    763          */
    764         AssertMsg(paEntries[0].uLastPort >= paEntries[0].uFirstPort, ("%#x %#x\n", paEntries[0].uLastPort, paEntries[0].uFirstPort));
    765         AssertMsg(paEntries[0].idx < pVM->iom.s.cIoPortRegs, ("%#x %#x\n", paEntries[0].idx, pVM->iom.s.cIoPortRegs));
    766 
    767         RTIOPORT uPortPrev = paEntries[0].uLastPort;
    768         for (i = 1; i < cEntries - 1; i++)
    769         {
    770             AssertMsg(paEntries[i].uLastPort >= paEntries[i].uFirstPort, ("%u: %#x %#x\n", i, paEntries[i].uLastPort, paEntries[i].uFirstPort));
    771             AssertMsg(paEntries[i].idx < pVM->iom.s.cIoPortRegs, ("%u: %#x %#x\n", i, paEntries[i].idx, pVM->iom.s.cIoPortRegs));
    772             AssertMsg(uPortPrev < paEntries[i].uFirstPort, ("%u: %#x %#x\n", i, uPortPrev, paEntries[i].uFirstPort));
    773             uPortPrev = paEntries[i].uLastPort;
    774         }
    775 #endif
    776     }
    777     else
    778     {
    779         AssertFailed();
    780         rc = VERR_IOM_IOPORTS_NOT_MAPPED;
    781     }
    782 
    783     IOM_UNLOCK_EXCL(pVM);
    784     return rc;
    785 }
    786 
    787 #ifdef VBOX_WITH_STATISTICS
    788 
    789 /**
    790  * Register statistics for an I/O port entry.
    791  */
    792 static void iomR3IoPortRegStats(PVM pVM, PIOMIOPORTENTRYR3 pRegEntry)
    793 {
    794     PIOMIOPORTSTATSENTRY pStats     = &pVM->iom.s.paIoPortStats[pRegEntry->idxStats];
    795     PCIOMIOPORTDESC      pExtDesc   = pRegEntry->paExtDescs;
    796     unsigned             uPort      = pRegEntry->uPort;
    797     unsigned const       uFirstPort = uPort;
    798     unsigned const       uEndPort   = uPort + pRegEntry->cPorts;
    799 
    800     /* Register a dummy statistics for the prefix. */
    801     char                 szName[80];
    802     size_t cchPrefix;
    803     if (uFirstPort < uEndPort - 1)
    804         cchPrefix = RTStrPrintf(szName, sizeof(szName), "/IOM/NewPorts/%04x-%04x", uFirstPort, uEndPort - 1);
    805     else
    806         cchPrefix = RTStrPrintf(szName, sizeof(szName), "/IOM/NewPorts/%04x", uPort);
    807     int rc = STAMR3Register(pVM, &pRegEntry->idxSelf, STAMTYPE_U16, STAMVISIBILITY_ALWAYS, szName,
    808                             STAMUNIT_NONE, pRegEntry->pszDesc);
    809     AssertRC(rc);
    810 
    811 
    812     /* Register stats for each port under it */
    813     do
    814     {
    815         size_t cchBaseNm;
    816         if (uFirstPort < uEndPort - 1)
    817             cchBaseNm = cchPrefix + RTStrPrintf(&szName[cchPrefix], sizeof(szName) - cchPrefix, "/%04x-", uPort);
    818         else
    819         {
    820             szName[cchPrefix] = '/';
    821             cchBaseNm = cchPrefix + 1;
    822         }
    823 
    824 # define SET_NM_SUFFIX(a_sz) memcpy(&szName[cchBaseNm], a_sz, sizeof(a_sz));
    825         const char * const pszInDesc  = pExtDesc ? pExtDesc->pszIn  : NULL;
    826         const char * const pszOutDesc = pExtDesc ? pExtDesc->pszOut : NULL;
    827 
    828         /* register the statistics counters. */
    829         SET_NM_SUFFIX("In-R3");
    830         rc = STAMR3Register(pVM, &pStats->InR3,      STAMTYPE_COUNTER, STAMVISIBILITY_USED, szName, STAMUNIT_OCCURENCES, pszInDesc); AssertRC(rc);
    831         SET_NM_SUFFIX("Out-R3");
    832         rc = STAMR3Register(pVM, &pStats->OutR3,     STAMTYPE_COUNTER, STAMVISIBILITY_USED, szName, STAMUNIT_OCCURENCES, pszOutDesc); AssertRC(rc);
    833         SET_NM_SUFFIX("In-RZ");
    834         rc = STAMR3Register(pVM, &pStats->InRZ,      STAMTYPE_COUNTER, STAMVISIBILITY_USED, szName, STAMUNIT_OCCURENCES, pszInDesc); AssertRC(rc);
    835         SET_NM_SUFFIX("Out-RZ");
    836         rc = STAMR3Register(pVM, &pStats->OutRZ,     STAMTYPE_COUNTER, STAMVISIBILITY_USED, szName, STAMUNIT_OCCURENCES, pszOutDesc); AssertRC(rc);
    837         SET_NM_SUFFIX("In-RZtoR3");
    838         rc = STAMR3Register(pVM, &pStats->InRZToR3,  STAMTYPE_COUNTER, STAMVISIBILITY_USED, szName, STAMUNIT_OCCURENCES, NULL); AssertRC(rc);
    839         SET_NM_SUFFIX("Out-RZtoR3");
    840         rc = STAMR3Register(pVM, &pStats->OutRZToR3, STAMTYPE_COUNTER, STAMVISIBILITY_USED, szName, STAMUNIT_OCCURENCES, NULL); AssertRC(rc);
    841 
    842         /* Profiling */
    843         SET_NM_SUFFIX("In-R3-Prof");
    844         rc = STAMR3Register(pVM, &pStats->ProfInR3,  STAMTYPE_PROFILE, STAMVISIBILITY_USED, szName, STAMUNIT_TICKS_PER_CALL, pszInDesc); AssertRC(rc);
    845         SET_NM_SUFFIX("Out-R3-Prof");
    846         rc = STAMR3Register(pVM, &pStats->ProfOutR3, STAMTYPE_PROFILE, STAMVISIBILITY_USED, szName, STAMUNIT_TICKS_PER_CALL, pszOutDesc); AssertRC(rc);
    847         SET_NM_SUFFIX("In-RZ-Prof");
    848         rc = STAMR3Register(pVM, &pStats->ProfInRZ,  STAMTYPE_PROFILE, STAMVISIBILITY_USED, szName, STAMUNIT_TICKS_PER_CALL, pszInDesc); AssertRC(rc);
    849         SET_NM_SUFFIX("Out-RZ-Prof");
    850         rc = STAMR3Register(pVM, &pStats->ProfOutRZ, STAMTYPE_PROFILE, STAMVISIBILITY_USED, szName, STAMUNIT_TICKS_PER_CALL, pszOutDesc); AssertRC(rc);
    851 
    852         pStats++;
    853         uPort++;
    854         if (pExtDesc)
    855             pExtDesc = pszInDesc || pszOutDesc ? pExtDesc + 1 : NULL;
    856     } while (uPort < uEndPort);
    857 }
    858 
    859 
    860 /**
    861  * Deregister statistics for an I/O port entry.
    862  */
    863 static void iomR3IoPortDeregStats(PVM pVM, PIOMIOPORTENTRYR3 pRegEntry, unsigned uPort)
    864 {
    865     char   szPrefix[80];
    866     size_t cchPrefix;
    867     if (pRegEntry->cPorts > 1)
    868         cchPrefix = RTStrPrintf(szPrefix, sizeof(szPrefix), "/IOM/NewPorts/%04x-%04x/", uPort, uPort + pRegEntry->cPorts - 1);
    869     else
    870         cchPrefix = RTStrPrintf(szPrefix, sizeof(szPrefix), "/IOM/NewPorts/%04x/", uPort);
    871     STAMR3DeregisterByPrefix(pVM->pUVM, szPrefix);
    872 }
    873 
    874 #endif /* VBOX_WITH_STATISTICS */
    875445#ifdef VBOX_WITH_STATISTICS
    876446
     
    17011271
    17021272
    1703 /**
    1704  * @callback_method_impl{FNIOMIOPORTNEWIN,
    1705  *      Dummy Port I/O Handler for IN operations.}
    1706  */
    1707 static DECLCALLBACK(VBOXSTRICTRC)
    1708 iomR3IOPortDummyNewIn(PPDMDEVINS pDevIns, void *pvUser, RTIOPORT Port, uint32_t *pu32, unsigned cb)
    1709 {
    1710     NOREF(pDevIns); NOREF(pvUser); NOREF(Port);
    1711     switch (cb)
    1712     {
    1713         case 1: *pu32 = 0xff; break;
    1714         case 2: *pu32 = 0xffff; break;
    1715         case 4: *pu32 = UINT32_C(0xffffffff); break;
    1716         default:
    1717             AssertReleaseMsgFailed(("cb=%d\n", cb));
    1718             return VERR_IOM_IOPORT_IPE_2;
    1719     }
    1720     return VINF_SUCCESS;
    1721 }
    1722 
    1723 
    1724 /**
    1725  * @callback_method_impl{FNIOMIOPORTNEWINSTRING,
    1726  *      Dummy Port I/O Handler for string IN operations.}
    1727  */
    1728 static DECLCALLBACK(VBOXSTRICTRC)
    1729 iomR3IOPortDummyNewInStr(PPDMDEVINS pDevIns, void *pvUser, RTIOPORT Port, uint8_t *pbDst, uint32_t *pcTransfer, unsigned cb)
    1730 {
    1731     NOREF(pDevIns); NOREF(pvUser); NOREF(Port); NOREF(pbDst); NOREF(pcTransfer); NOREF(cb);
    1732     return VINF_SUCCESS;
    1733 }
    1734 
    1735 
    1736 /**
    1737  * @callback_method_impl{FNIOMIOPORTNEWOUT,
    1738  *      Dummy Port I/O Handler for OUT operations.}
    1739  */
    1740 static DECLCALLBACK(VBOXSTRICTRC)
    1741 iomR3IOPortDummyNewOut(PPDMDEVINS pDevIns, void *pvUser, RTIOPORT Port, uint32_t u32, unsigned cb)
    1742 {
    1743     NOREF(pDevIns); NOREF(pvUser); NOREF(Port); NOREF(u32); NOREF(cb);
    1744     return VINF_SUCCESS;
    1745 }
    1746 
    1747 
    1748 /**
    1749  * @callback_method_impl{FNIOMIOPORTNEWOUTSTRING,
    1750  *      Dummy Port I/O Handler for string OUT operations.}
    1751  */
    1752 static DECLCALLBACK(VBOXSTRICTRC)
    1753 iomR3IOPortDummyNewOutStr(PPDMDEVINS pDevIns, void *pvUser, RTIOPORT Port, uint8_t const *pbSrc, uint32_t *pcTransfer, unsigned cb)
    1754 {
    1755     NOREF(pDevIns); NOREF(pvUser); NOREF(Port); NOREF(pbSrc); NOREF(pcTransfer); NOREF(cb);
    1756     return VINF_SUCCESS;
    1757 }
    1758 
    1759 
    1760 /**
    1761  * Display a single I/O port ring-3 range.
    1762  *
    1763  * @returns 0
    1764  * @param   pNode   Pointer to I/O port HC range.
    1765  * @param   pvUser  Pointer to info output callback structure.
    1766  */
    1767 static DECLCALLBACK(int) iomR3IOPortInfoOneR3(PAVLROIOPORTNODECORE pNode, void *pvUser)
    1768 {
    1769     PIOMIOPORTRANGER3 pRange = (PIOMIOPORTRANGER3)pNode;
    1770     PCDBGFINFOHLP pHlp = (PCDBGFINFOHLP)pvUser;
    1771     pHlp->pfnPrintf(pHlp,
    1772                     "%04x-%04x %p %p %p %p %s\n",
    1773                     pRange->Core.Key,
    1774                     pRange->Core.KeyLast,
    1775                     pRange->pDevIns,
    1776                     pRange->pfnInCallback,
    1777                     pRange->pfnOutCallback,
    1778                     pRange->pvUser,
    1779                     pRange->pszDesc);
    1780     return 0;
    1781 }
    1782 
    1783 
    1784 #if 0
    1785 /**
    1786  * Display a single I/O port GC range.
    1787  *
    1788  * @returns 0
    1789  * @param   pNode   Pointer to IOPORT GC range.
    1790  * @param   pvUser  Pointer to info output callback structure.
    1791  */
    1792 static DECLCALLBACK(int) iomR3IOPortInfoOneRC(PAVLROIOPORTNODECORE pNode, void *pvUser)
    1793 {
    1794     PIOMIOPORTRANGERC pRange = (PIOMIOPORTRANGERC)pNode;
    1795     PCDBGFINFOHLP pHlp = (PCDBGFINFOHLP)pvUser;
    1796     pHlp->pfnPrintf(pHlp,
    1797                     "%04x-%04x %RRv %RRv %RRv %RRv %s\n",
    1798                     pRange->Core.Key,
    1799                     pRange->Core.KeyLast,
    1800                     pRange->pDevIns,
    1801                     pRange->pfnInCallback,
    1802                     pRange->pfnOutCallback,
    1803                     pRange->pvUser,
    1804                     pRange->pszDesc);
    1805     return 0;
    1806 }
    1807 #endif
    1808 
    1809 
    1810 /**
    1811  * Display all registered I/O port ranges.
    1812  *
    1813  * @param   pVM         The cross context VM structure.
    1814  * @param   pHlp        The info helpers.
    1815  * @param   pszArgs     Arguments, ignored.
    1816  */
    1817 static DECLCALLBACK(void) iomR3IOPortInfo(PVM pVM, PCDBGFINFOHLP pHlp, const char *pszArgs)
    1818 {
    1819     /* No locking needed here as registerations are only happening during VMSTATE_CREATING. */
    1820     pHlp->pfnPrintf(pHlp,
    1821                     "I/O port registrations: %u (%u allocated)\n"
    1822                     " ## Ctx    Ports Mapping   PCI    Description\n",
    1823                     pVM->iom.s.cIoPortRegs, pVM->iom.s.cIoPortAlloc);
    1824     PIOMIOPORTENTRYR3 paRegs = pVM->iom.s.paIoPortRegs;
    1825     for (uint32_t i = 0; i < pVM->iom.s.cIoPortRegs; i++)
    1826     {
    1827         const char * const pszRing = paRegs[i].fRing0 ? paRegs[i].fRawMode ? "+0+C" : "+0  "
    1828                                    : paRegs[i].fRawMode ? "+C  " : "    ";
    1829         if (paRegs[i].fMapped && paRegs[i].pPciDev)
    1830             pHlp->pfnPrintf(pHlp, "%3u R3%s %04x  %04x-%04x pci%u/%u %s\n", paRegs[i].idxSelf, pszRing, paRegs[i].cPorts,
    1831                             paRegs[i].uPort, paRegs[i].uPort + paRegs[i].cPorts - 1,
    1832                             paRegs[i].pPciDev->idxSubDev, paRegs[i].iPciRegion, paRegs[i].pszDesc);
    1833         else if (paRegs[i].fMapped && !paRegs[i].pPciDev)
    1834             pHlp->pfnPrintf(pHlp, "%3u R3%s %04x  %04x-%04x        %s\n", paRegs[i].idxSelf, pszRing, paRegs[i].cPorts,
    1835                             paRegs[i].uPort, paRegs[i].uPort + paRegs[i].cPorts - 1, paRegs[i].pszDesc);
    1836         else if (paRegs[i].pPciDev)
    1837             pHlp->pfnPrintf(pHlp, "%3u R3%s %04x  unmapped  pci%u/%u %s\n", paRegs[i].idxSelf, pszRing, paRegs[i].cPorts,
    1838                             paRegs[i].pPciDev->idxSubDev, paRegs[i].iPciRegion, paRegs[i].pszDesc);
    1839         else
    1840             pHlp->pfnPrintf(pHlp, "%3u R3%s %04x  unmapped         %s\n",
    1841                             paRegs[i].idxSelf, pszRing, paRegs[i].cPorts, paRegs[i].pszDesc);
    1842     }
    1843 
    1844     /* Legacy registration: */
    1845     NOREF(pszArgs);
    1846     pHlp->pfnPrintf(pHlp,
    1847                     "I/O Port R3 ranges (pVM=%p)\n"
    1848                     "Range     %.*s %.*s %.*s %.*s Description\n",
    1849                     pVM,
    1850                     sizeof(RTHCPTR) * 2,      "pDevIns         ",
    1851                     sizeof(RTHCPTR) * 2,      "In              ",
    1852                     sizeof(RTHCPTR) * 2,      "Out             ",
    1853                     sizeof(RTHCPTR) * 2,      "pvUser          ");
    1854     IOM_LOCK_SHARED(pVM);
    1855     RTAvlroIOPortDoWithAll(&pVM->iom.s.pTreesR3->IOPortTreeR3, true, iomR3IOPortInfoOneR3, (void *)pHlp);
    1856     IOM_UNLOCK_SHARED(pVM);
    1857 
    1858     pHlp->pfnPrintf(pHlp,
    1859                     "I/O Port R0 ranges (pVM=%p)\n"
    1860                     "Range     %.*s %.*s %.*s %.*s Description\n",
    1861                     pVM,
    1862                     sizeof(RTHCPTR) * 2,      "pDevIns         ",
    1863                     sizeof(RTHCPTR) * 2,      "In              ",
    1864                     sizeof(RTHCPTR) * 2,      "Out             ",
    1865                     sizeof(RTHCPTR) * 2,      "pvUser          ");
    1866     IOM_LOCK_SHARED(pVM);
    1867     RTAvlroIOPortDoWithAll(&pVM->iom.s.pTreesR3->IOPortTreeR0, true, iomR3IOPortInfoOneR3, (void *)pHlp);
    1868     IOM_UNLOCK_SHARED(pVM);
    1869 }
    1870 
    18711273
    18721274/**
     
    29252327#endif /* VBOX_WITH_STATISTICS */
    29262328
     2329
     2330VMMR3_INT_DECL(int)  IOMR3MmioCreate(PVM pVM, PPDMDEVINS pDevIns, RTGCPHYS cbRegion, uint32_t fFlags, PPDMPCIDEV pPciDev,
     2331                                     uint32_t iPciRegion, PFNIOMMMIONEWWRITE pfnWrite, PFNIOMMMIONEWREAD pfnRead,
     2332                                     PFNIOMMMIONEWFILL pfnFill, void *pvUser, const char *pszDesc, PIOMMMIOHANDLE phRegion)
     2333{
     2334    RT_NOREF(pVM, pDevIns, cbRegion, fFlags, pPciDev, iPciRegion, pfnWrite, pfnRead, pfnFill, pvUser, pszDesc, phRegion);
     2335    return VERR_NOT_IMPLEMENTED;
     2336}
     2337
     2338VMMR3_INT_DECL(int)  IOMR3MmioMap(PVM pVM, PPDMDEVINS pDevIns, IOMMMIOHANDLE hRegion, RTGCPHYS GCPhys)
     2339{
     2340    RT_NOREF(pVM, pDevIns, hRegion, GCPhys);
     2341    return VERR_NOT_IMPLEMENTED;
     2342}
     2343
     2344VMMR3_INT_DECL(int)  IOMR3MmioUnmap(PVM pVM, PPDMDEVINS pDevIns, IOMMMIOHANDLE hRegion)
     2345{
     2346    RT_NOREF(pVM, pDevIns, hRegion);
     2347    return VERR_NOT_IMPLEMENTED;
     2348}
     2349
     2350VMMR3_INT_DECL(int)  IOMR3MmioReduce(PVM pVM, PPDMDEVINS pDevIns, IOMMMIOHANDLE hRegion, RTGCPHYS cbRegion)
     2351{
     2352    RT_NOREF(pVM, pDevIns, hRegion, cbRegion);
     2353    return VERR_NOT_IMPLEMENTED;
     2354}
     2355
Note: See TracChangeset for help on using the changeset viewer.

© 2024 Oracle Support Privacy / Do Not Sell My Info Terms of Use Trademark Policy Automated Access Etiquette