Changeset 80641 in vbox for trunk/src/VBox/VMM/include/IOMInline.h
- Timestamp:
- Sep 6, 2019 8:09:16 PM (6 years ago)
- svn:sync-xref-src-repo-rev:
- 133172
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/VMM/include/IOMInline.h
r80281 r80641 28 28 * @{ 29 29 */ 30 31 32 /** 33 * Gets the I/O port entry for the specified I/O port in the current context. 34 * 35 * @returns Pointer to I/O port entry. 36 * @returns NULL if no port registered. 37 * 38 * @param pVM The cross context VM structure. 39 * @param Port The I/O port lookup. 40 * @param pidxLastHint Pointer to IOMCPU::idxIoPortLastRead or 41 * IOMCPU::idxIoPortLastWrite. 42 * 43 * @note In ring-0 it is possible to get an uninitialized entry (pDevIns is 44 * NULL, cPorts is 0), in which case there should be ring-3 handlers 45 * for the entry. Use IOMIOPORTENTRYR0::idxSelf to get the ring-3 46 * entry. 47 */ 48 DECLINLINE(CTX_SUFF(PIOMIOPORTENTRY)) iomIoPortGetEntry(PVMCC pVM, RTIOPORT uPort, uint16_t *pidxLastHint) 49 { 50 Assert(IOM_IS_SHARED_LOCK_OWNER(pVM)); 51 52 #ifdef IN_RING0 53 uint32_t iEnd = RT_MIN(pVM->iom.s.cIoPortLookupEntries, pVM->iomr0.s.cIoPortAlloc); 54 PIOMIOPORTLOOKUPENTRY paLookup = pVM->iomr0.s.paIoPortLookup; 55 #else 56 uint32_t iEnd = pVM->iom.s.cIoPortLookupEntries; 57 PIOMIOPORTLOOKUPENTRY paLookup = pVM->iom.s.paIoPortLookup; 58 #endif 59 if (iEnd > 0) 60 { 61 uint32_t iFirst = 0; 62 uint32_t i = *pidxLastHint; 63 if (i < iEnd) 64 { /* likely */ } 65 else 66 i = iEnd / 2; 67 for (;;) 68 { 69 PIOMIOPORTLOOKUPENTRY pCur = &paLookup[i]; 70 if (pCur->uFirstPort > uPort) 71 { 72 if (i > iFirst) 73 iEnd = i; 74 else 75 return NULL; 76 } 77 else if (pCur->uLastPort < uPort) 78 { 79 i += 1; 80 if (i < iEnd) 81 iFirst = i; 82 else 83 return NULL; 84 } 85 else 86 { 87 *pidxLastHint = (uint16_t)i; 88 89 /* 90 * Translate the 'idx' member into a pointer. 91 */ 92 size_t const idx = pCur->idx; 93 #ifdef IN_RING0 94 AssertMsg(idx < pVM->iom.s.cIoPortRegs && idx < pVM->iomr0.s.cIoPortAlloc, 95 ("%#zx vs %#x/%x (port %#x)\n", idx, pVM->iom.s.cIoPortRegs, pVM->iomr0.s.cIoPortMax, uPort)); 96 if (idx < pVM->iomr0.s.cIoPortAlloc) 97 return &pVM->iomr0.s.paIoPortRegs[idx]; 98 #else 99 if (idx < pVM->iom.s.cIoPortRegs) 100 return &pVM->iom.s.paIoPortRegs[idx]; 101 AssertMsgFailed(("%#zx vs %#x (port %#x)\n", idx, pVM->iom.s.cIoPortRegs, uPort)); 102 #endif 103 break; 104 } 105 106 i = iFirst + (iEnd - iFirst) / 2; 107 } 108 } 109 return NULL; 110 } 111 112 113 #ifdef VBOX_WITH_STATISTICS 114 /** 115 * Gets the I/O port statistics entry . 116 * 117 * @returns Pointer to stats. Instead of NULL, a pointer to IoPortDummyStats is 118 * returned, so the caller does not need to check for NULL. 119 * 120 * @param pVM The cross context VM structure. 121 * @param pRegEntry The I/O port entry to get stats for. 122 */ 123 DECLINLINE(PIOMIOPORTSTATSENTRY) iomIoPortGetStats(PVMCC pVM, CTX_SUFF(PIOMIOPORTENTRY) pRegEntry) 124 { 125 size_t idxStats = pRegEntry->idxStats; 126 # ifdef IN_RING0 127 if (idxStats < pVM->iomr0.s.cIoPortStatsAllocation) 128 return &pVM->iomr0.s.paIoPortStats[idxStats]; 129 # else 130 if (idxStats < pVM->iom.s.cIoPortStats) 131 return &pVM->iom.s.paIoPortStats[idxStats]; 132 # endif 133 return &pVM->iom.s.IoPortDummyStats; 134 } 135 #endif 136 30 137 31 138 /**
Note:
See TracChangeset
for help on using the changeset viewer.