Changeset 81156 in vbox for trunk/src/VBox/VMM/VMMR3/IOM.cpp
- Timestamp:
- Oct 8, 2019 2:58:45 PM (5 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/VMM/VMMR3/IOM.cpp
r81136 r81156 138 138 static DECLCALLBACK(int) iomR3RelocateMMIOCallback(PAVLROGCPHYSNODECORE pNode, void *pvUser); 139 139 #endif 140 #ifdef VBOX_WITH_STATISTICS141 static void iomR3IoPortRegStats(PVM pVM, PIOMIOPORTENTRYR3 pRegEntry);142 static void iomR3IoPortDeregStats(PVM pVM, PIOMIOPORTENTRYR3 pRegEntry, unsigned uPort);143 #endif144 static DECLCALLBACK(void) iomR3IOPortInfo(PVM pVM, PCDBGFINFOHLP pHlp, const char *pszArgs);145 140 static DECLCALLBACK(void) iomR3MMIOInfo(PVM pVM, PCDBGFINFOHLP pHlp, const char *pszArgs); 146 141 static FNIOMIOPORTIN iomR3IOPortDummyIn; … … 148 143 static FNIOMIOPORTINSTRING iomR3IOPortDummyInStr; 149 144 static FNIOMIOPORTOUTSTRING iomR3IOPortDummyOutStr; 150 static FNIOMIOPORTNEWIN iomR3IOPortDummyNewIn;151 static FNIOMIOPORTNEWOUT iomR3IOPortDummyNewOut;152 static FNIOMIOPORTNEWINSTRING iomR3IOPortDummyNewInStr;153 static FNIOMIOPORTNEWOUTSTRING iomR3IOPortDummyNewOutStr;154 145 155 146 #ifdef VBOX_WITH_STATISTICS … … 208 199 * Info. 209 200 */ 210 DBGFR3InfoRegisterInternal(pVM, "ioport", "Dumps all IOPort ranges. No arguments.", &iomR3I OPortInfo);201 DBGFR3InfoRegisterInternal(pVM, "ioport", "Dumps all IOPort ranges. No arguments.", &iomR3IoPortInfo); 211 202 DBGFR3InfoRegisterInternal(pVM, "mmio", "Dumps all MMIO ranges. No arguments.", &iomR3MMIOInfo); 212 203 … … 452 443 453 444 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_STATISTICS502 uint16_t const idxStats = UINT16_MAX;503 #else504 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 #endif515 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 else596 {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 else609 {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 else617 {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 else630 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_STATISTICS644 /* Don't register stats here when we're creating the VM as the645 statistics table may still be reallocated. */646 if (pVM->enmVMState >= VMSTATE_CREATED)647 iomR3IoPortRegStats(pVM, pRegEntry);648 #endif649 650 #ifdef VBOX_STRICT651 /*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 #endif666 }667 else668 {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 else718 {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 else728 {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_STATISTICS738 iomR3IoPortDeregStats(pVM, pRegEntry, uPort);739 #endif740 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 else749 {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_STRICT761 /*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 #endif776 }777 else778 {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_STATISTICS788 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 else806 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 do814 {815 size_t cchBaseNm;816 if (uFirstPort < uEndPort - 1)817 cchBaseNm = cchPrefix + RTStrPrintf(&szName[cchPrefix], sizeof(szName) - cchPrefix, "/%04x-", uPort);818 else819 {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 else870 cchPrefix = RTStrPrintf(szPrefix, sizeof(szPrefix), "/IOM/NewPorts/%04x/", uPort);871 STAMR3DeregisterByPrefix(pVM->pUVM, szPrefix);872 }873 874 #endif /* VBOX_WITH_STATISTICS */875 445 #ifdef VBOX_WITH_STATISTICS 876 446 … … 1701 1271 1702 1272 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 01764 * @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 01785 /**1786 * Display a single I/O port GC range.1787 *1788 * @returns 01789 * @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 #endif1808 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 else1840 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 1871 1273 1872 1274 /** … … 2925 2327 #endif /* VBOX_WITH_STATISTICS */ 2926 2328 2329 2330 VMMR3_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 2338 VMMR3_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 2344 VMMR3_INT_DECL(int) IOMR3MmioUnmap(PVM pVM, PPDMDEVINS pDevIns, IOMMMIOHANDLE hRegion) 2345 { 2346 RT_NOREF(pVM, pDevIns, hRegion); 2347 return VERR_NOT_IMPLEMENTED; 2348 } 2349 2350 VMMR3_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.