VirtualBox

Changeset 81162 in vbox for trunk/src/VBox/VMM


Ignore:
Timestamp:
Oct 8, 2019 4:45:46 PM (5 years ago)
Author:
vboxsync
svn:sync-xref-src-repo-rev:
133796
Message:

IOM: New MMIO management code - work in progress. bugref:9218

Location:
trunk/src/VBox/VMM
Files:
2 edited
1 copied

Legend:

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

    r81156 r81162  
    210210    AssertPtrReturn(pDevIns, VERR_INVALID_POINTER);
    211211
    212     AssertMsgReturn(cPorts > 0 && cPorts <= _8K, ("cPorts=%s\n", cPorts), VERR_OUT_OF_RANGE);
     212    AssertMsgReturn(cPorts > 0 && cPorts <= _8K, ("cPorts=%#x\n", cPorts), VERR_OUT_OF_RANGE);
    213213    AssertReturn(!(fFlags & ~IOM_IOPORT_F_VALID_MASK), VERR_INVALID_FLAGS);
    214214
     
    357357                {
    358358                    /* Oops! We've got a conflict. */
    359                     AssertLogRelMsgFailed(("%u..%u (%s) conflicts with existing mapping %u..%u (%s)\n",
     359                    AssertLogRelMsgFailed(("%x..%x (%s) conflicts with existing mapping %x..%x (%s)\n",
    360360                                           uPort, uLastPort, pRegEntry->pszDesc,
    361361                                           pEntry->uFirstPort, pEntry->uLastPort, pVM->iom.s.paIoPortRegs[pEntry->idx].pszDesc));
     
    458458                {
    459459                    rc = VERR_IOM_IOPORT_IPE_1;
    460                     AssertLogRelMsgFailedBreak(("%u..%u (%s) not found!\n", uPort, uLastPort, pRegEntry->pszDesc));
     460                    AssertLogRelMsgFailedBreak(("%x..%x (%s) not found!\n", uPort, uLastPort, pRegEntry->pszDesc));
    461461                }
    462462            }
     
    468468                {
    469469                    rc = VERR_IOM_IOPORT_IPE_1;
    470                     AssertLogRelMsgFailedBreak(("%u..%u (%s) not found!\n", uPort, uLastPort, pRegEntry->pszDesc));
     470                    AssertLogRelMsgFailedBreak(("%x..%x (%s) not found!\n", uPort, uLastPort, pRegEntry->pszDesc));
    471471                }
    472472            }
     
    488488            else
    489489            {
    490                 AssertLogRelMsgFailed(("Lookig for %u..%u (%s), found %u..%u (%s) instead!\n",
     490                AssertLogRelMsgFailed(("Lookig for %x..%x (%s), found %x..%x (%s) instead!\n",
    491491                                       uPort, uLastPort, pRegEntry->pszDesc,
    492492                                       pEntry->uFirstPort, pEntry->uLastPort, pVM->iom.s.paIoPortRegs[pEntry->idx].pszDesc));
  • trunk/src/VBox/VMM/VMMR3/IOMR3Mmio.cpp

    r81157 r81162  
    11/* $Id$ */
    22/** @file
    3  * IOM - Input / Output Monitor, I/O port related APIs.
     3 * IOM - Input / Output Monitor, MMIO related APIs.
    44 */
    55
     
    4343
    4444/**
    45  * Register statistics for an I/O port entry.
    46  */
    47 void iomR3IoPortRegStats(PVM pVM, PIOMIOPORTENTRYR3 pRegEntry)
    48 {
    49     PIOMIOPORTSTATSENTRY pStats     = &pVM->iom.s.paIoPortStats[pRegEntry->idxStats];
    50     PCIOMIOPORTDESC      pExtDesc   = pRegEntry->paExtDescs;
    51     unsigned             uPort      = pRegEntry->uPort;
    52     unsigned const       uFirstPort = uPort;
    53     unsigned const       uEndPort   = uPort + pRegEntry->cPorts;
    54 
    55     /* Register a dummy statistics for the prefix. */
     45 * Register statistics for a MMIO entry.
     46 */
     47void iomR3MmioRegStats(PVM pVM, PIOMMMIOENTRYR3 pRegEntry)
     48{
     49    PIOMMMIOSTATSENTRY   pStats      = &pVM->iom.s.paMmioStats[pRegEntry->idxStats];
     50
     51    /* Format the prefix: */
    5652    char                 szName[80];
    57     size_t cchPrefix;
    58     if (uFirstPort < uEndPort - 1)
    59         cchPrefix = RTStrPrintf(szName, sizeof(szName), "/IOM/NewPorts/%04x-%04x", uFirstPort, uEndPort - 1);
    60     else
    61         cchPrefix = RTStrPrintf(szName, sizeof(szName), "/IOM/NewPorts/%04x", uPort);
    62     const char *pszDesc     = pRegEntry->pszDesc;
    63     char       *pszFreeDesc = NULL;
     53    size_t               cchPrefix = RTStrPrintf(szName, sizeof(szName), "/IOM/NewMmio/%RGp-%RGp",
     54                                                 pRegEntry->GCPhysMapping, pRegEntry->GCPhysMapping + pRegEntry->cbRegion - 1);
     55
     56    /* Mangle the description if this isn't the first device instance: */
     57    const char          *pszDesc     = pRegEntry->pszDesc;
     58    char                *pszFreeDesc = NULL;
    6459    if (pRegEntry->pDevIns && pRegEntry->pDevIns->iInstance > 0 && pszDesc)
    6560        pszDesc = pszFreeDesc = RTStrAPrintf2("%u / %s", pRegEntry->pDevIns->iInstance, pszDesc);
    66     int rc = STAMR3Register(pVM, &pRegEntry->idxSelf, STAMTYPE_U16, STAMVISIBILITY_ALWAYS, szName,
    67                             STAMUNIT_NONE, pRegEntry->pszDesc);
    68     AssertRC(rc);
     61
     62    /* Register statistics: */
     63    int rc = STAMR3Register(pVM, &pStats->Accesses,    STAMTYPE_COUNTER, STAMVISIBILITY_USED, szName, STAMUNIT_OCCURENCES, pszDesc); AssertRC(rc);
    6964    RTStrFree(pszFreeDesc);
    7065
    71     /* Register stats for each port under it */
    72     do
    73     {
    74         size_t cchBaseNm;
    75         if (uFirstPort < uEndPort - 1)
    76             cchBaseNm = cchPrefix + RTStrPrintf(&szName[cchPrefix], sizeof(szName) - cchPrefix, "/%04x-", uPort);
    77         else
    78         {
    79             szName[cchPrefix] = '/';
    80             cchBaseNm = cchPrefix + 1;
    81         }
    82 
    83 # define SET_NM_SUFFIX(a_sz) memcpy(&szName[cchBaseNm], a_sz, sizeof(a_sz));
    84         const char * const pszInDesc  = pExtDesc ? pExtDesc->pszIn  : NULL;
    85         const char * const pszOutDesc = pExtDesc ? pExtDesc->pszOut : NULL;
    86 
    87         /* register the statistics counters. */
    88         SET_NM_SUFFIX("In-R3");
    89         rc = STAMR3Register(pVM, &pStats->InR3,      STAMTYPE_COUNTER, STAMVISIBILITY_USED, szName, STAMUNIT_OCCURENCES, pszInDesc); AssertRC(rc);
    90         SET_NM_SUFFIX("Out-R3");
    91         rc = STAMR3Register(pVM, &pStats->OutR3,     STAMTYPE_COUNTER, STAMVISIBILITY_USED, szName, STAMUNIT_OCCURENCES, pszOutDesc); AssertRC(rc);
    92         SET_NM_SUFFIX("In-RZ");
    93         rc = STAMR3Register(pVM, &pStats->InRZ,      STAMTYPE_COUNTER, STAMVISIBILITY_USED, szName, STAMUNIT_OCCURENCES, pszInDesc); AssertRC(rc);
    94         SET_NM_SUFFIX("Out-RZ");
    95         rc = STAMR3Register(pVM, &pStats->OutRZ,     STAMTYPE_COUNTER, STAMVISIBILITY_USED, szName, STAMUNIT_OCCURENCES, pszOutDesc); AssertRC(rc);
    96         SET_NM_SUFFIX("In-RZtoR3");
    97         rc = STAMR3Register(pVM, &pStats->InRZToR3,  STAMTYPE_COUNTER, STAMVISIBILITY_USED, szName, STAMUNIT_OCCURENCES, NULL); AssertRC(rc);
    98         SET_NM_SUFFIX("Out-RZtoR3");
    99         rc = STAMR3Register(pVM, &pStats->OutRZToR3, STAMTYPE_COUNTER, STAMVISIBILITY_USED, szName, STAMUNIT_OCCURENCES, NULL); AssertRC(rc);
    100 
    101         /* Profiling */
    102         SET_NM_SUFFIX("In-R3-Prof");
    103         rc = STAMR3Register(pVM, &pStats->ProfInR3,  STAMTYPE_PROFILE, STAMVISIBILITY_USED, szName, STAMUNIT_TICKS_PER_CALL, pszInDesc); AssertRC(rc);
    104         SET_NM_SUFFIX("Out-R3-Prof");
    105         rc = STAMR3Register(pVM, &pStats->ProfOutR3, STAMTYPE_PROFILE, STAMVISIBILITY_USED, szName, STAMUNIT_TICKS_PER_CALL, pszOutDesc); AssertRC(rc);
    106         SET_NM_SUFFIX("In-RZ-Prof");
    107         rc = STAMR3Register(pVM, &pStats->ProfInRZ,  STAMTYPE_PROFILE, STAMVISIBILITY_USED, szName, STAMUNIT_TICKS_PER_CALL, pszInDesc); AssertRC(rc);
    108         SET_NM_SUFFIX("Out-RZ-Prof");
    109         rc = STAMR3Register(pVM, &pStats->ProfOutRZ, STAMTYPE_PROFILE, STAMVISIBILITY_USED, szName, STAMUNIT_TICKS_PER_CALL, pszOutDesc); AssertRC(rc);
    110 
    111         pStats++;
    112         uPort++;
    113         if (pExtDesc)
    114             pExtDesc = pszInDesc || pszOutDesc ? pExtDesc + 1 : NULL;
    115     } while (uPort < uEndPort);
    116 }
    117 
    118 
    119 /**
    120  * Deregister statistics for an I/O port entry.
    121  */
    122 static void iomR3IoPortDeregStats(PVM pVM, PIOMIOPORTENTRYR3 pRegEntry, unsigned uPort)
     66# define SET_NM_SUFFIX(a_sz) memcpy(&szName[cchPrefix], a_sz, sizeof(a_sz))
     67    SET_NM_SUFFIX("/Read-R3");
     68    rc = STAMR3Register(pVM, &pStats->ProfReadR3,  STAMTYPE_PROFILE, STAMVISIBILITY_USED, szName, STAMUNIT_TICKS_PER_CALL, NULL); AssertRC(rc);
     69    SET_NM_SUFFIX("/Write-R3");
     70    rc = STAMR3Register(pVM, &pStats->ProfWriteR3, STAMTYPE_PROFILE, STAMVISIBILITY_USED, szName, STAMUNIT_TICKS_PER_CALL, NULL); AssertRC(rc);
     71    SET_NM_SUFFIX("/Read-RZ");
     72    rc = STAMR3Register(pVM, &pStats->ProfReadRZ,  STAMTYPE_PROFILE, STAMVISIBILITY_USED, szName, STAMUNIT_TICKS_PER_CALL, NULL); AssertRC(rc);
     73    SET_NM_SUFFIX("/Write-RZ");
     74    rc = STAMR3Register(pVM, &pStats->ProfWriteRZ, STAMTYPE_PROFILE, STAMVISIBILITY_USED, szName, STAMUNIT_TICKS_PER_CALL, NULL); AssertRC(rc);
     75    SET_NM_SUFFIX("/Read-RZtoR3");
     76    rc = STAMR3Register(pVM, &pStats->ReadRZToR3,  STAMTYPE_COUNTER, STAMVISIBILITY_USED, szName, STAMUNIT_OCCURENCES,     NULL); AssertRC(rc);
     77    SET_NM_SUFFIX("/Write-RZtoR3");
     78    rc = STAMR3Register(pVM, &pStats->WriteRZToR3, STAMTYPE_COUNTER, STAMVISIBILITY_USED, szName, STAMUNIT_OCCURENCES,     NULL); AssertRC(rc);
     79}
     80
     81
     82/**
     83 * Deregister statistics for a MMIO entry.
     84 */
     85static void iomR3MmioDeregStats(PVM pVM, PIOMMMIOENTRYR3 pRegEntry, RTGCPHYS GCPhys)
    12386{
    12487    char   szPrefix[80];
    125     size_t cchPrefix;
    126     if (pRegEntry->cPorts > 1)
    127         cchPrefix = RTStrPrintf(szPrefix, sizeof(szPrefix), "/IOM/NewPorts/%04x-%04x/", uPort, uPort + pRegEntry->cPorts - 1);
    128     else
    129         cchPrefix = RTStrPrintf(szPrefix, sizeof(szPrefix), "/IOM/NewPorts/%04x/", uPort);
     88    RTStrPrintf(szPrefix, sizeof(szPrefix), "/IOM/NewMmio/%RGp-%RGp/", GCPhys, GCPhys + pRegEntry->cbRegion - 1);
    13089    STAMR3DeregisterByPrefix(pVM->pUVM, szPrefix);
    13190}
     
    13594
    13695/**
    137  * @callback_method_impl{FNIOMIOPORTNEWIN,
    138  *      Dummy Port I/O Handler for IN operations.}
    139  */
    140 static DECLCALLBACK(VBOXSTRICTRC)
    141 iomR3IOPortDummyNewIn(PPDMDEVINS pDevIns, void *pvUser, RTIOPORT Port, uint32_t *pu32, unsigned cb)
    142 {
    143     NOREF(pDevIns); NOREF(pvUser); NOREF(Port);
    144     switch (cb)
    145     {
    146         case 1: *pu32 = 0xff; break;
    147         case 2: *pu32 = 0xffff; break;
    148         case 4: *pu32 = UINT32_C(0xffffffff); break;
    149         default:
    150             AssertReleaseMsgFailed(("cb=%d\n", cb));
    151             return VERR_IOM_IOPORT_IPE_2;
    152     }
    153     return VINF_SUCCESS;
    154 }
    155 
    156 
    157 /**
    158  * @callback_method_impl{FNIOMIOPORTNEWINSTRING,
    159  *      Dummy Port I/O Handler for string IN operations.}
    160  */
    161 static DECLCALLBACK(VBOXSTRICTRC)
    162 iomR3IOPortDummyNewInStr(PPDMDEVINS pDevIns, void *pvUser, RTIOPORT Port, uint8_t *pbDst, uint32_t *pcTransfer, unsigned cb)
    163 {
    164     NOREF(pDevIns); NOREF(pvUser); NOREF(Port); NOREF(pbDst); NOREF(pcTransfer); NOREF(cb);
    165     return VINF_SUCCESS;
    166 }
    167 
    168 
    169 /**
    170  * @callback_method_impl{FNIOMIOPORTNEWOUT,
    171  *      Dummy Port I/O Handler for OUT operations.}
    172  */
    173 static DECLCALLBACK(VBOXSTRICTRC)
    174 iomR3IOPortDummyNewOut(PPDMDEVINS pDevIns, void *pvUser, RTIOPORT Port, uint32_t u32, unsigned cb)
    175 {
    176     NOREF(pDevIns); NOREF(pvUser); NOREF(Port); NOREF(u32); NOREF(cb);
    177     return VINF_SUCCESS;
    178 }
    179 
    180 
    181 /**
    182  * @callback_method_impl{FNIOMIOPORTNEWOUTSTRING,
    183  *      Dummy Port I/O Handler for string OUT operations.}
    184  */
    185 static DECLCALLBACK(VBOXSTRICTRC)
    186 iomR3IOPortDummyNewOutStr(PPDMDEVINS pDevIns, void *pvUser, RTIOPORT Port, uint8_t const *pbSrc, uint32_t *pcTransfer, unsigned cb)
    187 {
    188     NOREF(pDevIns); NOREF(pvUser); NOREF(Port); NOREF(pbSrc); NOREF(pcTransfer); NOREF(cb);
    189     return VINF_SUCCESS;
    190 }
    191 
    192 
    193 
    194 /**
    195  * Worker for PDMDEVHLPR3::pfnIoPortCreateEx.
    196  */
    197 VMMR3_INT_DECL(int)  IOMR3IoPortCreate(PVM pVM, PPDMDEVINS pDevIns, RTIOPORT cPorts, uint32_t fFlags, PPDMPCIDEV pPciDev,
    198                                        uint32_t iPciRegion, PFNIOMIOPORTNEWOUT pfnOut, PFNIOMIOPORTNEWIN pfnIn,
    199                                        PFNIOMIOPORTNEWOUTSTRING pfnOutStr, PFNIOMIOPORTNEWINSTRING pfnInStr, RTR3PTR pvUser,
    200                                        const char *pszDesc, PCIOMIOPORTDESC paExtDescs, PIOMIOPORTHANDLE phIoPorts)
     96 * Worker for PDMDEVHLPR3::pfnMmioCreateEx.
     97 */
     98VMMR3_INT_DECL(int)  IOMR3MmioCreate(PVM pVM, PPDMDEVINS pDevIns, RTGCPHYS cbRegion, uint32_t fFlags, PPDMPCIDEV pPciDev,
     99                                     uint32_t iPciRegion, PFNIOMMMIONEWWRITE pfnWrite, PFNIOMMMIONEWREAD pfnRead,
     100                                     PFNIOMMMIONEWFILL pfnFill, void *pvUser, const char *pszDesc, PIOMMMIOHANDLE phRegion)
    201101{
    202102    /*
    203103     * Validate input.
    204104     */
    205     AssertPtrReturn(phIoPorts, VERR_INVALID_POINTER);
    206     *phIoPorts = UINT32_MAX;
     105    AssertPtrReturn(phRegion, VERR_INVALID_POINTER);
     106    *phRegion = UINT32_MAX;
    207107    VM_ASSERT_EMT0_RETURN(pVM, VERR_VM_THREAD_NOT_EMT);
    208108    VM_ASSERT_STATE_RETURN(pVM, VMSTATE_CREATING, VERR_VM_INVALID_VM_STATE);
     
    210110    AssertPtrReturn(pDevIns, VERR_INVALID_POINTER);
    211111
    212     AssertMsgReturn(cPorts > 0 && cPorts <= _8K, ("cPorts=%s\n", cPorts), VERR_OUT_OF_RANGE);
    213     AssertReturn(!(fFlags & ~IOM_IOPORT_F_VALID_MASK), VERR_INVALID_FLAGS);
    214 
    215     AssertReturn(pfnOut || pfnIn || pfnOutStr || pfnInStr, VERR_INVALID_PARAMETER);
    216     AssertPtrNullReturn(pfnOut, VERR_INVALID_POINTER);
    217     AssertPtrNullReturn(pfnIn, VERR_INVALID_POINTER);
    218     AssertPtrNullReturn(pfnOutStr, VERR_INVALID_POINTER);
    219     AssertPtrNullReturn(pfnInStr, VERR_INVALID_POINTER);
     112    AssertMsgReturn(cbRegion > 0 && !(cbRegion & PAGE_OFFSET_MASK), ("cbRegion=%RGp\n", cbRegion), VERR_OUT_OF_RANGE);
     113    AssertReturn(!(fFlags & ~IOM_MMIO_F_VALID_MASK), VERR_INVALID_FLAGS);
     114
     115    AssertReturn(pfnWrite || pfnRead || pfnFill, VERR_INVALID_PARAMETER);
     116    AssertPtrNullReturn(pfnWrite, VERR_INVALID_POINTER);
     117    AssertPtrNullReturn(pfnRead, VERR_INVALID_POINTER);
     118    AssertPtrNullReturn(pfnFill, VERR_INVALID_POINTER);
    220119    AssertPtrReturn(pszDesc, VERR_INVALID_POINTER);
    221120    AssertReturn(*pszDesc != '\0', VERR_INVALID_POINTER);
    222121    AssertReturn(strlen(pszDesc) < 128, VERR_INVALID_POINTER);
    223     if (paExtDescs)
    224     {
    225         AssertPtrReturn(paExtDescs, VERR_INVALID_POINTER);
    226         for (size_t i = 0;; i++)
    227         {
    228             const char *pszIn  = paExtDescs[i].pszIn;
    229             const char *pszOut = paExtDescs[i].pszIn;
    230             if (!pszIn && !pszOut)
    231                 break;
    232             AssertReturn(i < _8K, VERR_OUT_OF_RANGE);
    233             AssertReturn(!pszIn  || strlen(pszIn)  < 128, VERR_INVALID_POINTER);
    234             AssertReturn(!pszOut || strlen(pszOut) < 128, VERR_INVALID_POINTER);
    235         }
    236     }
    237122
    238123    /*
     
    242127    uint16_t const idxStats        = UINT16_MAX;
    243128#else
    244     uint32_t const idxStats        = pVM->iom.s.cIoPortStats;
    245     uint32_t const cNewIoPortStats = idxStats + cPorts;
    246     AssertReturn(cNewIoPortStats <= _64K, VERR_IOM_TOO_MANY_IOPORT_REGISTRATIONS);
    247     if (cNewIoPortStats > pVM->iom.s.cIoPortStatsAllocation)
    248     {
    249         int rc = VMMR3CallR0Emt(pVM, pVM->apCpusR3[0], VMMR0_DO_IOM_GROW_IO_PORT_STATS, cNewIoPortStats, NULL);
     129    uint32_t const idxStats        = pVM->iom.s.cMmioStats;
     130    uint32_t const cNewMmioStats = idxStats + 1;
     131    AssertReturn(cNewMmioStats <= _64K, VERR_IOM_TOO_MANY_MMIO_REGISTRATIONS);
     132    if (cNewMmioStats > pVM->iom.s.cMmioStatsAllocation)
     133    {
     134        int rc = VMMR3CallR0Emt(pVM, pVM->apCpusR3[0], VMMR0_DO_IOM_GROW_MMIO_STATS, cNewMmioStats, NULL);
    250135        AssertLogRelRCReturn(rc, rc);
    251         AssertReturn(idxStats == pVM->iom.s.cIoPortStats, VERR_IOM_IOPORT_IPE_1);
    252         AssertReturn(cNewIoPortStats <= pVM->iom.s.cIoPortStatsAllocation, VERR_IOM_IOPORT_IPE_2);
     136        AssertReturn(idxStats == pVM->iom.s.cMmioStats, VERR_IOM_MMIO_IPE_1);
     137        AssertReturn(cNewMmioStats <= pVM->iom.s.cMmioStatsAllocation, VERR_IOM_MMIO_IPE_2);
    253138    }
    254139#endif
    255140
    256     uint32_t idx = pVM->iom.s.cIoPortRegs;
    257     if (idx >= pVM->iom.s.cIoPortAlloc)
    258     {
    259         int rc = VMMR3CallR0Emt(pVM, pVM->apCpusR3[0], VMMR0_DO_IOM_GROW_IO_PORTS, pVM->iom.s.cIoPortAlloc + 1, NULL);
     141    uint32_t idx = pVM->iom.s.cMmioRegs;
     142    if (idx >= pVM->iom.s.cMmioAlloc)
     143    {
     144        int rc = VMMR3CallR0Emt(pVM, pVM->apCpusR3[0], VMMR0_DO_IOM_GROW_MMIO_REGS, pVM->iom.s.cMmioAlloc + 1, NULL);
    260145        AssertLogRelRCReturn(rc, rc);
    261         AssertReturn(idx == pVM->iom.s.cIoPortRegs, VERR_IOM_IOPORT_IPE_1);
    262         AssertReturn(idx < pVM->iom.s.cIoPortAlloc, VERR_IOM_IOPORT_IPE_2);
     146        AssertReturn(idx == pVM->iom.s.cMmioRegs, VERR_IOM_MMIO_IPE_1);
     147        AssertReturn(idx < pVM->iom.s.cMmioAlloc, VERR_IOM_MMIO_IPE_2);
    263148    }
    264149
     
    266151     * Enter it.
    267152     */
    268     pVM->iom.s.paIoPortRegs[idx].pvUser             = pvUser;
    269     pVM->iom.s.paIoPortRegs[idx].pDevIns            = pDevIns;
    270     pVM->iom.s.paIoPortRegs[idx].pfnOutCallback     = pfnOut    ? pfnOut    : iomR3IOPortDummyNewOut;
    271     pVM->iom.s.paIoPortRegs[idx].pfnInCallback      = pfnIn     ? pfnIn     : iomR3IOPortDummyNewIn;
    272     pVM->iom.s.paIoPortRegs[idx].pfnOutStrCallback  = pfnOutStr ? pfnOutStr : iomR3IOPortDummyNewOutStr;
    273     pVM->iom.s.paIoPortRegs[idx].pfnInStrCallback   = pfnInStr  ? pfnInStr  : iomR3IOPortDummyNewInStr;
    274     pVM->iom.s.paIoPortRegs[idx].pszDesc            = pszDesc;
    275     pVM->iom.s.paIoPortRegs[idx].paExtDescs         = paExtDescs;
    276     pVM->iom.s.paIoPortRegs[idx].pPciDev            = pPciDev;
    277     pVM->iom.s.paIoPortRegs[idx].iPciRegion         = iPciRegion;
    278     pVM->iom.s.paIoPortRegs[idx].cPorts             = cPorts;
    279     pVM->iom.s.paIoPortRegs[idx].uPort              = UINT16_MAX;
    280     pVM->iom.s.paIoPortRegs[idx].idxStats           = (uint16_t)idxStats;
    281     pVM->iom.s.paIoPortRegs[idx].fMapped            = false;
    282     pVM->iom.s.paIoPortRegs[idx].fFlags             = (uint8_t)fFlags;
    283     pVM->iom.s.paIoPortRegs[idx].idxSelf            = idx;
    284 
    285     pVM->iom.s.cIoPortRegs = idx + 1;
    286     *phIoPorts = idx;
     153    pVM->iom.s.paMmioRegs[idx].cbRegion           = cbRegion;
     154    pVM->iom.s.paMmioRegs[idx].GCPhysMapping      = NIL_RTGCPHYS;
     155    pVM->iom.s.paMmioRegs[idx].pvUser             = pvUser;
     156    pVM->iom.s.paMmioRegs[idx].pDevIns            = pDevIns;
     157    pVM->iom.s.paMmioRegs[idx].pfnWriteCallback   = pfnWrite;
     158    pVM->iom.s.paMmioRegs[idx].pfnReadCallback    = pfnRead;
     159    pVM->iom.s.paMmioRegs[idx].pfnFillCallback    = pfnFill;
     160    pVM->iom.s.paMmioRegs[idx].pszDesc            = pszDesc;
     161    pVM->iom.s.paMmioRegs[idx].pPciDev            = pPciDev;
     162    pVM->iom.s.paMmioRegs[idx].iPciRegion         = iPciRegion;
     163    pVM->iom.s.paMmioRegs[idx].idxStats           = (uint16_t)idxStats;
     164    pVM->iom.s.paMmioRegs[idx].fMapped            = false;
     165    pVM->iom.s.paMmioRegs[idx].fFlags             = fFlags;
     166    pVM->iom.s.paMmioRegs[idx].idxSelf            = idx;
     167
     168    pVM->iom.s.cMmioRegs = idx + 1;
     169    *phRegion = idx;
    287170    return VINF_SUCCESS;
    288171}
     
    290173
    291174/**
    292  * Worker for PDMDEVHLPR3::pfnIoPortMap.
    293  */
    294 VMMR3_INT_DECL(int)  IOMR3IoPortMap(PVM pVM, PPDMDEVINS pDevIns, IOMIOPORTHANDLE hIoPorts, RTIOPORT uPort)
     175 * Worker for PDMDEVHLPR3::pfnMmioMap.
     176 */
     177VMMR3_INT_DECL(int)  IOMR3MmioMap(PVM pVM, PPDMDEVINS pDevIns, IOMMMIOHANDLE hRegion, RTGCPHYS GCPhys)
    295178{
    296179    /*
     
    298181     */
    299182    AssertPtrReturn(pDevIns, VERR_INVALID_HANDLE);
    300     AssertReturn(hIoPorts < pVM->iom.s.cIoPortRegs, VERR_IOM_INVALID_IOPORT_HANDLE);
    301     PIOMIOPORTENTRYR3 const pRegEntry = &pVM->iom.s.paIoPortRegs[hIoPorts];
    302     AssertReturn(pRegEntry->pDevIns == pDevIns, VERR_IOM_INVALID_IOPORT_HANDLE);
    303 
    304     RTIOPORT const cPorts = pRegEntry->cPorts;
    305     AssertMsgReturn(cPorts > 0 && cPorts <= _8K, ("cPorts=%s\n", cPorts), VERR_IOM_IOPORT_IPE_1);
    306     AssertReturn((uint32_t)uPort + cPorts <= _64K, VERR_OUT_OF_RANGE);
    307     RTIOPORT const uLastPort = uPort + cPorts - 1;
     183    AssertReturn(hRegion < pVM->iom.s.cMmioRegs, VERR_IOM_INVALID_MMIO_HANDLE);
     184    PIOMMMIOENTRYR3 const pRegEntry = &pVM->iom.s.paMmioRegs[hRegion];
     185    AssertReturn(pRegEntry->pDevIns == pDevIns, VERR_IOM_INVALID_MMIO_HANDLE);
     186
     187    RTGCPHYS const cbRegion = pRegEntry->cbRegion;
     188    AssertMsgReturn(cbRegion > 0 && cbRegion <= _1P, ("cbRegion=%RGp\n", cbRegion), VERR_IOM_MMIO_IPE_1);
     189    AssertReturn(GCPhys + cbRegion <= GCPhys, VERR_OUT_OF_RANGE);
     190    RTGCPHYS const GCPhysLast = GCPhys + cbRegion - 1;
    308191
    309192    /*
     
    315198    if (!pRegEntry->fMapped)
    316199    {
    317         uint32_t const cEntries = RT_MIN(pVM->iom.s.cIoPortLookupEntries, pVM->iom.s.cIoPortRegs);
    318         Assert(pVM->iom.s.cIoPortLookupEntries == cEntries);
    319 
    320         PIOMIOPORTLOOKUPENTRY paEntries = pVM->iom.s.paIoPortLookup;
    321         PIOMIOPORTLOOKUPENTRY pEntry;
     200        uint32_t const cEntries = RT_MIN(pVM->iom.s.cMmioLookupEntries, pVM->iom.s.cMmioRegs);
     201        Assert(pVM->iom.s.cMmioLookupEntries == cEntries);
     202
     203        PIOMMMIOLOOKUPENTRY paEntries = pVM->iom.s.paMmioLookup;
     204        PIOMMMIOLOOKUPENTRY pEntry;
    322205        if (cEntries > 0)
    323206        {
     
    328211            {
    329212                pEntry = &paEntries[i];
    330                 if (pEntry->uLastPort < uPort)
     213                if (pEntry->GCPhysLast < GCPhys)
    331214                {
    332215                    i += 1;
     
    342225                    }
    343226                }
    344                 else if (pEntry->uFirstPort > uLastPort)
     227                else if (pEntry->GCPhysFirst > GCPhysLast)
    345228                {
    346229                    if (i > iFirst)
     
    357240                {
    358241                    /* Oops! We've got a conflict. */
    359                     AssertLogRelMsgFailed(("%u..%u (%s) conflicts with existing mapping %u..%u (%s)\n",
    360                                            uPort, uLastPort, pRegEntry->pszDesc,
    361                                            pEntry->uFirstPort, pEntry->uLastPort, pVM->iom.s.paIoPortRegs[pEntry->idx].pszDesc));
     242                    AssertLogRelMsgFailed(("%RGp..%RGp (%s) conflicts with existing mapping %RGp..%RGp (%s)\n",
     243                                           GCPhys, GCPhysLast, pRegEntry->pszDesc,
     244                                           pEntry->GCPhysFirst, pEntry->GCPhysLast, pVM->iom.s.paMmioRegs[pEntry->idx].pszDesc));
    362245                    IOM_UNLOCK_EXCL(pVM);
    363                     return VERR_IOM_IOPORT_RANGE_CONFLICT;
     246                    return VERR_IOM_MMIO_RANGE_CONFLICT;
    364247                }
    365248
     
    373256         * Fill in the entry and bump the table size.
    374257         */
    375         pEntry->idx        = hIoPorts;
    376         pEntry->uFirstPort = uPort;
    377         pEntry->uLastPort  = uLastPort;
    378         pVM->iom.s.cIoPortLookupEntries = cEntries + 1;
    379 
    380         pRegEntry->uPort   = uPort;
    381         pRegEntry->fMapped = true;
     258        pEntry->idx         = hRegion;
     259        pEntry->GCPhysFirst = GCPhys;
     260        pEntry->GCPhysLast  = GCPhysLast;
     261        pVM->iom.s.cMmioLookupEntries = cEntries + 1;
     262
     263        pRegEntry->GCPhysMapping = GCPhys;
     264        pRegEntry->fMapped       = true;
    382265
    383266#ifdef VBOX_WITH_STATISTICS
     
    385268           statistics table may still be reallocated. */
    386269        if (pVM->enmVMState >= VMSTATE_CREATED)
    387             iomR3IoPortRegStats(pVM, pRegEntry);
     270            iomR3MmioRegStats(pVM, pRegEntry);
    388271#endif
    389272
     
    392275         * Assert table sanity.
    393276         */
    394         AssertMsg(paEntries[0].uLastPort >= paEntries[0].uFirstPort, ("%#x %#x\n", paEntries[0].uLastPort, paEntries[0].uFirstPort));
    395         AssertMsg(paEntries[0].idx < pVM->iom.s.cIoPortRegs, ("%#x %#x\n", paEntries[0].idx, pVM->iom.s.cIoPortRegs));
    396 
    397         RTIOPORT uPortPrev = paEntries[0].uLastPort;
     277        AssertMsg(paEntries[0].GCPhysLast >= paEntries[0].GCPhysFirst, ("%RGp %RGp\n", paEntries[0].GCPhysLast, paEntries[0].GCPhysFirst));
     278        AssertMsg(paEntries[0].idx < pVM->iom.s.cMmioRegs, ("%#x %#x\n", paEntries[0].idx, pVM->iom.s.cMmioRegs));
     279
     280        RTGCPHYS GCPhysPrev = paEntries[0].GCPhysLast;
    398281        for (size_t i = 1; i <= cEntries; i++)
    399282        {
    400             AssertMsg(paEntries[i].uLastPort >= paEntries[i].uFirstPort, ("%u: %#x %#x\n", i, paEntries[i].uLastPort, paEntries[i].uFirstPort));
    401             AssertMsg(paEntries[i].idx < pVM->iom.s.cIoPortRegs, ("%u: %#x %#x\n", i, paEntries[i].idx, pVM->iom.s.cIoPortRegs));
    402             AssertMsg(uPortPrev < paEntries[i].uFirstPort, ("%u: %#x %#x\n", i, uPortPrev, paEntries[i].uFirstPort));
    403             uPortPrev = paEntries[i].uLastPort;
     283            AssertMsg(paEntries[i].GCPhysLast >= paEntries[i].GCPhysFirst, ("%u: %RGp %RGp\n", i, paEntries[i].GCPhysLast, paEntries[i].GCPhysFirst));
     284            AssertMsg(paEntries[i].idx < pVM->iom.s.cMmioRegs, ("%u: %#x %#x\n", i, paEntries[i].idx, pVM->iom.s.cMmioRegs));
     285            AssertMsg(GCPhysPrev < paEntries[i].GCPhysFirst, ("%u: %RGp %RGp\n", i, GCPhysPrev, paEntries[i].GCPhysFirst));
     286            GCPhysPrev = paEntries[i].GCPhysLast;
    404287        }
    405288#endif
     
    408291    {
    409292        AssertFailed();
    410         rc = VERR_IOM_IOPORTS_ALREADY_MAPPED;
     293        rc = VERR_IOM_MMIO_ALREADY_MAPPED;
    411294    }
    412295
     
    417300
    418301/**
    419  * Worker for PDMDEVHLPR3::pfnIoPortUnmap.
    420  */
    421 VMMR3_INT_DECL(int)  IOMR3IoPortUnmap(PVM pVM, PPDMDEVINS pDevIns, IOMIOPORTHANDLE hIoPorts)
     302 * Worker for PDMDEVHLPR3::pfnMmioUnmap.
     303 */
     304VMMR3_INT_DECL(int)  IOMR3MmioUnmap(PVM pVM, PPDMDEVINS pDevIns, IOMMMIOHANDLE hRegion)
    422305{
    423306    /*
     
    425308     */
    426309    AssertPtrReturn(pDevIns, VERR_INVALID_HANDLE);
    427     AssertReturn(hIoPorts < pVM->iom.s.cIoPortRegs, VERR_IOM_INVALID_IOPORT_HANDLE);
    428     PIOMIOPORTENTRYR3 const pRegEntry = &pVM->iom.s.paIoPortRegs[hIoPorts];
    429     AssertReturn(pRegEntry->pDevIns == pDevIns, VERR_IOM_INVALID_IOPORT_HANDLE);
     310    AssertReturn(hRegion < pVM->iom.s.cMmioRegs, VERR_IOM_INVALID_MMIO_HANDLE);
     311    PIOMMMIOENTRYR3 const pRegEntry = &pVM->iom.s.paMmioRegs[hRegion];
     312    AssertReturn(pRegEntry->pDevIns == pDevIns, VERR_IOM_INVALID_MMIO_HANDLE);
    430313
    431314    /*
     
    437320    if (pRegEntry->fMapped)
    438321    {
    439         RTIOPORT const uPort     = pRegEntry->uPort;
    440         RTIOPORT const uLastPort = uPort + pRegEntry->cPorts - 1;
    441         uint32_t const cEntries  = RT_MIN(pVM->iom.s.cIoPortLookupEntries, pVM->iom.s.cIoPortRegs);
    442         Assert(pVM->iom.s.cIoPortLookupEntries == cEntries);
     322        RTGCPHYS const GCPhys     = pRegEntry->GCPhysMapping;
     323        RTGCPHYS const GCPhysLast = GCPhys + pRegEntry->cbRegion - 1;
     324        uint32_t const cEntries   = RT_MIN(pVM->iom.s.cMmioLookupEntries, pVM->iom.s.cMmioRegs);
     325        Assert(pVM->iom.s.cMmioLookupEntries == cEntries);
    443326        Assert(cEntries > 0);
    444327
    445         PIOMIOPORTLOOKUPENTRY paEntries = pVM->iom.s.paIoPortLookup;
     328        PIOMMMIOLOOKUPENTRY paEntries = pVM->iom.s.paMmioLookup;
    446329        uint32_t iFirst = 0;
    447330        uint32_t iEnd   = cEntries;
     
    449332        for (;;)
    450333        {
    451             PIOMIOPORTLOOKUPENTRY pEntry = &paEntries[i];
    452             if (pEntry->uLastPort < uPort)
     334            PIOMMMIOLOOKUPENTRY pEntry = &paEntries[i];
     335            if (pEntry->GCPhysLast < GCPhys)
    453336            {
    454337                i += 1;
     
    457340                else
    458341                {
    459                     rc = VERR_IOM_IOPORT_IPE_1;
    460                     AssertLogRelMsgFailedBreak(("%u..%u (%s) not found!\n", uPort, uLastPort, pRegEntry->pszDesc));
     342                    rc = VERR_IOM_MMIO_IPE_1;
     343                    AssertLogRelMsgFailedBreak(("%RGp..%RGp (%s) not found!\n", GCPhys, GCPhysLast, pRegEntry->pszDesc));
    461344                }
    462345            }
    463             else if (pEntry->uFirstPort > uLastPort)
     346            else if (pEntry->GCPhysFirst > GCPhysLast)
    464347            {
    465348                if (i > iFirst)
     
    467350                else
    468351                {
    469                     rc = VERR_IOM_IOPORT_IPE_1;
    470                     AssertLogRelMsgFailedBreak(("%u..%u (%s) not found!\n", uPort, uLastPort, pRegEntry->pszDesc));
     352                    rc = VERR_IOM_MMIO_IPE_1;
     353                    AssertLogRelMsgFailedBreak(("%RGp..%RGp (%s) not found!\n", GCPhys, GCPhysLast, pRegEntry->pszDesc));
    471354                }
    472355            }
    473             else if (pEntry->idx == hIoPorts)
     356            else if (pEntry->idx == hRegion)
    474357            {
    475                 Assert(pEntry->uFirstPort == uPort);
    476                 Assert(pEntry->uLastPort == uLastPort);
     358                Assert(pEntry->GCPhysFirst == GCPhys);
     359                Assert(pEntry->GCPhysLast == GCPhysLast);
    477360#ifdef VBOX_WITH_STATISTICS
    478                 iomR3IoPortDeregStats(pVM, pRegEntry, uPort);
     361                iomR3MmioDeregStats(pVM, pRegEntry, GCPhys);
    479362#endif
    480363                if (i + 1 < cEntries)
    481364                    memmove(pEntry, pEntry + 1, sizeof(*pEntry) * (cEntries - i - 1));
    482                 pVM->iom.s.cIoPortLookupEntries = cEntries - 1;
    483                 pRegEntry->uPort   = UINT16_MAX;
    484                 pRegEntry->fMapped = false;
     365                pVM->iom.s.cMmioLookupEntries = cEntries - 1;
     366                pRegEntry->GCPhysMapping = NIL_RTGCPHYS;
     367                pRegEntry->fMapped       = false;
    485368                rc = VINF_SUCCESS;
    486369                break;
     
    488371            else
    489372            {
    490                 AssertLogRelMsgFailed(("Lookig for %u..%u (%s), found %u..%u (%s) instead!\n",
    491                                        uPort, uLastPort, pRegEntry->pszDesc,
    492                                        pEntry->uFirstPort, pEntry->uLastPort, pVM->iom.s.paIoPortRegs[pEntry->idx].pszDesc));
    493                 rc = VERR_IOM_IOPORT_IPE_1;
     373                AssertLogRelMsgFailed(("Lookig for %RGp..%RGp (%s), found %RGp..%RGp (%s) instead!\n",
     374                                       GCPhys, GCPhysLast, pRegEntry->pszDesc,
     375                                       pEntry->GCPhysFirst, pEntry->GCPhysLast, pVM->iom.s.paMmioRegs[pEntry->idx].pszDesc));
     376                rc = VERR_IOM_MMIO_IPE_1;
    494377                break;
    495378            }
     
    502385         * Assert table sanity.
    503386         */
    504         AssertMsg(paEntries[0].uLastPort >= paEntries[0].uFirstPort, ("%#x %#x\n", paEntries[0].uLastPort, paEntries[0].uFirstPort));
    505         AssertMsg(paEntries[0].idx < pVM->iom.s.cIoPortRegs, ("%#x %#x\n", paEntries[0].idx, pVM->iom.s.cIoPortRegs));
    506 
    507         RTIOPORT uPortPrev = paEntries[0].uLastPort;
     387        AssertMsg(paEntries[0].GCPhysLast >= paEntries[0].GCPhysFirst, ("%RGp %RGp\n", paEntries[0].GCPhysLast, paEntries[0].GCPhysFirst));
     388        AssertMsg(paEntries[0].idx < pVM->iom.s.cMmioRegs, ("%#x %#x\n", paEntries[0].idx, pVM->iom.s.cMmioRegs));
     389
     390        RTGCPHYS GCPhysPrev = paEntries[0].GCPhysLast;
    508391        for (i = 1; i < cEntries - 1; i++)
    509392        {
    510             AssertMsg(paEntries[i].uLastPort >= paEntries[i].uFirstPort, ("%u: %#x %#x\n", i, paEntries[i].uLastPort, paEntries[i].uFirstPort));
    511             AssertMsg(paEntries[i].idx < pVM->iom.s.cIoPortRegs, ("%u: %#x %#x\n", i, paEntries[i].idx, pVM->iom.s.cIoPortRegs));
    512             AssertMsg(uPortPrev < paEntries[i].uFirstPort, ("%u: %#x %#x\n", i, uPortPrev, paEntries[i].uFirstPort));
    513             uPortPrev = paEntries[i].uLastPort;
     393            AssertMsg(paEntries[i].GCPhysLast >= paEntries[i].GCPhysFirst, ("%u: %RGp %RGp\n", i, paEntries[i].GCPhysLast, paEntries[i].GCPhysFirst));
     394            AssertMsg(paEntries[i].idx < pVM->iom.s.cMmioRegs, ("%u: %#x %#x\n", i, paEntries[i].idx, pVM->iom.s.cMmioRegs));
     395            AssertMsg(GCPhysPrev < paEntries[i].GCPhysFirst, ("%u: %RGp %RGp\n", i, GCPhysPrev, paEntries[i].GCPhysFirst));
     396            GCPhysPrev = paEntries[i].GCPhysLast;
    514397        }
    515398#endif
     
    518401    {
    519402        AssertFailed();
    520         rc = VERR_IOM_IOPORTS_NOT_MAPPED;
     403        rc = VERR_IOM_MMIO_NOT_MAPPED;
    521404    }
    522405
     
    527410
    528411/**
    529  * Display a single I/O port ring-3 range.
     412 * Display a single MMIO range.
    530413 *
    531414 * @returns 0
    532  * @param   pNode   Pointer to I/O port HC range.
     415 * @param   pNode   Pointer to MMIO R3 range.
    533416 * @param   pvUser  Pointer to info output callback structure.
    534417 */
    535 static DECLCALLBACK(int) iomR3IOPortInfoOneR3(PAVLROIOPORTNODECORE pNode, void *pvUser)
    536 {
    537     PIOMIOPORTRANGER3 pRange = (PIOMIOPORTRANGER3)pNode;
     418static DECLCALLBACK(int) iomR3MmioInfoOne(PAVLROGCPHYSNODECORE pNode, void *pvUser)
     419{
     420    PIOMMMIORANGE pRange = (PIOMMMIORANGE)pNode;
    538421    PCDBGFINFOHLP pHlp = (PCDBGFINFOHLP)pvUser;
    539422    pHlp->pfnPrintf(pHlp,
    540                     "%04x-%04x %p %p %p %p %s\n",
     423                    "%RGp-%RGp %RHv %RHv %RHv %RHv %RHv %s\n",
    541424                    pRange->Core.Key,
    542425                    pRange->Core.KeyLast,
    543                     pRange->pDevIns,
    544                     pRange->pfnInCallback,
    545                     pRange->pfnOutCallback,
    546                     pRange->pvUser,
     426                    pRange->pDevInsR3,
     427                    pRange->pfnReadCallbackR3,
     428                    pRange->pfnWriteCallbackR3,
     429                    pRange->pfnFillCallbackR3,
     430                    pRange->pvUserR3,
    547431                    pRange->pszDesc);
     432    pHlp->pfnPrintf(pHlp,
     433                    "%*s %RHv %RHv %RHv %RHv %RHv\n",
     434                    sizeof(RTGCPHYS) * 2 * 2 + 1, "R0",
     435                    pRange->pDevInsR0,
     436                    pRange->pfnReadCallbackR0,
     437                    pRange->pfnWriteCallbackR0,
     438                    pRange->pfnFillCallbackR0,
     439                    pRange->pvUserR0);
     440#if 0
     441    pHlp->pfnPrintf(pHlp,
     442                    "%*s %RRv %RRv %RRv %RRv %RRv\n",
     443                    sizeof(RTGCPHYS) * 2 * 2 + 1, "RC",
     444                    pRange->pDevInsRC,
     445                    pRange->pfnReadCallbackRC,
     446                    pRange->pfnWriteCallbackRC,
     447                    pRange->pfnFillCallbackRC,
     448                    pRange->pvUserRC);
     449#endif
    548450    return 0;
    549451}
     
    551453
    552454/**
    553  * Display all registered I/O port ranges.
     455 * Display all registered MMIO ranges.
    554456 *
    555457 * @param   pVM         The cross context VM structure.
     
    557459 * @param   pszArgs     Arguments, ignored.
    558460 */
    559 DECLCALLBACK(void) iomR3IoPortInfo(PVM pVM, PCDBGFINFOHLP pHlp, const char *pszArgs)
     461DECLCALLBACK(void) iomR3MmioInfo(PVM pVM, PCDBGFINFOHLP pHlp, const char *pszArgs)
    560462{
    561463    /* No locking needed here as registerations are only happening during VMSTATE_CREATING. */
    562464    pHlp->pfnPrintf(pHlp,
    563                     "I/O port registrations: %u (%u allocated)\n"
    564                     " ## Ctx    Ports Mapping   PCI    Description\n",
    565                     pVM->iom.s.cIoPortRegs, pVM->iom.s.cIoPortAlloc);
    566     PIOMIOPORTENTRYR3 paRegs = pVM->iom.s.paIoPortRegs;
    567     for (uint32_t i = 0; i < pVM->iom.s.cIoPortRegs; i++)
     465                    "MMIO registrations: %u (%u allocated)\n"
     466                    " ## Ctx    %.*s %.*s   PCI    Description\n",
     467                    pVM->iom.s.cMmioRegs, pVM->iom.s.cMmioAlloc,
     468                    sizeof(RTGCPHYS) * 2, "Size",
     469                    sizeof(RTGCPHYS) * 2 * 2 + 1, "Mapping");
     470    PIOMMMIOENTRYR3 paRegs = pVM->iom.s.paMmioRegs;
     471    for (uint32_t i = 0; i < pVM->iom.s.cMmioRegs; i++)
    568472    {
    569473        const char * const pszRing = paRegs[i].fRing0 ? paRegs[i].fRawMode ? "+0+C" : "+0  "
    570474                                   : paRegs[i].fRawMode ? "+C  " : "    ";
    571475        if (paRegs[i].fMapped && paRegs[i].pPciDev)
    572             pHlp->pfnPrintf(pHlp, "%3u R3%s %04x  %04x-%04x pci%u/%u %s\n", paRegs[i].idxSelf, pszRing, paRegs[i].cPorts,
    573                             paRegs[i].uPort, paRegs[i].uPort + paRegs[i].cPorts - 1,
     476            pHlp->pfnPrintf(pHlp, "%3u R3%s %RGp  %RGp-%RGp pci%u/%u %s\n", paRegs[i].idxSelf, pszRing, paRegs[i].cbRegion,
     477                            paRegs[i].GCPhysMapping, paRegs[i].GCPhysMapping + paRegs[i].cbRegion - 1,
    574478                            paRegs[i].pPciDev->idxSubDev, paRegs[i].iPciRegion, paRegs[i].pszDesc);
    575479        else if (paRegs[i].fMapped && !paRegs[i].pPciDev)
    576             pHlp->pfnPrintf(pHlp, "%3u R3%s %04x  %04x-%04x        %s\n", paRegs[i].idxSelf, pszRing, paRegs[i].cPorts,
    577                             paRegs[i].uPort, paRegs[i].uPort + paRegs[i].cPorts - 1, paRegs[i].pszDesc);
     480            pHlp->pfnPrintf(pHlp, "%3u R3%s %RGp  %RGp-%RGp        %s\n", paRegs[i].idxSelf, pszRing, paRegs[i].cbRegion,
     481                            paRegs[i].GCPhysMapping, paRegs[i].GCPhysMapping + paRegs[i].cbRegion - 1, paRegs[i].pszDesc);
    578482        else if (paRegs[i].pPciDev)
    579             pHlp->pfnPrintf(pHlp, "%3u R3%s %04x  unmapped  pci%u/%u %s\n", paRegs[i].idxSelf, pszRing, paRegs[i].cPorts,
    580                             paRegs[i].pPciDev->idxSubDev, paRegs[i].iPciRegion, paRegs[i].pszDesc);
     483            pHlp->pfnPrintf(pHlp, "%3u R3%s %RGp  %.*s pci%u/%u %s\n", paRegs[i].idxSelf, pszRing, paRegs[i].cbRegion,
     484                            sizeof(RTGCPHYS) * 2, "unmapped", paRegs[i].pPciDev->idxSubDev, paRegs[i].iPciRegion, paRegs[i].pszDesc);
    581485        else
    582             pHlp->pfnPrintf(pHlp, "%3u R3%s %04x  unmapped         %s\n",
    583                             paRegs[i].idxSelf, pszRing, paRegs[i].cPorts, paRegs[i].pszDesc);
     486            pHlp->pfnPrintf(pHlp, "%3u R3%s %RGp  %.*s        %s\n", paRegs[i].idxSelf, pszRing, paRegs[i].cbRegion,
     487                            sizeof(RTGCPHYS) * 2, "unmapped", paRegs[i].pszDesc);
    584488    }
    585489
     
    587491    NOREF(pszArgs);
    588492    pHlp->pfnPrintf(pHlp,
    589                     "I/O Port R3 ranges (pVM=%p)\n"
    590                     "Range     %.*s %.*s %.*s %.*s Description\n",
     493                    "MMIO ranges (pVM=%p)\n"
     494                    "%.*s %.*s %.*s %.*s %.*s %.*s %s\n",
    591495                    pVM,
     496                    sizeof(RTGCPHYS) * 4 + 1, "GC Phys Range                    ",
    592497                    sizeof(RTHCPTR) * 2,      "pDevIns         ",
    593                     sizeof(RTHCPTR) * 2,      "In              ",
    594                     sizeof(RTHCPTR) * 2,      "Out             ",
    595                     sizeof(RTHCPTR) * 2,      "pvUser          ");
     498                    sizeof(RTHCPTR) * 2,      "Read            ",
     499                    sizeof(RTHCPTR) * 2,      "Write           ",
     500                    sizeof(RTHCPTR) * 2,      "Fill            ",
     501                    sizeof(RTHCPTR) * 2,      "pvUser          ",
     502                                              "Description");
    596503    IOM_LOCK_SHARED(pVM);
    597     RTAvlroIOPortDoWithAll(&pVM->iom.s.pTreesR3->IOPortTreeR3, true, iomR3IOPortInfoOneR3, (void *)pHlp);
     504    RTAvlroGCPhysDoWithAll(&pVM->iom.s.pTreesR3->MMIOTree, true, iomR3MmioInfoOne, (void *)pHlp);
    598505    IOM_UNLOCK_SHARED(pVM);
    599 
    600     pHlp->pfnPrintf(pHlp,
    601                     "I/O Port R0 ranges (pVM=%p)\n"
    602                     "Range     %.*s %.*s %.*s %.*s Description\n",
    603                     pVM,
    604                     sizeof(RTHCPTR) * 2,      "pDevIns         ",
    605                     sizeof(RTHCPTR) * 2,      "In              ",
    606                     sizeof(RTHCPTR) * 2,      "Out             ",
    607                     sizeof(RTHCPTR) * 2,      "pvUser          ");
    608     IOM_LOCK_SHARED(pVM);
    609     RTAvlroIOPortDoWithAll(&pVM->iom.s.pTreesR3->IOPortTreeR0, true, iomR3IOPortInfoOneR3, (void *)pHlp);
    610     IOM_UNLOCK_SHARED(pVM);
    611 }
    612 
     506}
     507
  • trunk/src/VBox/VMM/include/IOMInternal.h

    r81156 r81162  
    270270
    271271
     272
     273/**
     274 * MMIO lookup table entry.
     275 */
     276typedef struct IOMMMIOLOOKUPENTRY
     277{
     278    /** The first port in the range. */
     279    RTGCPHYS                    GCPhysFirst;
     280    /** The last port in the range (inclusive). */
     281    RTGCPHYS                    GCPhysLast;
     282    /** The registration handle/index.
     283     * @todo bake this into the lower/upper bits of GCPhysFirst & GCPhysLast. */
     284    uint16_t                    idx;
     285    uint16_t                    abPadding[3];
     286} IOMMMIOLOOKUPENTRY;
     287/** Pointer to an MMIO lookup table entry. */
     288typedef IOMMMIOLOOKUPENTRY *PIOMMMIOLOOKUPENTRY;
     289/** Pointer to a const MMIO lookup table entry. */
     290typedef IOMMMIOLOOKUPENTRY const *PCIOMMMIOLOOKUPENTRY;
     291
     292/**
     293 * Ring-0 MMIO handle table entry.
     294 */
     295typedef struct IOMMMIOENTRYR0
     296{
     297    /** The number of bytes covered by this entry, 0 if entry not used. */
     298    RTGCPHYS                            cbRegion;
     299    /** Pointer to user argument. */
     300    RTR0PTR                             pvUser;
     301    /** Pointer to the associated device instance, NULL if entry not used. */
     302    R0PTRTYPE(PPDMDEVINS)               pDevIns;
     303    /** Pointer to the write callback function. */
     304    R0PTRTYPE(PFNIOMMMIONEWWRITE)       pfnWriteCallback;
     305    /** Pointer to the read callback function. */
     306    R0PTRTYPE(PFNIOMMMIONEWREAD)        pfnReadCallback;
     307    /** Pointer to the fill callback function. */
     308    R0PTRTYPE(PFNIOMMMIONEWFILL)        pfnFillCallback;
     309    /** The entry of the first statistics entry, UINT16_MAX if no stats. */
     310    uint16_t                            idxStats;
     311    /** Same as the handle index. */
     312    uint16_t                            idxSelf;
     313    /** IOM_MMIO_F_XXX (copied from ring-3). */
     314    uint32_t                            fFlags;
     315} IOMMMIOENTRYR0;
     316/** Pointer to a ring-0 MMIO handle table entry. */
     317typedef IOMMMIOENTRYR0 *PIOMMMIOENTRYR0;
     318/** Pointer to a const ring-0 MMIO handle table entry. */
     319typedef IOMMMIOENTRYR0 const *PCIOMMMIOENTRYR0;
     320
     321/**
     322 * Ring-3 MMIO handle table entry.
     323 */
     324typedef struct IOMMMIOENTRYR3
     325{
     326    /** The number of bytes covered by this entry. */
     327    RTGCPHYS                            cbRegion;
     328    /** The current mapping address (duplicates lookup table). */
     329    RTGCPHYS                            GCPhysMapping;
     330    /** Pointer to user argument. */
     331    RTR3PTR                             pvUser;
     332    /** Pointer to the associated device instance. */
     333    R3PTRTYPE(PPDMDEVINS)               pDevIns;
     334    /** Pointer to the write callback function. */
     335    R3PTRTYPE(PFNIOMMMIONEWWRITE)       pfnWriteCallback;
     336    /** Pointer to the read callback function. */
     337    R3PTRTYPE(PFNIOMMMIONEWREAD)        pfnReadCallback;
     338    /** Pointer to the fill callback function. */
     339    R3PTRTYPE(PFNIOMMMIONEWFILL)        pfnFillCallback;
     340    /** Description / Name. For easing debugging. */
     341    R3PTRTYPE(const char *)             pszDesc;
     342    /** PCI device the registration is associated with. */
     343    R3PTRTYPE(PPDMPCIDEV)               pPciDev;
     344    /** The PCI device region (high 16-bit word) and subregion (low word),
     345     *  UINT32_MAX if not applicable. */
     346    uint32_t                            iPciRegion;
     347    /** IOM_MMIO_F_XXX */
     348    uint32_t                            fFlags;
     349    /** The entry of the first statistics entry, UINT16_MAX if no stats. */
     350    uint16_t                            idxStats;
     351    /** Set if mapped, clear if not.
     352     * Only updated when critsect is held exclusively.   */
     353    bool                                fMapped;
     354    /** Set if there is an ring-0 entry too. */
     355    bool                                fRing0;
     356    /** Set if there is an raw-mode entry too. */
     357    bool                                fRawMode;
     358    uint8_t                             bPadding;
     359    /** Same as the handle index. */
     360    uint16_t                            idxSelf;
     361} IOMMMIOENTRYR3;
     362AssertCompileSize(IOMMMIOENTRYR3, sizeof(RTGCPHYS) * 2 + 7 * sizeof(RTR3PTR) + 16);
     363/** Pointer to a ring-3 MMIO handle table entry. */
     364typedef IOMMMIOENTRYR3 *PIOMMMIOENTRYR3;
     365/** Pointer to a const ring-3 MMIO handle table entry. */
     366typedef IOMMMIOENTRYR3 const *PCIOMMMIOENTRYR3;
     367
     368/**
     369 * MMIO statistics entry (one MMIO).
     370 */
     371typedef struct IOMMMIOSTATSENTRY
     372{
     373    /** Number of accesses (subtract ReadRZToR3 and WriteRZToR3 to get the right
     374     *  number). */
     375    STAMCOUNTER                 Accesses;
     376
     377    /** Profiling read handler overhead in R3. */
     378    STAMPROFILE                 ProfReadR3;
     379    /** Profiling write handler overhead in R3. */
     380    STAMPROFILE                 ProfWriteR3;
     381    /** Counting and profiling reads in R0/RC. */
     382    STAMPROFILE                 ProfReadRZ;
     383    /** Counting and profiling writes in R0/RC. */
     384    STAMPROFILE                 ProfWriteRZ;
     385
     386    /** Number of reads to this address from R0/RC which was serviced in R3. */
     387    STAMCOUNTER                 ReadRZToR3;
     388    /** Number of writes to this address from R0/RC which was serviced in R3. */
     389    STAMCOUNTER                 WriteRZToR3;
     390} IOMMMIOSTATSENTRY;
     391/** Pointer to MMIO statistics entry. */
     392typedef IOMMMIOSTATSENTRY *PIOMMMIOSTATSENTRY;
     393
     394
     395
    272396/**
    273397 * I/O port range descriptor, R3 version.
     
    537661    /** Number of I/O port registrations. */
    538662    uint32_t                        cIoPortRegs;
    539     /** The size of the paIoPortsRegs allocation (in entries). */
     663    /** The size of the paIoPortRegs allocation (in entries). */
    540664    uint32_t                        cIoPortAlloc;
    541665    /** I/O port registration table for ring-3.
     
    556680    /** Dummy stats entry so we don't need to check for NULL pointers so much. */
    557681    IOMIOPORTSTATSENTRY             IoPortDummyStats;
     682    /** @} */
     683
     684    /** @name MMIO ports
     685     * @note The updating of these variables is done exclusively from EMT(0).
     686     * @{ */
     687    /** Number of MMIO registrations. */
     688    uint32_t                        cMmioRegs;
     689    /** The size of the paMmioRegs allocation (in entries). */
     690    uint32_t                        cMmioAlloc;
     691    /** MMIO registration table for ring-3.
     692     * There is a parallel table in ring-0, IOMR0PERVM::paMmioRegs. */
     693    R3PTRTYPE(PIOMMMIOENTRYR3)      paMmioRegs;
     694    /** Number of entries in the lookup table. */
     695    uint32_t                        cMmioLookupEntries;
     696    uint32_t                        u32Padding2;
     697    /** MMIO lookup table. */
     698    R3PTRTYPE(PIOMMMIOLOOKUPENTRY)  paMmioLookup;
     699
     700    /** The number of valid entries in paioPortStats. */
     701    uint32_t                        cMmioStats;
     702    /** The size of the paMmioStats allocation (in entries). */
     703    uint32_t                        cMmioStatsAllocation;
     704    /** MMIO lookup table.   */
     705    R3PTRTYPE(PIOMMMIOSTATSENTRY)   paMmioStats;
     706    /** Dummy stats entry so we don't need to check for NULL pointers so much. */
     707    IOMMMIOSTATSENTRY               MmioDummyStats;
    558708    /** @} */
    559709
     
    623773    /** The higest ring-0 I/O port registration plus one. */
    624774    uint32_t                        cIoPortMax;
    625     /** The size of the paIoPortsRegs allocation (in entries). */
     775    /** The size of the paIoPortRegs allocation (in entries). */
    626776    uint32_t                        cIoPortAlloc;
    627777    /** I/O port registration table for ring-0.
     
    649799#endif
    650800    /** @} */
     801
     802    /** @name MMIO
     803     * @{ */
     804    /** The higest ring-0 MMIO registration plus one. */
     805    uint32_t                        cMmioMax;
     806    /** The size of the paMmioRegs allocation (in entries). */
     807    uint32_t                        cMmioAlloc;
     808    /** MMIO registration table for ring-0.
     809     * There is a parallel table for ring-3, paMmioRing3Regs. */
     810    R0PTRTYPE(PIOMIOPORTENTRYR0)    paMmioRegs;
     811    /** MMIO lookup table. */
     812    R0PTRTYPE(PIOMIOPORTLOOKUPENTRY) paMmioLookup;
     813    /** MMIO registration table for ring-3.
     814     * Also mapped to ring-3 as IOM::paMmioRegs. */
     815    R0PTRTYPE(PIOMIOPORTENTRYR3)    paMmioRing3Regs;
     816    /** Handle to the allocation backing both the ring-0 and ring-3 registration
     817     * tables as well as the lookup table. */
     818    RTR0MEMOBJ                      hMmioMemObj;
     819    /** Handle to the ring-3 mapping of the lookup and ring-3 registration table. */
     820    RTR0MEMOBJ                      hMmioMapObj;
     821#ifdef VBOX_WITH_STATISTICS
     822    /** The size of the paMmioStats allocation (in entries). */
     823    uint32_t                        cMmioStatsAllocation;
     824    /** MMIO lookup table.   */
     825    R0PTRTYPE(PIOMIOPORTSTATSENTRY) paMmioStats;
     826    /** Handle to the allocation backing the MMIO statistics. */
     827    RTR0MEMOBJ                      hMmioStatsMemObj;
     828    /** Handle to the ring-3 mapping of the MMIO statistics. */
     829    RTR0MEMOBJ                      hMmioStatsMapObj;
     830#endif
     831    /** @} */
     832
    651833} IOMR0PERVM;
    652834
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