Changeset 12612 in vbox for trunk/src/VBox/Devices/PC/DevAPIC.cpp
- Timestamp:
- Sep 19, 2008 5:58:06 PM (16 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/Devices/PC/DevAPIC.cpp
r12598 r12612 78 78 #define IOAPIC_UNLOCK(pThis) (pThis)->CTX_SUFF(pIoApicHlp)->pfnUnlock((pThis)->CTX_SUFF(pDevIns)) 79 79 80 /** @def FIRST_LAPIC80 /** @def LAPIC_BASE 81 81 * Return address of first LAPIC state. */ 82 #define FIRST_LAPIC(pThis) ((APICState*)(pThis)->CTX_SUFF(pLapics))83 84 #define FOR_EACH_LAPIC(dev, code)\82 #define LAPIC_BASE(pThis) ((APICState*)(pThis)->CTX_SUFF(pLapics)) 83 84 #define foreach_apic(dev, mask, code) \ 85 85 do { \ 86 86 uint32_t i; \ 87 APICState* apic = FIRST_LAPIC(dev);\88 for (i =0; i < dev->cCpus; i++)\87 APICState* apic = LAPIC_BASE(dev); \ 88 for (i = 0; i < dev->cCpus; i++) \ 89 89 { \ 90 code; \ 90 if (mask & (1 << (apic->id))) \ 91 { \ 92 code; \ 93 } \ 91 94 apic++; \ 92 95 } \ … … 285 288 } APICDeviceInfo; 286 289 287 DECLINLINE(APICState*) getL APIC(APICDeviceInfo* dev)290 DECLINLINE(APICState*) getLapic(APICDeviceInfo* dev) 288 291 { 289 292 uint32_t id = dev->CTX_SUFF(pApicHlp)->pfnGetCpuId(dev->CTX_SUFF(pDevIns)); 290 return FIRST_LAPIC(dev) + id; 291 } 292 293 return LAPIC_BASE(dev) + id; 294 } 295 296 297 DECLINLINE(void) cpuSetInterrupt(APICDeviceInfo* dev, uint32_t cpuid) 298 { 299 dev->CTX_SUFF(pApicHlp)->pfnSetInterruptFF(dev->CTX_SUFF(pDevIns)); 300 } 301 302 DECLINLINE(void) cpuClearInterrupt(APICDeviceInfo* dev, uint32_t cpuid) 303 { 304 dev->CTX_SUFF(pApicHlp)->pfnClearInterruptFF(dev->CTX_SUFF(pDevIns)); 305 } 293 306 #endif /* VBOX */ 294 307 … … 343 356 switch (delivery_mode) { 344 357 case APIC_DM_LOWPRI: 345 #ifndef VBOX 346 /* XXX: search for focus processor, arbitration */ 358 { 359 int d = -1; 360 if (deliver_bitmask) 361 d = ffs_bit(deliver_bitmask); 362 if (d >= 0) 347 363 { 348 int i, d; 349 d = -1; 350 for(i = 0; i < MAX_APIC_WORDS; i++) { 351 if (deliver_bitmask[i]) { 352 d = i * 32 + ffs_bit(deliver_bitmask[i]); 353 break; 354 } 355 } 356 if (d >= 0) { 357 apic_iter = local_apics[d]; 358 if (apic_iter) { 359 apic_set_irq(apic_iter, vector_num, trigger_mode); 360 } 361 } 364 APICState* apic = LAPIC_BASE(dev) + d; 365 apic_set_irq(dev, apic, vector_num, trigger_mode); 362 366 } 363 #else364 {365 int d = -1;366 if (deliver_bitmask)367 d = ffs_bit(deliver_bitmask);368 if (d >= 0)369 {370 APICState* apic = FIRST_LAPIC(dev) + d;371 apic_set_irq(dev, apic, vector_num, trigger_mode);372 }373 }374 #endif375 367 return; 368 } 376 369 case APIC_DM_FIXED: 377 370 /* XXX: arbitration */ … … 379 372 380 373 case APIC_DM_SMI: 374 /** @todo: what do we really do with SMI */ 375 foreach_apic(dev, deliver_bitmask, 376 cpuSetInterrupt(dev, apic->id)); 377 return; 378 381 379 case APIC_DM_NMI: 382 break; 380 /** @todo: what do we really do with NMI */ 381 foreach_apic(dev, deliver_bitmask, 382 cpuSetInterrupt(dev, apic->id)); 383 return; 383 384 384 385 case APIC_DM_INIT: 385 386 /* normal INIT IPI sent to processors */ 386 387 #ifdef VBOX 387 apic_init_ipi (s); 388 foreach_apic(dev, deliver_bitmask, 389 apic_init_ipi(apic)); 388 390 #else 389 391 for (apic_iter = first_local_apic; apic_iter != NULL; … … 403 405 404 406 #ifdef VBOX 405 if (deliver_bitmask & (1 << s->id))406 apic_set_irq (dev, s, vector_num, trigger_mode);407 foreach_apic(dev, deliver_bitmask, 408 apic_set_irq (dev, apic, vector_num, trigger_mode)); 407 409 #else /* VBOX */ 408 410 for (apic_iter = first_local_apic; apic_iter != NULL; … … 435 437 { 436 438 APICDeviceInfo *dev = PDMINS_2_DATA(pDevIns, APICDeviceInfo *); 437 APICState *s = getL APIC(dev);439 APICState *s = getLapic(dev); 438 440 Log(("cpu_set_apic_base: %016RX64\n", val)); 439 441 … … 447 449 448 450 /* Clear any pending APIC interrupt action flag. */ 449 dev->CTX_SUFF(pApicHlp)->pfnClearInterruptFF(dev->CTX_SUFF(pDevIns));451 cpuClearInterrupt(dev, s->id); 450 452 dev->CTX_SUFF(pApicHlp)->pfnChangeFeature(pDevIns, false); 451 453 } … … 518 520 { 519 521 APICDeviceInfo *dev = PDMINS_2_DATA(pDevIns, APICDeviceInfo *); 520 APICState *s = getL APIC(dev);522 APICState *s = getLapic(dev); 521 523 Log(("apicGetBase: %016llx\n", (uint64_t)s->apicbase)); 522 524 return s->apicbase; … … 526 528 { 527 529 APICDeviceInfo *dev = PDMINS_2_DATA(pDevIns, APICDeviceInfo *); 528 APICState *s = getL APIC(dev);530 APICState *s = getLapic(dev); 529 531 LogFlow(("apicSetTPR: val=%#x (trp %#x -> %#x)\n", val, s->tpr, (val & 0x0f) << 4)); 530 532 apic_update_tpr(dev, s, (val & 0x0f) << 4); … … 534 536 { 535 537 APICDeviceInfo *dev = PDMINS_2_DATA(pDevIns, APICDeviceInfo *); 536 APICState *s = getL APIC(dev);538 APICState *s = getLapic(dev); 537 539 Log2(("apicGetTPR: returns %#x\n", s->tpr >> 4)); 538 540 return s->tpr >> 4; … … 548 550 { 549 551 APICDeviceInfo *dev = PDMINS_2_DATA(pDevIns, APICDeviceInfo *); 550 APICState *s = getL APIC(dev);552 APICState *s = getLapic(dev); 551 553 LogFlow(("apicBusDeliverCallback: s=%p pDevIns=%p u8Dest=%#x u8DestMode=%#x u8DeliveryMode=%#x iVector=%#x u8Polarity=%#x u8TriggerMode=%#x\n", 552 554 s, pDevIns, u8Dest, u8DestMode, u8DeliveryMode, iVector, u8Polarity, u8TriggerMode)); … … 609 611 { 610 612 /* Clear any pending APIC interrupt action flag. */ 611 dev->CTX_SUFF(pApicHlp)->pfnClearInterruptFF(dev->CTX_SUFF(pDevIns));613 cpuClearInterrupt(dev, s->id); 612 614 return false; 613 615 } … … 624 626 cpu_interrupt(s->cpu_env, CPU_INTERRUPT_HARD); 625 627 #else 626 dev->CTX_SUFF(pApicHlp)->pfnSetInterruptFF(dev->CTX_SUFF(pDevIns));628 cpuSetInterrupt(dev, s->id); 627 629 return true; 628 630 #endif … … 638 640 if (!dev) 639 641 return false; 640 APICState *s = getL APIC(dev);642 APICState *s = getLapic(dev); 641 643 642 644 irrv = get_highest_priority_int(s->irr); … … 665 667 Log(("apic_update_tpr: deactivate interrupt that was masked by the TPR update (%x)\n", val)); 666 668 STAM_COUNTER_INC(&dev->StatClearedActiveIrq); 667 dev->CTX_SUFF(pApicHlp)->pfnClearInterruptFF(dev->CTX_SUFF(pDevIns));669 cpuClearInterrupt(dev, s->id); 668 670 } 669 671 } … … 700 702 #endif /* VBOX */ 701 703 { 702 #if 0703 uint32_t mask = 0;704 #ifndef VBOX705 APICState *apic_iter;706 #endif /* !VBOX */707 708 if (dest_mode == 0) {709 if (dest == 0xff)710 mask = 0xff;711 else712 mask = 1 << dest;713 } else {714 /* XXX: cluster mode */715 #ifdef VBOX716 if (dest & s->log_dest)717 mask |= 1 << s->id;718 #else /* !VBOX */719 for (apic_iter = first_local_apic; apic_iter != NULL;720 apic_iter = apic_iter->next_apic) {721 if (dest & apic_iter->log_dest)722 mask |= (1 << apic_iter->id);723 }724 #endif /* !VBOX */725 }726 727 return mask;728 #else729 704 uint32_t mask = 0; 730 705 … … 738 713 else 739 714 { 740 APICState *apic = FIRST_LAPIC(dev);715 APICState *apic = LAPIC_BASE(dev); 741 716 uint32_t i; 742 717 … … 763 738 764 739 return mask; 765 #endif766 740 } 767 741 … … 850 824 if (level == 0 && trig_mode == 1) { 851 825 #ifdef VBOX 852 FOR_EACH_LAPIC(dev, 853 if (deliver_bitmask & (1 << apic->id)) 854 { 855 apic->arb_id = apic->id; 856 }); 826 foreach_apic(dev, deliver_bitmask, 827 apic->arb_id = apic->id); 857 828 #else /* !VBOX */ 858 829 for (apic_iter = first_local_apic; apic_iter != NULL; … … 878 849 } 879 850 #else 880 FOR_EACH_LAPIC(dev, apic_startup(dev, apic, vector_num)); 851 foreach_apic(dev, deliver_bitmask, 852 apic_startup(dev, apic, vector_num)); 881 853 #endif /* !VBOX */ 882 854 return; … … 900 872 { 901 873 APICDeviceInfo *dev = PDMINS_2_DATA(pDevIns, APICDeviceInfo *); 902 APICState *s = getL APIC(dev);874 APICState *s = getLapic(dev); 903 875 #endif /* VBOX */ 904 876 int intno; … … 995 967 { 996 968 APICDeviceInfo *dev = PDMINS_2_DATA(pDevIns, APICDeviceInfo *); 997 APICState *s = getL APIC(dev);969 APICState *s = getLapic(dev); 998 970 dev->pApicHlpR3->pfnLock(pDevIns, VERR_INTERNAL_ERROR); 999 971 #endif /* VBOX */ … … 1654 1626 1655 1627 /* LAPIC */ 1656 1657 /* LAPICs MMIO is wrong, in SMP there is no relation between memory range and1658 lapic, it's only the CPU that executes this memory access is what matters */1659 1660 1628 PDMBOTHCBDECL(int) apicMMIORead(PPDMDEVINS pDevIns, void *pvUser, RTGCPHYS GCPhysAddr, void *pv, unsigned cb) 1661 1629 { 1662 1630 APICDeviceInfo *dev = PDMINS_2_DATA(pDevIns, APICDeviceInfo *); 1663 APICState *s = getL APIC(dev);1631 APICState *s = getLapic(dev); 1664 1632 1665 1633 #ifdef VBOX_WITH_SMP_GUESTS 1666 LogRel(("[SMP] apicMMIORead %p at %ullx\n", pDevIns, (uint64_t)GCPhysAddr));1667 #endif 1668 1669 /** @todo: add LAPIC range validity checks ( multipleLAPICs can theoretically have1634 LogRel(("[SMP] apicMMIORead at %llx\n", (uint64_t)GCPhysAddr)); 1635 #endif 1636 1637 /** @todo: add LAPIC range validity checks (different LAPICs can theoretically have 1670 1638 different physical addresses, see #3092) */ 1671 1639 … … 1715 1683 { 1716 1684 APICDeviceInfo *dev = PDMINS_2_DATA(pDevIns, APICDeviceInfo *); 1717 APICState *s = getLAPIC(dev); 1685 APICState *s = getLapic(dev); 1686 1687 #ifdef VBOX_WITH_SMP_GUESTS 1688 LogRel(("[SMP] apicMMIOWrite at %llx\n", (uint64_t)GCPhysAddr)); 1689 #endif 1718 1690 1719 1691 /** @todo: add LAPIC range validity checks (multiple LAPICs can theoretically have … … 1752 1724 { 1753 1725 APICDeviceInfo *dev = PDMINS_2_DATA(pDevIns, APICDeviceInfo *); 1754 /* @todo: process all LAPICS */ 1755 APICState* s = FIRST_LAPIC(dev);1756 apic_save(pSSMHandle, s);1757 /* @todo: save CPU count? */ 1726 1727 /* save all APICs data, @todo: is it correct? */ 1728 foreach_apic(dev, 0xffffffff, apic_save(pSSMHandle, apic)); 1729 1758 1730 return TMR3TimerSave(dev->CTX_SUFF(pTimer), pSSMHandle); 1759 1731 } … … 1765 1737 { 1766 1738 APICDeviceInfo *dev = PDMINS_2_DATA(pDevIns, APICDeviceInfo *); 1767 /* @todo: process all LAPICS */ 1768 APICState* s = FIRST_LAPIC(dev); 1769 if (apic_load(pSSMHandle, s, u32Version)) { 1770 AssertFailed(); 1771 return VERR_SSM_UNSUPPORTED_DATA_UNIT_VERSION; 1772 } 1773 /* @todo: restore CPU count? */ 1739 /* load all APICs data, @todo: is it correct? */ 1740 foreach_apic(dev, 0xffffffff, 1741 if (apic_load(pSSMHandle, apic, u32Version)) 1742 { 1743 AssertFailed(); 1744 return VERR_SSM_UNSUPPORTED_DATA_UNIT_VERSION; 1745 } 1746 ); 1774 1747 return TMR3TimerLoad(dev->CTX_SUFF(pTimer), pSSMHandle); 1775 1748 } … … 1786 1759 1787 1760 /* @todo: process all LAPICS? Or only one? */ 1788 APICState* s = FIRST_LAPIC(dev);1761 APICState* s = LAPIC_BASE(dev); 1789 1762 1790 1763 apic_init_ipi(s); … … 1796 1769 dev->pApicHlpR3->pfnChangeFeature(dev->pDevInsR3, true); 1797 1770 /* Clear any pending APIC interrupt action flag. */ 1798 dev->pApicHlpR3->pfnClearInterruptFF(pDevIns);1771 cpuClearInterrupt(dev, s->id); 1799 1772 APIC_UNLOCK(dev); 1800 1773 } … … 1812 1785 } 1813 1786 1814 DECLINLINE(void) initA PIC(APICState* apic, uint8_t id)1787 DECLINLINE(void) initApicData(APICState* apic, uint8_t id) 1815 1788 { 1816 1789 int i; 1817 ::memset(apic, 0, sizeof(*apic));1790 memset(apic, 0, sizeof(*apic)); 1818 1791 apic->apicbase = UINT32_C(0xfee00000) | MSR_IA32_APICBASE_BSP | MSR_IA32_APICBASE_ENABLE; 1819 1792 for (i = 0; i < APIC_LVT_NB; i++) … … 1894 1867 for (i = 0; i < cCpus; i++) 1895 1868 { 1896 initA PIC((APICState*)pThis->pLapicsR3+i, i);1869 initApicData((APICState*)pThis->pLapicsR3 + i, i); 1897 1870 } 1898 1871 … … 1976 1949 * (see IA32_APIC_BASE_MSR) 1977 1950 */ 1978 rc = PDMDevHlpMMIORegister(pDevIns, FIRST_LAPIC(pThis)->apicbase & ~0xfff, 0x1000, pThis,1951 rc = PDMDevHlpMMIORegister(pDevIns, LAPIC_BASE(pThis)->apicbase & ~0xfff, 0x1000, pThis, 1979 1952 apicMMIOWrite, apicMMIORead, NULL, "APIC Memory"); 1980 1953 if (RT_FAILURE(rc)) … … 1984 1957 pThis->pApicHlpRC = pThis->pApicHlpR3->pfnGetRCHelpers(pDevIns); 1985 1958 1986 rc = PDMDevHlpMMIORegisterGC(pDevIns, FIRST_LAPIC(pThis)->apicbase & ~0xfff, 0x1000, 0,1959 rc = PDMDevHlpMMIORegisterGC(pDevIns, LAPIC_BASE(pThis)->apicbase & ~0xfff, 0x1000, 0, 1987 1960 "apicMMIOWrite", "apicMMIORead", NULL); 1988 1961 if (RT_FAILURE(rc)) … … 1993 1966 pThis->pApicHlpR0 = pThis->pApicHlpR3->pfnGetR0Helpers(pDevIns); 1994 1967 1995 rc = PDMDevHlpMMIORegisterR0(pDevIns, FIRST_LAPIC(pThis)->apicbase & ~0xfff, 0x1000, 0,1968 rc = PDMDevHlpMMIORegisterR0(pDevIns, LAPIC_BASE(pThis)->apicbase & ~0xfff, 0x1000, 0, 1996 1969 "apicMMIOWrite", "apicMMIORead", NULL); 1997 1970 if (RT_FAILURE(rc)) … … 2080 2053 2081 2054 #endif /* IN_RING3 */ 2082 2083 2084 2055 2085 2056
Note:
See TracChangeset
for help on using the changeset viewer.