Changeset 60716 in vbox
- Timestamp:
- Apr 27, 2016 1:11:46 PM (9 years ago)
- svn:sync-xref-src-repo-rev:
- 106902
- Location:
- trunk
- Files:
-
- 15 edited
Legend:
- Unmodified
- Added
- Removed
-
TabularUnified trunk/include/VBox/err.h ¶
r60622 r60716 2736 2736 2737 2737 2738 /** @name APIC Status Codes 2739 * @{ 2740 */ 2741 /** No pending interrupt. */ 2742 #define VERR_APIC_INTR_NOT_PENDING (-6700) 2743 /** Pending interrupt is masked by TPR. */ 2744 #define VERR_APIC_INTR_MASKED_BY_TPR (-6701) 2745 /** @} */ 2746 2738 2747 /* SED-END */ 2739 2748 -
TabularUnified trunk/include/VBox/vmm/pdmapi.h ¶
r60405 r60716 51 51 VMM_INT_DECL(int) PDMIoApicSendMsi(PVM pVM, RTGCPHYS GCAddr, uint32_t uValue, uint32_t uTagSrc); 52 52 VMM_INT_DECL(bool) PDMHasApic(PVM pVM); 53 VMM_INT_DECL(int) PDMApicHasPendingIrq(PVM pVM, bool *pfPending);54 53 VMMDECL(VBOXSTRICTRC) PDMApicSetBaseMsr(PVMCPU pVCpu, uint64_t u64Base); 55 54 VMMDECL(VBOXSTRICTRC) PDMApicGetBaseMsr(PVMCPU pVCpu, uint64_t *pu64Base, bool fIgnoreErrors); 56 55 VMMDECL(int) PDMApicSetTPR(PVMCPU pVCpu, uint8_t u8TPR); 57 VMMDECL(int) PDMApicGetTPR(PVMCPU pVCpu, uint8_t *pu8TPR, bool *pfPending, uint8_t *pu8PendingI rq);56 VMMDECL(int) PDMApicGetTPR(PVMCPU pVCpu, uint8_t *pu8TPR, bool *pfPending, uint8_t *pu8PendingIntr); 58 57 VMM_INT_DECL(VBOXSTRICTRC) PDMApicWriteMsr(PVMCPU pVCpu, uint32_t u32Reg, uint64_t u64Value); 59 58 VMM_INT_DECL(VBOXSTRICTRC) PDMApicReadMsr(PVMCPU pVCpu, uint32_t u32Reg, uint64_t *pu64Value); -
TabularUnified trunk/include/VBox/vmm/pdmdev.h ¶
r60406 r60716 1154 1154 * Get a pending interrupt. 1155 1155 * 1156 * @returns Pending interrupt number, -1 if no interrupt is 1157 * pending. 1156 * @returns VBox status code. 1158 1157 * @param pDevIns Device instance of the APIC. 1159 1158 * @param pVCpu The cross context virtual CPU structure. 1160 * @param puTagSrc Where to return the tag source (tracing purposes). 1161 * @remarks Caller enters the PDM critical section 1162 */ 1163 DECLR3CALLBACKMEMBER(int, pfnGetInterruptR3,(PPDMDEVINS pDevIns, PVMCPU pVCpu, uint32_t *puTagSrc)); 1164 1165 /** 1166 * Check if the APIC has a pending interrupt/if a TPR change would activate one. 1167 * 1168 * @returns true if an interrupt is pending, false otherwise. 1169 * @param pDevIns Device instance of the APIC. 1170 * @param pVCpu The cross context virtual CPU structure. 1171 * @param pu8PendingIrq Where to store the highest priority pending IRQ 1172 * (optional, can be NULL). 1173 * @remarks Unlike the other callbacks, the PDM lock may not always be entered 1174 * prior to calling this method. 1175 */ 1176 DECLR3CALLBACKMEMBER(bool, pfnHasPendingIrqR3,(PPDMDEVINS pDevIns, PVMCPU pVCpu, uint8_t *pu8PendingIrq)); 1159 * @param pu8Vector Where to store the vector. 1160 * @param pu32TagSrc Where to return the tag source (tracing 1161 * purposes). 1162 * @remarks Caller enters the PDM critical section. 1163 */ 1164 DECLR3CALLBACKMEMBER(int, pfnGetInterruptR3,(PPDMDEVINS pDevIns, PVMCPU pVCpu, uint8_t *pu8Vector, uint32_t *pu32TagSrc)); 1177 1165 1178 1166 /** … … 1213 1201 * @param pDevIns Device instance of the APIC. 1214 1202 * @param pVCpu The cross context virtual CPU structure. 1203 * @param pfPending Where to store if there is an interrupt pending 1204 * (optional, can be NULL). 1205 * @param pu8PendingIntr Where to store the pending interrupt vector 1206 * (optional, can be NULL). 1215 1207 * @remarks Caller enters the PDM critical section. 1216 1208 */ 1217 DECLR3CALLBACKMEMBER(uint8_t, pfnGetTprR3,(PPDMDEVINS pDevIns, PVMCPU pVCpu ));1209 DECLR3CALLBACKMEMBER(uint8_t, pfnGetTprR3,(PPDMDEVINS pDevIns, PVMCPU pVCpu, bool *pfPending, uint8_t *pu8PendingIntr)); 1218 1210 1219 1211 /** … … 1296 1288 /** The name of the RC GetInterrupt entry point. */ 1297 1289 const char *pszGetInterruptRC; 1298 /** The name of the RC HasPendingIrq entry point. */1299 const char *pszHasPendingIrqRC;1300 1290 /** The name of the RC SetBaseMsr entry point. */ 1301 1291 const char *pszSetBaseMsrRC; … … 1319 1309 /** The name of the R0 GetInterrupt entry point. */ 1320 1310 const char *pszGetInterruptR0; 1321 /** The name of the R0 HasPendingIrq entry point. */1322 const char *pszHasPendingIrqR0;1323 1311 /** The name of the R0 SetBaseMsr entry point. */ 1324 1312 const char *pszSetBaseMsrR0; … … 1344 1332 1345 1333 /** Current PDMAPICREG version number. */ 1346 #define PDM_APICREG_VERSION PDM_VERSION_MAKE(0xfff6, 3, 0)1334 #define PDM_APICREG_VERSION PDM_VERSION_MAKE(0xfff6, 4, 0) 1347 1335 1348 1336 -
TabularUnified trunk/src/VBox/Devices/PC/DevAPIC.cpp ¶
r60695 r60716 520 520 } 521 521 } 522 523 524 static int apic_get_ppr_zero_tpr(APICState *pApic) 525 { 526 return Apic256BitReg_FindLastSetBit(&pApic->isr, 0); 527 } 528 529 530 /* Check if the APIC has a pending interrupt/if a TPR change would active one. */ 531 static bool apicHasPendingIntr(PPDMDEVINS pDevIns, PVMCPU pVCpu, uint8_t *pu8PendingIrq) 532 { 533 APICDeviceInfo *pDev = PDMINS_2_DATA(pDevIns, APICDeviceInfo *); 534 if (!pDev) 535 return false; 536 537 /* We don't perform any locking here as that would cause a lot of contention for VT-x/AMD-V. */ 538 539 APICState *pApic = apicGetStateById(pDev, pVCpu->idCpu); 540 541 /* 542 * All our callbacks now come from single IOAPIC, thus locking 543 * seems to be excessive now 544 */ 545 /** @todo check excessive locking whatever... */ 546 int irrv = Apic256BitReg_FindLastSetBit(&pApic->irr, -1); 547 if (irrv < 0) 548 return false; 549 550 int isrv = apic_get_ppr_zero_tpr(pApic); 551 552 if (isrv && (irrv & 0xf0) <= (isrv & 0xf0)) 553 return false; 554 555 if (pu8PendingIrq) 556 { 557 Assert(irrv >= 0 && irrv <= (int)UINT8_MAX); 558 *pu8PendingIrq = (uint8_t)irrv; 559 } 560 return true; 561 } 562 522 563 523 564 static int apic_bus_deliver(APICDeviceInfo *pDev, … … 653 694 } 654 695 655 PDMBOTHCBDECL(uint8_t) apicGetTPR(PPDMDEVINS pDevIns, PVMCPU pVCpu )696 PDMBOTHCBDECL(uint8_t) apicGetTPR(PPDMDEVINS pDevIns, PVMCPU pVCpu, bool *pfPending, uint8_t *pu8PendingIntr) 656 697 { 657 698 /* We don't perform any locking here as that would cause a lot of contention for VT-x/AMD-V. */ … … 659 700 APICState *pApic = apicGetStateById(pDev, pVCpu->idCpu); 660 701 Log2(("apicGetTPR: returns %#x\n", pApic->tpr)); 702 703 if (pfPending) 704 *pfPending = apicHasPendingIntr(pDevIns, pVCpu, pu8PendingIntr); 661 705 return pApic->tpr; 662 706 } … … 1203 1247 } 1204 1248 1205 static int apic_get_ppr_zero_tpr(APICState *pApic)1206 {1207 return Apic256BitReg_FindLastSetBit(&pApic->isr, 0);1208 }1209 1210 1249 static int apic_get_arb_pri(APICState const *pApic) 1211 1250 { … … 1231 1270 return false; 1232 1271 apicCpuSetInterrupt(pDev, pApic); 1233 return true;1234 }1235 1236 /* Check if the APIC has a pending interrupt/if a TPR change would active one. */1237 PDMBOTHCBDECL(bool) apicHasPendingIrq(PPDMDEVINS pDevIns, PVMCPU pVCpu, uint8_t *pu8PendingIrq)1238 {1239 APICDeviceInfo *pDev = PDMINS_2_DATA(pDevIns, APICDeviceInfo *);1240 if (!pDev)1241 return false;1242 1243 /* We don't perform any locking here as that would cause a lot of contention for VT-x/AMD-V. */1244 1245 APICState *pApic = apicGetStateById(pDev, pVCpu->idCpu);1246 1247 /*1248 * All our callbacks now come from single IOAPIC, thus locking1249 * seems to be excessive now1250 */1251 /** @todo check excessive locking whatever... */1252 int irrv = Apic256BitReg_FindLastSetBit(&pApic->irr, -1);1253 if (irrv < 0)1254 return false;1255 1256 int ppr = apic_get_ppr_zero_tpr(pApic);1257 1258 if (ppr && (irrv & 0xf0) <= (ppr & 0xf0))1259 return false;1260 1261 if (pu8PendingIrq)1262 {1263 Assert(irrv >= 0 && irrv <= (int)UINT8_MAX);1264 *pu8PendingIrq = (uint8_t)irrv;1265 }1266 1272 return true; 1267 1273 } … … 1450 1456 1451 1457 1452 PDMBOTHCBDECL(int) apicGetInterrupt(PPDMDEVINS pDevIns, PVMCPU pVCpu, uint 32_t *puTagSrc)1458 PDMBOTHCBDECL(int) apicGetInterrupt(PPDMDEVINS pDevIns, PVMCPU pVCpu, uint8_t *pu8Vector, uint32_t *pu32TagSrc) 1453 1459 { 1454 1460 APICDeviceInfo *pDev = PDMINS_2_DATA(pDevIns, APICDeviceInfo *); … … 1457 1463 { 1458 1464 Log(("apic_get_interrupt: returns -1 (!pDev)\n")); 1459 return -1;1465 return VERR_APIC_INTR_NOT_PENDING; 1460 1466 } 1461 1467 … … 1467 1473 { 1468 1474 Log(("CPU%d: apic_get_interrupt: returns -1 (APIC_SV_ENABLE)\n", pApic->phys_id)); 1469 return -1;1475 return VERR_APIC_INTR_NOT_PENDING; 1470 1476 } 1471 1477 … … 1475 1481 { 1476 1482 Log(("CPU%d: apic_get_interrupt: returns -1 (irr)\n", pApic->phys_id)); 1477 return -1;1483 return VERR_APIC_INTR_NOT_PENDING; 1478 1484 } 1479 1485 1480 1486 if (pApic->tpr && (uint32_t)intno <= pApic->tpr) 1481 1487 { 1482 *puTagSrc = 0; 1483 Log(("apic_get_interrupt: returns %d (sp)\n", pApic->spurious_vec & 0xff)); 1484 return pApic->spurious_vec & 0xff; 1488 *pu32TagSrc = 0; 1489 *pu8Vector = pApic->spurious_vec & 0xff; 1490 Log(("apic_get_interrupt: returns %d (sp)\n", *pu8Vector)); 1491 return VINF_SUCCESS; 1485 1492 } 1486 1493 … … 1488 1495 Apic256BitReg_SetBit(&pApic->isr, intno); 1489 1496 1490 *pu TagSrc = pApic->auTags[intno];1497 *pu32TagSrc = pApic->auTags[intno]; 1491 1498 pApic->auTags[intno] = 0; 1492 1499 1493 1500 apic_update_irq(pDev, pApic); 1494 1501 1495 LogFlow(("CPU%d: apic_get_interrupt: returns %d / %#x\n", pApic->phys_id, intno, *puTagSrc)); 1496 return intno; 1502 LogFlow(("CPU%d: apic_get_interrupt: returns %d / %#x\n", pApic->phys_id, intno, *pu32TagSrc)); 1503 *pu8Vector = (uint8_t)intno; 1504 return VINF_SUCCESS; 1497 1505 } 1498 1506 … … 2409 2417 ApicReg.u32Version = PDM_APICREG_VERSION; 2410 2418 ApicReg.pfnGetInterruptR3 = apicGetInterrupt; 2411 ApicReg.pfnHasPendingIrqR3 = apicHasPendingIrq;2412 2419 ApicReg.pfnSetBaseMsrR3 = apicSetBase; 2413 2420 ApicReg.pfnGetBaseMsrR3 = apicGetBase; … … 2422 2429 { 2423 2430 ApicReg.pszGetInterruptRC = "apicGetInterrupt"; 2424 ApicReg.pszHasPendingIrqRC = "apicHasPendingIrq";2425 2431 ApicReg.pszSetBaseMsrRC = "apicSetBase"; 2426 2432 ApicReg.pszGetBaseMsrRC = "apicGetBase"; … … 2434 2440 2435 2441 ApicReg.pszGetInterruptR0 = "apicGetInterrupt"; 2436 ApicReg.pszHasPendingIrqR0 = "apicHasPendingIrq";2437 2442 ApicReg.pszSetBaseMsrR0 = "apicSetBase"; 2438 2443 ApicReg.pszGetBaseMsrR0 = "apicGetBase"; … … 2448 2453 { 2449 2454 ApicReg.pszGetInterruptRC = NULL; 2450 ApicReg.pszHasPendingIrqRC = NULL;2451 2455 ApicReg.pszSetBaseMsrRC = NULL; 2452 2456 ApicReg.pszGetBaseMsrRC = NULL; … … 2460 2464 2461 2465 ApicReg.pszGetInterruptR0 = NULL; 2462 ApicReg.pszHasPendingIrqR0 = NULL;2463 2466 ApicReg.pszSetBaseMsrR0 = NULL; 2464 2467 ApicReg.pszGetBaseMsrR0 = NULL; -
TabularUnified trunk/src/VBox/VMM/VMMAll/APICAll.cpp ¶
r60707 r60716 429 429 } 430 430 return rcNotFound; 431 }432 433 434 /**435 * Gets the highest priority pending interrupt.436 *437 * @returns true if any interrupt is pending, false otherwise.438 * @param pVCpu The cross context virtual CPU structure.439 * @param pu8PendingIntr Where to store the interrupt vector if the440 * interrupt is pending, optional can be NULL.441 */442 static bool apicGetHighestPendingInterrupt(PVMCPU pVCpu, uint8_t *pu8PendingIntr)443 {444 PCXAPICPAGE pXApicPage = VMCPU_TO_CXAPICPAGE(pVCpu);445 int const irrv = apicGetLastSetBit(&pXApicPage->irr, -1);446 if (irrv >= 0)447 {448 Assert(irrv <= (int)UINT8_MAX);449 if (pu8PendingIntr)450 *pu8PendingIntr = (uint8_t)irrv;451 return true;452 }453 return false;454 431 } 455 432 … … 2112 2089 2113 2090 /** 2091 * Gets the highest priority pending interrupt. 2092 * 2093 * @returns true if any interrupt is pending, false otherwise. 2094 * @param pVCpu The cross context virtual CPU structure. 2095 * @param pu8PendingIntr Where to store the interrupt vector if the 2096 * interrupt is pending (optional, can be NULL). 2097 */ 2098 static bool apicGetHighestPendingInterrupt(PVMCPU pVCpu, uint8_t *pu8PendingIntr) 2099 { 2100 PCXAPICPAGE pXApicPage = VMCPU_TO_CXAPICPAGE(pVCpu); 2101 int const irrv = apicGetLastSetBit(&pXApicPage->irr, -1); 2102 if (irrv >= 0) 2103 { 2104 Assert(irrv <= (int)UINT8_MAX); 2105 if (pu8PendingIntr) 2106 *pu8PendingIntr = (uint8_t)irrv; 2107 return true; 2108 } 2109 return false; 2110 } 2111 2112 2113 /** 2114 2114 * @interface_method_impl{PDMAPICREG,pfnGetTprR3} 2115 2115 */ 2116 VMMDECL(uint8_t) APICGetTpr(PPDMDEVINS pDevIns, PVMCPU pVCpu )2116 VMMDECL(uint8_t) APICGetTpr(PPDMDEVINS pDevIns, PVMCPU pVCpu, bool *pfPending, uint8_t *pu8PendingIntr) 2117 2117 { 2118 2118 VMCPU_ASSERT_EMT(pVCpu); 2119 2119 PCXAPICPAGE pXApicPage = VMCPU_TO_CXAPICPAGE(pVCpu); 2120 2121 if (pfPending) 2122 { 2123 /* 2124 * Just return whatever the highest pending interrupt is in the IRR. 2125 * The caller is responsible for figuring out if it's masked by the TPR etc. 2126 */ 2127 *pfPending = apicGetHighestPendingInterrupt(pVCpu, pu8PendingIntr); 2128 } 2129 2120 2130 return pXApicPage->tpr.u8Tpr; 2121 2131 } … … 2282 2292 2283 2293 /** 2284 * @interface_method_impl{PDMAPICREG,pfnHasPendingIrqR3}2285 */2286 VMMDECL(bool) APICHasPendingIrq(PPDMDEVINS pDevIns, PVMCPU pVCpu, uint8_t *pu8PendingIrq)2287 {2288 return apicGetHighestPendingInterrupt(pVCpu, pu8PendingIrq);2289 }2290 2291 2292 /**2293 2294 * @interface_method_impl{PDMAPICREG,pfnGetInterruptR3} 2294 2295 */ 2295 VMMDECL(int) APICGetInterrupt(PPDMDEVINS pDevIns, PVMCPU pVCpu, uint32_t *puTagSrc) 2296 { 2297 VMCPU_ASSERT_EMT(pVCpu); 2296 VMMDECL(int) APICGetInterrupt(PPDMDEVINS pDevIns, PVMCPU pVCpu, uint8_t *pu8Vector, uint32_t *pu32TagSrc) 2297 { 2298 VMCPU_ASSERT_EMT(pVCpu); 2299 Assert(pu8Vector); 2300 NOREF(pu32TagSrc); 2298 2301 2299 2302 LogFlow(("APIC%u: APICGetInterrupt\n", pVCpu->idCpu)); … … 2306 2309 APICUpdatePendingInterrupts(pVCpu); 2307 2310 int const irrv = apicGetLastSetBit(&pXApicPage->irr, -1); 2308 if ( irrv >= 0)2311 if (RT_LIKELY(irrv >= 0)) 2309 2312 { 2310 2313 Assert(irrv <= (int)UINT8_MAX); … … 2316 2319 */ 2317 2320 uint8_t const uTpr = pXApicPage->tpr.u8Tpr; 2318 if (uTpr > 0 && uVector <= uTpr)2319 { 2320 Log2(("APIC%u: APICGetInterrupt: Spurious interrupt. uVector=%#x uTpr=%#x SpuriousVector=%#x\n", pVCpu->idCpu,2321 if (uTpr > 0 && XAPIC_TPR_GET_TP(uVector) <= XAPIC_TPR_GET_TP(uTpr)) 2322 { 2323 Log2(("APIC%u: APICGetInterrupt: Interrupt masked. uVector=%#x uTpr=%#x SpuriousVector=%#x\n", pVCpu->idCpu, 2321 2324 uVector, uTpr, pXApicPage->svr.u.u8SpuriousVector)); 2322 return pXApicPage->svr.u.u8SpuriousVector; 2323 } 2324 2325 *pu8Vector = uVector; 2326 return VERR_APIC_INTR_MASKED_BY_TPR; 2327 } 2328 2329 /* 2330 * The PPR should be up-to-date at this point and we're on EMT (so no parallel updates). 2331 * Subject the pending vector to PPR prioritization. 2332 */ 2325 2333 uint8_t const uPpr = pXApicPage->ppr.u8Ppr; 2326 2334 if ( !uPpr 2327 || 2335 || XAPIC_PPR_GET_PP(uVector) > XAPIC_PPR_GET_PP(uPpr)) 2328 2336 { 2329 2337 apicClearVectorInReg(&pXApicPage->irr, uVector); … … 2333 2341 2334 2342 Log2(("APIC%u: APICGetInterrupt: Valid Interrupt. uVector=%#x\n", pVCpu->idCpu, uVector)); 2335 return uVector; 2343 *pu8Vector = uVector; 2344 return VINF_SUCCESS; 2336 2345 } 2337 2346 else 2338 Log2(("APIC%u: APICGetInterrupt: Interrupt's priority is not higher than the PPR uVector=%#x PPR=%#x\n",2347 Log2(("APIC%u: APICGetInterrupt: Interrupt's priority is not higher than the PPR. uVector=%#x PPR=%#x\n", 2339 2348 pVCpu->idCpu, uVector, uPpr)); 2340 2349 } … … 2345 2354 Log2(("APIC%u: APICGetInterrupt: APIC %s disabled\n", pVCpu->idCpu, !fApicHwEnabled ? "hardware" : "software")); 2346 2355 2347 return -1;2356 return VERR_APIC_INTR_NOT_PENDING; 2348 2357 } 2349 2358 -
TabularUnified trunk/src/VBox/VMM/VMMAll/PDMAll.cpp ¶
r60573 r60716 40 40 * 41 41 * @returns VBox status code. 42 * @retval VINF_SUCCESS on success. 43 * @retval VERR_APIC_INTR_MASKED_BY_TPR when an APIC interrupt is pending but 44 * can't be delivered due to TPR priority. 45 * @retval VERR_NO_DATA if there is no interrupt to be delivered (either APIC 46 * has been software-disabled since it flagged something was pending, 47 * or other reasons). 48 * 42 49 * @param pVCpu The cross context virtual CPU structure. 43 50 * @param pu8Interrupt Where to store the interrupt on success. … … 60 67 Assert(pVM->pdm.s.Apic.CTX_SUFF(pfnGetInterrupt)); 61 68 uint32_t uTagSrc; 62 int i = pVM->pdm.s.Apic.CTX_SUFF(pfnGetInterrupt)(pVM->pdm.s.Apic.CTX_SUFF(pDevIns), pVCpu, &uTagSrc); 63 #ifndef VBOX_WITH_NEW_APIC 64 AssertMsg(i <= 255 && i >= 0, ("i=%d\n", i)); 65 #endif 66 if (i >= 0) 69 uint8_t uVector; 70 int rc = pVM->pdm.s.Apic.CTX_SUFF(pfnGetInterrupt)(pVM->pdm.s.Apic.CTX_SUFF(pDevIns), pVCpu, &uVector, &uTagSrc); 71 if ( rc == VINF_SUCCESS 72 || rc == VERR_APIC_INTR_MASKED_BY_TPR) 67 73 { 68 74 #ifndef VBOX_WITH_NEW_APIC 69 75 pdmUnlock(pVM); 70 76 #endif 71 *pu8Interrupt = (uint8_t)i; 72 VBOXVMM_PDM_IRQ_GET(pVCpu, RT_LOWORD(uTagSrc), RT_HIWORD(uTagSrc), i); 73 return VINF_SUCCESS; 77 *pu8Interrupt = uVector; 78 if (rc == VINF_SUCCESS) 79 VBOXVMM_PDM_IRQ_GET(pVCpu, RT_LOWORD(uTagSrc), RT_HIWORD(uTagSrc), uVector); 80 return rc; 74 81 } 75 82 } … … 99 106 } 100 107 101 /** @todo Figure out exactly why we can get here without anything being set. (REM) */ 108 /* 109 * One scenario where we may possibly get here is if the APIC signalled a pending interrupt, 110 * got an APIC MMIO/MSR VM-exit which disabled the APIC. We could, in theory, clear the APIC 111 * force-flag from all the places which disables the APIC but letting PDMGetInterrupt() fail 112 * without returning a valid interrupt still needs to be handled for the TPR masked case, 113 * so we shall just handle it here regardless if we choose to update the APIC code in the future. 114 */ 102 115 103 116 pdmUnlock(pVM); … … 313 326 314 327 /** 315 * Check if the APIC has a pending interrupt/if a TPR change would active one.316 * 317 * @returns V INF_SUCCESS or VERR_PDM_NO_APIC_INSTANCE.318 * @param pVCpu The cross context virtual CPU structure.319 * @param pfPending Pending state (out).320 */ 321 VMM _INT_DECL(int) PDMApicHasPendingIrq(PVMCPU pVCpu, bool *pfPending)328 * Set the TPR (Task Priority Register). 329 * 330 * @returns VBox status code. 331 * @param pVCpu The cross context virtual CPU structure. 332 * @param u8TPR The new TPR. 333 */ 334 VMMDECL(int) PDMApicSetTPR(PVMCPU pVCpu, uint8_t u8TPR) 322 335 { 323 336 PVM pVM = pVCpu->CTX_SUFF(pVM); 324 337 if (pVM->pdm.s.Apic.CTX_SUFF(pDevIns)) 325 338 { 326 Assert(pVM->pdm.s.Apic.CTX_SUFF(pfnHasPendingIrq));327 pdmLock(pVM);328 *pfPending = pVM->pdm.s.Apic.CTX_SUFF(pfnHasPendingIrq)(pVM->pdm.s.Apic.CTX_SUFF(pDevIns), pVCpu, NULL /*pu8PendingIrq*/);329 pdmUnlock(pVM);330 return VINF_SUCCESS;331 }332 return VERR_PDM_NO_APIC_INSTANCE;333 }334 335 336 /**337 * Set the TPR (task priority register).338 *339 * @returns VBox status code.340 * @param pVCpu The cross context virtual CPU structure.341 * @param u8TPR The new TPR.342 */343 VMMDECL(int) PDMApicSetTPR(PVMCPU pVCpu, uint8_t u8TPR)344 {345 PVM pVM = pVCpu->CTX_SUFF(pVM);346 if (pVM->pdm.s.Apic.CTX_SUFF(pDevIns))347 {348 339 Assert(pVM->pdm.s.Apic.CTX_SUFF(pfnSetTpr)); 340 #ifdef VBOX_WITH_NEW_APIC 341 pVM->pdm.s.Apic.CTX_SUFF(pfnSetTpr)(pVM->pdm.s.Apic.CTX_SUFF(pDevIns), pVCpu, u8TPR); 342 #else 349 343 pdmLock(pVM); 350 344 pVM->pdm.s.Apic.CTX_SUFF(pfnSetTpr)(pVM->pdm.s.Apic.CTX_SUFF(pDevIns), pVCpu, u8TPR); 351 345 pdmUnlock(pVM); 346 #endif 352 347 return VINF_SUCCESS; 353 348 } … … 357 352 358 353 /** 359 * Get the TPR ( task priority register).354 * Get the TPR (Task Priority Register). 360 355 * 361 356 * @returns VINF_SUCCESS or VERR_PDM_NO_APIC_INSTANCE. 362 357 * @param pVCpu The cross context virtual CPU structure. 363 358 * @param pu8TPR Where to store the TRP. 364 * @param pfPending Pending interrupt state (out, optional). 365 * @param pu8PendingIrq Where to store the highest-priority pending IRQ 359 * @param pfPending Where to store whether there is a pending interrupt 366 360 * (out, optional). 361 * @param pu8PendingIntr Where to store the highest-priority pending 362 * interrupt (out, optional). 367 363 * 368 364 * @remarks No-long-jump zone!!! 369 365 */ 370 VMMDECL(int) PDMApicGetTPR(PVMCPU pVCpu, uint8_t *pu8TPR, bool *pfPending, uint8_t *pu8PendingI rq)366 VMMDECL(int) PDMApicGetTPR(PVMCPU pVCpu, uint8_t *pu8TPR, bool *pfPending, uint8_t *pu8PendingIntr) 371 367 { 372 368 PVM pVM = pVCpu->CTX_SUFF(pVM); … … 380 376 */ 381 377 Assert(pVM->pdm.s.Apic.CTX_SUFF(pfnGetTpr)); 382 *pu8TPR = pVM->pdm.s.Apic.CTX_SUFF(pfnGetTpr)(pApicIns, pVCpu); 383 if (pfPending) 384 *pfPending = pVM->pdm.s.Apic.CTX_SUFF(pfnHasPendingIrq)(pApicIns, pVCpu, pu8PendingIrq); 378 *pu8TPR = pVM->pdm.s.Apic.CTX_SUFF(pfnGetTpr)(pApicIns, pVCpu, pfPending, pu8PendingIntr); 385 379 return VINF_SUCCESS; 386 380 } -
TabularUnified trunk/src/VBox/VMM/VMMR0/HMSVMR0.cpp ¶
r60574 r60716 2670 2670 uint8_t u8Interrupt; 2671 2671 int rc = PDMGetInterrupt(pVCpu, &u8Interrupt); 2672 if ( RT_SUCCESS(rc))2672 if (rc == VINF_SUCCESS) 2673 2673 { 2674 2674 Log4(("Injecting external interrupt u8Interrupt=%#x\n", u8Interrupt)); … … 2680 2680 hmR0SvmSetPendingEvent(pVCpu, &Event, 0 /* GCPtrFaultAddress */); 2681 2681 } 2682 else if (rc == VERR_APIC_INTR_MASKED_BY_TPR) 2683 { 2684 /* 2685 * AMD-V has no TPR thresholding feature. We just avoid posting the interrupt. 2686 * We just avoid delivering the TPR-masked interrupt here. TPR will be updated 2687 * always via hmR0SvmLoadGuestState() -> hmR0SvmLoadGuestApicState(). 2688 */ 2689 Assert(!VMCPU_FF_IS_PENDING(pVCpu, (VMCPU_FF_INTERRUPT_APIC))); 2690 } 2682 2691 else 2683 2692 { 2684 /* This can happen with the new APIC code. */2685 #ifndef VBOX_WITH_NEW_APIC2686 2693 Assert(!VMCPU_FF_IS_PENDING(pVCpu, (VMCPU_FF_INTERRUPT_APIC | VMCPU_FF_INTERRUPT_PIC))); 2687 #endif2688 2694 STAM_COUNTER_INC(&pVCpu->hm.s.StatSwitchGuestIrq); 2689 2695 } -
TabularUnified trunk/src/VBox/VMM/VMMR0/HMVMXR0.cpp ¶
r60573 r60716 3343 3343 3344 3344 /** 3345 * Sets the TPR threshold in the VMCS. 3346 * 3347 * @returns VBox status code. 3348 * @param pVCpu The cross context virtual CPU structure. 3349 * @param u32TprThreshold The TPR threshold (task-priority class only). 3350 */ 3351 DECLINLINE(int) hmR0VmxApicSetTprThreshold(PVMCPU pVCpu, uint32_t u32TprThreshold) 3352 { 3353 Assert(!(u32TprThreshold & 0xfffffff0)); /* Bits 31:4 MBZ. */ 3354 Assert(pVCpu->hm.s.vmx.u32ProcCtls & VMX_VMCS_CTRL_PROC_EXEC_USE_TPR_SHADOW); 3355 return VMXWriteVmcs32(VMX_VMCS32_CTRL_TPR_THRESHOLD, u32TprThreshold); 3356 } 3357 3358 3359 /** 3345 3360 * Loads the guest APIC and related state. 3346 3361 * … … 3387 3402 u32TprThreshold = u8TprPriority; /* Required for Vista 64-bit guest, see @bugref{6398}. */ 3388 3403 } 3389 Assert(!(u32TprThreshold & 0xfffffff0)); /* Bits 31:4 MBZ. */ 3390 3391 rc = VMXWriteVmcs32(VMX_VMCS32_CTRL_TPR_THRESHOLD, u32TprThreshold); 3404 3405 rc = hmR0VmxApicSetTprThreshold(pVCpu, u32TprThreshold); 3392 3406 AssertRCReturn(rc, rc); 3393 3407 } … … 7434 7448 uint8_t u8Interrupt; 7435 7449 rc = PDMGetInterrupt(pVCpu, &u8Interrupt); 7436 if ( RT_SUCCESS(rc))7450 if (rc == VINF_SUCCESS) 7437 7451 { 7438 7452 Log4(("Pending interrupt vcpu[%RU32] u8Interrupt=%#x \n", pVCpu->idCpu, u8Interrupt)); … … 7442 7456 hmR0VmxSetPendingEvent(pVCpu, u32IntInfo, 0 /* cbInstr */, 0 /* u32ErrCode */, 0 /* GCPtrfaultAddress */); 7443 7457 } 7458 else if (rc == VERR_APIC_INTR_MASKED_BY_TPR) 7459 { 7460 Assert(!VMCPU_FF_IS_PENDING(pVCpu, (VMCPU_FF_INTERRUPT_APIC))); 7461 if (pVCpu->hm.s.vmx.u32ProcCtls & VMX_VMCS_CTRL_PROC_EXEC_USE_TPR_SHADOW) 7462 hmR0VmxApicSetTprThreshold(pVCpu, u8Interrupt >> 4); 7463 } 7444 7464 else 7445 7465 { 7446 /* This can happen with the new APIC code. */7447 #ifndef VBOX_WITH_NEW_APIC7448 7466 Assert(!VMCPU_FF_IS_PENDING(pVCpu, (VMCPU_FF_INTERRUPT_APIC | VMCPU_FF_INTERRUPT_PIC))); 7449 #endif7450 7467 STAM_COUNTER_INC(&pVCpu->hm.s.StatSwitchGuestIrq); 7451 7468 } -
TabularUnified trunk/src/VBox/VMM/VMMR3/APIC.cpp ¶
r60695 r60716 815 815 AssertRCReturn(rc, rc); 816 816 pApicCpu->uApicBaseMsr = uApicBaseLo; 817 Log2(("APIC%u: apicR3LoadLegacyVCpuData: uApicBaseMsr=%#RX64\n", pVCpu->idCpu, pApicCpu->uApicBaseMsr)); 817 818 818 819 switch (uVersion) 819 820 { 820 case APIC_SAVED_STATE_VERSION_ANCIENT:821 {822 uint8_t uPhysApicId;823 SSMR3GetU8(pSSM, &pXApicPage->id.u8ApicId);824 SSMR3GetU8(pSSM, &uPhysApicId); NOREF(uPhysApicId); /* PhysId == pVCpu->idCpu */825 break;826 }827 828 821 case APIC_SAVED_STATE_VERSION_VBOX_50: 829 822 case APIC_SAVED_STATE_VERSION_VBOX_30: … … 833 826 SSMR3GetU32(pSSM, &uPhysApicId); NOREF(uPhysApicId); /* PhysId == pVCpu->idCpu */ 834 827 SSMR3GetU32(pSSM, &uArbId); NOREF(uArbId); /* ArbID is & was unused. */ 828 break; 829 } 830 831 case APIC_SAVED_STATE_VERSION_ANCIENT: 832 { 833 uint8_t uPhysApicId; 834 SSMR3GetU8(pSSM, &pXApicPage->id.u8ApicId); 835 SSMR3GetU8(pSSM, &uPhysApicId); NOREF(uPhysApicId); /* PhysId == pVCpu->idCpu */ 835 836 break; 836 837 } … … 1160 1161 pApicDev->pCritSectRC = pApicDev->pApicHlpR3->pfnGetRCCritSect(pDevIns); 1161 1162 1162 pApic->pApicDevRC = PDMINS_2_DATA_RCPTR(pDevIns); 1163 if (pApic->pvApicPibRC != NIL_RTRCPTR) 1164 pApic->pvApicPibRC = MMHyperR3ToRC(pVM, (RTR3PTR)pApic->pvApicPibR3); 1163 pApic->pApicDevRC = PDMINS_2_DATA_RCPTR(pDevIns); 1164 pApic->pvApicPibRC += offDelta; 1165 1165 1166 1166 for (VMCPUID idCpu = 0; idCpu < pVM->cCpus; idCpu++) … … 1170 1170 pApicCpu->pTimerRC = TMTimerRCPtr(pApicCpu->pTimerR3); 1171 1171 1172 if (pApicCpu->pvApicPageRC != NIL_RTRCPTR) 1173 pApicCpu->pvApicPageRC = MMHyperR3ToRC(pVM, (RTR3PTR)pApicCpu->pvApicPageR3); 1174 if (pApicCpu->pvApicPibRC != NIL_RTRCPTR) 1175 pApicCpu->pvApicPibRC = MMHyperR3ToRC(pVM, (RTR3PTR)pApicCpu->pvApicPibR3); 1172 pApicCpu->pvApicPageRC += offDelta; 1173 pApicCpu->pvApicPibRC += offDelta; 1174 Log2(("APIC%u: apicR3Relocate: APIC PIB at %RGv\n", pVCpu->idCpu, pApicCpu->pvApicPibRC)); 1176 1175 } 1177 1176 } … … 1339 1338 pApicCpu->pvApicPibR3 = (RTR3PTR)((RTR3UINTPTR)pApic->pvApicPibR3 + offApicPib); 1340 1339 if (fNeedsGCMapping) 1341 pApicCpu->pvApicPibRC += offApicPib;1340 pApicCpu->pvApicPibRC = (RTRCPTR)((RTRCUINTPTR)pApic->pvApicPibRC + offApicPib); 1342 1341 1343 1342 /* Initialize the virtual-APIC state. */ … … 1352 1351 Assert(pApicCpu->pvApicPageR0 != NIL_RTR0PTR); 1353 1352 Assert(!fNeedsGCMapping || pApicCpu->pvApicPageRC != NIL_RTRCPTR); 1353 Assert(!fNeedsGCMapping || pApic->pvApicPibRC == pVM->aCpus[0].apic.s.pvApicPibRC); 1354 1354 #endif 1355 1355 } … … 1490 1490 ApicReg.u32Version = PDM_APICREG_VERSION; 1491 1491 ApicReg.pfnGetInterruptR3 = APICGetInterrupt; 1492 ApicReg.pfnHasPendingIrqR3 = APICHasPendingIrq;1493 1492 ApicReg.pfnSetBaseMsrR3 = APICSetBaseMsr; 1494 1493 ApicReg.pfnGetBaseMsrR3 = APICGetBaseMsr; … … 1508 1507 { 1509 1508 ApicReg.pszGetInterruptRC = "APICGetInterrupt"; 1510 ApicReg.pszHasPendingIrqRC = "APICHasPendingIrq";1511 1509 ApicReg.pszSetBaseMsrRC = "APICSetBaseMsr"; 1512 1510 ApicReg.pszGetBaseMsrRC = "APICGetBaseMsr"; … … 1520 1518 1521 1519 ApicReg.pszGetInterruptR0 = "APICGetInterrupt"; 1522 ApicReg.pszHasPendingIrqR0 = "APICHasPendingIrq";1523 1520 ApicReg.pszSetBaseMsrR0 = "APICSetBaseMsr"; 1524 1521 ApicReg.pszGetBaseMsrR0 = "APICGetBaseMsr"; -
TabularUnified trunk/src/VBox/VMM/VMMR3/PDM.cpp ¶
r60404 r60716 509 509 pVM->pdm.s.Apic.pDevInsRC += offDelta; 510 510 pVM->pdm.s.Apic.pfnGetInterruptRC += offDelta; 511 pVM->pdm.s.Apic.pfnHasPendingIrqRC += offDelta;512 511 pVM->pdm.s.Apic.pfnSetBaseMsrRC += offDelta; 513 512 pVM->pdm.s.Apic.pfnGetBaseMsrRC += offDelta; -
TabularUnified trunk/src/VBox/VMM/VMMR3/PDMDevHlp.cpp ¶
r60407 r60716 2644 2644 } 2645 2645 if ( !pApicReg->pfnGetInterruptR3 2646 || !pApicReg->pfnHasPendingIrqR32647 2646 || !pApicReg->pfnSetBaseMsrR3 2648 2647 || !pApicReg->pfnGetBaseMsrR3 … … 2656 2655 { 2657 2656 Assert(pApicReg->pfnGetInterruptR3); 2658 Assert(pApicReg->pfnHasPendingIrqR3);2659 2657 Assert(pApicReg->pfnSetBaseMsrR3); 2660 2658 Assert(pApicReg->pfnGetBaseMsrR3); … … 2670 2668 } 2671 2669 if ( ( pApicReg->pszGetInterruptRC 2672 || pApicReg->pszHasPendingIrqRC2673 2670 || pApicReg->pszSetBaseMsrRC 2674 2671 || pApicReg->pszGetBaseMsrRC … … 2681 2678 || pApicReg->pszGetTimerFreqRC) 2682 2679 && ( !VALID_PTR(pApicReg->pszGetInterruptRC) 2683 || !VALID_PTR(pApicReg->pszHasPendingIrqRC)2684 2680 || !VALID_PTR(pApicReg->pszSetBaseMsrRC) 2685 2681 || !VALID_PTR(pApicReg->pszGetBaseMsrRC) … … 2694 2690 { 2695 2691 Assert(VALID_PTR(pApicReg->pszGetInterruptRC)); 2696 Assert(VALID_PTR(pApicReg->pszHasPendingIrqRC));2697 2692 Assert(VALID_PTR(pApicReg->pszSetBaseMsrRC)); 2698 2693 Assert(VALID_PTR(pApicReg->pszGetBaseMsrRC)); … … 2708 2703 } 2709 2704 if ( ( pApicReg->pszGetInterruptR0 2710 || pApicReg->pszHasPendingIrqR02711 2705 || pApicReg->pszSetBaseMsrR0 2712 2706 || pApicReg->pszGetBaseMsrR0 … … 2719 2713 || pApicReg->pszGetTimerFreqR0) 2720 2714 && ( !VALID_PTR(pApicReg->pszGetInterruptR0) 2721 || !VALID_PTR(pApicReg->pszHasPendingIrqR0)2722 2715 || !VALID_PTR(pApicReg->pszSetBaseMsrR0) 2723 2716 || !VALID_PTR(pApicReg->pszGetBaseMsrR0) … … 2732 2725 { 2733 2726 Assert(VALID_PTR(pApicReg->pszGetInterruptR0)); 2734 Assert(VALID_PTR(pApicReg->pszHasPendingIrqR0));2735 2727 Assert(VALID_PTR(pApicReg->pszSetBaseMsrR0)); 2736 2728 Assert(VALID_PTR(pApicReg->pszGetBaseMsrR0)); … … 2773 2765 if (RT_SUCCESS(rc)) 2774 2766 { 2775 rc = pdmR3DevGetSymbolRCLazy(pDevIns, pApicReg->pszHasPendingIrqRC, &pVM->pdm.s.Apic.pfnHasPendingIrqRC);2776 AssertMsgRC(rc, ("%s::%s rc=%Rrc\n", pDevIns->pReg->szRCMod, pApicReg->pszHasPendingIrqRC, rc));2777 }2778 if (RT_SUCCESS(rc))2779 {2780 2767 rc = pdmR3DevGetSymbolRCLazy(pDevIns, pApicReg->pszSetBaseMsrRC, &pVM->pdm.s.Apic.pfnSetBaseMsrRC); 2781 2768 AssertMsgRC(rc, ("%s::%s rc=%Rrc\n", pDevIns->pReg->szRCMod, pApicReg->pszSetBaseMsrRC, rc)); … … 2832 2819 pVM->pdm.s.Apic.pDevInsRC = 0; 2833 2820 pVM->pdm.s.Apic.pfnGetInterruptRC = 0; 2834 pVM->pdm.s.Apic.pfnHasPendingIrqRC = 0;2835 2821 pVM->pdm.s.Apic.pfnSetBaseMsrRC = 0; 2836 2822 pVM->pdm.s.Apic.pfnGetBaseMsrRC = 0; … … 2853 2839 if (RT_SUCCESS(rc)) 2854 2840 { 2855 rc = pdmR3DevGetSymbolR0Lazy(pDevIns, pApicReg->pszHasPendingIrqR0, &pVM->pdm.s.Apic.pfnHasPendingIrqR0);2856 AssertMsgRC(rc, ("%s::%s rc=%Rrc\n", pDevIns->pReg->szR0Mod, pApicReg->pszHasPendingIrqR0, rc));2857 }2858 if (RT_SUCCESS(rc))2859 {2860 2841 rc = pdmR3DevGetSymbolR0Lazy(pDevIns, pApicReg->pszSetBaseMsrR0, &pVM->pdm.s.Apic.pfnSetBaseMsrR0); 2861 2842 AssertMsgRC(rc, ("%s::%s rc=%Rrc\n", pDevIns->pReg->szR0Mod, pApicReg->pszSetBaseMsrR0, rc)); … … 2912 2893 { 2913 2894 pVM->pdm.s.Apic.pfnGetInterruptR0 = 0; 2914 pVM->pdm.s.Apic.pfnHasPendingIrqR0 = 0;2915 2895 pVM->pdm.s.Apic.pfnSetBaseMsrR0 = 0; 2916 2896 pVM->pdm.s.Apic.pfnGetBaseMsrR0 = 0; … … 2930 2910 pVM->pdm.s.Apic.pDevInsR3 = pDevIns; 2931 2911 pVM->pdm.s.Apic.pfnGetInterruptR3 = pApicReg->pfnGetInterruptR3; 2932 pVM->pdm.s.Apic.pfnHasPendingIrqR3 = pApicReg->pfnHasPendingIrqR3;2933 2912 pVM->pdm.s.Apic.pfnSetBaseMsrR3 = pApicReg->pfnSetBaseMsrR3; 2934 2913 pVM->pdm.s.Apic.pfnGetBaseMsrR3 = pApicReg->pfnGetBaseMsrR3; -
TabularUnified trunk/src/VBox/VMM/VMMR3/TRPM.cpp ¶
r60573 r60716 1509 1509 # endif 1510 1510 1511 uint8_t u8Interrupt ;1511 uint8_t u8Interrupt = 0; 1512 1512 int rc = PDMGetInterrupt(pVCpu, &u8Interrupt); 1513 1513 Log(("TRPMR3InjectEvent: CPU%d u8Interrupt=%d (%#x) rc=%Rrc\n", pVCpu->idCpu, u8Interrupt, u8Interrupt, rc)); … … 1555 1555 else 1556 1556 { 1557 #ifndef VBOX_WITH_NEW_APIC 1558 AssertRC(rc); 1559 #endif 1557 /* Can happen if the interrupt is masked by TPR or APIC is disabled. */ 1558 AssertMsg(rc == VERR_APIC_INTR_MASKED_BY_TPR || rc == VERR_NO_DATA, ("PDMGetInterrupt failed. rc=%Rrc\n", rc)); 1560 1559 return HMR3IsActive(pVCpu) ? VINF_EM_RESCHEDULE_HM : VINF_EM_RESCHEDULE_REM; /* (Heed the halted state if this is changed!) */ 1561 1560 } 1562 1561 #else /* !TRPM_FORWARD_TRAPS_IN_GC */ 1563 uint8_t u8Interrupt ;1562 uint8_t u8Interrupt = 0; 1564 1563 int rc = PDMGetInterrupt(pVCpu, &u8Interrupt); 1565 1564 Log(("TRPMR3InjectEvent: u8Interrupt=%d (%#x) rc=%Rrc\n", u8Interrupt, u8Interrupt, rc)); … … 1569 1568 AssertRC(rc); 1570 1569 STAM_COUNTER_INC(&pVM->trpm.s.paStatForwardedIRQR3[u8Interrupt]); 1571 return HMR3IsActive(pVCpu) ? VINF_EM_RESCHEDULE_HM : VINF_EM_RESCHEDULE_REM; 1572 } 1570 } 1571 else 1572 { 1573 /* Can happen if the interrupt is masked by TPR or APIC is disabled. */ 1574 AssertMsg(rc == VERR_APIC_INTR_MASKED_BY_TPR || rc == VERR_NO_DATA, ("PDMGetInterrupt failed. rc=%Rrc\n", rc)); 1575 } 1576 return HMR3IsActive(pVCpu) ? VINF_EM_RESCHEDULE_HM : VINF_EM_RESCHEDULE_REM; /* (Heed the halted state if this is changed!) */ 1573 1577 #endif /* !TRPM_FORWARD_TRAPS_IN_GC */ 1574 1578 } -
TabularUnified trunk/src/VBox/VMM/VMMRC/TRPMRCHandlers.cpp ¶
r58123 r60716 249 249 else if (VMCPU_FF_IS_PENDING(pVCpu, VMCPU_FF_TRPM_SYNC_IDT)) 250 250 rc = VINF_EM_RAW_TO_R3; 251 /* P ending interrupt: dispatch it. */251 /* Possibly pending interrupt: dispatch it. */ 252 252 else if ( VMCPU_FF_IS_PENDING(pVCpu, VMCPU_FF_INTERRUPT_APIC | VMCPU_FF_INTERRUPT_PIC) 253 253 && !VMCPU_FF_IS_SET(pVCpu, VMCPU_FF_INHIBIT_INTERRUPTS) … … 258 258 rc = PDMGetInterrupt(pVCpu, &u8Interrupt); 259 259 Log(("trpmGCExitTrap: u8Interrupt=%d (%#x) rc=%Rrc\n", u8Interrupt, u8Interrupt, rc)); 260 AssertFatalMsgRC(rc, ("PDMGetInterrupt failed with %Rrc\n", rc)); 261 rc = TRPMForwardTrap(pVCpu, pRegFrame, (uint32_t)u8Interrupt, 0, TRPM_TRAP_NO_ERRORCODE, TRPM_HARDWARE_INT, uOldActiveVector); 262 /* can't return if successful */ 263 Assert(rc != VINF_SUCCESS); 264 265 /* Stop the profile counter that was started in TRPMGCHandlersA.asm */ 266 Assert(uOldActiveVector <= 16); 267 STAM_PROFILE_ADV_STOP(&pVM->trpm.s.aStatGCTraps[uOldActiveVector], a); 268 269 /* Assert the trap and go to the recompiler to dispatch it. */ 270 TRPMAssertTrap(pVCpu, u8Interrupt, TRPM_HARDWARE_INT); 271 272 STAM_PROFILE_ADV_START(&pVM->trpm.s.aStatGCTraps[uOldActiveVector], a); 273 rc = VINF_EM_RAW_INTERRUPT_PENDING; 260 if (RT_SUCCESS(rc)) 261 { 262 rc = TRPMForwardTrap(pVCpu, pRegFrame, (uint32_t)u8Interrupt, 0, TRPM_TRAP_NO_ERRORCODE, TRPM_HARDWARE_INT, uOldActiveVector); 263 /* can't return if successful */ 264 Assert(rc != VINF_SUCCESS); 265 266 /* Stop the profile counter that was started in TRPMRCHandlersA.asm */ 267 Assert(uOldActiveVector <= 16); 268 STAM_PROFILE_ADV_STOP(&pVM->trpm.s.aStatGCTraps[uOldActiveVector], a); 269 270 /* Assert the trap and go to the recompiler to dispatch it. */ 271 TRPMAssertTrap(pVCpu, u8Interrupt, TRPM_HARDWARE_INT); 272 273 STAM_PROFILE_ADV_START(&pVM->trpm.s.aStatGCTraps[uOldActiveVector], a); 274 rc = VINF_EM_RAW_INTERRUPT_PENDING; 275 } 276 else if ( rc == VERR_APIC_INTR_MASKED_BY_TPR /* Can happen if TPR is too high for the newly arrived interrupt. */ 277 || rc == VERR_NO_DATA) /* Can happen if the APIC is disabled. */ 278 { 279 STAM_PROFILE_ADV_STOP(&pVM->trpm.s.aStatGCTraps[uOldActiveVector], a); 280 rc = VINF_SUCCESS; 281 } 282 else 283 AssertFatalMsgRC(rc, ("PDMGetInterrupt failed. rc=%Rrc\n", rc)); 274 284 } 275 285 /* -
TabularUnified trunk/src/VBox/VMM/include/APICInternal.h ¶
r60695 r60716 633 633 VMMDECL(uint64_t) APICGetBaseMsr(PPDMDEVINS pDevIns, PVMCPU pVCpu); 634 634 VMMDECL(VBOXSTRICTRC) APICSetBaseMsr(PPDMDEVINS pDevIns, PVMCPU pVCpu, uint64_t uBase); 635 VMMDECL(uint8_t) APICGetTpr(PPDMDEVINS pDevIns, PVMCPU pVCpu );635 VMMDECL(uint8_t) APICGetTpr(PPDMDEVINS pDevIns, PVMCPU pVCpu, bool *pfPending, uint8_t *pu8PendingIntr); 636 636 VMMDECL(void) APICSetTpr(PPDMDEVINS pDevIns, PVMCPU pVCpu, uint8_t u8Tpr); 637 637 VMMDECL(uint64_t) APICGetTimerFreq(PPDMDEVINS pDevIns); … … 640 640 VMMDECL(VBOXSTRICTRC) APICReadMsr(PPDMDEVINS pDevIns, PVMCPU pVCpu, uint32_t u32Reg, uint64_t *pu64Val); 641 641 VMMDECL(VBOXSTRICTRC) APICWriteMsr(PPDMDEVINS pDevIns, PVMCPU pVCpu, uint32_t u32Reg, uint64_t u64Val); 642 VMMDECL(bool) APICHasPendingIrq(PPDMDEVINS pDevIns, PVMCPU pVCpu, uint8_t *pu8PendingIrq); 643 VMMDECL(int) APICGetInterrupt(PPDMDEVINS pDevIns, PVMCPU pVCpu, uint32_t *puTagSrc); 642 VMMDECL(int) APICGetInterrupt(PPDMDEVINS pDevIns, PVMCPU pVCpu, uint8_t *puVector, uint32_t *puTagSrc); 644 643 VMMDECL(void) APICSetInterruptFF(PVMCPU pVCpu, PDMAPICIRQ enmType); 645 644 VMMDECL(void) APICClearInterruptFF(PVMCPU pVCpu, PDMAPICIRQ enmType); -
TabularUnified trunk/src/VBox/VMM/include/PDMInternal.h ¶
r60404 r60716 563 563 { 564 564 /** Pointer to the APIC device instance - R3 Ptr. */ 565 PPDMDEVINSR3 pDevInsR3;565 PPDMDEVINSR3 pDevInsR3; 566 566 /** @copydoc PDMAPICREG::pfnGetInterruptR3 */ 567 DECLR3CALLBACKMEMBER(int, pfnGetInterruptR3,(PPDMDEVINS pDevIns, PVMCPU pVCpu, uint32_t *puTagSrc)); 568 /** @copydoc PDMAPICREG::pfnHasPendingIrqR3 */ 569 DECLR3CALLBACKMEMBER(bool, pfnHasPendingIrqR3,(PPDMDEVINS pDevIns, PVMCPU pVCpu, uint8_t *pu8PendingIrq)); 567 DECLR3CALLBACKMEMBER(int, pfnGetInterruptR3,(PPDMDEVINS pDevIns, PVMCPU pVCpu, uint8_t *pu8Vector, 568 uint32_t *pu32TagSrc)); 570 569 /** @copydoc PDMAPICREG::pfnSetBaseMsrR3 */ 571 570 DECLR3CALLBACKMEMBER(VBOXSTRICTRC, pfnSetBaseMsrR3,(PPDMDEVINS pDevIns, PVMCPU pVCpu, uint64_t u64Base)); 572 571 /** @copydoc PDMAPICREG::pfnGetBaseMsrR3 */ 573 DECLR3CALLBACKMEMBER(uint64_t, pfnGetBaseMsrR3,(PPDMDEVINS pDevIns, PVMCPU pVCpu));572 DECLR3CALLBACKMEMBER(uint64_t, pfnGetBaseMsrR3,(PPDMDEVINS pDevIns, PVMCPU pVCpu)); 574 573 /** @copydoc PDMAPICREG::pfnSetTprR3 */ 575 DECLR3CALLBACKMEMBER(void, pfnSetTprR3,(PPDMDEVINS pDevIns, PVMCPU pVCpu, uint8_t u8Tpr));574 DECLR3CALLBACKMEMBER(void, pfnSetTprR3,(PPDMDEVINS pDevIns, PVMCPU pVCpu, uint8_t u8Tpr)); 576 575 /** @copydoc PDMAPICREG::pfnGetTprR3 */ 577 DECLR3CALLBACKMEMBER(uint8_t, pfnGetTprR3,(PPDMDEVINS pDevIns, PVMCPU pVCpu));576 DECLR3CALLBACKMEMBER(uint8_t, pfnGetTprR3,(PPDMDEVINS pDevIns, PVMCPU pVCpu, bool *pfPending, uint8_t *pu8PendingIntr)); 578 577 /** @copydoc PDMAPICREG::pfnWriteMsrR3 */ 579 DECLR3CALLBACKMEMBER(VBOXSTRICTRC, pfnWriteMsrR3, 578 DECLR3CALLBACKMEMBER(VBOXSTRICTRC, pfnWriteMsrR3,(PPDMDEVINS pDevIns, PVMCPU pVCpu, uint32_t u32Reg, uint64_t u64Value)); 580 579 /** @copydoc PDMAPICREG::pfnReadMsrR3 */ 581 DECLR3CALLBACKMEMBER(VBOXSTRICTRC, pfnReadMsrR3, 580 DECLR3CALLBACKMEMBER(VBOXSTRICTRC, pfnReadMsrR3,(PPDMDEVINS pDevIns, PVMCPU pVCpu, uint32_t u32Reg, uint64_t *pu64Value)); 582 581 /** @copydoc PDMAPICREG::pfnBusDeliverR3 */ 583 DECLR3CALLBACKMEMBER(int, pfnBusDeliverR3,(PPDMDEVINS pDevIns, uint8_t uDest, uint8_t uDestMode, uint8_t uDeliveryMode, 584 uint8_t uVector, uint8_t uPolarity, uint8_t uTriggerMode, uint32_t uTagSrc)); 582 DECLR3CALLBACKMEMBER(int, pfnBusDeliverR3,(PPDMDEVINS pDevIns, uint8_t uDest, uint8_t uDestMode, 583 uint8_t uDeliveryMode, uint8_t uVector, uint8_t uPolarity, 584 uint8_t uTriggerMode, uint32_t uTagSrc)); 585 585 /** @copydoc PDMAPICREG::pfnLocalInterruptR3 */ 586 586 DECLR3CALLBACKMEMBER(VBOXSTRICTRC, pfnLocalInterruptR3,(PPDMDEVINS pDevIns, PVMCPU pVCpu, uint8_t u8Pin, uint8_t u8Level, 587 587 int rcRZ)); 588 588 /** @copydoc PDMAPICREG::pfnGetTimerFreqR3 */ 589 DECLR3CALLBACKMEMBER(uint64_t, pfnGetTimerFreqR3,(PPDMDEVINS pDevIns));589 DECLR3CALLBACKMEMBER(uint64_t, pfnGetTimerFreqR3,(PPDMDEVINS pDevIns)); 590 590 591 591 /** Pointer to the APIC device instance - R0 Ptr. */ 592 PPDMDEVINSR0 pDevInsR0;592 PPDMDEVINSR0 pDevInsR0; 593 593 /** @copydoc PDMAPICREG::pfnGetInterruptR3 */ 594 DECLR0CALLBACKMEMBER(int, pfnGetInterruptR0,(PPDMDEVINS pDevIns, PVMCPU pVCpu, uint32_t *puTagSrc)); 595 /** @copydoc PDMAPICREG::pfnHasPendingIrqR3 */ 596 DECLR0CALLBACKMEMBER(bool, pfnHasPendingIrqR0,(PPDMDEVINS pDevIns, PVMCPU pVCpu, uint8_t *pu8PendingIrq)); 594 DECLR0CALLBACKMEMBER(int, pfnGetInterruptR0,(PPDMDEVINS pDevIns, PVMCPU pVCpu, uint8_t *pu8Vector, 595 uint32_t *pu32TagSrc)); 597 596 /** @copydoc PDMAPICREG::pfnSetBaseMsrR3 */ 598 597 DECLR0CALLBACKMEMBER(VBOXSTRICTRC, pfnSetBaseMsrR0,(PPDMDEVINS pDevIns, PVMCPU pVCpu, uint64_t u64Base)); 599 598 /** @copydoc PDMAPICREG::pfnGetBaseMsrR3 */ 600 DECLR0CALLBACKMEMBER(uint64_t, pfnGetBaseMsrR0,(PPDMDEVINS pDevIns, PVMCPU pVCpu));599 DECLR0CALLBACKMEMBER(uint64_t, pfnGetBaseMsrR0,(PPDMDEVINS pDevIns, PVMCPU pVCpu)); 601 600 /** @copydoc PDMAPICREG::pfnSetTprR3 */ 602 DECLR0CALLBACKMEMBER(void, pfnSetTprR0,(PPDMDEVINS pDevIns, PVMCPU pVCpu, uint8_t u8Tpr));601 DECLR0CALLBACKMEMBER(void, pfnSetTprR0,(PPDMDEVINS pDevIns, PVMCPU pVCpu, uint8_t u8Tpr)); 603 602 /** @copydoc PDMAPICREG::pfnGetTprR3 */ 604 DECLR0CALLBACKMEMBER(uint8_t, pfnGetTprR0,(PPDMDEVINS pDevIns, PVMCPU pVCpu));603 DECLR0CALLBACKMEMBER(uint8_t, pfnGetTprR0,(PPDMDEVINS pDevIns, PVMCPU pVCpu, bool *pfPending, uint8_t *pu8PendingIntr)); 605 604 /** @copydoc PDMAPICREG::pfnWriteMsrR3 */ 606 DECLR0CALLBACKMEMBER(VBOXSTRICTRC, pfnWriteMsrR0, 605 DECLR0CALLBACKMEMBER(VBOXSTRICTRC, pfnWriteMsrR0,(PPDMDEVINS pDevIns, PVMCPU pVCpu, uint32_t u32Reg, uint64_t u64Value)); 607 606 /** @copydoc PDMAPICREG::pfnReadMsrR3 */ 608 DECLR0CALLBACKMEMBER(VBOXSTRICTRC, pfnReadMsrR0, 607 DECLR0CALLBACKMEMBER(VBOXSTRICTRC, pfnReadMsrR0,(PPDMDEVINS pDevIns, PVMCPU pVCpu, uint32_t u32Reg, uint64_t *pu64Value)); 609 608 /** @copydoc PDMAPICREG::pfnBusDeliverR3 */ 610 DECLR0CALLBACKMEMBER(int, pfnBusDeliverR0,(PPDMDEVINS pDevIns, uint8_t u8Dest, uint8_t u8DestMode, uint8_t u8DeliveryMode, 611 uint8_t iVector, uint8_t u8Polarity, uint8_t u8TriggerMode, uint32_t uTagSrc)); 609 DECLR0CALLBACKMEMBER(int, pfnBusDeliverR0,(PPDMDEVINS pDevIns, uint8_t u8Dest, uint8_t u8DestMode, 610 uint8_t u8DeliveryMode, uint8_t iVector, uint8_t u8Polarity, 611 uint8_t u8TriggerMode, uint32_t uTagSrc)); 612 612 /** @copydoc PDMAPICREG::pfnLocalInterruptR3 */ 613 613 DECLR0CALLBACKMEMBER(VBOXSTRICTRC, pfnLocalInterruptR0,(PPDMDEVINS pDevIns, PVMCPU pVCpu, uint8_t u8Pin, uint8_t u8Level, 614 614 int rcRZ)); 615 615 /** @copydoc PDMAPICREG::pfnGetTimerFreqR3 */ 616 DECLR0CALLBACKMEMBER(uint64_t, pfnGetTimerFreqR0,(PPDMDEVINS pDevIns));616 DECLR0CALLBACKMEMBER(uint64_t, pfnGetTimerFreqR0,(PPDMDEVINS pDevIns)); 617 617 618 618 /** Pointer to the APIC device instance - RC Ptr. */ 619 PPDMDEVINSRC pDevInsRC;619 PPDMDEVINSRC pDevInsRC; 620 620 /** @copydoc PDMAPICREG::pfnGetInterruptR3 */ 621 DECLRCCALLBACKMEMBER(int, pfnGetInterruptRC,(PPDMDEVINS pDevIns, PVMCPU pVCpu, uint32_t *puTagSrc)); 622 /** @copydoc PDMAPICREG::pfnHasPendingIrqR3 */ 623 DECLRCCALLBACKMEMBER(bool, pfnHasPendingIrqRC,(PPDMDEVINS pDevIns, PVMCPU pVCpu, uint8_t *pu8PendingIrq)); 621 DECLRCCALLBACKMEMBER(int, pfnGetInterruptRC,(PPDMDEVINS pDevIns, PVMCPU pVCpu, uint8_t *pu8Vector, 622 uint32_t *pu32TagSrc)); 624 623 /** @copydoc PDMAPICREG::pfnSetBaseMsrR3 */ 625 624 DECLRCCALLBACKMEMBER(VBOXSTRICTRC, pfnSetBaseMsrRC,(PPDMDEVINS pDevIns, PVMCPU pVCpu, uint64_t u64Base)); 626 625 /** @copydoc PDMAPICREG::pfnGetBaseMsrR3 */ 627 DECLRCCALLBACKMEMBER(uint64_t, pfnGetBaseMsrRC,(PPDMDEVINS pDevIns, PVMCPU pVCpu));626 DECLRCCALLBACKMEMBER(uint64_t, pfnGetBaseMsrRC,(PPDMDEVINS pDevIns, PVMCPU pVCpu)); 628 627 /** @copydoc PDMAPICREG::pfnSetTprR3 */ 629 DECLRCCALLBACKMEMBER(void, pfnSetTprRC,(PPDMDEVINS pDevIns, PVMCPU pVCpu, uint8_t u8Tpr));628 DECLRCCALLBACKMEMBER(void, pfnSetTprRC,(PPDMDEVINS pDevIns, PVMCPU pVCpu, uint8_t u8Tpr)); 630 629 /** @copydoc PDMAPICREG::pfnGetTprR3 */ 631 DECLRCCALLBACKMEMBER(uint8_t, pfnGetTprRC,(PPDMDEVINS pDevIns, PVMCPU pVCpu));630 DECLRCCALLBACKMEMBER(uint8_t, pfnGetTprRC,(PPDMDEVINS pDevIns, PVMCPU pVCpu, bool *pfPending, uint8_t *pu8PendingIntr)); 632 631 /** @copydoc PDMAPICREG::pfnWriteMsrR3 */ 633 DECLRCCALLBACKMEMBER(VBOXSTRICTRC, pfnWriteMsrRC, 632 DECLRCCALLBACKMEMBER(VBOXSTRICTRC, pfnWriteMsrRC,(PPDMDEVINS pDevIns, PVMCPU pVCpu, uint32_t u32Reg, uint64_t u64Value)); 634 633 /** @copydoc PDMAPICREG::pfnReadMsrR3 */ 635 DECLRCCALLBACKMEMBER(VBOXSTRICTRC, pfnReadMsrRC, 634 DECLRCCALLBACKMEMBER(VBOXSTRICTRC, pfnReadMsrRC,(PPDMDEVINS pDevIns, PVMCPU pVCpu, uint32_t u32Reg, uint64_t *pu64Value)); 636 635 /** @copydoc PDMAPICREG::pfnBusDeliverR3 */ 637 DECLRCCALLBACKMEMBER(int, pfnBusDeliverRC,(PPDMDEVINS pDevIns, uint8_t u8Dest, uint8_t u8DestMode, uint8_t u8DeliveryMode, 638 uint8_t iVector, uint8_t u8Polarity, uint8_t u8TriggerMode, uint32_t uTagSrc)); 636 DECLRCCALLBACKMEMBER(int, pfnBusDeliverRC,(PPDMDEVINS pDevIns, uint8_t u8Dest, uint8_t u8DestMode, 637 uint8_t u8DeliveryMode, uint8_t iVector, uint8_t u8Polarity, 638 uint8_t u8TriggerMode, uint32_t uTagSrc)); 639 639 /** @copydoc PDMAPICREG::pfnLocalInterruptR3 */ 640 640 DECLRCCALLBACKMEMBER(VBOXSTRICTRC, pfnLocalInterruptRC,(PPDMDEVINS pDevIns, PVMCPU pVCpu, uint8_t u8Pin, uint8_t u8Level, 641 641 int rcRZ)); 642 642 /** @copydoc PDMAPICREG::pfnGetTimerFreqR3 */ 643 DECLRCCALLBACKMEMBER(uint64_t, pfnGetTimerFreqRC,(PPDMDEVINS pDevIns)); 643 DECLRCCALLBACKMEMBER(uint64_t, pfnGetTimerFreqRC,(PPDMDEVINS pDevIns)); 644 645 uint8_t Alignment[4]; 644 646 } PDMAPIC; 645 647
Note:
See TracChangeset
for help on using the changeset viewer.