- Timestamp:
- Sep 18, 2008 5:47:53 PM (16 years ago)
- Location:
- trunk/src/VBox
- Files:
-
- 4 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/Devices/PC/DevAPIC.cpp
r12570 r12588 78 78 #define IOAPIC_UNLOCK(pThis) (pThis)->CTX_SUFF(pIoApicHlp)->pfnUnlock((pThis)->CTX_SUFF(pDevIns)) 79 79 80 /** @def FIRST_LAPIC 81 * Return address of first LAPIC state. If this macro is use - it's probably 82 * something wrong or fishy with the code using it, unless explained. */ 83 #define FIRST_LAPIC(pThis) ((APICState*)(pThis)->CTX_SUFF(pLapics)) 80 84 81 85 #endif /* VBOX */ … … 181 185 QEMUTimer *timer; 182 186 struct APICState *next_apic; 183 #else /* VBOX */184 #ifdef VBOX_WITH_SMP_GUESTS185 //struct APICState *next_apic;186 #endif187 /** The device instance - R3 Ptr. */188 PPDMDEVINSR3 pDevInsR3;189 /** The APIC helpers - R3 Ptr. */190 PCPDMAPICHLPR3 pApicHlpR3;191 /** The APIC timer - R3 Ptr. */192 PTMTIMERR3 pTimerR3;193 194 /** The device instance - R0 Ptr. */195 PPDMDEVINSR0 pDevInsR0;196 /** The APIC helpers - R0 Ptr. */197 PCPDMAPICHLPR0 pApicHlpR0;198 /** The APIC timer - R0 Ptr. */199 PTMTIMERR0 pTimerR0;200 201 /** The device instance - RC Ptr. */202 PPDMDEVINSRC pDevInsRC;203 /** The APIC helpers - RC Ptr. */204 PCPDMAPICHLPRC pApicHlpRC;205 /** The APIC timer - RC Ptr. */206 PTMTIMERRC pTimerRC;207 208 /** Number of attempts made to optimize TPR accesses. */209 uint32_t ulTPRPatchAttempts;210 211 # ifdef VBOX_WITH_STATISTICS212 STAMCOUNTER StatMMIOReadGC;213 STAMCOUNTER StatMMIOReadHC;214 STAMCOUNTER StatMMIOWriteGC;215 STAMCOUNTER StatMMIOWriteHC;216 STAMCOUNTER StatClearedActiveIrq;217 # endif218 187 #endif /* VBOX */ 219 188 } APICState; … … 255 224 #ifdef VBOX 256 225 typedef struct IOAPICState IOAPICState; 226 227 typedef struct 228 { 229 /** The device instance - R3 Ptr. */ 230 PPDMDEVINSR3 pDevInsR3; 231 /** The APIC helpers - R3 Ptr. */ 232 PCPDMAPICHLPR3 pApicHlpR3; 233 /** The APIC timer - R3 Ptr. */ 234 PTMTIMERR3 pTimerR3; 235 /** LAPICs states - R3 Ptr */ 236 RTR3PTR pLapicsR3; 237 238 /** The device instance - R0 Ptr. */ 239 PPDMDEVINSR0 pDevInsR0; 240 /** The APIC helpers - R0 Ptr. */ 241 PCPDMAPICHLPR0 pApicHlpR0; 242 /** The APIC timer - R0 Ptr. */ 243 PTMTIMERR0 pTimerR0; 244 /** LAPICs states - R0 Ptr */ 245 RTR0PTR pLapicsR0; 246 247 /** The device instance - RC Ptr. */ 248 PPDMDEVINSRC pDevInsRC; 249 /** The APIC helpers - RC Ptr. */ 250 PCPDMAPICHLPRC pApicHlpRC; 251 /** The APIC timer - RC Ptr. */ 252 PTMTIMERRC pTimerRC; 253 /** LAPICs states - RC Ptr */ 254 RTRCPTR pLapicsRC; 255 256 /** Number of attempts made to optimize TPR accesses. */ 257 uint32_t ulTPRPatchAttempts; 258 259 /** Number of LAPICs on the system (same as CPU count). */ 260 uint32_t cCpus; 261 262 # ifdef VBOX_WITH_STATISTICS 263 STAMCOUNTER StatMMIOReadGC; 264 STAMCOUNTER StatMMIOReadHC; 265 STAMCOUNTER StatMMIOWriteGC; 266 STAMCOUNTER StatMMIOWriteHC; 267 STAMCOUNTER StatClearedActiveIrq; 268 # endif 269 } APICDeviceInfo; 270 271 DECLINLINE(APICState*) getLAPIC(APICDeviceInfo* dev) 272 { 273 uint32_t id = dev->CTX_SUFF(pApicHlp)->pfnGetCpuId(dev->CTX_SUFF(pDevIns)); 274 return FIRST_LAPIC(dev) + id; 275 } 276 257 277 #endif /* VBOX */ 258 278 … … 265 285 266 286 static void apic_init_ipi(APICState *s); 267 static void apic_set_irq(APIC State *s, int vector_num, int trigger_mode);268 static bool apic_update_irq(APIC State *s);287 static void apic_set_irq(APICDeviceInfo* dev, APICState *s, int vector_num, int trigger_mode); 288 static bool apic_update_irq(APICDeviceInfo* dev, APICState *s); 269 289 270 290 #ifdef VBOX … … 286 306 PDMBOTHCBDECL(void) ioapicSetIrq(PPDMDEVINS pDevIns, int iIrq, int iLevel); 287 307 288 static void apic_update_tpr(APIC State *s, uint32_t val);308 static void apic_update_tpr(APICDeviceInfo *dev, APICState* s, uint32_t val); 289 309 __END_DECLS 290 310 #endif /* VBOX */ … … 297 317 APICState *apic_iter; 298 318 #else /* VBOX */ 299 static void apic_bus_deliver(APICState *s, uint32_t deliver_bitmask, uint8_t delivery_mode, 319 static void apic_bus_deliver(APICDeviceInfo* dev, 320 APICState *s, uint32_t deliver_bitmask, uint8_t delivery_mode, 300 321 uint8_t vector_num, uint8_t polarity, 301 322 uint8_t trigger_mode) … … 336 357 #ifdef VBOX 337 358 if (deliver_bitmask & (1 << s->id)) 338 apic_set_irq ( s, vector_num, trigger_mode);359 apic_set_irq (dev, s, vector_num, trigger_mode); 339 360 #else /* VBOX */ 340 361 for (apic_iter = first_local_apic; apic_iter != NULL; … … 366 387 PDMBOTHCBDECL(void) apicSetBase(PPDMDEVINS pDevIns, uint64_t val) 367 388 { 368 APICState *s = PDMINS_2_DATA(pDevIns, APICState *); 389 APICDeviceInfo *dev = PDMINS_2_DATA(pDevIns, APICDeviceInfo *); 390 APICState *s = getLAPIC(dev); 369 391 Log(("cpu_set_apic_base: %016RX64\n", val)); 370 392 … … 378 400 379 401 /* Clear any pending APIC interrupt action flag. */ 380 s->CTX_SUFF(pApicHlp)->pfnClearInterruptFF(s->CTX_SUFF(pDevIns));381 s->CTX_SUFF(pApicHlp)->pfnChangeFeature(pDevIns, false);402 dev->CTX_SUFF(pApicHlp)->pfnClearInterruptFF(dev->CTX_SUFF(pDevIns)); 403 dev->CTX_SUFF(pApicHlp)->pfnChangeFeature(pDevIns, false); 382 404 } 383 405 } … … 448 470 PDMBOTHCBDECL(uint64_t) apicGetBase(PPDMDEVINS pDevIns) 449 471 { 450 APICState *s = PDMINS_2_DATA(pDevIns, APICState *); 472 APICDeviceInfo *dev = PDMINS_2_DATA(pDevIns, APICDeviceInfo *); 473 APICState *s = getLAPIC(dev); 451 474 Log(("apicGetBase: %016llx\n", (uint64_t)s->apicbase)); 452 475 return s->apicbase; … … 455 478 PDMBOTHCBDECL(void) apicSetTPR(PPDMDEVINS pDevIns, uint8_t val) 456 479 { 457 APICState *s = PDMINS_2_DATA(pDevIns, APICState *); 480 APICDeviceInfo *dev = PDMINS_2_DATA(pDevIns, APICDeviceInfo *); 481 APICState *s = getLAPIC(dev); 458 482 LogFlow(("apicSetTPR: val=%#x (trp %#x -> %#x)\n", val, s->tpr, (val & 0x0f) << 4)); 459 apic_update_tpr( s, (val & 0x0f) << 4);483 apic_update_tpr(dev, s, (val & 0x0f) << 4); 460 484 } 461 485 462 486 PDMBOTHCBDECL(uint8_t) apicGetTPR(PPDMDEVINS pDevIns) 463 487 { 464 APICState *s = PDMINS_2_DATA(pDevIns, APICState *); 488 APICDeviceInfo *dev = PDMINS_2_DATA(pDevIns, APICDeviceInfo *); 489 APICState *s = getLAPIC(dev); 465 490 Log2(("apicGetTPR: returns %#x\n", s->tpr >> 4)); 466 491 return s->tpr >> 4; … … 475 500 uint8_t u8TriggerMode) 476 501 { 477 APICState *s = PDMINS_2_DATA(pDevIns, APICState *); 502 APICDeviceInfo *dev = PDMINS_2_DATA(pDevIns, APICDeviceInfo *); 503 APICState *s = getLAPIC(dev); 478 504 LogFlow(("apicBusDeliverCallback: s=%p pDevIns=%p u8Dest=%#x u8DestMode=%#x u8DeliveryMode=%#x iVector=%#x u8Polarity=%#x u8TriggerMode=%#x\n", 479 505 s, pDevIns, u8Dest, u8DestMode, u8DeliveryMode, iVector, u8Polarity, u8TriggerMode)); 480 apic_bus_deliver( s, apic_get_delivery_bitmask(s, u8Dest, u8DestMode),506 apic_bus_deliver(dev, s, apic_get_delivery_bitmask(s, u8Dest, u8DestMode), 481 507 u8DeliveryMode, iVector, u8Polarity, u8TriggerMode); 482 508 } … … 533 559 534 560 /* signal the CPU if an irq is pending */ 535 static bool apic_update_irq(APIC State *s)561 static bool apic_update_irq(APICDeviceInfo *dev, APICState* s) 536 562 { 537 563 int irrv, ppr; … … 540 566 { 541 567 /* Clear any pending APIC interrupt action flag. */ 542 s->CTX_SUFF(pApicHlp)->pfnClearInterruptFF(s->CTX_SUFF(pDevIns));568 dev->CTX_SUFF(pApicHlp)->pfnClearInterruptFF(dev->CTX_SUFF(pDevIns)); 543 569 return false; 544 570 } … … 555 581 cpu_interrupt(s->cpu_env, CPU_INTERRUPT_HARD); 556 582 #else 557 s->CTX_SUFF(pApicHlp)->pfnSetInterruptFF(s->CTX_SUFF(pDevIns));583 dev->CTX_SUFF(pApicHlp)->pfnSetInterruptFF(dev->CTX_SUFF(pDevIns)); 558 584 return true; 559 585 #endif … … 566 592 { 567 593 int irrv, ppr; 568 569 APICState *s = PDMINS_2_DATA(pDevIns, APICState *); 570 if (!s) 594 APICDeviceInfo *dev = PDMINS_2_DATA(pDevIns, APICDeviceInfo *); 595 if (!dev) 571 596 return false; 597 APICState *s = getLAPIC(dev); 572 598 573 599 irrv = get_highest_priority_int(s->irr); … … 582 608 } 583 609 584 static void apic_update_tpr(APIC State *s, uint32_t val)610 static void apic_update_tpr(APICDeviceInfo *dev, APICState* s, uint32_t val) 585 611 { 586 612 bool fIrqIsActive = false; 587 613 bool fIrqWasActive = false; 588 614 589 fIrqWasActive = apic_update_irq( s);615 fIrqWasActive = apic_update_irq(dev, s); 590 616 s->tpr = val; 591 fIrqIsActive = apic_update_irq( s);617 fIrqIsActive = apic_update_irq(dev, s); 592 618 593 619 /* If an interrupt is pending and now masked, then clear the FF flag. */ … … 595 621 { 596 622 Log(("apic_update_tpr: deactivate interrupt that was masked by the TPR update (%x)\n", val)); 597 STAM_COUNTER_INC(& s->StatClearedActiveIrq);598 s->CTX_SUFF(pApicHlp)->pfnClearInterruptFF(s->CTX_SUFF(pDevIns));599 } 600 } 601 #endif 602 603 static void apic_set_irq(APIC State *s, int vector_num, int trigger_mode)623 STAM_COUNTER_INC(&dev->StatClearedActiveIrq); 624 dev->CTX_SUFF(pApicHlp)->pfnClearInterruptFF(dev->CTX_SUFF(pDevIns)); 625 } 626 } 627 #endif 628 629 static void apic_set_irq(APICDeviceInfo *dev, APICState* s, int vector_num, int trigger_mode) 604 630 { 605 631 LogFlow(("apic_set_irq vector=%x, trigger_mode=%x\n", vector_num, trigger_mode)); … … 609 635 else 610 636 reset_bit(s->tmr, vector_num); 611 apic_update_irq( s);612 } 613 614 static void apic_eoi(APIC State *s)637 apic_update_irq(dev, s); 638 } 639 640 static void apic_eoi(APICDeviceInfo *dev, APICState* s) 615 641 { 616 642 int isrv; … … 622 648 /* XXX: send the EOI packet to the APIC bus to allow the I/O APIC to 623 649 set the remote IRR bit for level triggered interrupts. */ 624 apic_update_irq( s);650 apic_update_irq(dev, s); 625 651 } 626 652 … … 683 709 } 684 710 685 static void apic_deliver(APICState *s, uint8_t dest, uint8_t dest_mode, 711 static void apic_deliver(APICDeviceInfo* dev, APICState *s, 712 uint8_t dest, uint8_t dest_mode, 686 713 uint8_t delivery_mode, uint8_t vector_num, 687 714 uint8_t polarity, uint8_t trigger_mode) … … 757 784 trigger_mode); 758 785 #else /* VBOX */ 759 apic_bus_deliver( s, deliver_bitmask, delivery_mode, vector_num, polarity,786 apic_bus_deliver(dev, s, deliver_bitmask, delivery_mode, vector_num, polarity, 760 787 trigger_mode); 761 788 #endif /* VBOX */ … … 769 796 PDMBOTHCBDECL(int) apicGetInterrupt(PPDMDEVINS pDevIns) 770 797 { 771 APICState *s = PDMINS_2_DATA(pDevIns, APICState *); 798 APICDeviceInfo *dev = PDMINS_2_DATA(pDevIns, APICDeviceInfo *); 799 APICState *s = getLAPIC(dev); 772 800 #endif /* VBOX */ 773 801 int intno; … … 796 824 reset_bit(s->irr, intno); 797 825 set_bit(s->isr, intno); 798 apic_update_irq( s);826 apic_update_irq(dev, s); 799 827 LogFlow(("apic_get_interrupt: returns %d\n", intno)); 800 828 return intno; 801 829 } 802 830 803 static uint32_t apic_get_current_count(APIC State *s)831 static uint32_t apic_get_current_count(APICDeviceInfo* dev, APICState *s) 804 832 { 805 833 int64_t d; … … 809 837 s->count_shift; 810 838 #else /* VBOX */ 811 d = (TMTimerGet( s->CTX_SUFF(pTimer)) - s->initial_count_load_time) >>839 d = (TMTimerGet(dev->CTX_SUFF(pTimer)) - s->initial_count_load_time) >> 812 840 s->count_shift; 813 841 #endif /* VBOX */ … … 824 852 } 825 853 826 static void apic_timer_update(APIC State *s, int64_t current_time)854 static void apic_timer_update(APICDeviceInfo* dev, APICState *s, int64_t current_time) 827 855 { 828 856 int64_t next_time, d; … … 842 870 qemu_mod_timer(s->timer, next_time); 843 871 #else 844 TMTimerSet( s->CTX_SUFF(pTimer), next_time);872 TMTimerSet(dev->CTX_SUFF(pTimer), next_time); 845 873 #endif 846 874 s->next_time = next_time; … … 850 878 qemu_del_timer(s->timer); 851 879 #else 852 TMTimerStop( s->CTX_SUFF(pTimer));880 TMTimerStop(dev->CTX_SUFF(pTimer)); 853 881 #endif 854 882 } … … 863 891 static DECLCALLBACK(void) apicTimer(PPDMDEVINS pDevIns, PTMTIMER pTimer) 864 892 { 865 APICState *s = PDMINS_2_DATA(pDevIns, APICState *); 866 s->pApicHlpR3->pfnLock(pDevIns, VERR_INTERNAL_ERROR); 893 APICDeviceInfo *dev = PDMINS_2_DATA(pDevIns, APICDeviceInfo *); 894 APICState *s = getLAPIC(dev); 895 dev->pApicHlpR3->pfnLock(pDevIns, VERR_INTERNAL_ERROR); 867 896 #endif /* VBOX */ 868 897 869 898 if (!(s->lvt[APIC_LVT_TIMER] & APIC_LVT_MASKED)) { 870 899 LogFlow(("apic_timer: trigger irq\n")); 871 apic_set_irq( s, s->lvt[APIC_LVT_TIMER] & 0xff, APIC_TRIGGER_EDGE);872 } 873 apic_timer_update( s, s->next_time);874 875 #ifdef VBOX 876 APIC_UNLOCK( s);900 apic_set_irq(dev, s, s->lvt[APIC_LVT_TIMER] & 0xff, APIC_TRIGGER_EDGE); 901 } 902 apic_timer_update(dev, s, s->next_time); 903 904 #ifdef VBOX 905 APIC_UNLOCK(dev); 877 906 #endif 878 907 } … … 884 913 return 0; 885 914 } 886 887 915 static uint32_t apic_mem_readw(void *opaque, target_phys_addr_t addr) 888 916 { … … 906 934 APICState *s; 907 935 #else /* VBOX */ 908 static uint32_t apic_mem_readl(APIC State *s, target_phys_addr_t addr)936 static uint32_t apic_mem_readl(APICDeviceInfo* dev, APICState *s, target_phys_addr_t addr) 909 937 { 910 938 #endif /* VBOX */ … … 997 1025 break; 998 1026 case 0x39: 999 val = apic_get_current_count( s);1027 val = apic_get_current_count(dev, s); 1000 1028 break; 1001 1029 case 0x3e: … … 1020 1048 APICState *s; 1021 1049 #else /* VBOX */ 1022 static int apic_mem_writel(APIC State *s, target_phys_addr_t addr, uint32_t val)1050 static int apic_mem_writel(APICDeviceInfo* dev, APICState *s, target_phys_addr_t addr, uint32_t val) 1023 1051 { 1024 1052 #endif /* VBOX */ … … 1046 1074 case 0x08: 1047 1075 #ifdef VBOX 1048 apic_update_tpr( s, val);1076 apic_update_tpr(dev, s, val); 1049 1077 #else 1050 1078 s->tpr = val; … … 1057 1085 break; 1058 1086 case 0x0b: /* EOI */ 1059 apic_eoi( s);1087 apic_eoi(dev, s); 1060 1088 break; 1061 1089 case 0x0d: … … 1067 1095 case 0x0f: 1068 1096 s->spurious_vec = val & 0x1ff; 1069 apic_update_irq( s);1097 apic_update_irq(dev, s); 1070 1098 break; 1071 1099 #ifndef VBOX … … 1085 1113 case 0x30: 1086 1114 s->icr[0] = val; 1087 apic_deliver( s, (s->icr[1] >> 24) & 0xff, (s->icr[0] >> 11) & 1,1115 apic_deliver(dev, s, (s->icr[1] >> 24) & 0xff, (s->icr[0] >> 11) & 1, 1088 1116 (s->icr[0] >> 8) & 7, (s->icr[0] & 0xff), 1089 1117 (s->icr[0] >> 14) & 1, (s->icr[0] >> 15) & 1); … … 1104 1132 apic_timer_update(s, qemu_get_clock(vm_clock)); 1105 1133 #else /* VBOX */ 1106 apic_timer_update( s, TMTimerGet(s->CTX_SUFF(pTimer)));1134 apic_timer_update(dev, s, TMTimerGet(dev->CTX_SUFF(pTimer))); 1107 1135 #endif /* VBOX*/ 1108 1136 } … … 1113 1141 s->initial_count_load_time = qemu_get_clock(vm_clock); 1114 1142 #else /* VBOX */ 1115 s->initial_count_load_time = TMTimerGet( s->CTX_SUFF(pTimer));1143 s->initial_count_load_time = TMTimerGet(dev->CTX_SUFF(pTimer)); 1116 1144 #endif /* VBOX*/ 1117 apic_timer_update( s, s->initial_count_load_time);1145 apic_timer_update(dev, s, s->initial_count_load_time); 1118 1146 break; 1119 1147 case 0x39: … … 1212 1240 return 0; 1213 1241 } 1214 1242 #ifndef VBOX 1215 1243 static void apic_reset(void *opaque) 1216 1244 { 1217 1245 APICState *s = (APICState*)opaque; 1218 #ifdef VBOX1219 TMTimerStop(s->CTX_SUFF(pTimer));1220 1221 /* malc, I've removed the initing duplicated in apic_init_ipi(). This1222 * arb_id was left over.. */1223 s->arb_id = 0;1224 1225 /* Reset should re-enable the APIC. */1226 s->apicbase = 0xfee00000 | MSR_IA32_APICBASE_BSP | MSR_IA32_APICBASE_ENABLE;1227 s->pApicHlpR3->pfnChangeFeature(s->pDevInsR3, true);1228 1229 #endif /* VBOX */1230 1246 apic_init_ipi(s); 1231 1247 } 1248 #endif 1232 1249 1233 1250 #endif /* IN_RING3 */ … … 1543 1560 PDMBOTHCBDECL(int) apicMMIORead(PPDMDEVINS pDevIns, void *pvUser, RTGCPHYS GCPhysAddr, void *pv, unsigned cb) 1544 1561 { 1545 APICState *s = PDMINS_2_DATA(pDevIns, APICState *); 1562 APICDeviceInfo *dev = PDMINS_2_DATA(pDevIns, APICDeviceInfo *); 1563 APICState *s = getLAPIC(dev); 1546 1564 1547 1565 #ifdef VBOX_WITH_SMP_GUESTS … … 1549 1567 #endif 1550 1568 1551 STAM_COUNTER_INC(&CTXSUFF( s->StatMMIORead));1569 STAM_COUNTER_INC(&CTXSUFF(dev->StatMMIORead)); 1552 1570 switch (cb) 1553 1571 { … … 1579 1597 #endif 1580 1598 #endif /* experimental */ 1581 APIC_LOCK( s, VINF_IOM_HC_MMIO_READ);1582 *(uint32_t *)pv = apic_mem_readl( s, GCPhysAddr);1583 APIC_UNLOCK( s);1599 APIC_LOCK(dev, VINF_IOM_HC_MMIO_READ); 1600 *(uint32_t *)pv = apic_mem_readl(dev, s, GCPhysAddr); 1601 APIC_UNLOCK(dev); 1584 1602 break; 1585 1603 } … … 1593 1611 PDMBOTHCBDECL(int) apicMMIOWrite(PPDMDEVINS pDevIns, void *pvUser, RTGCPHYS GCPhysAddr, void *pv, unsigned cb) 1594 1612 { 1595 APICState *s = PDMINS_2_DATA(pDevIns, APICState *); 1596 1597 STAM_COUNTER_INC(&CTXSUFF(s->StatMMIOWrite)); 1613 APICDeviceInfo *dev = PDMINS_2_DATA(pDevIns, APICDeviceInfo *); 1614 APICState *s = getLAPIC(dev); 1615 1616 STAM_COUNTER_INC(&CTXSUFF(dev->StatMMIOWrite)); 1598 1617 switch (cb) 1599 1618 { … … 1606 1625 { 1607 1626 int rc; 1608 APIC_LOCK( s, VINF_IOM_HC_MMIO_WRITE);1609 rc = apic_mem_writel( s, GCPhysAddr, *(uint32_t *)pv);1610 APIC_UNLOCK( s);1627 APIC_LOCK(dev, VINF_IOM_HC_MMIO_WRITE); 1628 rc = apic_mem_writel(dev, s, GCPhysAddr, *(uint32_t *)pv); 1629 APIC_UNLOCK(dev); 1611 1630 return rc; 1612 1631 } … … 1626 1645 static DECLCALLBACK(int) apicSaveExec(PPDMDEVINS pDevIns, PSSMHANDLE pSSMHandle) 1627 1646 { 1628 APICState *s = PDMINS_2_DATA(pDevIns, APICState *); 1647 APICDeviceInfo *dev = PDMINS_2_DATA(pDevIns, APICDeviceInfo *); 1648 /* @todo: process all LAPICS */ 1649 APICState* s = FIRST_LAPIC(dev); 1629 1650 apic_save(pSSMHandle, s); 1630 return TMR3TimerSave(s->CTX_SUFF(pTimer), pSSMHandle); 1651 /* @todo: save CPU count? */ 1652 return TMR3TimerSave(dev->CTX_SUFF(pTimer), pSSMHandle); 1631 1653 } 1632 1654 … … 1636 1658 static DECLCALLBACK(int) apicLoadExec(PPDMDEVINS pDevIns, PSSMHANDLE pSSMHandle, uint32_t u32Version) 1637 1659 { 1638 APICState *s = PDMINS_2_DATA(pDevIns, APICState *); 1660 APICDeviceInfo *dev = PDMINS_2_DATA(pDevIns, APICDeviceInfo *); 1661 /* @todo: process all LAPICS */ 1662 APICState* s = FIRST_LAPIC(dev); 1639 1663 if (apic_load(pSSMHandle, s, u32Version)) { 1640 1664 AssertFailed(); 1641 1665 return VERR_SSM_UNSUPPORTED_DATA_UNIT_VERSION; 1642 1666 } 1643 return TMR3TimerLoad(s->CTX_SUFF(pTimer), pSSMHandle); 1667 /* @todo: restore CPU count? */ 1668 return TMR3TimerLoad(dev->CTX_SUFF(pTimer), pSSMHandle); 1644 1669 } 1645 1670 … … 1649 1674 static DECLCALLBACK(void) apicReset(PPDMDEVINS pDevIns) 1650 1675 { 1651 APICState *s = PDMINS_2_DATA(pDevIns, APICState *); 1652 s->pApicHlpR3->pfnLock(pDevIns, VERR_INTERNAL_ERROR); 1653 apic_reset(s); 1676 APICDeviceInfo* dev = PDMINS_2_DATA(pDevIns, APICDeviceInfo *); 1677 dev->pApicHlpR3->pfnLock(pDevIns, VERR_INTERNAL_ERROR); 1678 1679 TMTimerStop(dev->CTX_SUFF(pTimer)); 1680 1681 /* @todo: process all LAPICS? Or only one? */ 1682 APICState* s = FIRST_LAPIC(dev); 1683 1684 apic_init_ipi(s); 1685 /* malc, I've removed the initing duplicated in apic_init_ipi(). This 1686 * arb_id was left over.. */ 1687 s->arb_id = 0; 1688 /* Reset should re-enable the APIC. */ 1689 s->apicbase = 0xfee00000 | MSR_IA32_APICBASE_BSP | MSR_IA32_APICBASE_ENABLE; 1690 dev->pApicHlpR3->pfnChangeFeature(dev->pDevInsR3, true); 1654 1691 /* Clear any pending APIC interrupt action flag. */ 1655 s->pApicHlpR3->pfnClearInterruptFF(pDevIns);1656 APIC_UNLOCK( s);1692 dev->pApicHlpR3->pfnClearInterruptFF(pDevIns); 1693 APIC_UNLOCK(dev); 1657 1694 } 1658 1695 … … 1662 1699 static DECLCALLBACK(void) apicRelocate(PPDMDEVINS pDevIns, RTGCINTPTR offDelta) 1663 1700 { 1664 APICState *pThis = PDMINS_2_DATA(pDevIns, APICState *); 1701 APICDeviceInfo *pThis = PDMINS_2_DATA(pDevIns, APICDeviceInfo *); 1702 1665 1703 pThis->pDevInsRC = PDMDEVINS_2_RCPTR(pDevIns); 1666 1704 pThis->pApicHlpRC = pThis->pApicHlpR3->pfnGetRCHelpers(pDevIns); 1667 1705 pThis->pTimerRC = TMTimerRCPtr(pThis->CTX_SUFF(pTimer)); 1706 } 1707 1708 DECLINLINE(void) initAPIC(APICState* apic, uint8_t id) 1709 { 1710 int i; 1711 ::memset(apic, 0, sizeof(*apic)); 1712 apic->apicbase = UINT32_C(0xfee00000) | MSR_IA32_APICBASE_BSP | MSR_IA32_APICBASE_ENABLE; 1713 for (i = 0; i < APIC_LVT_NB; i++) 1714 apic->lvt[i] = 1 << 16; /* mask LVT */ 1715 apic->spurious_vec = 0xff; 1716 apic->id = id; 1668 1717 } 1669 1718 … … 1673 1722 static DECLCALLBACK(int) apicConstruct(PPDMDEVINS pDevIns, int iInstance, PCFGMNODE pCfgHandle) 1674 1723 { 1675 APICState *pThis = PDMINS_2_DATA(pDevIns, APICState *);1676 1724 PDMAPICREG ApicReg; 1677 1725 int rc; 1678 inti;1726 uint32_t i; 1679 1727 bool fIOAPIC; 1680 1728 bool fGCEnabled; 1681 1729 bool fR0Enabled; 1682 1683 #ifndef VBOX_WITH_SMP_GUESTS 1730 APICDeviceInfo *pThis = PDMINS_2_DATA(pDevIns, APICDeviceInfo *); 1731 uint32_t cCpus; 1732 1733 /* 1734 * Only single device instance. 1735 */ 1684 1736 Assert(iInstance == 0); 1685 #else1686 LogRel(("[SMP] apicConstruct: %d %p\n", iInstance, pDevIns));1687 #endif1688 1737 1689 1738 /* 1690 1739 * Validate configuration. 1691 1740 */ 1692 if (!CFGMR3AreValuesValid(pCfgHandle, "IOAPIC\0" "GCEnabled\0" "R0Enabled\0")) 1741 if (!CFGMR3AreValuesValid(pCfgHandle, 1742 "IOAPIC\0" 1743 "GCEnabled\0" 1744 "R0Enabled\0" 1745 "NumCPUs\0")) 1693 1746 return VERR_PDM_DEVINS_UNKNOWN_CFG_VALUES; 1694 1747 … … 1707 1760 return PDMDEV_SET_ERROR(pDevIns, rc, 1708 1761 N_("Configuration error: Failed to query boolean value \"R0Enabled\"")); 1709 Log(("APIC: fR0Enabled=%RTbool fGCEnabled=%RTbool fIOAPIC=%RTbool\n", fR0Enabled, fGCEnabled, fIOAPIC)); 1762 1763 rc = CFGMR3QueryU32Def(pCfgHandle, "NumCPUs", &cCpus, 1); 1764 if (RT_FAILURE(rc)) 1765 return PDMDEV_SET_ERROR(pDevIns, rc, 1766 N_("Configuration error: Failed to query integer value \"NumCPUs\"")); 1767 1768 Log(("APIC: cCpus=%d fR0Enabled=%RTbool fGCEnabled=%RTbool fIOAPIC=%RTbool\n", cCpus, fR0Enabled, fGCEnabled, fIOAPIC)); 1710 1769 1711 1770 /* … … 1715 1774 pThis->pDevInsR0 = PDMDEVINS_2_R0PTR(pDevIns); 1716 1775 pThis->pDevInsRC = PDMDEVINS_2_RCPTR(pDevIns); 1717 pThis->apicbase = UINT32_C(0xfee00000) | MSR_IA32_APICBASE_BSP | MSR_IA32_APICBASE_ENABLE; 1718 for (i = 0; i < APIC_LVT_NB; i++) 1719 pThis->lvt[i] = 1 << 16; /* mask LVT */ 1720 pThis->spurious_vec = 0xff; 1721 1776 1777 PVM pVM = PDMDevHlpGetVM(pDevIns); 1778 1779 /* 1780 * We are not freeing this memory, as it's automatically released when guest exits. 1781 */ 1782 rc = MMHyperAlloc(pVM, cCpus*sizeof(APICState), 1, MM_TAG_PDM_DEVICE_USER, (void **)&pThis->pLapicsR3); 1783 if (RT_FAILURE(rc)) 1784 return VERR_NO_MEMORY; 1785 pThis->pLapicsR0 = MMHyperR3ToR0(pVM, pThis->pLapicsR3); 1786 pThis->pLapicsRC = MMHyperR3ToRC(pVM, pThis->pLapicsR3); 1787 1788 for (i = 0; i < cCpus; i++) 1789 { 1790 initAPIC((APICState*)pThis->pLapicsR3+i, i); 1791 } 1722 1792 1723 1793 /* … … 1797 1867 /* 1798 1868 * Register the MMIO range. 1869 * @todo: may need to rethink for cases when different LAPICs mapped to different address 1870 * (see IA32_APIC_BASE_MSR) 1799 1871 */ 1800 rc = PDMDevHlpMMIORegister(pDevIns, pThis->apicbase & ~0xfff, 0x1000, pThis,1872 rc = PDMDevHlpMMIORegister(pDevIns, FIRST_LAPIC(pThis)->apicbase & ~0xfff, 0x1000, pThis, 1801 1873 apicMMIOWrite, apicMMIORead, NULL, "APIC Memory"); 1802 1874 if (RT_FAILURE(rc)) … … 1806 1878 pThis->pApicHlpRC = pThis->pApicHlpR3->pfnGetRCHelpers(pDevIns); 1807 1879 1808 rc = PDMDevHlpMMIORegisterGC(pDevIns, pThis->apicbase & ~0xfff, 0x1000, 0,1880 rc = PDMDevHlpMMIORegisterGC(pDevIns, FIRST_LAPIC(pThis)->apicbase & ~0xfff, 0x1000, 0, 1809 1881 "apicMMIOWrite", "apicMMIORead", NULL); 1810 1882 if (RT_FAILURE(rc)) … … 1815 1887 pThis->pApicHlpR0 = pThis->pApicHlpR3->pfnGetR0Helpers(pDevIns); 1816 1888 1817 rc = PDMDevHlpMMIORegisterR0(pDevIns, pThis->apicbase & ~0xfff, 0x1000, 0,1889 rc = PDMDevHlpMMIORegisterR0(pDevIns, FIRST_LAPIC(pThis)->apicbase & ~0xfff, 0x1000, 0, 1818 1890 "apicMMIOWrite", "apicMMIORead", NULL); 1819 1891 if (RT_FAILURE(rc)) … … 1834 1906 * Saved state. 1835 1907 */ 1836 rc = PDMDevHlpSSMRegister(pDevIns, pDevIns->pDevReg->szDeviceName, iInstance, 1/* version */,1908 rc = PDMDevHlpSSMRegister(pDevIns, pDevIns->pDevReg->szDeviceName, iInstance, 2 /* version */, 1837 1909 sizeof(*pThis), NULL, apicSaveExec, NULL, NULL, apicLoadExec, NULL); 1838 1910 if (RT_FAILURE(rc)) … … 1874 1946 PDM_DEVREG_CLASS_PIC, 1875 1947 /* cMaxInstances */ 1876 #ifdef VBOX_WITH_SMP_GUESTS1877 8,1878 #else1879 1948 1, 1880 #endif1881 1949 /* cbInstance */ 1882 1950 sizeof(APICState), -
trunk/src/VBox/Devices/testcase/tstDeviceStructSize.cpp
r11556 r12588 224 224 // CHECK_MEMBER_ALIGNMENT(PCNetState, StatMMIOReadGC, 8); 225 225 CHECK_MEMBER_ALIGNMENT(DEVPIC, StatSetIrqGC, 8); 226 CHECK_MEMBER_ALIGNMENT(APIC State, StatMMIOReadGC, 8);226 CHECK_MEMBER_ALIGNMENT(APICDeviceInfo, StatMMIOReadGC, 8); 227 227 CHECK_MEMBER_ALIGNMENT(IOAPICState, StatMMIOReadGC, 8); 228 228 CHECK_MEMBER_ALIGNMENT(IOAPICState, StatMMIOReadGC, 8); -
trunk/src/VBox/Devices/testcase/tstDeviceStructSizeGC.cpp
r12509 r12588 567 567 GEN_CHECK_OFF(APICState, initial_count_load_time); 568 568 GEN_CHECK_OFF(APICState, next_time); 569 GEN_CHECK_OFF(APICState, pDevInsR3); 570 GEN_CHECK_OFF(APICState, pApicHlpR3); 571 GEN_CHECK_OFF(APICState, pTimerR3); 572 GEN_CHECK_OFF(APICState, pDevInsR0); 573 GEN_CHECK_OFF(APICState, pApicHlpR0); 574 GEN_CHECK_OFF(APICState, pTimerR0); 575 GEN_CHECK_OFF(APICState, pDevInsRC); 576 GEN_CHECK_OFF(APICState, pApicHlpRC); 577 GEN_CHECK_OFF(APICState, pTimerRC); 578 GEN_CHECK_OFF(APICState, ulTPRPatchAttempts); 569 570 GEN_CHECK_SIZE(APICDeviceInfo); 571 GEN_CHECK_OFF(APICDeviceInfo, pDevInsR3); 572 GEN_CHECK_OFF(APICDeviceInfo, pApicHlpR3); 573 GEN_CHECK_OFF(APICDeviceInfo, pTimerR3); 574 GEN_CHECK_OFF(APICDeviceInfo, pDevInsR0); 575 GEN_CHECK_OFF(APICDeviceInfo, pApicHlpR0); 576 GEN_CHECK_OFF(APICDeviceInfo, pTimerR0); 577 GEN_CHECK_OFF(APICDeviceInfo, pDevInsRC); 578 GEN_CHECK_OFF(APICDeviceInfo, pApicHlpRC); 579 GEN_CHECK_OFF(APICDeviceInfo, pTimerRC); 580 GEN_CHECK_OFF(APICDeviceInfo, ulTPRPatchAttempts); 579 581 #ifdef VBOX_WITH_STATISTICS 580 GEN_CHECK_OFF(APIC State, StatMMIOReadGC);581 GEN_CHECK_OFF(APIC State, StatMMIOWriteHC);582 GEN_CHECK_OFF(APICDeviceInfo, StatMMIOReadGC); 583 GEN_CHECK_OFF(APICDeviceInfo, StatMMIOWriteHC); 582 584 #endif 583 585 -
trunk/src/VBox/Main/ConsoleImpl2.cpp
r12520 r12588 499 499 /* 500 500 * Advanced Programmable Interrupt Controller. 501 * SMP: Each CPU has a LAPIC (cross-calls). 501 * SMP: Each CPU has a LAPIC, but we have a single device representing all LAPICs states, 502 * thus only single insert 502 503 */ 503 504 rc = CFGMR3InsertNode(pDevices, "apic", &pDev); RC_CHECK(); 504 for (unsigned iCpu = 0; iCpu < cCpus; iCpu++) 505 { 506 rc = CFGMR3InsertNodeF(pDev, &pInst, "%u", iCpu); RC_CHECK(); 507 rc = CFGMR3InsertInteger(pInst, "Trusted", 1); /* boolean */ RC_CHECK(); 508 rc = CFGMR3InsertNode(pInst, "Config", &pCfg); RC_CHECK(); 509 rc = CFGMR3InsertInteger(pCfg, "IOAPIC", fIOAPIC); RC_CHECK(); 510 } 511 505 rc = CFGMR3InsertNode(pDev, "0", &pInst); RC_CHECK(); 506 rc = CFGMR3InsertInteger(pInst, "Trusted", 1); /* boolean */ RC_CHECK(); 507 rc = CFGMR3InsertNode(pInst, "Config", &pCfg); RC_CHECK(); 508 rc = CFGMR3InsertInteger(pCfg, "IOAPIC", fIOAPIC); RC_CHECK(); 509 rc = CFGMR3InsertInteger(pCfg, "NumCPUs", cCpus); RC_CHECK(); 510 511 /* SMP: @todo: IOAPIC may be required for SMP configs */ 512 512 if (fIOAPIC) 513 513 {
Note:
See TracChangeset
for help on using the changeset viewer.