Changeset 61685 in vbox for trunk/src/VBox
- Timestamp:
- Jun 13, 2016 4:04:42 PM (9 years ago)
- svn:sync-xref-src-repo-rev:
- 108043
- Location:
- trunk/src/VBox
- Files:
-
- 5 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/Devices/PC/DevIOAPIC_New.cpp
r61375 r61685 81 81 #define IOAPIC_VER_HAS_PRQ(a_Reg) RT_BOOL((a_Reg) & RT_BIT_32(15)) 82 82 83 /** Index register - Valid write mask. */ 84 #define IOAPIC_INDEX_VALID_WRITE_MASK UINT32_C(0xff) 85 83 86 /** Arbitration register - Gets the ID. */ 84 87 #define IOAPIC_ARB_GET_ID(a_Reg) ((a_Reg) >> 24 & 0xf) … … 90 93 #define IOAPIC_RTE_VECTOR UINT64_C(0xff) 91 94 /** Redirection table entry - Delivery mode. */ 92 #define IOAPIC_RTE_DELIVERY_MODE (RT_BIT _64(8) | RT_BIT_64(9) | RT_BIT_64(10))95 #define IOAPIC_RTE_DELIVERY_MODE (RT_BIT(8) | RT_BIT(9) | RT_BIT(10)) 93 96 /** Redirection table entry - Destination mode. */ 94 #define IOAPIC_RTE_DEST_MODE RT_BIT _64(11)97 #define IOAPIC_RTE_DEST_MODE RT_BIT(11) 95 98 /** Redirection table entry - Delivery status. */ 96 #define IOAPIC_RTE_DELIVERY_STATUS RT_BIT _64(12)99 #define IOAPIC_RTE_DELIVERY_STATUS RT_BIT(12) 97 100 /** Redirection table entry - Interrupt input pin polarity. */ 98 #define IOAPIC_RTE_POLARITY RT_BIT _64(13)101 #define IOAPIC_RTE_POLARITY RT_BIT(13) 99 102 /** Redirection table entry - Remote IRR. */ 100 #define IOAPIC_RTE_REMOTE_IRR RT_BIT _64(14)103 #define IOAPIC_RTE_REMOTE_IRR RT_BIT(14) 101 104 /** Redirection table entry - Trigger Mode. */ 102 #define IOAPIC_RTE_TRIGGER_MODE RT_BIT _64(15)105 #define IOAPIC_RTE_TRIGGER_MODE RT_BIT(15) 103 106 /** Redirection table entry - the mask bit number. */ 104 107 #define IOAPIC_RTE_MASK_BIT 16 105 108 /** Redirection table entry - the mask. */ 106 #define IOAPIC_RTE_MASK RT_BIT _64(IOAPIC_RTE_MASK_BIT)109 #define IOAPIC_RTE_MASK RT_BIT(IOAPIC_RTE_MASK_BIT) 107 110 /** Redirection table entry - Extended Destination ID. */ 108 111 #define IOAPIC_RTE_EXT_DEST_ID UINT64_C(0x00ff000000000000) … … 151 154 /** Redirection table entry - Trigger mode level. */ 152 155 #define IOAPIC_RTE_TRIGGER_MODE_LEVEL 1 156 /** Redirection table entry - Destination mode physical. */ 157 #define IOAPIC_RTE_DEST_MODE_PHYSICAL 0 158 /** Redirection table entry - Destination mode logical. */ 159 #define IOAPIC_RTE_DEST_MODE_LOGICAL 1 160 153 161 154 162 /** Index of indirect registers in the I/O APIC register table. */ … … 193 201 * Structures and Typedefs * 194 202 *********************************************************************************************************************************/ 203 /** 204 * The I/O Redirection Table Entry (RTE). 205 */ 206 typedef union RTE 207 { 208 /** Unsigned integer view. */ 209 uint64_t volatile u; 210 /** 64 bit unsigned integer view. */ 211 uint64_t volatile au64[1]; 212 /** 32 bit unsigned integer view. */ 213 uint32_t volatile au32[2]; 214 } RTE; 215 AssertCompileSize(RTE, sizeof(uint64_t)); 216 217 /** 218 * The per-VM I/O APIC device state. 219 */ 195 220 typedef struct IOAPIC 196 221 { … … 211 236 212 237 /** The ID register. */ 213 uint8_t 238 uint8_t volatile u8Id; 214 239 /** The index register. */ 215 uint8_t 240 uint8_t volatile u8Index; 216 241 /** Number of CPUs. */ 217 242 uint8_t cCpus; 218 243 /* Alignment padding. */ 219 244 uint8_t u8Padding0[5]; 220 #if IOAPIC_HARDWARE_VERSION == IOAPIC_HARDWARE_VERSION_ICH9221 /** The EOI register. */222 uint32_t u32Eoi;223 uint32_t u32Padding1;224 #else225 uint64_t u64Padding0;226 #endif227 245 228 246 /** The redirection table registers. */ 229 uint64_tau64RedirTable[IOAPIC_NUM_INTR_PINS];247 RTE au64RedirTable[IOAPIC_NUM_INTR_PINS]; 230 248 /** The IRQ tags and source IDs for each pin (tracing purposes). */ 231 249 uint32_t au32TagSrc[IOAPIC_NUM_INTR_PINS]; … … 233 251 /** Alignment padding. */ 234 252 uint32_t u32Padding2; 235 /** The internal IRR reflecting interrupt lines. */236 uint32_t 253 /** The internal IRR reflecting state of the interrupt lines. */ 254 uint32_t volatile uIrr; 237 255 238 256 #ifdef VBOX_WITH_STATISTICS … … 264 282 /** Number of SetEoi calls in RC. */ 265 283 STAMCOUNTER StatSetEoiRC; 284 285 /** Number of redundant edge-triggered interrupts. */ 286 STAMCOUNTER StatRedundantEdgeIntr; 287 /** Number of redundant level-triggered interrupts. */ 288 STAMCOUNTER StatRedundantLevelIntr; 289 /** Number of suppressed level-triggered interrupts (by remote IRR). */ 290 STAMCOUNTER StatSuppressedLevelIntr; 266 291 #endif 267 292 } IOAPIC; … … 310 335 { 311 336 Log2(("IOAPIC: ioapicSetId: uValue=%#RX32\n", uValue)); 312 pThis->u8Id = (uValue >> 24) & IOAPIC_ID_MASK;337 ASMAtomicWriteU8(&pThis->u8Id, (uValue >> 24) & IOAPIC_ID_MASK); 313 338 } 314 339 … … 337 362 { 338 363 LogFlow(("IOAPIC: ioapicSetIndex: uValue=%#RX32\n", uValue)); 339 pThis->u8Index = uValue & 0xff;364 ASMAtomicWriteU8(&pThis->u8Index, uValue & IOAPIC_INDEX_VALID_WRITE_MASK); 340 365 } 341 366 … … 360 385 * @param pThis The IOAPIC instance. 361 386 * @param idxRte The index of the RTE. 362 */ 363 static void ioapicSignalIrqForRte(PIOAPIC pThis, uint8_t idxRte) 364 { 365 /* Check if there's an interrupt on the corresponding interrupt input pin. */ 366 uint32_t const uPinMask = UINT32_C(1) << idxRte; 367 if (pThis->uIrr & uPinMask) 368 { 369 /* Ensure the RTE isn't masked. */ 370 uint64_t const u64Rte = pThis->au64RedirTable[idxRte]; 371 if (!IOAPIC_RTE_IS_MASKED(u64Rte)) 387 * 388 * @remarks It is the responsibility of the caller to verify that an interrupt is 389 * pending for the pin corresponding to the RTE before calling this 390 * function. 391 */ 392 static void ioapicSignalIntrForRte(PIOAPIC pThis, uint8_t idxRte) 393 { 394 /* Ensure the RTE isn't masked. */ 395 uint64_t const u64Rte = pThis->au64RedirTable[idxRte].u; 396 if (!IOAPIC_RTE_IS_MASKED(u64Rte)) 397 { 398 /* We cannot accept another level-triggered interrupt until remote IRR has been cleared. */ 399 uint8_t const u8TriggerMode = IOAPIC_RTE_GET_TRIGGER_MODE(u64Rte); 400 if (u8TriggerMode == IOAPIC_RTE_TRIGGER_MODE_LEVEL) 372 401 { 373 uint32_t const u32TagSrc = pThis->au32TagSrc[idxRte]; 374 uint8_t const u8Vector = IOAPIC_RTE_GET_VECTOR(u64Rte); 375 uint8_t const u8DeliveryMode = IOAPIC_RTE_GET_DELIVERY_MODE(u64Rte); 376 uint8_t const u8DestMode = IOAPIC_RTE_GET_DEST_MODE(u64Rte); 377 uint8_t const u8Polarity = IOAPIC_RTE_GET_POLARITY(u64Rte); 378 uint8_t const u8TriggerMode = IOAPIC_RTE_GET_TRIGGER_MODE(u64Rte); 379 uint8_t const u8Dest = IOAPIC_RTE_GET_DEST(u64Rte); 380 381 /* We cannot accept another level-triggered interrupt until remote IRR has been cleared. */ 382 if (u8TriggerMode == IOAPIC_RTE_TRIGGER_MODE_LEVEL) 402 uint8_t const u8RemoteIrr = IOAPIC_RTE_GET_REMOTE_IRR(u64Rte); 403 if (u8RemoteIrr) 383 404 { 384 uint8_t const u8RemoteIrr = IOAPIC_RTE_GET_REMOTE_IRR(u64Rte); 385 if (u8RemoteIrr) 386 return; 405 STAM_COUNTER_INC(&pThis->StatSuppressedLevelIntr); 406 return; 387 407 } 388 389 /* 390 * Deliver to the local APIC via the system/3-wire-APIC bus. 391 */ 392 int rc = pThis->CTX_SUFF(pIoApicHlp)->pfnApicBusDeliver(pThis->CTX_SUFF(pDevIns), 393 u8Dest, 394 u8DestMode, 395 u8DeliveryMode, 396 u8Vector, 397 u8Polarity, 398 u8TriggerMode, 399 u32TagSrc); 400 /* Can't reschedule to R3. */ 401 Assert(rc == VINF_SUCCESS); 402 403 /* 404 * For edge triggered interrupts, we can clear our IRR bit to receive further 405 * edge-triggered interrupts, as the local APIC has accepted the interrupt. 406 */ 407 if (u8TriggerMode == IOAPIC_RTE_TRIGGER_MODE_EDGE) 408 { 409 pThis->uIrr &= ~uPinMask; 410 pThis->au32TagSrc[idxRte] = 0; 411 } 412 else 413 { 414 /* 415 * For level triggered interrupts, we set the remote IRR bit to indicate 416 * the local APIC has accepted the interrupt. 417 */ 418 Assert(u8TriggerMode == IOAPIC_RTE_TRIGGER_MODE_LEVEL); 419 pThis->au64RedirTable[idxRte] |= IOAPIC_RTE_REMOTE_IRR; 420 } 408 } 409 410 uint8_t const u8Vector = IOAPIC_RTE_GET_VECTOR(u64Rte); 411 uint8_t const u8DeliveryMode = IOAPIC_RTE_GET_DELIVERY_MODE(u64Rte); 412 uint8_t const u8DestMode = IOAPIC_RTE_GET_DEST_MODE(u64Rte); 413 uint8_t const u8Polarity = IOAPIC_RTE_GET_POLARITY(u64Rte); 414 uint8_t const u8Dest = IOAPIC_RTE_GET_DEST(u64Rte); 415 uint32_t const u32TagSrc = pThis->au32TagSrc[idxRte]; 416 417 Log2(("IOAPIC: Signaling %s-triggered interrupt. Dest=%#x DestMode=%s Vector=%#x (%u)", 418 u8TriggerMode == IOAPIC_RTE_TRIGGER_MODE_EDGE ? "edge" : "level", u8Dest, 419 u8DestMode == IOAPIC_RTE_DEST_MODE_PHYSICAL ? "physical" : "logical", u8Vector, u8Vector)); 420 421 /* 422 * Deliver to the local APIC via the system/3-wire-APIC bus. 423 */ 424 int rc = pThis->CTX_SUFF(pIoApicHlp)->pfnApicBusDeliver(pThis->CTX_SUFF(pDevIns), 425 u8Dest, 426 u8DestMode, 427 u8DeliveryMode, 428 u8Vector, 429 u8Polarity, 430 u8TriggerMode, 431 u32TagSrc); 432 /* Can't reschedule to R3. */ 433 Assert(rc == VINF_SUCCESS); 434 435 /* 436 * For level-triggered interrupts, we set the remote IRR bit to indicate 437 * the local APIC has accepted the interrupt. 438 * 439 * For edge-triggered interrupts, we should not clear the IRR bit as it 440 * should remain intact to reflect the state of the interrupt line. 441 * The device will explicitly transition to inactive state via the 442 * ioapicSetIrq() callback. 443 */ 444 if (u8TriggerMode == IOAPIC_RTE_TRIGGER_MODE_LEVEL) 445 { 446 Assert(u8TriggerMode == IOAPIC_RTE_TRIGGER_MODE_LEVEL); 447 ASMAtomicOrU32(&pThis->au64RedirTable[idxRte].au32[0], IOAPIC_RTE_REMOTE_IRR); 421 448 } 422 449 } … … 436 463 uint32_t uValue; 437 464 if (!(uIndex & 1)) 438 uValue = RT_LO_U32(pThis->au64RedirTable[idxRte])& RT_LO_U32(IOAPIC_RTE_VALID_READ_MASK);465 uValue = pThis->au64RedirTable[idxRte].au32[0] & RT_LO_U32(IOAPIC_RTE_VALID_READ_MASK); 439 466 else 440 uValue = RT_HI_U32(pThis->au64RedirTable[idxRte])& RT_HI_U32(IOAPIC_RTE_VALID_READ_MASK);467 uValue = pThis->au64RedirTable[idxRte].au32[1] & RT_HI_U32(IOAPIC_RTE_VALID_READ_MASK); 441 468 442 469 LogFlow(("IOAPIC: ioapicGetRedirTableEntry: uIndex=%#RX32 idxRte=%u returns %#RX32\n", uIndex, idxRte, uValue)); … … 462 489 * Update only the valid, writable bits. 463 490 */ 464 uint64_t const u64Rte = pThis->au64RedirTable[idxRte] ;491 uint64_t const u64Rte = pThis->au64RedirTable[idxRte].u; 465 492 if (!(uIndex & 1)) 466 493 { 467 494 uint32_t const u32RteNewLo = uValue & RT_LO_U32(IOAPIC_RTE_VALID_WRITE_MASK); 468 uint64_t const u64RteHi = u64Rte & UINT64_C(0xffffffff00000000); 469 pThis->au64RedirTable[idxRte] = u64RteHi | u32RteNewLo; 495 ASMAtomicWriteU32(&pThis->au64RedirTable[idxRte].au32[0], u32RteNewLo); 470 496 } 471 497 else 472 498 { 473 uint32_t const u32RteLo = RT_LO_U32(u64Rte); 474 uint64_t const u64RteNewHi = (uint64_t)(uValue & RT_HI_U32(IOAPIC_RTE_VALID_WRITE_MASK)) << 32; 475 pThis->au64RedirTable[idxRte] = u64RteNewHi | u32RteLo; 476 } 477 478 ioapicSignalIrqForRte(pThis, idxRte); 499 uint32_t const u32RteNewHi = uValue & RT_HI_U32(IOAPIC_RTE_VALID_WRITE_MASK); 500 ASMAtomicWriteU32(&pThis->au64RedirTable[idxRte].au32[1], u32RteNewHi); 501 } 502 503 /* 504 * Signal the next pending interrupt for this RTE. 505 */ 506 uint32_t const uPinMask = UINT32_C(1) << idxRte; 507 if (pThis->uIrr & uPinMask) 508 ioapicSignalIntrForRte(pThis, idxRte); 479 509 480 510 LogFlow(("IOAPIC: ioapicSetRedirTableEntry: uIndex=%#RX32 idxRte=%u uValue=%#RX32\n", uIndex, idxRte, uValue)); … … 547 577 /** 548 578 * @interface_method_impl{PDMIOAPICREG,pfnSetEoiR3} 549 * @remarks The device critsect is entered by the caller(s).550 579 */ 551 580 PDMBOTHCBDECL(void) ioapicSetEoi(PPDMDEVINS pDevIns, uint8_t u8Vector) … … 557 586 for (uint8_t idxRte = 0; idxRte < RT_ELEMENTS(pThis->au64RedirTable); idxRte++) 558 587 { 559 uint64_t const u64Rte = pThis->au64RedirTable[idxRte] ;588 uint64_t const u64Rte = pThis->au64RedirTable[idxRte].u; 560 589 if (IOAPIC_RTE_GET_VECTOR(u64Rte) == u8Vector) 561 590 { 562 pThis->au64RedirTable[idxRte] &= ~IOAPIC_RTE_REMOTE_IRR;591 ASMAtomicAndU32(&pThis->au64RedirTable[idxRte].au32[0], ~IOAPIC_RTE_REMOTE_IRR); 563 592 Log2(("IOAPIC: ioapicSetEoi: Cleared remote IRR for RTE %u\n", idxRte)); 564 ioapicSignalIrqForRte(pThis, idxRte); 593 594 /* 595 * Signal the next pending interrupt for this RTE. 596 */ 597 uint32_t const uPinMask = UINT32_C(1) << idxRte; 598 if (pThis->uIrr & uPinMask) 599 ioapicSignalIntrForRte(pThis, idxRte); 565 600 } 566 601 } … … 570 605 /** 571 606 * @interface_method_impl{PDMIOAPICREG,pfnSetIrqR3} 572 * @remarks The device critsect is entered by the caller(s).573 607 */ 574 608 PDMBOTHCBDECL(void) ioapicSetIrq(PPDMDEVINS pDevIns, int iIrq, int iLevel, uint32_t uTagSrc) … … 579 613 STAM_COUNTER_INC(&pThis->CTX_SUFF(StatSetIrq)); 580 614 581 if (iIrq >= 0 && iIrq < (int)RT_ELEMENTS(pThis->au64RedirTable)) 582 { 583 uint8_t const idxRte = iIrq; 584 uint64_t const u64Rte = pThis->au64RedirTable[idxRte]; 585 uint8_t const u8TriggerMode = IOAPIC_RTE_GET_TRIGGER_MODE(u64Rte); 586 uint32_t const uPinMask = UINT32_C(1) << idxRte; 615 if (RT_LIKELY(iIrq >= 0 && iIrq < (int)RT_ELEMENTS(pThis->au64RedirTable))) 616 { 617 uint8_t const idxRte = iIrq; 618 uint32_t const uPinMask = UINT32_C(1) << idxRte; 619 uint32_t const u32RteLo = pThis->au64RedirTable[idxRte].au32[0]; 620 uint8_t const u8TriggerMode = IOAPIC_RTE_GET_TRIGGER_MODE(u32RteLo); 621 622 bool fActive = RT_BOOL(iLevel & 1); 623 /** @todo Polarity is busted elsewhere, we need to fix that 624 * first. See @bugref{8386#c7}. */ 625 #if 0 626 uint8_t const u8Polarity = IOAPIC_RTE_GET_POLARITY(u32RteLo); 627 fActive ^= u8Polarity; */ 628 #endif 629 if (!fActive) 630 { 631 ASMAtomicAndU32(&pThis->uIrr, ~uPinMask); 632 return; 633 } 634 635 /* 636 * If the device is flip-flopping the interrupt line, there's no need to 637 * set and unset the IRR as they're atomic operations and the fewer the 638 * better. 639 */ 640 bool const fTouchIrr = !((iLevel & PDM_IRQ_LEVEL_FLIP_FLOP) == PDM_IRQ_LEVEL_FLIP_FLOP); 587 641 588 642 if (u8TriggerMode == IOAPIC_RTE_TRIGGER_MODE_EDGE) 589 643 { 590 /** @todo Consider polarity for edge-triggered interrupts? There 591 * seems to be a conflict between "The Unabridged Pentium" 592 * book and the I/O APIC specs. */ 593 if (iLevel) 644 /* 645 * For edge-triggered interrupts, we need to act only on an edge transition. 646 * See ICH9 spec. 13.5.7 "REDIR_TBL: Redirection Table (LPC I/F-D31:F0)" 647 */ 648 uint32_t const uPrevIrr = pThis->uIrr & uPinMask; 649 if (!uPrevIrr) 594 650 { 595 pThis->uIrr |= uPinMask; 651 if (fTouchIrr) 652 ASMAtomicOrU32(&pThis->uIrr, uPinMask); 653 596 654 if (!pThis->au32TagSrc[idxRte]) 597 655 pThis->au32TagSrc[idxRte] = uTagSrc; … … 599 657 pThis->au32TagSrc[idxRte] = RT_BIT_32(31); 600 658 601 ioapicSignalI rqForRte(pThis, idxRte);659 ioapicSignalIntrForRte(pThis, idxRte); 602 660 } 603 661 else 604 pThis->uIrr &= ~uPinMask; 662 { 663 STAM_COUNTER_INC(&pThis->StatRedundantEdgeIntr); 664 Log2(("IOAPIC: Redundant edge-triggered interrupt %#x (%u)\n", idxRte, idxRte)); 665 } 605 666 } 606 667 else … … 608 669 Assert(u8TriggerMode == IOAPIC_RTE_TRIGGER_MODE_LEVEL); 609 670 610 bool fActive = RT_BOOL(iLevel & 1);611 /** @todo Polarity is busted elsewhere, we need to fix that612 * first. See @bugref{8386#c7}. */613 #if 0 614 uint8_t const u8Polarity = IOAPIC_RTE_GET_POLARITY(u64Rte);615 fActive ^= u8Polarity; */616 #endif 617 618 if (fActive)671 /* 672 * For level-triggered interrupts, redundant interrupts are not a problem 673 * and will eventually be delivered anyway after an EOI, but our PDM devices 674 * should not typically call us with no change to the level. 675 */ 676 uint32_t const uPrevIrr = pThis->uIrr & uPinMask; 677 if (!uPrevIrr) 678 { /* likely */ } 679 else 619 680 { 620 pThis->uIrr |= uPinMask; 621 if (!pThis->au32TagSrc[idxRte]) 622 pThis->au32TagSrc[idxRte] = uTagSrc; 623 else 624 pThis->au32TagSrc[idxRte] = RT_BIT_32(31); 625 626 ioapicSignalIrqForRte(pThis, idxRte); 627 628 if ((iLevel & PDM_IRQ_LEVEL_FLIP_FLOP) == PDM_IRQ_LEVEL_FLIP_FLOP) 629 { 630 pThis->uIrr &= ~uPinMask; 631 pThis->au32TagSrc[idxRte] = 0; 632 } 681 STAM_COUNTER_INC(&pThis->StatRedundantLevelIntr); 682 Log2(("IOAPIC: Redundant level-triggered interrupt %#x (%u)\n", idxRte, idxRte)); 633 683 } 684 685 if (fTouchIrr) 686 ASMAtomicOrU32(&pThis->uIrr, uPinMask); 687 688 if (!pThis->au32TagSrc[idxRte]) 689 pThis->au32TagSrc[idxRte] = uTagSrc; 634 690 else 635 pThis->uIrr &= ~uPinMask; 691 pThis->au32TagSrc[idxRte] = RT_BIT_32(31); 692 693 ioapicSignalIntrForRte(pThis, idxRte); 636 694 } 637 695 } … … 641 699 /** 642 700 * @interface_method_impl{PDMIOAPICREG,pfnSendMsiR3} 643 * @remarks The device critsect is entered by the caller(s).644 701 */ 645 702 PDMBOTHCBDECL(void) ioapicSendMsi(PPDMDEVINS pDevIns, RTGCPHYS GCPhys, uint32_t uValue, uint32_t uTagSrc) … … 689 746 STAM_COUNTER_INC(&pThis->CTX_SUFF(StatMmioRead)); 690 747 691 IOAPIC_LOCK(pThis, VINF_IOM_R3_MMIO_READ);692 693 748 int rc = VINF_SUCCESS; 694 749 uint32_t *puValue = (uint32_t *)pv; … … 710 765 } 711 766 712 IOAPIC_UNLOCK(pThis);713 714 767 LogFlow(("IOAPIC: ioapicMmioRead: offReg=%#x, returns %#RX32\n", offReg, *puValue)); 715 768 return rc; … … 725 778 726 779 STAM_COUNTER_INC(&pThis->CTX_SUFF(StatMmioWrite)); 727 728 IOAPIC_LOCK(pThis, VINF_IOM_R3_MMIO_WRITE);729 780 730 781 Assert(!(GCPhysAddr & 3)); … … 757 808 } 758 809 759 IOAPIC_UNLOCK(pThis);760 810 return VINF_SUCCESS; 761 811 } … … 926 976 }; 927 977 928 const uint64_t u Entry = pThis->au64RedirTable[idxRte];929 const char *pszDestMode = IOAPIC_RTE_GET_DEST_MODE(u Entry) == 0 ? "phys" : "log ";930 const uint8_t uDest = IOAPIC_RTE_GET_DEST(u Entry);931 const uint8_t uMask = IOAPIC_RTE_GET_MASK(u Entry);932 const char *pszTriggerMode = IOAPIC_RTE_GET_TRIGGER_MODE(u Entry) == 0 ? "edge " : "level";933 const uint8_t uRemoteIrr = IOAPIC_RTE_GET_REMOTE_IRR(u Entry);934 const char *pszPolarity = IOAPIC_RTE_GET_POLARITY(u Entry) == 0 ? "acthi" : "actlo";935 const char *pszDeliveryStatus = IOAPIC_RTE_GET_DELIVERY_STATUS(u Entry) == 0 ? "idle" : "pend";936 const uint8_t uDeliveryMode = IOAPIC_RTE_GET_DELIVERY_MODE(u Entry);937 978 const uint64_t u64Rte = pThis->au64RedirTable[idxRte].u; 979 const char *pszDestMode = IOAPIC_RTE_GET_DEST_MODE(u64Rte) == 0 ? "phys" : "log "; 980 const uint8_t uDest = IOAPIC_RTE_GET_DEST(u64Rte); 981 const uint8_t uMask = IOAPIC_RTE_GET_MASK(u64Rte); 982 const char *pszTriggerMode = IOAPIC_RTE_GET_TRIGGER_MODE(u64Rte) == 0 ? "edge " : "level"; 983 const uint8_t uRemoteIrr = IOAPIC_RTE_GET_REMOTE_IRR(u64Rte); 984 const char *pszPolarity = IOAPIC_RTE_GET_POLARITY(u64Rte) == 0 ? "acthi" : "actlo"; 985 const char *pszDeliveryStatus = IOAPIC_RTE_GET_DELIVERY_STATUS(u64Rte) == 0 ? "idle" : "pend"; 986 const uint8_t uDeliveryMode = IOAPIC_RTE_GET_DELIVERY_MODE(u64Rte); 987 Assert(uDeliveryMode < RT_ELEMENTS(s_apszDeliveryModes)); 938 988 const char *pszDeliveryMode = s_apszDeliveryModes[uDeliveryMode]; 939 const uint8_t uVector = IOAPIC_RTE_GET_VECTOR(u Entry);989 const uint8_t uVector = IOAPIC_RTE_GET_VECTOR(u64Rte); 940 990 941 991 pHlp->pfnPrintf(pHlp, " %02d %s %02x %u %u %s %u %s %s %s %3u (%016llx)\n", … … 951 1001 pszDeliveryMode, 952 1002 uVector, 953 pThis->au64RedirTable[idxRte]);1003 u64Rte); 954 1004 } 955 1005 } … … 968 1018 SSMR3PutU8(pSSM, pThis->u8Index); 969 1019 for (uint8_t idxRte = 0; idxRte < RT_ELEMENTS(pThis->au64RedirTable); idxRte++) 970 SSMR3PutU64(pSSM, pThis->au64RedirTable[idxRte] );1020 SSMR3PutU64(pSSM, pThis->au64RedirTable[idxRte].u); 971 1021 972 1022 return VINF_SUCCESS; … … 994 1044 995 1045 if (uVersion == IOAPIC_SAVED_STATE_VERSION) 996 SSMR3GetU32(pSSM, &pThis->uIrr);997 998 SSMR3GetU8(pSSM, &pThis->u8Id);999 SSMR3GetU8(pSSM, &pThis->u8Index);1046 SSMR3GetU32(pSSM, (uint32_t *)&pThis->uIrr); 1047 1048 SSMR3GetU8(pSSM, (uint8_t *)&pThis->u8Id); 1049 SSMR3GetU8(pSSM, (uint8_t *)&pThis->u8Index); 1000 1050 for (uint8_t idxRte = 0; idxRte < RT_ELEMENTS(pThis->au64RedirTable); idxRte++) 1001 SSMR3GetU64(pSSM, &pThis->au64RedirTable[idxRte]);1051 SSMR3GetU64(pSSM, (uint64_t *)&pThis->au64RedirTable[idxRte].u); 1002 1052 1003 1053 return VINF_SUCCESS; … … 1013 1063 LogFlow(("IOAPIC: ioapicR3Reset: pThis=%p\n", pThis)); 1014 1064 1015 /* We lock here to prevent concurrent writes from ioapicSetIrq() from device threads. */ 1016 IOAPIC_LOCK_VOID(pThis); 1017 1018 pThis->uIrr = 0; 1019 pThis->u8Index = 0; 1020 pThis->u8Id = 0; 1065 /* There might be devices threads calling ioapicSetIrq() in parallel, hence the atomics. */ 1066 ASMAtomicWriteU32(&pThis->uIrr, 0); 1067 ASMAtomicWriteU8(&pThis->u8Index, 0); 1068 ASMAtomicWriteU8(&pThis->u8Id, 0); 1021 1069 1022 1070 for (uint8_t idxRte = 0; idxRte < RT_ELEMENTS(pThis->au64RedirTable); idxRte++) 1023 1071 { 1024 pThis->au64RedirTable[idxRte] = IOAPIC_RTE_MASK; 1025 pThis->au32TagSrc[idxRte] = 0; 1026 } 1027 1028 IOAPIC_UNLOCK(pThis); 1072 ASMAtomicWriteU64(&pThis->au64RedirTable[idxRte].u, IOAPIC_RTE_MASK); 1073 pThis->au32TagSrc[idxRte] = 0; 1074 } 1029 1075 } 1030 1076 … … 1064 1110 PDMDEV_VALIDATE_CONFIG_RETURN(pDevIns, "NumCPUs|RZEnabled", ""); 1065 1111 1112 /* The number of CPUs is currently unused, but left in CFGM and saved-state in case an ID of 0 is 1113 upsets some guest which we haven't yet tested. */ 1066 1114 uint32_t cCpus; 1067 1115 int rc = CFGMR3QueryU32Def(pCfg, "NumCPUs", &cCpus, 1); 1068 1116 if (RT_FAILURE(rc)) 1069 1117 return PDMDEV_SET_ERROR(pDevIns, rc, N_("Configuration error: Failed to query integer value \"NumCPUs\"")); 1070 if (cCpus > UINT8_MAX - 2) /* ID 255 is broadcast and the IO-APIC needs one (ID=cCpus). */1071 {1072 return PDMDevHlpVMSetError(pDevIns, rc, RT_SRC_POS,1073 N_("Configuration error: Max %u CPUs, %u specified"), UINT8_MAX - 1, cCpus);1074 }1075 1118 pThis->cCpus = (uint8_t)cCpus; 1076 1119 … … 1084 1127 1085 1128 /* 1086 * We shall do locking for this device via IOAPIC helpers.1129 * We don't do any locking for the IOAPIC device. 1087 1130 */ 1088 1131 rc = PDMDevHlpSetDeviceCritSect(pDevIns, PDMDevHlpCritSectGetNop(pDevIns)); … … 1183 1226 PDMDevHlpSTAMRegister(pDevIns, &pThis->StatSetIrqRC, STAMTYPE_COUNTER, "/Devices/IOAPIC/RC/SetIrqRC", STAMUNIT_OCCURENCES, "Number of IOAPIC SetIrq calls in RC."); 1184 1227 PDMDevHlpSTAMRegister(pDevIns, &pThis->StatSetEoiRC, STAMTYPE_COUNTER, "/Devices/IOAPIC/RC/SetEoiRC", STAMUNIT_OCCURENCES, "Number of IOAPIC SetEoi calls in RC."); 1228 1229 PDMDevHlpSTAMRegister(pDevIns, &pThis->StatRedundantEdgeIntr, STAMTYPE_COUNTER, "/Devices/IOAPIC/RedundantEdgeIntr", STAMUNIT_OCCURENCES, "Number of redundant edge-triggered interrupts (no IRR change)."); 1230 PDMDevHlpSTAMRegister(pDevIns, &pThis->StatRedundantLevelIntr, STAMTYPE_COUNTER, "/Devices/IOAPIC/RedundantLevelIntr", STAMUNIT_OCCURENCES, "Number of redundant level-triggered interrupts (no IRR change)."); 1231 PDMDevHlpSTAMRegister(pDevIns, &pThis->StatSuppressedLevelIntr, STAMTYPE_COUNTER, "/Devices/IOAPIC/SuppressedLevelIntr", STAMUNIT_OCCURENCES, "Number of suppressed level-triggered interrupts by remote IRR."); 1185 1232 #endif 1186 1233 -
trunk/src/VBox/VMM/VMMAll/PDMAll.cpp
r60804 r61685 194 194 { 195 195 Assert(pVM->pdm.s.IoApic.CTX_SUFF(pfnSetIrq)); 196 #ifdef VBOX_WITH_NEW_IOAPIC 197 pVM->pdm.s.IoApic.CTX_SUFF(pfnSetIrq)(pVM->pdm.s.IoApic.CTX_SUFF(pDevIns), u8Irq, u8Level, uTagSrc); 198 #else 196 199 pdmLock(pVM); 197 200 pVM->pdm.s.IoApic.CTX_SUFF(pfnSetIrq)(pVM->pdm.s.IoApic.CTX_SUFF(pDevIns), u8Irq, u8Level, uTagSrc); 198 201 pdmUnlock(pVM); 202 #endif 199 203 return VINF_SUCCESS; 200 204 } … … 216 220 { 217 221 Assert(pVM->pdm.s.IoApic.CTX_SUFF(pfnSendMsi)); 222 #ifdef VBOX_WITH_NEW_IOAPIC 223 pVM->pdm.s.IoApic.CTX_SUFF(pfnSendMsi)(pVM->pdm.s.IoApic.CTX_SUFF(pDevIns), GCAddr, uValue, uTagSrc); 224 #else 218 225 pdmLock(pVM); 219 226 pVM->pdm.s.IoApic.CTX_SUFF(pfnSendMsi)(pVM->pdm.s.IoApic.CTX_SUFF(pDevIns), GCAddr, uValue, uTagSrc); 220 227 pdmUnlock(pVM); 228 #endif 221 229 return VINF_SUCCESS; 222 230 } -
trunk/src/VBox/VMM/VMMR0/PDMR0Device.cpp
r61356 r61685 618 618 { 619 619 Assert(pVM->pdm.s.IoApic.CTX_SUFF(pfnSetEoi)); 620 pdmLock(pVM);621 620 pVM->pdm.s.IoApic.CTX_SUFF(pfnSetEoi)(pVM->pdm.s.IoApic.CTX_SUFF(pDevIns), u8Vector); 622 pdmUnlock(pVM);623 621 } 624 622 #endif … … 743 741 { 744 742 PDMDEV_ASSERT_DEVINS(pDevIns); 743 #ifdef VBOX_WITH_NEW_IOAPIC 744 AssertFailed(); 745 #endif 745 746 return pdmLockEx(pDevIns->Internal.s.pVMR0, rc); 746 747 } … … 751 752 { 752 753 PDMDEV_ASSERT_DEVINS(pDevIns); 754 #ifdef VBOX_WITH_NEW_IOAPIC 755 AssertFailed(); 756 #endif 753 757 pdmUnlock(pDevIns->Internal.s.pVMR0); 754 758 } … … 798 802 if (pVM->pdm.s.IoApic.pDevInsR0) 799 803 { 804 #ifdef VBOX_WITH_NEW_IOAPIC 805 pVM->pdm.s.IoApic.pfnSetIrqR0(pVM->pdm.s.IoApic.pDevInsR0, iIrq, iLevel, uTagSrc); 806 #else 800 807 pdmLock(pVM); 801 808 pVM->pdm.s.IoApic.pfnSetIrqR0(pVM->pdm.s.IoApic.pDevInsR0, iIrq, iLevel, uTagSrc); 802 809 pdmUnlock(pVM); 810 #endif 803 811 } 804 812 else if (pVM->pdm.s.IoApic.pDevInsR3) … … 830 838 if (pVM->pdm.s.IoApic.pDevInsR0) 831 839 { 840 #ifdef VBOX_WITH_NEW_IOAPIC 841 pVM->pdm.s.IoApic.pfnSendMsiR0(pVM->pdm.s.IoApic.pDevInsR0, GCPhys, uValue, uTagSrc); 842 #else 832 843 pdmLock(pVM); 833 844 pVM->pdm.s.IoApic.pfnSendMsiR0(pVM->pdm.s.IoApic.pDevInsR0, GCPhys, uValue, uTagSrc); 834 845 pdmUnlock(pVM); 846 #endif 835 847 } 836 848 else 837 {838 849 AssertFatalMsgFailed(("Lazy bastards!")); 839 }840 850 } 841 851 -
trunk/src/VBox/VMM/VMMR3/PDMDevMiscHlp.cpp
r61364 r61685 281 281 { 282 282 Assert(pVM->pdm.s.IoApic.CTX_SUFF(pfnSetEoi)); 283 pdmLock(pVM);284 283 pVM->pdm.s.IoApic.CTX_SUFF(pfnSetEoi)(pVM->pdm.s.IoApic.CTX_SUFF(pDevIns), u8Vector); 285 pdmUnlock(pVM); 286 } 287 #endif 288 } 289 284 } 285 #endif 286 } 290 287 291 288 … … 495 492 PDMDEV_ASSERT_DEVINS(pDevIns); 496 493 LogFlow(("pdmR3IoApicHlp_Lock: caller='%s'/%d: rc=%Rrc\n", pDevIns->pReg->szName, pDevIns->iInstance, rc)); 494 #ifdef VBOX_WITH_NEW_IOAPIC 495 AssertFailed(); 496 #endif 497 497 return pdmLockEx(pDevIns->Internal.s.pVMR3, rc); 498 498 } … … 504 504 PDMDEV_ASSERT_DEVINS(pDevIns); 505 505 LogFlow(("pdmR3IoApicHlp_Unlock: caller='%s'/%d:\n", pDevIns->pReg->szName, pDevIns->iInstance)); 506 #ifdef VBOX_WITH_NEW_IOAPIC 507 AssertFailed(); 508 #endif 506 509 pdmUnlock(pDevIns->Internal.s.pVMR3); 507 510 } -
trunk/src/VBox/VMM/VMMRC/PDMRCDevice.cpp
r61356 r61685 573 573 { 574 574 Assert(pVM->pdm.s.IoApic.CTX_SUFF(pfnSetEoi)); 575 pdmLock(pVM);576 575 pVM->pdm.s.IoApic.CTX_SUFF(pfnSetEoi)(pVM->pdm.s.IoApic.CTX_SUFF(pDevIns), u8Vector); 577 pdmUnlock(pVM);578 576 } 579 577 #endif … … 698 696 { 699 697 PDMDEV_ASSERT_DEVINS(pDevIns); 698 #ifdef VBOX_WITH_NEW_IOAPIC 699 AssertFailed(); 700 #endif 700 701 return pdmLockEx(pDevIns->Internal.s.pVMRC, rc); 701 702 } … … 706 707 { 707 708 PDMDEV_ASSERT_DEVINS(pDevIns); 709 #ifdef VBOX_WITH_NEW_IOAPIC 710 AssertFailed(); 711 #endif 708 712 pdmUnlock(pDevIns->Internal.s.pVMRC); 709 713 } … … 753 757 if (pVM->pdm.s.IoApic.pDevInsRC) 754 758 { 759 #ifdef VBOX_WITH_NEW_IOAPIC 760 pVM->pdm.s.IoApic.pfnSetIrqRC(pVM->pdm.s.IoApic.pDevInsRC, iIrq, iLevel, uTagSrc); 761 #else 755 762 pdmLock(pVM); 756 763 pVM->pdm.s.IoApic.pfnSetIrqRC(pVM->pdm.s.IoApic.pDevInsRC, iIrq, iLevel, uTagSrc); 757 764 pdmUnlock(pVM); 765 #endif 758 766 } 759 767 else if (pVM->pdm.s.IoApic.pDevInsR3) … … 786 794 if (pVM->pdm.s.IoApic.pDevInsRC) 787 795 { 796 #ifdef VBOX_WITH_NEW_IOAPIC 797 pVM->pdm.s.IoApic.pfnSendMsiRC(pVM->pdm.s.IoApic.pDevInsRC, GCPhys, uValue, uTagSrc); 798 #else 788 799 pdmLock(pVM); 789 800 pVM->pdm.s.IoApic.pfnSendMsiRC(pVM->pdm.s.IoApic.pDevInsRC, GCPhys, uValue, uTagSrc); 790 801 pdmUnlock(pVM); 802 #endif 791 803 } 792 804 else 793 {794 805 AssertFatalMsgFailed(("Lazy bastarts!")); 795 }796 806 } 797 807
Note:
See TracChangeset
for help on using the changeset viewer.