Changeset 12634 in vbox for trunk/src/VBox/Devices/PC
- Timestamp:
- Sep 22, 2008 12:42:33 PM (16 years ago)
- svn:sync-xref-src-repo-rev:
- 36916
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/Devices/PC/DevAPIC.cpp
r12626 r12634 55 55 56 56 /** @def APIC_LOCK 57 * Acquires the PDM lock. This is a NOP if locking is disabled. */ 57 * Acquires the PDM lock. */ 58 #define APIC_LOCK(pThis, rc) \ 59 do { \ 60 int rc2 = (pThis)->CTX_SUFF(pApicHlp)->pfnLock((pThis)->CTX_SUFF(pDevIns), rc); \ 61 if (rc2 != VINF_SUCCESS) \ 62 return rc2; \ 63 } while (0) 64 65 /** @def APIC_LOCK_VOID 66 * Acquires the PDM lock and does not expect failure (i.e. ring-3 only!). */ 67 #define APIC_LOCK_VOID(pThis, rc) \ 68 do { \ 69 int rc2 = (pThis)->CTX_SUFF(pApicHlp)->pfnLock((pThis)->CTX_SUFF(pDevIns), rc); \ 70 AssertLogRelRCReturnVoid(rc2); \ 71 } while (0) 72 58 73 /** @def APIC_UNLOCK 59 * Releases the PDM lock. This is a NOP if locking is disabled. */ 74 * Releases the PDM lock. */ 75 #define APIC_UNLOCK(pThis) \ 76 (pThis)->CTX_SUFF(pApicHlp)->pfnUnlock((pThis)->CTX_SUFF(pDevIns)) 77 60 78 /** @def IOAPIC_LOCK 61 * Acquires the PDM lock. This is a NOP if locking is disabled. */ 62 /** @def IOAPIC_UNLOCK 63 * Releases the PDM lock. This is a NOP if locking is disabled. */ 64 #define APIC_LOCK(pThis, rc) \ 65 do { \ 66 int rc2 = (pThis)->CTX_SUFF(pApicHlp)->pfnLock((pThis)->CTX_SUFF(pDevIns), rc); \ 67 if (rc2 != VINF_SUCCESS) \ 68 return rc2; \ 69 } while (0) 70 #define APIC_LOCK_VOID(pThis, rc) \ 71 do { \ 72 int rc2 = (pThis)->CTX_SUFF(pApicHlp)->pfnLock((pThis)->CTX_SUFF(pDevIns), rc); \ 73 if (rc2 != VINF_SUCCESS) \ 74 return; \ 75 } while (0) 76 #define APIC_UNLOCK(pThis) \ 77 (pThis)->CTX_SUFF(pApicHlp)->pfnUnlock((pThis)->CTX_SUFF(pDevIns)) 79 * Acquires the PDM lock. */ 78 80 #define IOAPIC_LOCK(pThis, rc) \ 79 81 do { \ … … 82 84 return rc2; \ 83 85 } while (0) 86 87 /** @def IOAPIC_UNLOCK 88 * Releases the PDM lock. */ 84 89 #define IOAPIC_UNLOCK(pThis) (pThis)->CTX_SUFF(pIoApicHlp)->pfnUnlock((pThis)->CTX_SUFF(pDevIns)) 85 90 86 91 /** @def LAPIC_BASE 87 * Return address of first LAPIC state. */ 92 * Return address of first LAPIC state. */ 88 93 #define LAPIC_BASE(pThis) ((APICState*)(pThis)->CTX_SUFF(pLapics)) 89 94 … … 100 105 apic++; \ 101 106 } \ 102 } while (0) 107 } while (0) 103 108 104 109 # define set_bit(pvBitmap, iBit) ASMBitSet(pvBitmap, iBit) … … 212 217 /** The APIC timer - R3 Ptr. */ 213 218 PTMTIMERR3 pTimerR3; 214 219 215 220 /** The APIC timer - R0 Ptr. */ 216 221 PTMTIMERR0 pTimerR0; 217 222 218 223 /** The APIC timer - RC Ptr. */ 219 224 PTMTIMERRC pTimerRC; 220 225 221 226 /** Alignment */ 222 227 uint32_t Alignment1; … … 268 273 PCPDMAPICHLPR3 pApicHlpR3; 269 274 /** LAPICs states - R3 Ptr */ 270 RTR3PTR pLapicsR3; 275 RTR3PTR pLapicsR3; 271 276 272 277 /** The device instance - R0 Ptr. */ … … 275 280 PCPDMAPICHLPR0 pApicHlpR0; 276 281 /** LAPICs states - R0 Ptr */ 277 RTR0PTR pLapicsR0; 282 RTR0PTR pLapicsR0; 278 283 279 284 /** The device instance - RC Ptr. */ … … 282 287 PCPDMAPICHLPRC pApicHlpRC; 283 288 /** LAPICs states - RC Ptr */ 284 RTRCPTR pLapicsRC; 285 289 RTRCPTR pLapicsRC; 290 286 291 /** Alignment */ 287 292 uint32_t Alignment0; … … 289 294 /** Number of attempts made to optimize TPR accesses. */ 290 295 uint32_t ulTPRPatchAttempts; 291 296 292 297 /** Number of CPUs on the system (same as LAPIC count). */ 293 298 uint32_t cCpus; … … 374 379 if (deliver_bitmask) 375 380 d = ffs_bit(deliver_bitmask); 376 if (d >= 0) 381 if (d >= 0) 377 382 { 378 383 APICState* apic = LAPIC_BASE(dev) + d; … … 453 458 APICState *s = getLapic(dev); 454 459 Log(("cpu_set_apic_base: %016RX64\n", val)); 455 460 456 461 /** @todo: do we need to lock here ? */ 457 462 /* APIC_LOCK_VOID(dev, VERR_INTERNAL_ERROR); */ … … 657 662 return false; 658 663 APICState *s = getLapic(dev); 659 664 660 665 /* 661 666 * All our callbacks now come from single IOAPIC, thus locking 662 * seems to be excessive now (@todo: check) 667 * seems to be excessive now (@todo: check) 663 668 */ 664 669 irrv = get_highest_priority_int(s->irr); … … 725 730 uint32_t mask = 0; 726 731 727 if (dest_mode == 0) 732 if (dest_mode == 0) 728 733 { 729 if (dest == 0xff) 734 if (dest == 0xff) 730 735 mask = 0xff; 731 else 736 else 732 737 mask = 1 << dest; 733 } 734 else 738 } 739 else 735 740 { 736 741 APICState *apic = LAPIC_BASE(dev); 737 742 uint32_t i; 738 743 739 744 /* XXX: cluster mode */ 740 for(i = 0; i < dev->cCpus; i++) 745 for(i = 0; i < dev->cCpus; i++) 741 746 { 742 if (apic->dest_mode == 0xf) 747 if (apic->dest_mode == 0xf) 743 748 { 744 749 if (dest & apic->log_dest) 745 750 mask |= (1 << apic->id); 746 } 747 else if (apic->dest_mode == 0x0) 751 } 752 else if (apic->dest_mode == 0x0) 748 753 { 749 if ((dest & 0xf0) == (apic->log_dest & 0xf0) 754 if ((dest & 0xf0) == (apic->log_dest & 0xf0) 750 755 && 751 (dest & apic->log_dest & 0x0f)) 756 (dest & apic->log_dest & 0x0f)) 752 757 { 753 758 mask |= (1 << i); … … 802 807 #endif 803 808 } 804 static void apic_deliver(APICDeviceInfo* dev, APICState *s, 809 static void apic_deliver(APICDeviceInfo* dev, APICState *s, 805 810 uint8_t dest, uint8_t dest_mode, 806 811 uint8_t delivery_mode, uint8_t vector_num, … … 814 819 815 820 LogFlow(("apic_deliver dest=%x dest_mode=%x delivery_mode=%x vector_num=%x polarity=%x trigger_mode=%x\n", dest, dest_mode, delivery_mode, vector_num, polarity, trigger_mode)); 816 821 817 822 switch (dest_shorthand) { 818 823 case 0: … … 833 838 break; 834 839 } 835 840 836 841 switch (delivery_mode) { 837 842 case APIC_DM_LOWPRI: … … 1666 1671 #endif 1667 1672 1668 /** @todo: add LAPIC range validity checks (different LAPICs can theoretically have 1673 /** @todo: add LAPIC range validity checks (different LAPICs can theoretically have 1669 1674 different physical addresses, see #3092) */ 1670 1675 … … 1720 1725 #endif 1721 1726 1722 /** @todo: add LAPIC range validity checks (multiple LAPICs can theoretically have 1727 /** @todo: add LAPIC range validity checks (multiple LAPICs can theoretically have 1723 1728 different physical addresses, see #3092) */ 1724 1729 … … 1769 1774 APICDeviceInfo *dev = PDMINS_2_DATA(pDevIns, APICDeviceInfo *); 1770 1775 /* load all APICs data, @todo: is it correct? */ 1771 foreach_apic(dev, 0xffffffff, 1776 foreach_apic(dev, 0xffffffff, 1772 1777 if (apic_load(pSSMHandle, apic, u32Version)) 1773 1778 { … … 1810 1815 APICDeviceInfo *dev = PDMINS_2_DATA(pDevIns, APICDeviceInfo *); 1811 1816 #ifdef VBOX_WITH_SMP_GUESTS 1812 LogRel(("[SMP]: relocate apic on %llx\n", offDelta)); 1817 LogRel(("[SMP]: relocate apic on %llx\n", offDelta)); 1813 1818 #endif 1814 1819 dev->pDevInsRC = PDMDEVINS_2_RCPTR(pDevIns); … … 1845 1850 APICState *apic; 1846 1851 1847 /* 1852 /* 1848 1853 * Only single device instance. 1849 1854 */ … … 1853 1858 * Validate configuration. 1854 1859 */ 1855 if (!CFGMR3AreValuesValid(pCfgHandle, 1856 "IOAPIC\0" 1857 "GCEnabled\0" 1860 if (!CFGMR3AreValuesValid(pCfgHandle, 1861 "IOAPIC\0" 1862 "GCEnabled\0" 1858 1863 "R0Enabled\0" 1859 1864 "NumCPUs\0")) … … 1874 1879 return PDMDEV_SET_ERROR(pDevIns, rc, 1875 1880 N_("Configuration error: Failed to query boolean value \"R0Enabled\"")); 1876 1881 1877 1882 rc = CFGMR3QueryU32Def(pCfgHandle, "NumCPUs", &cCpus, 1); 1878 1883 if (RT_FAILURE(rc)) … … 1891 1896 1892 1897 PVM pVM = PDMDevHlpGetVM(pDevIns); 1893 /* 1898 /* 1894 1899 * We are not freeing this memory, as it's automatically released when guest exits. 1895 1900 */ … … 1899 1904 pThis->pLapicsR0 = MMHyperR3ToR0(pVM, pThis->pLapicsR3); 1900 1905 pThis->pLapicsRC = MMHyperR3ToRC(pVM, pThis->pLapicsR3); 1901 1906 1902 1907 for (i = 0, apic = LAPIC_BASE(pThis); i < cCpus; i++) 1903 1908 {
Note:
See TracChangeset
for help on using the changeset viewer.