Changeset 81913 in vbox
- Timestamp:
- Nov 17, 2019 8:14:50 PM (5 years ago)
- svn:sync-xref-src-repo-rev:
- 134710
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/Devices/PC/DevPIC.cpp
r81912 r81913 62 62 /** @def PIC_UNLOCK 63 63 * Releases the PDM lock. This is a NOP if locking is disabled. */ 64 #define PIC_LOCK( pThis, rc) \64 #define PIC_LOCK(a_pDevIns, a_pThis, rc) \ 65 65 do { \ 66 int rc2 = ( pThis)->CTX_SUFF(pPicHlp)->pfnLock((pThis)->CTX_SUFF(pDevIns), rc); \66 int rc2 = (a_pThis)->CTX_SUFF(pPicHlp)->pfnLock((a_pDevIns), rc); \ 67 67 if (rc2 != VINF_SUCCESS) \ 68 68 return rc2; \ 69 69 } while (0) 70 #define PIC_UNLOCK(pThis) \ 71 (pThis)->CTX_SUFF(pPicHlp)->pfnUnlock((pThis)->CTX_SUFF(pDevIns)) 72 73 74 /* debug PIC */ 75 #define DEBUG_PIC 76 77 /*#define DEBUG_IRQ_COUNT*/ 78 70 #define PIC_UNLOCK(a_pDevIns, a_pThis) \ 71 (a_pThis)->CTX_SUFF(pPicHlp)->pfnUnlock((a_pDevIns)) 72 73 74 /********************************************************************************************************************************* 75 * Structures and Typedefs * 76 *********************************************************************************************************************************/ 79 77 /** 80 78 * The instance data of one (1) PIC. … … 82 80 typedef struct PICSTATE 83 81 { 84 uint8_t last_irr; /**< edge detection */ 85 uint8_t irr; /**< interrupt request register */ 86 uint8_t imr; /**< interrupt mask register */ 87 uint8_t isr; /**< interrupt service register */ 88 uint8_t priority_add; /**< highest irq priority */ 89 uint8_t irq_base; 90 uint8_t read_reg_select; 91 uint8_t poll; 92 uint8_t special_mask; 93 uint8_t init_state; 94 uint8_t auto_eoi; 95 uint8_t rotate_on_auto_eoi; 96 uint8_t special_fully_nested_mode; 97 uint8_t init4; /**< true if 4 byte init */ 98 uint8_t elcr; /**< PIIX edge/trigger selection*/ 99 uint8_t elcr_mask; 100 /** Pointer to the device instance, R3 Ptr. */ 101 PPDMDEVINSR3 pDevInsR3; 102 /** Pointer to the device instance, R0 Ptr. */ 103 PPDMDEVINSR0 pDevInsR0; 104 /** Pointer to the device instance, RC Ptr. */ 105 PPDMDEVINSRC pDevInsRC; 82 uint8_t last_irr; /**< edge detection */ 83 uint8_t irr; /**< interrupt request register */ 84 uint8_t imr; /**< interrupt mask register */ 85 uint8_t isr; /**< interrupt service register */ 86 uint8_t priority_add; /**< highest irq priority */ 87 uint8_t irq_base; 88 uint8_t read_reg_select; 89 uint8_t poll; 90 uint8_t special_mask; 91 uint8_t init_state; 92 uint8_t auto_eoi; 93 uint8_t rotate_on_auto_eoi; 94 uint8_t special_fully_nested_mode; 95 uint8_t init4; /**< true if 4 byte init */ 96 uint8_t elcr; /**< PIIX edge/trigger selection*/ 97 uint8_t elcr_mask; 98 /** The IRQ tags and source IDs for each (tracing purposes). */ 99 uint32_t auTags[8]; 106 100 /** The PIC index (0 or 1). */ 107 101 uint8_t idxPic; 108 uint8_t abAlignment0[3]; /**< Alignment padding. */ 109 /** The IRQ tags and source IDs for each (tracing purposes). */ 110 uint32_t auTags[8]; 102 uint8_t abAlignment0[7]; /**< Alignment padding. */ 111 103 /** The two I/O ports at 0x20 or 0xa0. */ 112 104 IOMIOPORTHANDLE hIoPorts0; … … 126 118 /** The two interrupt controllers. */ 127 119 PICSTATE aPics[2]; 128 /** Pointer to the device instance - R3 Ptr. */129 PPDMDEVINSR3 pDevInsR3;130 120 /** Pointer to the PIC R3 helpers. */ 131 121 R3PTRTYPE(PCPDMPICHLP) pPicHlpR3; 132 /** Pointer to the device instance - R0 Ptr. */133 PPDMDEVINSR0 pDevInsR0;134 122 /** Pointer to the PIC R0 helpers. */ 135 123 R0PTRTYPE(PCPDMPICHLP) pPicHlpR0; 136 /** Pointer to the device instance - RC Ptr. */137 PPDMDEVINSRC pDevInsRC;138 124 /** Pointer to the PIC RC helpers. */ 139 125 RCPTRTYPE(PCPDMPICHLP) pPicHlpRC; 140 126 /** Number of release log entries. Used to prevent flooding. */ 141 127 uint32_t cRelLogEntries; 142 uint32_t u32AlignmentPadding;143 128 #ifdef VBOX_WITH_STATISTICS 144 129 STAMCOUNTER StatSetIrqRZ; … … 153 138 154 139 155 #ifndef VBOX_DEVICE_STRUCT_TESTCASE 140 #ifndef VBOX_DEVICE_STRUCT_TESTCASE /* The rest of the file! */ 141 156 142 #ifdef LOG_ENABLED 157 143 DECLINLINE(void) DumpPICState(PPICSTATE pPic, const char *pszFn) 158 144 { 159 PDEVPIC pThis = PDMDEVINS_2_DATA(pPic->CTX_SUFF(pDevIns), PDEVPIC);160 161 145 Log2(("%s: pic%d: elcr=%x last_irr=%x irr=%x imr=%x isr=%x irq_base=%x\n", 162 pszFn, (&pThis->aPics[0] == pPic) ? 0 : 1, 163 pPic->elcr, pPic->last_irr, pPic->irr, pPic->imr, pPic->isr, pPic->irq_base)); 146 pszFn, pPic->idxPic, pPic->elcr, pPic->last_irr, pPic->irr, pPic->imr, pPic->isr, pPic->irq_base)); 164 147 } 165 148 #else … … 265 248 /* raise irq to CPU if necessary. must be called every time the active 266 249 irq may change */ 267 static int pic_update_irq(P DEVPIC pThis)250 static int pic_update_irq(PPDMDEVINS pDevIns, PDEVPIC pThis) 268 251 { 269 252 int irq2, irq; … … 291 274 if (irq != 2 || irq2 != -1) 292 275 { 293 #if defined(DEBUG_PIC)294 276 for (int i = 0; i < 2; i++) 295 277 Log(("pic%d: imr=%x irr=%x padd=%d\n", i, pThis->aPics[i].imr, pThis->aPics[i].irr, pThis->aPics[i].priority_add)); 296 278 Log(("pic: cpu_interrupt\n")); 297 #endif 298 pThis->CTX_SUFF(pPicHlp)->pfnSetInterruptFF(pThis->CTX_SUFF(pDevIns)); 279 pThis->CTX_SUFF(pPicHlp)->pfnSetInterruptFF(pDevIns); 299 280 } 300 281 else … … 305 286 306 287 /* if this was the only pending irq, then we must clear the interrupt ff flag */ 307 pThis->CTX_SUFF(pPicHlp)->pfnClearInterruptFF(p This->CTX_SUFF(pDevIns));288 pThis->CTX_SUFF(pPicHlp)->pfnClearInterruptFF(pDevIns); 308 289 309 290 /** @todo Is this correct? */ … … 311 292 312 293 /* Call ourselves again just in case other interrupts are pending */ 313 return pic_update_irq(p This);294 return pic_update_irq(pDevIns, pThis); 314 295 } 315 296 } … … 319 300 320 301 /* we must clear the interrupt ff flag */ 321 pThis->CTX_SUFF(pPicHlp)->pfnClearInterruptFF(p This->CTX_SUFF(pDevIns));302 pThis->CTX_SUFF(pPicHlp)->pfnClearInterruptFF(pDevIns); 322 303 } 323 304 return VINF_SUCCESS; … … 335 316 { 336 317 PDEVPIC pThis = PDMDEVINS_2_DATA(pDevIns, PDEVPIC); 337 Assert(pThis->CTX_SUFF(pDevIns) == pDevIns);338 Assert(pThis->aPics[0].CTX_SUFF(pDevIns) == pDevIns);339 Assert(pThis->aPics[1].CTX_SUFF(pDevIns) == pDevIns);340 318 AssertMsgReturnVoid(iIrq < 16, ("iIrq=%d\n", iIrq)); 341 319 … … 350 328 * line must be held high for a while to avoid spurious interrupts. 351 329 */ 352 pic_set_irq1(& pThis->aPics[iIrq >> 3], iIrq & 7, 0, uTagSrc);353 pic_update_irq(p This);354 } 355 pic_set_irq1(& pThis->aPics[iIrq >> 3], iIrq & 7, iLevel & PDM_IRQ_LEVEL_HIGH, uTagSrc);356 pic_update_irq(p This);330 pic_set_irq1(&RT_SAFE_SUBSCRIPT(pThis->aPics, iIrq >> 3), iIrq & 7, 0, uTagSrc); 331 pic_update_irq(pDevIns, pThis); 332 } 333 pic_set_irq1(&RT_SAFE_SUBSCRIPT(pThis->aPics, iIrq >> 3), iIrq & 7, iLevel & PDM_IRQ_LEVEL_HIGH, uTagSrc); 334 pic_update_irq(pDevIns, pThis); 357 335 } 358 336 … … 433 411 *puTagSrc = 0; 434 412 } 435 pic_update_irq(p This);413 pic_update_irq(pDevIns, pThis); 436 414 437 415 Log(("picGetInterrupt: 0x%02x pending 0:%d 1:%d\n", intno, pic_get_irq(&pThis->aPics[0]), pic_get_irq(&pThis->aPics[1]))); … … 462 440 463 441 464 static VBOXSTRICTRC pic_ioport_write(P DEVPIC pThis, PPICSTATE pPic, uint32_t addr, uint32_t val)442 static VBOXSTRICTRC pic_ioport_write(PPDMDEVINS pDevIns, PDEVPIC pThis, PPICSTATE pPic, uint32_t addr, uint32_t val) 465 443 { 466 444 VBOXSTRICTRC rc = VINF_SUCCESS; … … 476 454 pic_reset(pPic); 477 455 /* deassert a pending interrupt */ 478 pThis->CTX_SUFF(pPicHlp)->pfnClearInterruptFF(p This->CTX_SUFF(pDevIns));456 pThis->CTX_SUFF(pPicHlp)->pfnClearInterruptFF(pDevIns); 479 457 480 458 pPic->init_state = 1; … … 514 492 if (cmd == 5) 515 493 pPic->priority_add = (irq + 1) & 7; 516 rc = pic_update_irq(p This);494 rc = pic_update_irq(pDevIns, pThis); 517 495 Assert(rc == VINF_SUCCESS); 518 496 DumpPICState(pPic, "eoi"); … … 525 503 Log(("pic_write: EOI2 for irq %d\n", irq)); 526 504 pPic->isr &= ~(1 << irq); 527 rc = pic_update_irq(p This);505 rc = pic_update_irq(pDevIns, pThis); 528 506 Assert(rc == VINF_SUCCESS); 529 507 DumpPICState(pPic, "eoi2"); … … 534 512 pPic->priority_add = (val + 1) & 7; 535 513 Log(("pic_write: lowest priority %d (highest %d)\n", val & 7, pPic->priority_add)); 536 rc = pic_update_irq(p This);514 rc = pic_update_irq(pDevIns, pThis); 537 515 Assert(rc == VINF_SUCCESS); 538 516 break; … … 544 522 pPic->isr &= ~(1 << irq); 545 523 pPic->priority_add = (irq + 1) & 7; 546 rc = pic_update_irq(p This);524 rc = pic_update_irq(pDevIns, pThis); 547 525 Assert(rc == VINF_SUCCESS); 548 526 DumpPICState(pPic, "eoi3"); … … 562 540 /* normal mode */ 563 541 pPic->imr = val; 564 rc = pic_update_irq(p This);542 rc = pic_update_irq(pDevIns, pThis); 565 543 Assert(rc == VINF_SUCCESS); 566 544 break; … … 588 566 589 567 590 static uint32_t pic_poll_read(PPICSTATE pPic, uint32_t addr1) 591 { 592 PDEVPIC pThis = RT_FROM_MEMBER_DYN(pPic, DEVPIC, aPics[pPic->idxPic]); 593 568 static uint32_t pic_poll_read(PPDMDEVINS pDevIns, PDEVPIC pThis, PPICSTATE pPic, uint32_t addr1) 569 { 594 570 int ret = pic_get_irq(pPic); 595 571 if (ret >= 0) … … 605 581 pPic->isr &= ~(1 << ret); 606 582 if (addr1 >> 7 || ret != 2) 607 pic_update_irq(p This);583 pic_update_irq(pDevIns, pThis); 608 584 } 609 585 else 610 586 { 611 587 ret = 0; 612 pic_update_irq(p This);588 pic_update_irq(pDevIns, pThis); 613 589 } 614 590 … … 617 593 618 594 619 static uint32_t pic_ioport_read(PP ICSTATE pPic, uint32_t addr1, int *pRC)595 static uint32_t pic_ioport_read(PPDMDEVINS pDevIns, PDEVPIC pThis, PPICSTATE pPic, uint32_t addr1, int *pRC) 620 596 { 621 597 unsigned int addr; … … 628 604 if (pPic->poll) 629 605 { 630 ret = pic_poll_read(p Pic, addr1);606 ret = pic_poll_read(pDevIns, pThis, pPic, addr1); 631 607 pPic->poll = 0; 632 608 } … … 663 639 { 664 640 int rc; 665 PIC_LOCK(p This, VINF_IOM_R3_IOPORT_READ);666 *pu32 = pic_ioport_read( &RT_SAFE_SUBSCRIPT(pThis->aPics, iPic), offPort, &rc);667 PIC_UNLOCK(p This);641 PIC_LOCK(pDevIns, pThis, VINF_IOM_R3_IOPORT_READ); 642 *pu32 = pic_ioport_read(pDevIns, pThis, &RT_SAFE_SUBSCRIPT(pThis->aPics, iPic), offPort, &rc); 643 PIC_UNLOCK(pDevIns, pThis); 668 644 return rc; 669 645 } … … 685 661 { 686 662 VBOXSTRICTRC rc; 687 PIC_LOCK(p This, VINF_IOM_R3_IOPORT_WRITE);688 rc = pic_ioport_write(p This, &RT_SAFE_SUBSCRIPT(pThis->aPics, iPic), offPort, u32);689 PIC_UNLOCK(p This);663 PIC_LOCK(pDevIns, pThis, VINF_IOM_R3_IOPORT_WRITE); 664 rc = pic_ioport_write(pDevIns, pThis, &RT_SAFE_SUBSCRIPT(pThis->aPics, iPic), offPort, u32); 665 PIC_UNLOCK(pDevIns, pThis); 690 666 return rc; 691 667 } … … 701 677 if (cb == 1) 702 678 { 703 PPICSTATE pPic = (PPICSTATE)pvUser; 704 PIC_LOCK(PDMDEVINS_2_DATA(pDevIns, PDEVPIC), VINF_IOM_R3_IOPORT_READ); 679 PDEVPIC pThis = PDMDEVINS_2_DATA(pDevIns, PDEVPIC); 680 PPICSTATE pPic = (PPICSTATE)pvUser; 681 PIC_LOCK(pDevIns, pThis, VINF_IOM_R3_IOPORT_READ); 705 682 *pu32 = pPic->elcr; 706 PIC_UNLOCK( PDMDEVINS_2_DATA(pDevIns, PDEVPIC));683 PIC_UNLOCK(pDevIns, pThis); 707 684 return VINF_SUCCESS; 708 685 } … … 719 696 if (cb == 1) 720 697 { 721 PPICSTATE pPic = (PPICSTATE)pvUser; 722 PIC_LOCK(PDMDEVINS_2_DATA(pDevIns, PDEVPIC), VINF_IOM_R3_IOPORT_WRITE); 698 PDEVPIC pThis = PDMDEVINS_2_DATA(pDevIns, PDEVPIC); 699 PPICSTATE pPic = (PPICSTATE)pvUser; 700 PIC_LOCK(pDevIns, pThis, VINF_IOM_R3_IOPORT_WRITE); 723 701 pPic->elcr = u32 & pPic->elcr_mask; 724 PIC_UNLOCK( PDMDEVINS_2_DATA(pDevIns, PDEVPIC));702 PIC_UNLOCK(pDevIns, pThis); 725 703 } 726 704 RT_NOREF(offPort); … … 742 720 * Show info. 743 721 */ 744 for (int i = 0; i < 2; i++)722 for (int i = 0; i < RT_ELEMENTS(pThis->aPics); i++) 745 723 { 746 724 PPICSTATE pPic = &pThis->aPics[i]; … … 844 822 pic_reset(&pThis->aPics[i]); 845 823 846 PIC_UNLOCK(p This);824 PIC_UNLOCK(pDevIns, pThis); 847 825 } 848 826 … … 853 831 static DECLCALLBACK(void) picR3Relocate(PPDMDEVINS pDevIns, RTGCINTPTR offDelta) 854 832 { 855 RT_NOREF1(offDelta); 856 PDEVPIC pThis = PDMDEVINS_2_DATA(pDevIns, PDEVPIC); 857 unsigned i; 858 859 pThis->pDevInsRC = PDMDEVINS_2_RCPTR(pDevIns); 833 PDEVPIC pThis = PDMDEVINS_2_DATA(pDevIns, PDEVPIC); 860 834 pThis->pPicHlpRC += offDelta; 861 for (i = 0; i < RT_ELEMENTS(pThis->aPics); i++)862 pThis->aPics[i].pDevInsRC = PDMDEVINS_2_RCPTR(pDevIns);863 835 } 864 836 … … 886 858 */ 887 859 Assert(RT_ELEMENTS(pThis->aPics) == 2); 888 pThis->pDevInsR3 = pDevIns;889 pThis->pDevInsR0 = PDMDEVINS_2_R0PTR(pDevIns);890 pThis->pDevInsRC = PDMDEVINS_2_RCPTR(pDevIns);891 860 pThis->aPics[0].elcr_mask = 0xf8; 892 861 pThis->aPics[1].elcr_mask = 0xde; 893 pThis->aPics[0].pDevInsR3 = pDevIns;894 pThis->aPics[1].pDevInsR3 = pDevIns;895 pThis->aPics[0].pDevInsR0 = PDMDEVINS_2_R0PTR(pDevIns);896 pThis->aPics[1].pDevInsR0 = PDMDEVINS_2_R0PTR(pDevIns);897 pThis->aPics[0].pDevInsRC = PDMDEVINS_2_RCPTR(pDevIns);898 pThis->aPics[1].pDevInsRC = PDMDEVINS_2_RCPTR(pDevIns);899 862 pThis->aPics[0].idxPic = 0; 900 863 pThis->aPics[1].idxPic = 1; … … 953 916 picR3Reset(pDevIns); 954 917 955 # ifdef VBOX_WITH_STATISTICS918 # ifdef VBOX_WITH_STATISTICS 956 919 /* 957 920 * Statistics. … … 963 926 PDMDevHlpSTAMRegister(pDevIns, &pThis->StatClearedActiveMasterIRQ, STAMTYPE_COUNTER, "Masked/ActiveMaster", STAMUNIT_OCCURENCES, "Number of cleared master irqs."); 964 927 PDMDevHlpSTAMRegister(pDevIns, &pThis->StatClearedActiveSlaveIRQ, STAMTYPE_COUNTER, "Masked/ActiveSlave", STAMUNIT_OCCURENCES, "Number of cleared slave irqs."); 965 # endif928 # endif 966 929 967 930 return VINF_SUCCESS; … … 992 955 993 956 /* I/O port callbacks: */ 957 Assert(RT_ELEMENTS(pThis->aPics) == 2); 994 958 rc = PDMDevHlpIoPortSetUpContext(pDevIns, pThis->aPics[0].hIoPorts0, picIOPortWrite, picIOPortRead, (void *)0); 995 959 AssertRCReturn(rc, VERR_INTERNAL_ERROR_2);
Note:
See TracChangeset
for help on using the changeset viewer.