Changeset 20734 in vbox
- Timestamp:
- Jun 20, 2009 6:28:44 PM (16 years ago)
- svn:sync-xref-src-repo-rev:
- 48850
- Location:
- trunk/src/VBox/Devices
- Files:
-
- 2 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/Devices/PC/DevAPIC.cpp
r20676 r20734 92 92 #define IOAPIC_UNLOCK(pThis) (pThis)->CTX_SUFF(pIoApicHlp)->pfnUnlock((pThis)->CTX_SUFF(pDevIns)) 93 93 94 /** @def LAPIC_BASE95 * Return address of first LAPIC state. */96 #define LAPIC_BASE(pThis) ((APICState*)(pThis)->CTX_SUFF(pLapics))97 94 98 95 #define foreach_apic(dev, mask, code) \ 99 96 do { \ 100 97 uint32_t i; \ 101 APICState * apic = LAPIC_BASE(dev);\98 APICState *apic = (dev)->CTX_SUFF(paLapics); \ 102 99 for (i = 0; i < dev->cCpus; i++) \ 103 100 { \ … … 222 219 uint32_t Alignment0; 223 220 #endif 221 #ifndef VBOX 224 222 int64_t initial_count_load_time, next_time; 225 #ifndef VBOX226 223 QEMUTimer *timer; 227 224 struct APICState *next_apic; 228 225 #else 226 /** The time stamp of the initial_count load, i.e. when it was started. */ 227 uint64_t initial_count_load_time; 228 /** The time stamp of the next timer callback. */ 229 uint64_t next_time; 229 230 /** The APIC timer - R3 Ptr. */ 230 PTMTIMERR3 pTimerR3; 231 231 PTMTIMERR3 pTimerR3; 232 232 /** The APIC timer - R0 Ptr. */ 233 PTMTIMERR0 pTimerR0; 234 233 PTMTIMERR0 pTimerR0; 235 234 /** The APIC timer - RC Ptr. */ 236 PTMTIMERRC pTimerRC; 237 235 PTMTIMERRC pTimerRC; 236 /** Whether the timer is armed or not */ 237 bool fTimerArmed; 238 238 /** Alignment */ 239 uint32_t Alignment1; 239 bool afAlignment[3]; 240 /** Timer description timer. */ 241 R3PTRTYPE(char *) pszDesc; 242 # ifdef VBOX_WITH_STATISTICS 243 STAMCOUNTER StatTimerSetInitialCount; 244 STAMCOUNTER StatTimerSetInitialCountArm; 245 STAMCOUNTER StatTimerSetInitialCountDisarm; 246 STAMCOUNTER StatTimerSetLvt; 247 STAMCOUNTER StatTimerSetLvtClearPeriodic; 248 STAMCOUNTER StatTimerSetLvtPostponed; 249 STAMCOUNTER StatTimerSetLvtArmed; 250 STAMCOUNTER StatTimerSetLvtArm; 251 STAMCOUNTER StatTimerSetLvtArmRetries; 252 STAMCOUNTER StatTimerSetLvtNoRelevantChange; 253 # endif 240 254 #endif /* VBOX */ 241 255 } APICState; … … 265 279 266 280 # ifdef VBOX_WITH_STATISTICS 267 STAMCOUNTER StatMMIOReadGC;268 STAMCOUNTER StatMMIOReadHC;269 STAMCOUNTER StatMMIOWriteGC;270 STAMCOUNTER StatMMIOWriteHC;271 STAMCOUNTER StatSetIrqGC;272 STAMCOUNTER StatSetIrqHC;281 STAMCOUNTER StatMMIOReadGC; 282 STAMCOUNTER StatMMIOReadHC; 283 STAMCOUNTER StatMMIOWriteGC; 284 STAMCOUNTER StatMMIOWriteHC; 285 STAMCOUNTER StatSetIrqGC; 286 STAMCOUNTER StatSetIrqHC; 273 287 # endif 274 288 #endif /* VBOX */ … … 285 299 PCPDMAPICHLPR3 pApicHlpR3; 286 300 /** LAPICs states - R3 Ptr */ 287 R TR3PTR pLapicsR3;301 R3PTRTYPE(APICState *) paLapicsR3; 288 302 /** The critical section - R3 Ptr. */ 289 303 R3PTRTYPE(PPDMCRITSECT) pCritSectR3; … … 294 308 PCPDMAPICHLPR0 pApicHlpR0; 295 309 /** LAPICs states - R0 Ptr */ 296 R TR0PTR pLapicsR0;310 R0PTRTYPE(APICState *) paLapicsR0; 297 311 /** The critical section - R3 Ptr. */ 298 312 R0PTRTYPE(PPDMCRITSECT) pCritSectR0; … … 303 317 PCPDMAPICHLPRC pApicHlpRC; 304 318 /** LAPICs states - RC Ptr */ 305 R TRCPTR pLapicsRC;319 RCPTRTYPE(APICState *) paLapicsRC; 306 320 /** The critical section - R3 Ptr. */ 307 321 RCPTRTYPE(PPDMCRITSECT) pCritSectRC; … … 318 332 319 333 # ifdef VBOX_WITH_STATISTICS 320 STAMCOUNTER StatMMIOReadGC;321 STAMCOUNTER StatMMIOReadHC;322 STAMCOUNTER StatMMIOWriteGC;323 STAMCOUNTER StatMMIOWriteHC;324 STAMCOUNTER StatClearedActiveIrq;334 STAMCOUNTER StatMMIOReadGC; 335 STAMCOUNTER StatMMIOReadHC; 336 STAMCOUNTER StatMMIOWriteGC; 337 STAMCOUNTER StatMMIOWriteHC; 338 STAMCOUNTER StatClearedActiveIrq; 325 339 # endif 326 340 } APICDeviceInfo; 327 328 static void apic_eoi(APICDeviceInfo *dev, APICState* s);329 static int apic_deliver(APICDeviceInfo* dev, APICState *s,330 uint8_t dest, uint8_t dest_mode,331 uint8_t delivery_mode, uint8_t vector_num,332 uint8_t polarity, uint8_t trigger_mode);333 static void apic_timer_update(APICDeviceInfo* dev, APICState *s,334 int64_t current_time);335 static int apic_get_arb_pri(APICState *s);336 static int apic_get_ppr(APICState *s);337 static uint32_t apic_get_current_count(APICDeviceInfo* dev, APICState *s);338 339 340 DECLINLINE(APICState*) getLapicById(APICDeviceInfo* dev, VMCPUID id)341 {342 AssertFatalMsg(id < dev->cCpus, ("CPU id %d out of range\n", id));343 return LAPIC_BASE(dev) + id;344 }345 346 DECLINLINE(APICState*) getLapic(APICDeviceInfo* dev)347 {348 /* LAPIC's array is indexed by CPU id */349 VMCPUID id = dev->CTX_SUFF(pApicHlp)->pfnGetCpuId(dev->CTX_SUFF(pDevIns));350 return getLapicById(dev, id);351 }352 353 DECLINLINE(VMCPUID) getCpuFromLapic(APICDeviceInfo* dev, APICState *s)354 {355 /* for now we assume LAPIC physical id == CPU id */356 return VMCPUID(s->phys_id);357 }358 359 DECLINLINE(void) cpuSetInterrupt(APICDeviceInfo* dev, APICState *s)360 {361 Log2(("apic: setting interrupt flag for cpu %d\n", getCpuFromLapic(dev, s)));362 dev->CTX_SUFF(pApicHlp)->pfnSetInterruptFF(dev->CTX_SUFF(pDevIns),363 getCpuFromLapic(dev, s));364 }365 366 DECLINLINE(void) cpuClearInterrupt(APICDeviceInfo* dev, APICState *s)367 {368 Log2(("apic: clear interrupt flag\n"));369 dev->CTX_SUFF(pApicHlp)->pfnClearInterruptFF(dev->CTX_SUFF(pDevIns),370 getCpuFromLapic(dev, s));371 }372 373 #ifdef IN_RING3374 DECLINLINE(void) cpuSendSipi(APICDeviceInfo* dev, APICState *s, int vector)375 {376 Log2(("apic: send SIPI vector=%d\n", vector));377 378 dev->pApicHlpR3->pfnSendSipi(dev->pDevInsR3,379 getCpuFromLapic(dev, s),380 vector);381 }382 383 DECLINLINE(void) cpuSendInitIpi(APICDeviceInfo* dev, APICState *s)384 {385 Log2(("apic: send init IPI\n"));386 387 dev->pApicHlpR3->pfnSendInitIpi(dev->pDevInsR3,388 getCpuFromLapic(dev, s));389 }390 #endif391 392 DECLINLINE(uint32_t) getApicEnableBits(APICDeviceInfo* dev)393 {394 switch (dev->enmVersion)395 {396 case PDMAPICVERSION_NONE:397 return 0;398 case PDMAPICVERSION_APIC:399 return MSR_IA32_APICBASE_ENABLE;400 case PDMAPICVERSION_X2APIC:401 return MSR_IA32_APICBASE_ENABLE | MSR_IA32_APICBASE_X2ENABLE ;402 default:403 AssertMsgFailed(("Unsuported APIC version %d\n", dev->enmVersion));404 return 0;405 }406 }407 408 DECLINLINE(PDMAPICVERSION) getApicMode(APICState *apic)409 {410 switch (((apic->apicbase) >> 10) & 0x3)411 {412 case 0:413 return PDMAPICVERSION_NONE;414 case 1:415 default:416 /* Invalid */417 return PDMAPICVERSION_NONE;418 case 2:419 return PDMAPICVERSION_APIC;420 case 3:421 return PDMAPICVERSION_X2APIC;422 }423 }424 425 341 #endif /* VBOX */ 426 342 427 343 #ifndef VBOX_DEVICE_STRUCT_TESTCASE 344 428 345 #ifndef VBOX 429 346 static int apic_io_memory; … … 432 349 #endif /* !VBOX */ 433 350 434 static void apic_init_ipi(APICDeviceInfo* dev, APICState *s);435 static void apic_set_irq(APICDeviceInfo* dev, APICState *s, int vector_num, int trigger_mode);436 static bool apic_update_irq(APICDeviceInfo* dev, APICState *s);437 351 438 352 #ifdef VBOX 439 static uint32_t apic_get_delivery_bitmask(APICDeviceInfo* dev, uint8_t dest, uint8_t dest_mode); 353 /******************************************************************************* 354 * Internal Functions * 355 *******************************************************************************/ 440 356 RT_C_DECLS_BEGIN 441 357 PDMBOTHCBDECL(int) apicMMIORead(PPDMDEVINS pDevIns, void *pvUser, RTGCPHYS GCPhysAddr, void *pv, unsigned cb); … … 458 374 static void apic_update_tpr(APICDeviceInfo *dev, APICState* s, uint32_t val); 459 375 RT_C_DECLS_END 376 377 static void apic_eoi(APICDeviceInfo *dev, APICState* s); /* */ 378 static uint32_t apic_get_delivery_bitmask(APICDeviceInfo* dev, uint8_t dest, uint8_t dest_mode); 379 static int apic_deliver(APICDeviceInfo* dev, APICState *s, 380 uint8_t dest, uint8_t dest_mode, 381 uint8_t delivery_mode, uint8_t vector_num, 382 uint8_t polarity, uint8_t trigger_mode); 383 static int apic_get_arb_pri(APICState *s); 384 static int apic_get_ppr(APICState *s); 385 static uint32_t apic_get_current_count(APICDeviceInfo* dev, APICState *s); 386 static void apicTimerSetInitialCount(APICDeviceInfo *dev, APICState *s, uint32_t initial_count); 387 static void apicTimerSetLvt(APICDeviceInfo *dev, APICState *pThis, uint32_t fNew); 388 389 #endif /* VBOX */ 390 391 static void apic_init_ipi(APICDeviceInfo* dev, APICState *s); 392 static void apic_set_irq(APICDeviceInfo* dev, APICState *s, int vector_num, int trigger_mode); 393 static bool apic_update_irq(APICDeviceInfo* dev, APICState *s); 394 395 396 #ifdef VBOX 397 398 DECLINLINE(APICState*) getLapicById(APICDeviceInfo* dev, VMCPUID id) 399 { 400 AssertFatalMsg(id < dev->cCpus, ("CPU id %d out of range\n", id)); 401 return &dev->CTX_SUFF(paLapics)[id]; 402 } 403 404 DECLINLINE(APICState*) getLapic(APICDeviceInfo* dev) 405 { 406 /* LAPIC's array is indexed by CPU id */ 407 VMCPUID id = dev->CTX_SUFF(pApicHlp)->pfnGetCpuId(dev->CTX_SUFF(pDevIns)); 408 return getLapicById(dev, id); 409 } 410 411 DECLINLINE(VMCPUID) getCpuFromLapic(APICDeviceInfo* dev, APICState *s) 412 { 413 /* for now we assume LAPIC physical id == CPU id */ 414 return VMCPUID(s->phys_id); 415 } 416 417 DECLINLINE(void) cpuSetInterrupt(APICDeviceInfo* dev, APICState *s) 418 { 419 Log2(("apic: setting interrupt flag for cpu %d\n", getCpuFromLapic(dev, s))); 420 dev->CTX_SUFF(pApicHlp)->pfnSetInterruptFF(dev->CTX_SUFF(pDevIns), 421 getCpuFromLapic(dev, s)); 422 } 423 424 DECLINLINE(void) cpuClearInterrupt(APICDeviceInfo* dev, APICState *s) 425 { 426 Log2(("apic: clear interrupt flag\n")); 427 dev->CTX_SUFF(pApicHlp)->pfnClearInterruptFF(dev->CTX_SUFF(pDevIns), 428 getCpuFromLapic(dev, s)); 429 } 430 431 # ifdef IN_RING3 432 433 DECLINLINE(void) cpuSendSipi(APICDeviceInfo* dev, APICState *s, int vector) 434 { 435 Log2(("apic: send SIPI vector=%d\n", vector)); 436 437 dev->pApicHlpR3->pfnSendSipi(dev->pDevInsR3, 438 getCpuFromLapic(dev, s), 439 vector); 440 } 441 442 DECLINLINE(void) cpuSendInitIpi(APICDeviceInfo* dev, APICState *s) 443 { 444 Log2(("apic: send init IPI\n")); 445 446 dev->pApicHlpR3->pfnSendInitIpi(dev->pDevInsR3, 447 getCpuFromLapic(dev, s)); 448 } 449 450 # endif /* IN_RING3 */ 451 452 DECLINLINE(uint32_t) getApicEnableBits(APICDeviceInfo* dev) 453 { 454 switch (dev->enmVersion) 455 { 456 case PDMAPICVERSION_NONE: 457 return 0; 458 case PDMAPICVERSION_APIC: 459 return MSR_IA32_APICBASE_ENABLE; 460 case PDMAPICVERSION_X2APIC: 461 return MSR_IA32_APICBASE_ENABLE | MSR_IA32_APICBASE_X2ENABLE ; 462 default: 463 AssertMsgFailed(("Unsuported APIC version %d\n", dev->enmVersion)); 464 return 0; 465 } 466 } 467 468 DECLINLINE(PDMAPICVERSION) getApicMode(APICState *apic) 469 { 470 switch (((apic->apicbase) >> 10) & 0x3) 471 { 472 case 0: 473 return PDMAPICVERSION_NONE; 474 case 1: 475 default: 476 /* Invalid */ 477 return PDMAPICVERSION_NONE; 478 case 2: 479 return PDMAPICVERSION_APIC; 480 case 3: 481 return PDMAPICVERSION_X2APIC; 482 } 483 } 484 460 485 #endif /* VBOX */ 461 486 … … 566 591 { 567 592 APICDeviceInfo *dev = PDMINS_2_DATA(pDevIns, APICDeviceInfo *); 568 APICState *s = getLapic(dev); 593 APICState *s = getLapic(dev); /** @todo fix interface */ 569 594 Log(("cpu_set_apic_base: %016RX64\n", val)); 570 595 … … 606 631 } 607 632 #endif /* VBOX */ 633 608 634 #ifndef VBOX 609 635 … … 672 698 { 673 699 APICDeviceInfo *dev = PDMINS_2_DATA(pDevIns, APICDeviceInfo *); 674 APICState *s = getLapic(dev); 700 APICState *s = getLapic(dev); /** @todo fix interface */ 675 701 LogFlow(("apicGetBase: %016llx\n", (uint64_t)s->apicbase)); 676 702 return s->apicbase; … … 693 719 } 694 720 721 /** 722 * x2APIC MSR write interface. 723 * 724 * @returns VBox status code. 725 * 726 * @param pDevIns The device instance. 727 * @param idCpu The ID of the virtual CPU and thereby APIC index. 728 * @param u32Reg Register to write (ecx). 729 * @param u64Value The value to write (eax:edx / rax). 730 * 731 */ 695 732 PDMBOTHCBDECL(int) apicWriteMSR(PPDMDEVINS pDevIns, VMCPUID idCpu, uint32_t u32Reg, uint64_t u64Value) 696 733 { … … 701 738 return VERR_EM_INTERPRETER; 702 739 740 APICState *pThis = getLapicById(dev, idCpu); 741 703 742 uint32_t index = (u32Reg - MSR_IA32_APIC_START) & 0xff; 704 705 APICState* apic = getLapicById(dev, idCpu);706 707 743 switch (index) 708 744 { 709 745 case 0x02: 710 apic->id = (u64Value >> 24);746 pThis->id = (u64Value >> 24); 711 747 break; 712 748 case 0x03: 713 749 break; 714 750 case 0x08: 715 apic_update_tpr(dev, apic, u64Value);751 apic_update_tpr(dev, pThis, u64Value); 716 752 break; 717 753 case 0x09: case 0x0a: … … 719 755 break; 720 756 case 0x0b: /* EOI */ 721 apic_eoi(dev, apic);757 apic_eoi(dev, pThis); 722 758 break; 723 759 case 0x0d: 724 apic->log_dest = u64Value >> 24;760 pThis->log_dest = u64Value >> 24; 725 761 break; 726 762 case 0x0e: 727 apic->dest_mode = u64Value >> 28;763 pThis->dest_mode = u64Value >> 28; 728 764 break; 729 765 case 0x0f: 730 apic->spurious_vec = u64Value & 0x1ff;731 apic_update_irq(dev, apic);766 pThis->spurious_vec = u64Value & 0x1ff; 767 apic_update_irq(dev, pThis); 732 768 break; 733 769 case 0x10: case 0x11: case 0x12: case 0x13: case 0x14: case 0x15: case 0x16: case 0x17: … … 740 776 case 0x30: 741 777 /* Here one of the differences with regular APIC: ICR is single 64-bit register */ 742 apic->icr[0] = (uint32_t)u64Value;743 apic->icr[1] = (uint32_t)(u64Value >> 32);744 rc = apic_deliver(dev, apic, (apic->icr[1] >> 24) & 0xff, (apic->icr[0] >> 11) & 1,745 ( apic->icr[0] >> 8) & 7, (apic->icr[0] & 0xff),746 ( apic->icr[0] >> 14) & 1, (apic->icr[0] >> 15) & 1);747 break; 748 case 0x32 : case 0x33: case 0x34: case 0x35: case 0x36: case 0x37:749 {750 int n = index - 0x32;751 apic->lvt[n] = u64Value;752 if (n == APIC_LVT_TIMER) 753 apic_timer_update(dev, apic, TMTimerGet(apic->CTX_SUFF(pTimer)));754 }755 break;778 pThis->icr[0] = (uint32_t)u64Value; 779 pThis->icr[1] = (uint32_t)(u64Value >> 32); 780 rc = apic_deliver(dev, pThis, (pThis->icr[1] >> 24) & 0xff, (pThis->icr[0] >> 11) & 1, 781 (pThis->icr[0] >> 8) & 7, (pThis->icr[0] & 0xff), 782 (pThis->icr[0] >> 14) & 1, (pThis->icr[0] >> 15) & 1); 783 break; 784 case 0x32 + APIC_LVT_TIMER: 785 AssertCompile(APIC_LVT_TIMER == 0); 786 apicTimerSetLvt(dev, pThis, u64Value); 787 break; 788 789 case 0x33: case 0x34: case 0x35: case 0x36: case 0x37: 790 pThis->lvt[index - 0x32] = u64Value; 791 break; 756 792 case 0x38: 757 apic->initial_count = u64Value; 758 apic->initial_count_load_time = TMTimerGet(apic->CTX_SUFF(pTimer)); 759 apic_timer_update(dev, apic, apic->initial_count_load_time); 793 apicTimerSetInitialCount(dev, pThis, u64Value); 760 794 break; 761 795 case 0x39: … … 765 799 { 766 800 int v; 767 apic->divide_conf = u64Value & 0xb;768 v = ( apic->divide_conf & 3) | ((apic->divide_conf >> 1) & 4);769 apic->count_shift = (v + 1) & 7;801 pThis->divide_conf = u64Value & 0xb; 802 v = (pThis->divide_conf & 3) | ((pThis->divide_conf >> 1) & 4); 803 pThis->count_shift = (v + 1) & 7; 770 804 break; 771 805 } … … 784 818 default: 785 819 AssertMsgFailed(("apicWriteMSR: unknown index %x\n", index)); 786 apic->esr |= ESR_ILLEGAL_ADDRESS;820 pThis->esr |= ESR_ILLEGAL_ADDRESS; 787 821 break; 788 822 } … … 790 824 return rc; 791 825 } 826 827 /** 828 * x2APIC MSR read interface. 829 * 830 * @returns VBox status code. 831 * 832 * @param pDevIns The device instance. 833 * @param idCpu The ID of the virtual CPU and thereby APIC index. 834 * @param u32Reg Register to write (ecx). 835 * @param pu64Value Where to return the value (eax:edx / rax). 836 */ 792 837 PDMBOTHCBDECL(int) apicReadMSR(PPDMDEVINS pDevIns, VMCPUID idCpu, uint32_t u32Reg, uint64_t *pu64Value) 793 838 { … … 972 1017 if (!dev) 973 1018 return false; 974 APICState *s = getLapic(dev); 1019 APICState *s = getLapic(dev); /** @todo fix interface */ 975 1020 976 1021 /* … … 1050 1095 else 1051 1096 { 1052 APICState *apic = LAPIC_BASE(dev);1097 APICState *apic = dev->CTX_SUFF(paLapics); 1053 1098 uint32_t i; 1054 1099 … … 1218 1263 APIC_LOCK(dev, VERR_INTERNAL_ERROR); 1219 1264 1220 APICState *s = getLapic(dev); 1265 APICState *s = getLapic(dev); /** @todo fix interface */ 1221 1266 int intno; 1222 1267 … … 1248 1293 } 1249 1294 1250 static uint32_t apic_get_current_count(APICDeviceInfo *dev, APICState *s)1295 static uint32_t apic_get_current_count(APICDeviceInfo *dev, APICState *s) 1251 1296 { 1252 1297 int64_t d; … … 1271 1316 } 1272 1317 1318 #ifndef VBOX /* we've replaced all the code working the APIC timer. */ 1319 1273 1320 static void apic_timer_update(APICDeviceInfo* dev, APICState *s, int64_t current_time) 1274 1321 { … … 1286 1333 } 1287 1334 next_time = s->initial_count_load_time + (d << s->count_shift); 1288 # ifndef VBOX1335 # ifndef VBOX 1289 1336 qemu_mod_timer(s->timer, next_time); 1290 # else1337 # else 1291 1338 TMTimerSet(s->CTX_SUFF(pTimer), next_time); 1292 #endif 1339 s->fTimerArmed = true; 1340 # endif 1293 1341 s->next_time = next_time; 1294 1342 } else { 1295 1343 no_timer: 1296 # ifndef VBOX1344 # ifndef VBOX 1297 1345 qemu_del_timer(s->timer); 1298 # else1346 # else 1299 1347 TMTimerStop(s->CTX_SUFF(pTimer)); 1300 #endif 1301 } 1302 } 1303 1304 #ifdef IN_RING3 1305 # ifndef VBOX 1348 s->fTimerArmed = false; 1349 # endif 1350 } 1351 } 1352 1306 1353 static void apic_timer(void *opaque) 1307 1354 { 1308 1355 APICState *s = opaque; 1309 # else /* VBOX */1310 static DECLCALLBACK(void) apicTimer(PPDMDEVINS pDevIns, PTMTIMER pTimer, void *pvUser)1311 {1312 APICDeviceInfo *dev = PDMINS_2_DATA(pDevIns, APICDeviceInfo *);1313 APICState *s = (APICState *)pvUser;1314 Assert(s->pTimerR3 == pTimer);1315 # endif /* VBOX */1316 1356 1317 1357 if (!(s->lvt[APIC_LVT_TIMER] & APIC_LVT_MASKED)) { … … 1321 1361 apic_timer_update(dev, s, s->next_time); 1322 1362 } 1323 #endif /* IN_RING3 */ 1363 1364 #else /* VBOX */ 1365 1366 /** 1367 * Implementation of the 0380h access: Timer reset + new initial count. 1368 * 1369 * @param dev The device state. 1370 * @param pThis The APIC sub-device state. 1371 * @param u32NewInitialCount The new initial count for the timer. 1372 */ 1373 static void apicTimerSetInitialCount(APICDeviceInfo *dev, APICState *pThis, uint32_t u32NewInitialCount) 1374 { 1375 STAM_COUNTER_INC(&pThis->StatTimerSetInitialCount); 1376 pThis->initial_count = u32NewInitialCount; 1377 1378 /* 1379 * Don't (re-)arm the timer if the it's masked or if it's 1380 * a zero length one-shot timer. 1381 */ 1382 /** @todo check the correct behavior of setting a 0 initial_count for a one-shot 1383 * timer. This is just copying the behavior of the original code. */ 1384 if ( !(pThis->lvt[APIC_LVT_TIMER] & APIC_LVT_MASKED) 1385 && ( (pThis->lvt[APIC_LVT_TIMER] & APIC_LVT_TIMER_PERIODIC) 1386 || u32NewInitialCount != 0)) 1387 { 1388 /* 1389 * Calculate the relative next time and perform a combined timer get/set 1390 * operation. This avoids racing the clock between get and set. 1391 */ 1392 uint64_t cTicksNext = u32NewInitialCount; 1393 cTicksNext += 1; 1394 cTicksNext <<= pThis->count_shift; 1395 TMTimerSetRelative(pThis->CTX_SUFF(pTimer), cTicksNext, &pThis->initial_count_load_time); 1396 pThis->next_time = pThis->initial_count_load_time + cTicksNext; 1397 pThis->fTimerArmed = true; 1398 STAM_COUNTER_INC(&pThis->StatTimerSetInitialCountArm); 1399 } 1400 else 1401 { 1402 /* Stop it if necessary and record the load time for unmasking. */ 1403 if (pThis->fTimerArmed) 1404 { 1405 STAM_COUNTER_INC(&pThis->StatTimerSetInitialCountDisarm); 1406 TMTimerStop(pThis->CTX_SUFF(pTimer)); 1407 pThis->fTimerArmed = false; 1408 } 1409 pThis->initial_count_load_time = TMTimerGet(pThis->CTX_SUFF(pTimer)); 1410 } 1411 } 1412 1413 /** 1414 * Implementation of the 0320h access: change the LVT flags. 1415 * 1416 * @param dev The device state. 1417 * @param pThis The APIC sub-device state to operate on. 1418 * @param fNew The new flags. 1419 */ 1420 static void apicTimerSetLvt(APICDeviceInfo *dev, APICState *pThis, uint32_t fNew) 1421 { 1422 STAM_COUNTER_INC(&pThis->StatTimerSetLvt); 1423 1424 /* 1425 * Make the flag change, saving the old ones so we can avoid 1426 * unnecessary work. 1427 */ 1428 uint32_t const fOld = pThis->lvt[APIC_LVT_TIMER]; 1429 pThis->lvt[APIC_LVT_TIMER] = fNew; 1430 1431 /* Only the masked and peridic bits are relevant (see apic_timer_update). */ 1432 if ( (fOld & (APIC_LVT_MASKED | APIC_LVT_TIMER_PERIODIC)) 1433 != (fNew & (APIC_LVT_MASKED | APIC_LVT_TIMER_PERIODIC))) 1434 { 1435 /* 1436 * If changed to one-shot from periodic, stop the timer if we're not 1437 * in the first period. 1438 */ 1439 /** @todo check how clearing the periodic flag really should behave when not 1440 * in period 1. The current code just mirrors the behavior of the 1441 * original implementation. */ 1442 if ( (fOld & APIC_LVT_TIMER_PERIODIC) 1443 && !(fNew & APIC_LVT_TIMER_PERIODIC)) 1444 { 1445 STAM_COUNTER_INC(&pThis->StatTimerSetLvtClearPeriodic); 1446 uint64_t cTicks = (pThis->next_time - pThis->initial_count_load_time) >> pThis->count_shift; 1447 if (cTicks >= pThis->initial_count) 1448 { 1449 /* not first period, stop it. */ 1450 TMTimerStop(pThis->CTX_SUFF(pTimer)); 1451 pThis->fTimerArmed = false; 1452 } 1453 /* else: first period, let it fire normally. */ 1454 } 1455 1456 /* 1457 * We postpone stopping the timer when it's masked, this way we can 1458 * avoid some timer work when the guest temporarily masks the timer. 1459 * (apicTimerCallback will stop it if still masked.) 1460 */ 1461 if (fNew & APIC_LVT_MASKED) 1462 STAM_COUNTER_INC(&pThis->StatTimerSetLvtPostponed); 1463 else if (pThis->fTimerArmed) 1464 STAM_COUNTER_INC(&pThis->StatTimerSetLvtArmed); 1465 /* 1466 * If unmasked and not armed, we have to rearm the timer so it will 1467 * fire at the end of the current period. 1468 * This is code is currently RACING the virtual sync clock! 1469 */ 1470 else if (fOld & APIC_LVT_MASKED) 1471 { 1472 STAM_COUNTER_INC(&pThis->StatTimerSetLvtArm); 1473 for (unsigned cTries = 0; ; cTries++) 1474 { 1475 uint64_t NextTS; 1476 uint64_t cTicks = (TMTimerGet(pThis->CTX_SUFF(pTimer)) - pThis->initial_count_load_time) >> pThis->count_shift; 1477 if (fNew & APIC_LVT_TIMER_PERIODIC) 1478 NextTS = ((cTicks / ((uint64_t)pThis->initial_count + 1)) + 1) * ((uint64_t)pThis->initial_count + 1); 1479 else 1480 { 1481 if (cTicks >= pThis->initial_count) 1482 break; 1483 NextTS = (uint64_t)pThis->initial_count + 1; 1484 } 1485 NextTS <<= pThis->count_shift; 1486 NextTS += pThis->initial_count_load_time; 1487 1488 /* Try avoid the assertion in TM.cpp... this isn't perfect! */ 1489 if ( NextTS > TMTimerGet(pThis->CTX_SUFF(pTimer)) 1490 || cTries > 10) 1491 { 1492 TMTimerSet(pThis->CTX_SUFF(pTimer), NextTS); 1493 pThis->next_time = NextTS; 1494 pThis->fTimerArmed = true; 1495 break; 1496 } 1497 STAM_COUNTER_INC(&pThis->StatTimerSetLvtArmRetries); 1498 } 1499 } 1500 } 1501 else 1502 STAM_COUNTER_INC(&pThis->StatTimerSetLvtNoRelevantChange); 1503 } 1504 1505 # ifdef IN_RING3 1506 /** 1507 * Timer callback function. 1508 * 1509 * @param pDevIns The device state. 1510 * @param pTimer The timer handle. 1511 * @param pvUser User argument pointing to the APIC instance. 1512 */ 1513 static DECLCALLBACK(void) apicTimerCallback(PPDMDEVINS pDevIns, PTMTIMER pTimer, void *pvUser) 1514 { 1515 APICDeviceInfo *dev = PDMINS_2_DATA(pDevIns, APICDeviceInfo *); 1516 APICState *pThis = (APICState *)pvUser; 1517 Assert(pThis->pTimerR3 == pTimer); 1518 Assert(pThis->fTimerArmed); 1519 1520 if (!(pThis->lvt[APIC_LVT_TIMER] & APIC_LVT_MASKED)) { 1521 LogFlow(("apic_timer: trigger irq\n")); 1522 apic_set_irq(dev, pThis, pThis->lvt[APIC_LVT_TIMER] & 0xff, APIC_TRIGGER_EDGE); 1523 1524 if (pThis->lvt[APIC_LVT_TIMER] & APIC_LVT_TIMER_PERIODIC) { 1525 /* new interval. */ 1526 pThis->next_time += (uint64_t)pThis->initial_count + 1; 1527 TMTimerSet(pThis->CTX_SUFF(pTimer), pThis->next_time); 1528 pThis->fTimerArmed = true; 1529 } else { 1530 /* single shot. */ 1531 pThis->fTimerArmed = false; 1532 } 1533 } else { 1534 /* masked, do not rearm. */ 1535 pThis->fTimerArmed = false; 1536 } 1537 } 1538 # endif /* IN_RING3 */ 1539 1540 #endif /* VBOX */ 1324 1541 1325 1542 #ifndef VBOX … … 1537 1754 case 0x32 ... 0x37: 1538 1755 #else /* VBOX */ 1539 case 0x32: case 0x33: case 0x34: case 0x35: case 0x36: case 0x37: 1756 case 0x32 + APIC_LVT_TIMER: 1757 AssertCompile(APIC_LVT_TIMER == 0); 1758 apicTimerSetLvt(dev, s, val); 1759 break; 1760 case 0x33: case 0x34: case 0x35: case 0x36: case 0x37: 1540 1761 #endif /* VBOX */ 1541 1762 { 1542 1763 int n = index - 0x32; 1543 1764 s->lvt[n] = val; 1765 #ifndef VBOX 1544 1766 if (n == APIC_LVT_TIMER) 1545 #ifndef VBOX1546 1767 apic_timer_update(s, qemu_get_clock(vm_clock)); 1768 #endif /* !VBOX*/ 1769 } 1770 break; 1771 case 0x38: 1772 #ifndef VBOX 1773 s->initial_count = val; 1774 s->initial_count_load_time = qemu_get_clock(vm_clock); 1775 apic_timer_update(dev, s, s->initial_count_load_time); 1547 1776 #else /* VBOX */ 1548 apic_timer_update(dev, s, TMTimerGet(s->CTX_SUFF(pTimer)));1777 apicTimerSetInitialCount(dev, s, val); 1549 1778 #endif /* VBOX*/ 1550 }1551 break;1552 case 0x38:1553 s->initial_count = val;1554 #ifndef VBOX1555 s->initial_count_load_time = qemu_get_clock(vm_clock);1556 #else /* VBOX */1557 s->initial_count_load_time = TMTimerGet(s->CTX_SUFF(pTimer));1558 #endif /* VBOX*/1559 apic_timer_update(dev, s, s->initial_count_load_time);1560 1779 break; 1561 1780 case 0x39: … … 1686 1905 1687 1906 #ifdef VBOX 1688 TMR3TimerLoad(s->CTX_SUFF(pTimer), f); 1689 #endif 1690 1691 return VINF_SUCCESS; 1907 int rc = TMR3TimerLoad(s->CTX_SUFF(pTimer), f); 1908 s->fTimerArmed = TMTimerIsActive(s->CTX_SUFF(pTimer)); 1909 #endif 1910 1911 return VINF_SUCCESS; /** @todo darn mess! */ 1692 1912 } 1693 1913 #ifndef VBOX … … 2153 2373 static DECLCALLBACK(void) apicReset(PPDMDEVINS pDevIns) 2154 2374 { 2375 APICDeviceInfo *dev = PDMINS_2_DATA(pDevIns, APICDeviceInfo *); 2155 2376 unsigned i; 2156 APICDeviceInfo* dev = PDMINS_2_DATA(pDevIns, APICDeviceInfo *);2157 APICState *apic;2158 2377 2159 2378 APIC_LOCK_VOID(dev, VERR_INTERNAL_ERROR); 2160 2379 2161 2380 /* Reset all APICs. */ 2162 for (i = 0 , apic = LAPIC_BASE(dev); i < dev->cCpus; i++)2163 {2164 TMTimerStop( apic->CTX_SUFF(pTimer));2381 for (i = 0; i < dev->cCpus; i++) { 2382 APICState *pApic = &dev->CTX_SUFF(paLapics)[i]; 2383 TMTimerStop(pApic->CTX_SUFF(pTimer)); 2165 2384 2166 2385 /* Do not send an init ipi to the VCPU; we take 2167 2386 * care of the proper init ourselves. 2168 apic_init_ipi(dev, apic);2387 apic_init_ipi(dev, pApic); 2169 2388 */ 2170 2389 2171 2390 /* malc, I've removed the initing duplicated in apic_init_ipi(). This 2172 2391 * arb_id was left over.. */ 2173 apic->arb_id = 0;2392 pApic->arb_id = 0; 2174 2393 /* Reset should re-enable the APIC. */ 2175 apic->apicbase = 0xfee00000 | MSR_IA32_APICBASE_ENABLE;2176 if ( apic->phys_id == 0)2177 apic->apicbase |= MSR_IA32_APICBASE_BSP;2394 pApic->apicbase = 0xfee00000 | MSR_IA32_APICBASE_ENABLE; 2395 if (pApic->phys_id == 0) 2396 pApic->apicbase |= MSR_IA32_APICBASE_BSP; 2178 2397 2179 2398 /* Clear any pending APIC interrupt action flag. */ 2180 cpuClearInterrupt(dev, apic); 2181 2182 apic++; 2399 cpuClearInterrupt(dev, pApic); 2183 2400 } 2184 2401 dev->pApicHlpR3->pfnChangeFeature(dev->pDevInsR3, dev->enmVersion); … … 2195 2412 pThis->pDevInsRC = PDMDEVINS_2_RCPTR(pDevIns); 2196 2413 pThis->pApicHlpRC = pThis->pApicHlpR3->pfnGetRCHelpers(pDevIns); 2197 pThis->p LapicsRC = MMHyperR3ToRC(PDMDevHlpGetVM(pDevIns), pThis->pLapicsR3);2414 pThis->paLapicsRC = MMHyperR3ToRC(PDMDevHlpGetVM(pDevIns), pThis->paLapicsR3); 2198 2415 pThis->pCritSectRC = pThis->pApicHlpR3->pfnGetRCCritSect(pDevIns); 2199 for each_apic(pThis, 0xffffffff,2200 apic->pTimerRC = TMTimerRCPtr(apic->CTX_SUFF(pTimer)));2416 for (uint32_t i = 0; i < pThis->cCpus; i++) 2417 pThis->paLapicsR3[i].pTimerRC = TMTimerRCPtr(pThis->paLapicsR3[i].pTimerR3); 2201 2418 } 2202 2419 … … 2228 2445 APICDeviceInfo *pThis = PDMINS_2_DATA(pDevIns, APICDeviceInfo *); 2229 2446 uint32_t cCpus; 2230 APICState *apic;2231 2447 2232 2448 /* … … 2286 2502 * We are not freeing this memory, as it's automatically released when guest exits. 2287 2503 */ 2288 rc = MMHyperAlloc(pVM, cCpus *sizeof(APICState), 1, MM_TAG_PDM_DEVICE_USER, (void **)&pThis->pLapicsR3);2504 rc = MMHyperAlloc(pVM, cCpus * sizeof(APICState), 1, MM_TAG_PDM_DEVICE_USER, (void **)&pThis->paLapicsR3); 2289 2505 if (RT_FAILURE(rc)) 2290 2506 return VERR_NO_MEMORY; 2291 pThis->pLapicsR0 = MMHyperR3ToR0(pVM, pThis->pLapicsR3); 2292 pThis->pLapicsRC = MMHyperR3ToRC(pVM, pThis->pLapicsR3); 2293 2294 for (i = 0, apic = LAPIC_BASE(pThis); i < cCpus; i++) 2295 { 2296 initApicData(apic, i); 2297 apic++; 2298 } 2507 pThis->paLapicsR0 = MMHyperR3ToR0(pVM, pThis->paLapicsR3); 2508 pThis->paLapicsRC = MMHyperR3ToRC(pVM, pThis->paLapicsR3); 2509 2510 for (i = 0; i < cCpus; i++) 2511 initApicData(&pThis->paLapicsR3[i], i); 2299 2512 2300 2513 /* … … 2356 2569 Assert(pDevIns->pDevHlpR3->pfnAPICRegister); 2357 2570 rc = pDevIns->pDevHlpR3->pfnAPICRegister(pDevIns, &ApicReg, &pThis->pApicHlpR3); 2358 if (RT_FAILURE(rc)) 2359 { 2360 AssertLogRelMsgFailed(("APICRegister -> %Rrc\n", rc)); 2361 return rc; 2362 } 2571 AssertLogRelRCReturn(rc, rc); 2363 2572 pThis->pCritSectR3 = pThis->pApicHlpR3->pfnGetR3CritSect(pDevIns); 2364 2573 … … 2368 2577 uint32_t u32Eax, u32Ebx, u32Ecx, u32Edx; 2369 2578 PDMDevHlpGetCpuId(pDevIns, 0, &u32Eax, &u32Ebx, &u32Ecx, &u32Edx); 2370 if (u32Eax >= 1) 2371 { 2579 if (u32Eax >= 1) { 2372 2580 if ( fIOAPIC /* If IOAPIC is enabled, enable Local APIC in any case */ 2373 2581 || ( u32Ebx == X86_CPUID_VENDOR_INTEL_EBX … … 2376 2584 || ( u32Ebx == X86_CPUID_VENDOR_AMD_EBX 2377 2585 && u32Ecx == X86_CPUID_VENDOR_AMD_ECX 2378 && u32Edx == X86_CPUID_VENDOR_AMD_EDX /* AuthenticAMD */)) 2379 { 2586 && u32Edx == X86_CPUID_VENDOR_AMD_EDX /* AuthenticAMD */)) { 2380 2587 LogRel(("Activating Local APIC\n")); 2381 2588 pThis->pApicHlpR3->pfnChangeFeature(pDevIns, pThis->enmVersion); … … 2386 2593 * Register the MMIO range. 2387 2594 */ 2388 rc = PDMDevHlpMMIORegister(pDevIns, LAPIC_BASE(pThis)->apicbase & ~0xfff, 0x1000, pThis, 2595 uint32_t ApicBase = pThis->paLapicsR3[0].apicbase & ~0xfff; 2596 rc = PDMDevHlpMMIORegister(pDevIns, ApicBase, 0x1000, pThis, 2389 2597 apicMMIOWrite, apicMMIORead, NULL, "APIC Memory"); 2390 2598 if (RT_FAILURE(rc)) … … 2395 2603 pThis->pCritSectRC = pThis->pApicHlpR3->pfnGetRCCritSect(pDevIns); 2396 2604 2397 rc = PDMDevHlpMMIORegisterGC(pDevIns, LAPIC_BASE(pThis)->apicbase & ~0xfff, 0x1000, 0,2605 rc = PDMDevHlpMMIORegisterGC(pDevIns, ApicBase, 0x1000, 0, 2398 2606 "apicMMIOWrite", "apicMMIORead", NULL); 2399 2607 if (RT_FAILURE(rc)) … … 2405 2613 pThis->pCritSectR0 = pThis->pApicHlpR3->pfnGetR0CritSect(pDevIns); 2406 2614 2407 rc = PDMDevHlpMMIORegisterR0(pDevIns, LAPIC_BASE(pThis)->apicbase & ~0xfff, 0x1000, 0,2615 rc = PDMDevHlpMMIORegisterR0(pDevIns, ApicBase, 0x1000, 0, 2408 2616 "apicMMIOWrite", "apicMMIORead", NULL); 2409 2617 if (RT_FAILURE(rc)) … … 2414 2622 * Create the APIC timers. 2415 2623 */ 2416 for (i = 0, apic = LAPIC_BASE(pThis); i < cCpus; i++) 2417 { 2418 rc = PDMDevHlpTMTimerCreate(pDevIns, TMCLOCK_VIRTUAL_SYNC, apicTimer, apic, 2419 TMTIMER_FLAGS_NO_CRIT_SECT, "APIC Timer", &apic->pTimerR3); 2624 for (i = 0; i < cCpus; i++) { 2625 APICState *pApic = &pThis->paLapicsR3[i]; 2626 pApic->pszDesc = MMR3HeapAPrintf(pVM, MM_TAG_PDM_DEVICE_USER, "APIC Timer #%u", i); 2627 rc = PDMDevHlpTMTimerCreate(pDevIns, TMCLOCK_VIRTUAL_SYNC, apicTimerCallback, pApic, 2628 TMTIMER_FLAGS_NO_CRIT_SECT, pApic->pszDesc, &pApic->pTimerR3); 2420 2629 if (RT_FAILURE(rc)) 2421 2630 return rc; 2422 apic->pTimerR0 = TMTimerR0Ptr(apic->pTimerR3); 2423 apic->pTimerRC = TMTimerRCPtr(apic->pTimerR3); 2424 TMR3TimerSetCritSect(apic->pTimerR3, pThis->pCritSectR3); 2425 apic++; 2631 pApic->pTimerR0 = TMTimerR0Ptr(pApic->pTimerR3); 2632 pApic->pTimerRC = TMTimerRCPtr(pApic->pTimerR3); 2633 TMR3TimerSetCritSect(pApic->pTimerR3, pThis->pCritSectR3); 2426 2634 } 2427 2635 … … 2443 2651 PDMDevHlpSTAMRegister(pDevIns, &pThis->StatMMIOWriteHC, STAMTYPE_COUNTER, "/Devices/APIC/MMIOWriteHC", STAMUNIT_OCCURENCES, "Number of APIC MMIO writes in HC."); 2444 2652 PDMDevHlpSTAMRegister(pDevIns, &pThis->StatClearedActiveIrq,STAMTYPE_COUNTER, "/Devices/APIC/MaskedActiveIRQ", STAMUNIT_OCCURENCES, "Number of cleared irqs."); 2653 for (i = 0; i < cCpus; i++) { 2654 APICState *pApic = &pThis->paLapicsR3[i]; 2655 PDMDevHlpSTAMRegisterF(pDevIns, &pApic->StatTimerSetInitialCount, STAMTYPE_COUNTER, STAMVISIBILITY_ALWAYS, STAMUNIT_OCCURENCES, "Calls to apicTimerSetInitialCount.", "/Devices/APIC/%u/TimerSetInitialCount", i); 2656 PDMDevHlpSTAMRegisterF(pDevIns, &pApic->StatTimerSetInitialCountArm, STAMTYPE_COUNTER, STAMVISIBILITY_ALWAYS, STAMUNIT_OCCURENCES, "TMTimerSetRelative calls.", "/Devices/APIC/%u/TimerSetInitialCount/Arm", i); 2657 PDMDevHlpSTAMRegisterF(pDevIns, &pApic->StatTimerSetInitialCountDisarm, STAMTYPE_COUNTER, STAMVISIBILITY_ALWAYS, STAMUNIT_OCCURENCES, "TMTimerStop calls.", "/Devices/APIC/%u/TimerSetInitialCount/Disasm", i); 2658 PDMDevHlpSTAMRegisterF(pDevIns, &pApic->StatTimerSetLvt, STAMTYPE_COUNTER, STAMVISIBILITY_ALWAYS, STAMUNIT_OCCURENCES, "Calls to apicTimerSetLvt.", "/Devices/APIC/%u/TimerSetLvt", i); 2659 PDMDevHlpSTAMRegisterF(pDevIns, &pApic->StatTimerSetLvtClearPeriodic, STAMTYPE_COUNTER, STAMVISIBILITY_ALWAYS, STAMUNIT_OCCURENCES, "Clearing APIC_LVT_TIMER_PERIODIC.", "/Devices/APIC/%u/TimerSetLvt/ClearPeriodic", i); 2660 PDMDevHlpSTAMRegisterF(pDevIns, &pApic->StatTimerSetLvtPostponed, STAMTYPE_COUNTER, STAMVISIBILITY_ALWAYS, STAMUNIT_OCCURENCES, "TMTimerStop postponed.", "/Devices/APIC/%u/TimerSetLvt/Postponed", i); 2661 PDMDevHlpSTAMRegisterF(pDevIns, &pApic->StatTimerSetLvtArmed, STAMTYPE_COUNTER, STAMVISIBILITY_ALWAYS, STAMUNIT_OCCURENCES, "TMTimerSet avoided.", "/Devices/APIC/%u/TimerSetLvt/Armed", i); 2662 PDMDevHlpSTAMRegisterF(pDevIns, &pApic->StatTimerSetLvtArm, STAMTYPE_COUNTER, STAMVISIBILITY_ALWAYS, STAMUNIT_OCCURENCES, "TMTimerSet necessary.", "/Devices/APIC/%u/TimerSetLvt/Arm", i); 2663 PDMDevHlpSTAMRegisterF(pDevIns, &pApic->StatTimerSetLvtArmRetries, STAMTYPE_COUNTER, STAMVISIBILITY_ALWAYS, STAMUNIT_OCCURENCES, "TMTimerSet retries.", "/Devices/APIC/%u/TimerSetLvt/ArmRetries", i); 2664 PDMDevHlpSTAMRegisterF(pDevIns, &pApic->StatTimerSetLvtNoRelevantChange,STAMTYPE_COUNTER, STAMVISIBILITY_ALWAYS, STAMUNIT_OCCURENCES, "No relevant flags changed.", "/Devices/APIC/%u/TimerSetLvt/NoRelevantChange", i); 2665 } 2445 2666 #endif 2446 2667 … … 2515 2736 2516 2737 STAM_COUNTER_INC(&CTXSUFF(s->StatMMIORead)); 2517 switch (cb) 2518 { 2519 case 1: 2520 *(uint8_t *)pv = ioapic_mem_readl(s, GCPhysAddr); 2521 break; 2522 2523 case 2: 2524 *(uint16_t *)pv = ioapic_mem_readl(s, GCPhysAddr); 2525 break; 2526 2527 case 4: 2528 *(uint32_t *)pv = ioapic_mem_readl(s, GCPhysAddr); 2529 break; 2530 2531 default: 2532 AssertReleaseMsgFailed(("cb=%d\n", cb)); /* for now we assume simple accesses. */ 2533 IOAPIC_UNLOCK(s); 2534 return VERR_INTERNAL_ERROR; 2738 switch (cb) { 2739 case 1: 2740 *(uint8_t *)pv = ioapic_mem_readl(s, GCPhysAddr); 2741 break; 2742 2743 case 2: 2744 *(uint16_t *)pv = ioapic_mem_readl(s, GCPhysAddr); 2745 break; 2746 2747 case 4: 2748 *(uint32_t *)pv = ioapic_mem_readl(s, GCPhysAddr); 2749 break; 2750 2751 default: 2752 AssertReleaseMsgFailed(("cb=%d\n", cb)); /* for now we assume simple accesses. */ 2753 IOAPIC_UNLOCK(s); 2754 return VERR_INTERNAL_ERROR; 2535 2755 } 2536 2756 IOAPIC_UNLOCK(s); … … 2543 2763 2544 2764 STAM_COUNTER_INC(&CTXSUFF(s->StatMMIOWrite)); 2545 switch (cb) 2546 { 2547 case 1: 2548 case 2: 2549 case 4: 2550 IOAPIC_LOCK(s, VINF_IOM_HC_MMIO_WRITE); 2551 ioapic_mem_writel(s, GCPhysAddr, *(uint32_t *)pv); 2552 IOAPIC_UNLOCK(s); 2553 break; 2554 2555 default: 2556 AssertReleaseMsgFailed(("cb=%d\n", cb)); /* for now we assume simple accesses. */ 2557 return VERR_INTERNAL_ERROR; 2765 switch (cb) { 2766 case 1: 2767 case 2: 2768 case 4: 2769 IOAPIC_LOCK(s, VINF_IOM_HC_MMIO_WRITE); 2770 ioapic_mem_writel(s, GCPhysAddr, *(uint32_t *)pv); 2771 IOAPIC_UNLOCK(s); 2772 break; 2773 2774 default: 2775 AssertReleaseMsgFailed(("cb=%d\n", cb)); /* for now we assume simple accesses. */ 2776 return VERR_INTERNAL_ERROR; 2558 2777 } 2559 2778 return VINF_SUCCESS; -
trunk/src/VBox/Devices/testcase/tstDeviceStructSizeGC.cpp
r20092 r20734 590 590 GEN_CHECK_OFF(APICState, pTimerR0); 591 591 GEN_CHECK_OFF(APICState, pTimerRC); 592 GEN_CHECK_OFF(APICState, fTimerArmed); 593 GEN_CHECK_OFF(APICState, pszDesc); 594 GEN_CHECK_OFF(APICState, StatTimerSetInitialCount); 595 GEN_CHECK_OFF(APICState, StatTimerSetLvtNoRelevantChange); 592 596 593 597 GEN_CHECK_SIZE(APICDeviceInfo); 594 598 GEN_CHECK_OFF(APICDeviceInfo, pDevInsR3); 595 599 GEN_CHECK_OFF(APICDeviceInfo, pApicHlpR3); 596 GEN_CHECK_OFF(APICDeviceInfo, p LapicsR3);600 GEN_CHECK_OFF(APICDeviceInfo, paLapicsR3); 597 601 GEN_CHECK_OFF(APICDeviceInfo, pCritSectR3); 598 602 GEN_CHECK_OFF(APICDeviceInfo, pDevInsR0); 599 603 GEN_CHECK_OFF(APICDeviceInfo, pApicHlpR0); 600 GEN_CHECK_OFF(APICDeviceInfo, p LapicsR0);604 GEN_CHECK_OFF(APICDeviceInfo, paLapicsR0); 601 605 GEN_CHECK_OFF(APICDeviceInfo, pCritSectR0); 602 606 GEN_CHECK_OFF(APICDeviceInfo, pDevInsRC); 603 607 GEN_CHECK_OFF(APICDeviceInfo, pApicHlpRC); 604 GEN_CHECK_OFF(APICDeviceInfo, p LapicsRC);608 GEN_CHECK_OFF(APICDeviceInfo, paLapicsRC); 605 609 GEN_CHECK_OFF(APICDeviceInfo, pCritSectRC); 606 610 GEN_CHECK_OFF(APICDeviceInfo, enmVersion);
Note:
See TracChangeset
for help on using the changeset viewer.