Lines Matching defs:pApic

5  * @remarks This code does not use pThis, it uses pDev and pApic due to the
268 * @remarks This is generally pointed to by a parameter or variable named pApic.
409 static void apic_update_tpr(APICDeviceInfo *pDev, APICState *pApic, uint32_t val);
411 static void apic_eoi(APICDeviceInfo *pDev, APICState *pApic); /* */
413 static int apic_deliver(APICDeviceInfo *pDev, APICState *pApic,
417 static int apic_get_arb_pri(APICState const *pApic);
418 static int apic_get_ppr(APICState const *pApic);
419 static uint32_t apic_get_current_count(APICDeviceInfo const *pDev, APICState const *pApic);
420 static void apicTimerSetInitialCount(APICDeviceInfo *pDev, APICState *pApic, uint32_t initial_count);
421 static void apicTimerSetLvt(APICDeviceInfo *pDev, APICState *pApic, uint32_t fNew);
422 static void apicSendInitIpi(APICDeviceInfo *pDev, APICState *pApic);
424 static void apicR3InitIpi(APICDeviceInfo *pDev, APICState *pApic);
425 static void apic_set_irq(APICDeviceInfo *pDev, APICState *pApic, int vector_num, int trigger_mode, uint32_t uTagSrc);
426 static bool apic_update_irq(APICDeviceInfo *pDev, APICState *pApic);
445 DECLINLINE(VMCPUID) getCpuFromLapic(APICDeviceInfo *pDev, APICState *pApic)
448 return (VMCPUID)pApic->phys_id;
451 DECLINLINE(void) apicCpuSetInterrupt(APICDeviceInfo *pDev, APICState *pApic, PDMAPICIRQ enmType = PDMAPICIRQ_HARDWARE)
453 LogFlow(("apic: setting interrupt flag for cpu %d\n", getCpuFromLapic(pDev, pApic)));
455 getCpuFromLapic(pDev, pApic));
458 DECLINLINE(void) apicCpuClearInterrupt(APICDeviceInfo *pDev, APICState *pApic, PDMAPICIRQ enmType = PDMAPICIRQ_HARDWARE)
462 getCpuFromLapic(pDev, pApic));
467 DECLINLINE(void) apicR3CpuSendSipi(APICDeviceInfo *pDev, APICState *pApic, int vector)
472 getCpuFromLapic(pDev, pApic),
476 DECLINLINE(void) apicR3CpuSendInitIpi(APICDeviceInfo *pDev, APICState *pApic)
481 getCpuFromLapic(pDev, pApic));
534 APICState *pApic = apicGetStateById(pDev, idDstCpu);
535 apic_set_irq(pDev, pApic, vector_num, trigger_mode, uTagSrc);
587 APICState *pApic = apicGetStateById(pDev, idCpu);
594 PDMAPICVERSION oldMode = getApicMode(pApic);
595 pApic->apicbase = (val & 0xfffff000) /* base */
597 | (pApic->apicbase & MSR_IA32_APICBASE_BSP) /* keep BSP bit */;
598 PDMAPICVERSION newMode = getApicMode(pApic);
606 pApic->spurious_vec &= ~APIC_SV_ENABLE;
608 apicCpuClearInterrupt(pDev, pApic);
636 APICState *pApic = apicGetStateById(pDev, idCpu);
637 LogFlow(("apicGetBase: %016llx\n", (uint64_t)pApic->apicbase));
638 return pApic->apicbase;
645 APICState *pApic = apicGetStateById(pDev, idCpu);
646 LogFlow(("apicSetTPR: val=%#x (trp %#x -> %#x)\n", val, pApic->tpr, val));
647 apic_update_tpr(pDev, pApic, val);
654 APICState *pApic = apicGetStateById(pDev, idCpu);
655 Log2(("apicGetTPR: returns %#x\n", pApic->tpr));
656 return pApic->tpr;
663 APICState *pApic = apicGetStateById(pDev, 0);
664 uint64_t uTimer = TMTimerGetFreq(pApic->CTX_SUFF(pTimer));
675 * @param pApic The APIC being written to.
682 static int apicWriteRegisterInvalid(APICDeviceInfo *pDev, APICState *pApic, uint32_t iReg, uint64_t u64Value,
685 Log(("apicWriteRegisterInvalid/%u: iReg=%#x fMsr=%RTbool u64Value=%#llx\n", pApic->phys_id, iReg, fMsr, u64Value));
687 "iReg=%#x fMsr=%RTbool u64Value=%#llx id=%u\n", iReg, fMsr, u64Value, pApic->phys_id);
689 pApic->esr |= ESR_ILLEGAL_ADDRESS;
701 * @param pApic The APIC being written to.
708 static int apicWriteRegister(APICDeviceInfo *pDev, APICState *pApic, uint32_t iReg, uint64_t u64Value,
718 pApic->id = (u64Value >> 24); /** @todo r=bird: Is the range supposed to be 40 bits??? */
728 apic_update_tpr(pDev, pApic, u64Value);
738 apic_eoi(pDev, pApic);
744 pApic->log_dest = (u64Value >> 24) & 0xff;
750 pApic->dest_mode = u64Value >> 28; /** @todo r=bird: range? This used to be 32-bit before morphed into an MSR handler. */
756 pApic->spurious_vec = u64Value & 0x1ff;
757 apic_update_irq(pDev, pApic);
770 pApic->icr[0] = (uint32_t)u64Value;
772 pApic->icr[1] = (uint32_t)(u64Value >> 32);
773 rc = apic_deliver(pDev, pApic, (pApic->icr[1] >> 24) & 0xff, (pApic->icr[0] >> 11) & 1,
774 (pApic->icr[0] >> 8) & 7, (pApic->icr[0] & 0xff),
775 (pApic->icr[0] >> 14) & 1, (pApic->icr[0] >> 15) & 1);
783 pApic->icr[1] = (uint64_t)u64Value;
787 rc = apicWriteRegisterInvalid(pDev, pApic, iReg, u64Value, rcBusy, fMsr);
792 APIC_AND_TM_LOCK(pDev, pApic, rcBusy);
793 apicTimerSetLvt(pDev, pApic, u64Value);
794 APIC_AND_TM_UNLOCK(pDev, pApic);
799 pApic->lvt[iReg - 0x32] = u64Value;
804 APIC_AND_TM_LOCK(pDev, pApic, rcBusy);
805 apicTimerSetInitialCount(pDev, pApic, u64Value);
806 APIC_AND_TM_UNLOCK(pDev, pApic);
816 pApic->divide_conf = u64Value & 0xb;
817 int v = (pApic->divide_conf & 3) | ((pApic->divide_conf >> 1) & 4);
818 pApic->count_shift = (v + 1) & 7;
831 VMCPUSET_ADD(&SelfSet, pApic->id);
845 rc = apicWriteRegisterInvalid(pDev, pApic, iReg, u64Value, rcBusy, fMsr);
858 * @param pApic The APIC being read to.
865 static int apicReadRegisterInvalid(APICDeviceInfo *pDev, APICState *pApic, uint32_t iReg, uint64_t *pu64Value,
868 Log(("apicReadRegisterInvalid/%u: iReg=%#x fMsr=%RTbool\n", pApic->phys_id, iReg, fMsr));
870 "iReg=%#x fMsr=%RTbool id=%u\n", iReg, fMsr, pApic->phys_id);
872 pApic->esr |= ESR_ILLEGAL_ADDRESS;
884 * @param pApic The APIC being read to.
891 static int apicReadRegister(APICDeviceInfo *pDev, APICState *pApic, uint32_t iReg, uint64_t *pu64Value,
901 *pu64Value = pApic->id << 24;
918 *pu64Value = pApic->tpr;
923 *pu64Value = apic_get_arb_pri(pApic);
929 *pu64Value = apic_get_ppr(pApic);
940 *pu64Value = (uint64_t)pApic->log_dest << 24;
947 *pu64Value = ((uint64_t)pApic->dest_mode << 28) | UINT32_C(0xfffffff);
953 *pu64Value = pApic->spurious_vec;
959 *pu64Value = pApic->isr.au32Bitmap[iReg & 7];
965 *pu64Value = pApic->tmr.au32Bitmap[iReg & 7];
971 *pu64Value = pApic->irr.au32Bitmap[iReg & 7];
977 *pu64Value = pApic->esr;
985 *pu64Value = RT_MAKE_U64(pApic->icr[0], pApic->icr[1]);
987 *pu64Value = pApic->icr[0];
993 rc = apicReadRegisterInvalid(pDev, pApic, iReg, pu64Value, rcBusy, fMsr);
997 *pu64Value = pApic->icr[1];
1004 *pu64Value = pApic->lvt[iReg - 0x32];
1010 *pu64Value = pApic->initial_count;
1015 APIC_AND_TM_LOCK(pDev, pApic, rcBusy);
1016 *pu64Value = apic_get_current_count(pDev, pApic);
1017 APIC_AND_TM_UNLOCK(pDev, pApic);
1022 *pu64Value = pApic->divide_conf;
1034 rc = apicReadRegisterInvalid(pDev, pApic, iReg, pu64Value, rcBusy, fMsr);
1042 rc = apicReadRegisterInvalid(pDev, pApic, iReg, pu64Value, rcBusy, fMsr);
1057 APICState *pApic = apicGetStateById(pDev, idCpu);
1059 return apicWriteRegister(pDev, pApic, iReg, u64Value, VINF_SUCCESS /*rcBusy*/, true /*fMsr*/);
1073 APICState *pApic = apicGetStateById(pDev, idCpu);
1075 return apicReadRegister(pDev, pApic, iReg, pu64Value, VINF_SUCCESS /*rcBusy*/, true /*fMsr*/);
1102 APICState *pApic = apicGetStateById(pDev, 0);
1108 if (!(pApic->spurious_vec & APIC_SV_ENABLE))
1112 apicCpuSetInterrupt(pDev, pApic, PDMAPICIRQ_EXTINT);
1114 apicCpuClearInterrupt(pDev, pApic, PDMAPICIRQ_EXTINT);
1130 u32Lvec = pApic->lvt[APIC_LVT_LINT0 + u8Pin]; /* Fetch corresponding LVT entry. */
1145 apicCpuSetInterrupt(pDev, pApic, enmType);
1147 apicCpuClearInterrupt(pDev, pApic, enmType);
1178 apicCpuSetInterrupt(pDev, pApic, enmType);
1183 static int apic_get_ppr(APICState const *pApic)
1187 int tpr = (pApic->tpr >> 4);
1188 int isrv = Apic256BitReg_FindLastSetBit(&pApic->isr, 0);
1191 ppr = pApic->tpr;
1197 static int apic_get_ppr_zero_tpr(APICState *pApic)
1199 return Apic256BitReg_FindLastSetBit(&pApic->isr, 0);
1202 static int apic_get_arb_pri(APICState const *pApic)
1209 static bool apic_update_irq(APICDeviceInfo *pDev, APICState *pApic)
1211 if (!(pApic->spurious_vec & APIC_SV_ENABLE))
1214 apicCpuClearInterrupt(pDev, pApic);
1218 int irrv = Apic256BitReg_FindLastSetBit(&pApic->irr, -1);
1221 int ppr = apic_get_ppr(pApic);
1224 apicCpuSetInterrupt(pDev, pApic);
1237 APICState *pApic = apicGetStateById(pDev, idCpu);
1244 int irrv = Apic256BitReg_FindLastSetBit(&pApic->irr, -1);
1248 int ppr = apic_get_ppr_zero_tpr(pApic);
1261 static void apic_update_tpr(APICDeviceInfo *pDev, APICState *pApic, uint32_t val)
1266 fIrqWasActive = apic_update_irq(pDev, pApic);
1267 pApic->tpr = val;
1268 fIrqIsActive = apic_update_irq(pDev, pApic);
1275 apicCpuClearInterrupt(pDev, pApic);
1279 static void apic_set_irq(APICDeviceInfo *pDev, APICState *pApic, int vector_num, int trigger_mode, uint32_t uTagSrc)
1281 LogFlow(("CPU%d: apic_set_irq vector=%x trigger_mode=%x uTagSrc=%#x\n", pApic->phys_id, vector_num, trigger_mode, uTagSrc));
1283 Apic256BitReg_SetBit(&pApic->irr, vector_num);
1285 Apic256BitReg_SetBit(&pApic->tmr, vector_num);
1287 Apic256BitReg_ClearBit(&pApic->tmr, vector_num);
1289 if (!pApic->auTags[vector_num])
1290 pApic->auTags[vector_num] = uTagSrc;
1292 pApic->auTags[vector_num] |= RT_BIT_32(31);
1294 apic_update_irq(pDev, pApic);
1297 static void apic_eoi(APICDeviceInfo *pDev, APICState *pApic)
1299 int isrv = Apic256BitReg_FindLastSetBit(&pApic->isr, -1);
1302 Apic256BitReg_ClearBit(&pApic->isr, isrv);
1303 LogFlow(("CPU%d: apic_eoi isrv=%x\n", pApic->phys_id, isrv));
1306 apic_update_irq(pDev, pApic);
1343 static void apicR3InitIpi(APICDeviceInfo *pDev, APICState *pApic)
1348 pApic->lvt[i] = 1 << 16; /* mask LVT */
1349 pApic->tpr = 0;
1350 pApic->spurious_vec = 0xff;
1351 pApic->log_dest = 0;
1352 pApic->dest_mode = 0xff; /** @todo 0xff???? */
1353 Apic256BitReg_Empty(&pApic->isr);
1354 Apic256BitReg_Empty(&pApic->tmr);
1355 Apic256BitReg_Empty(&pApic->irr);
1356 pApic->esr = 0;
1357 memset(pApic->icr, 0, sizeof(pApic->icr));
1358 pApic->divide_conf = 0;
1359 pApic->count_shift = 1;
1360 pApic->initial_count = 0;
1361 pApic->initial_count_load_time = 0;
1362 pApic->next_time = 0;
1366 static void apicSendInitIpi(APICDeviceInfo *pDev, APICState *pApic)
1368 apicR3InitIpi(pDev, pApic);
1369 apicR3CpuSendInitIpi(pDev, pApic);
1373 static void apicR3Startup(APICDeviceInfo *pDev, APICState *pApic, int vector_num)
1375 Log(("[SMP] apicR3Startup: %d on CPUs %d\n", vector_num, pApic->phys_id));
1376 apicR3CpuSendSipi(pDev, pApic, vector_num);
1381 static int apic_deliver(APICDeviceInfo *pDev, APICState *pApic,
1386 int dest_shorthand = (pApic->icr[0] >> 18) & 3;
1397 VMCPUSET_ADD(&DstSet, pApic->id);
1404 VMCPUSET_DEL(&DstSet, pApic->id);
1412 uint32_t const trig_mode = (pApic->icr[0] >> 15) & 1;
1413 uint32_t const level = (pApic->icr[0] >> 14) & 1;
1419 Log(("CPU%d: APIC_DM_INIT arbitration id(s) set\n", pApic->phys_id));
1456 APICState *pApic = apicGetStateById(pDev, idCpu);
1458 if (!(pApic->spurious_vec & APIC_SV_ENABLE))
1460 Log(("CPU%d: apic_get_interrupt: returns -1 (APIC_SV_ENABLE)\n", pApic->phys_id));
1465 int intno = Apic256BitReg_FindLastSetBit(&pApic->irr, -1);
1468 Log(("CPU%d: apic_get_interrupt: returns -1 (irr)\n", pApic->phys_id));
1472 if (pApic->tpr && (uint32_t)intno <= pApic->tpr)
1475 Log(("apic_get_interrupt: returns %d (sp)\n", pApic->spurious_vec & 0xff));
1476 return pApic->spurious_vec & 0xff;
1479 Apic256BitReg_ClearBit(&pApic->irr, intno);
1480 Apic256BitReg_SetBit(&pApic->isr, intno);
1482 *puTagSrc = pApic->auTags[intno];
1483 pApic->auTags[intno] = 0;
1485 apic_update_irq(pDev, pApic);
1487 LogFlow(("CPU%d: apic_get_interrupt: returns %d / %#x\n", pApic->phys_id, intno, *puTagSrc));
1495 static uint32_t apic_get_current_count(APICDeviceInfo const *pDev, APICState const *pApic)
1497 int64_t d = (TMTimerGet(pApic->CTX_SUFF(pTimer)) - pApic->initial_count_load_time)
1498 >> pApic->count_shift;
1501 if (pApic->lvt[APIC_LVT_TIMER] & APIC_LVT_TIMER_PERIODIC)
1503 val = pApic->initial_count - (d % ((uint64_t)pApic->initial_count + 1));
1504 else if (d >= pApic->initial_count)
1507 val = pApic->initial_count - d;
1515 * @param pApic The device state.
1517 DECLINLINE(void) apicDoFrequencyHinting(APICState *pApic)
1519 if ( pApic->uHintedInitialCount != pApic->initial_count
1520 || pApic->uHintedCountShift != (uint32_t)pApic->count_shift)
1522 pApic->uHintedInitialCount = pApic->initial_count;
1523 pApic->uHintedCountShift = pApic->count_shift;
1526 if (pApic->initial_count > 0)
1528 Assert((unsigned)pApic->count_shift < 30);
1529 uint64_t cTickPerPeriod = ((uint64_t)pApic->initial_count + 1) << pApic->count_shift;
1530 uHz = TMTimerGetFreq(pApic->CTX_SUFF(pTimer)) / cTickPerPeriod;
1534 TMTimerSetFrequencyHint(pApic->CTX_SUFF(pTimer), uHz);
1543 * @param pApic The APIC sub-device state.
1546 static void apicTimerSetInitialCount(APICDeviceInfo *pDev, APICState *pApic, uint32_t u32NewInitialCount)
1548 STAM_COUNTER_INC(&pApic->StatTimerSetInitialCount);
1549 pApic->initial_count = u32NewInitialCount;
1555 if ( !(pApic->lvt[APIC_LVT_TIMER] & APIC_LVT_MASKED)
1564 cTicksNext <<= pApic->count_shift;
1565 TMTimerSetRelative(pApic->CTX_SUFF(pTimer), cTicksNext, &pApic->initial_count_load_time);
1566 pApic->next_time = pApic->initial_count_load_time + cTicksNext;
1567 pApic->fTimerArmed = true;
1568 apicDoFrequencyHinting(pApic);
1569 STAM_COUNTER_INC(&pApic->StatTimerSetInitialCountArm);
1571 cTicksNext, cTicksNext, u32NewInitialCount, pApic->count_shift, pApic->next_time));
1576 if (pApic->fTimerArmed)
1578 STAM_COUNTER_INC(&pApic->StatTimerSetInitialCountDisarm);
1579 TMTimerStop(pApic->CTX_SUFF(pTimer));
1580 pApic->fTimerArmed = false;
1581 pApic->uHintedCountShift = pApic->uHintedInitialCount = 0;
1583 pApic->initial_count_load_time = TMTimerGet(pApic->CTX_SUFF(pTimer));
1584 Log(("apicTimerSetInitialCount: ic=%#x sh=%#x iclt=%#llx\n", u32NewInitialCount, pApic->count_shift, pApic->initial_count_load_time));
1592 * @param pApic The APIC sub-device state to operate on.
1595 static void apicTimerSetLvt(APICDeviceInfo *pDev, APICState *pApic, uint32_t fNew)
1597 STAM_COUNTER_INC(&pApic->StatTimerSetLvt);
1603 uint32_t const fOld = pApic->lvt[APIC_LVT_TIMER];
1604 pApic->lvt[APIC_LVT_TIMER] = fNew;
1620 STAM_COUNTER_INC(&pApic->StatTimerSetLvtClearPeriodic);
1621 uint64_t cTicks = (pApic->next_time - pApic->initial_count_load_time) >> pApic->count_shift;
1622 if (cTicks >= pApic->initial_count)
1625 TMTimerStop(pApic->CTX_SUFF(pTimer));
1626 pApic->fTimerArmed = false;
1627 pApic->uHintedCountShift = pApic->uHintedInitialCount = 0;
1638 STAM_COUNTER_INC(&pApic->StatTimerSetLvtPostponed);
1639 else if (pApic->fTimerArmed)
1640 STAM_COUNTER_INC(&pApic->StatTimerSetLvtArmed);
1649 && pApic->initial_count > 0)
1651 STAM_COUNTER_INC(&pApic->StatTimerSetLvtArm);
1655 uint64_t cTicks = (TMTimerGet(pApic->CTX_SUFF(pTimer)) - pApic->initial_count_load_time) >> pApic->count_shift;
1657 NextTS = ((cTicks / ((uint64_t)pApic->initial_count + 1)) + 1) * ((uint64_t)pApic->initial_count + 1);
1660 if (cTicks >= pApic->initial_count)
1662 NextTS = (uint64_t)pApic->initial_count + 1;
1664 NextTS <<= pApic->count_shift;
1665 NextTS += pApic->initial_count_load_time;
1668 if ( NextTS > TMTimerGet(pApic->CTX_SUFF(pTimer))
1671 TMTimerSet(pApic->CTX_SUFF(pTimer), NextTS);
1672 pApic->next_time = NextTS;
1673 pApic->fTimerArmed = true;
1674 apicDoFrequencyHinting(pApic);
1675 Log(("apicTimerSetLvt: ic=%#x sh=%#x nxt=%#llx\n", pApic->initial_count, pApic->count_shift, pApic->next_time));
1678 STAM_COUNTER_INC(&pApic->StatTimerSetLvtArmRetries);
1683 STAM_COUNTER_INC(&pApic->StatTimerSetLvtNoRelevantChange);
1698 APICState *pApic = (APICState *)pvUser;
1699 Assert(pApic->pTimerR3 == pTimer);
1700 Assert(pApic->fTimerArmed);
1704 if (!(pApic->lvt[APIC_LVT_TIMER] & APIC_LVT_MASKED)) {
1706 apic_set_irq(pDev, pApic, pApic->lvt[APIC_LVT_TIMER] & 0xff, APIC_TRIGGER_EDGE,
1709 if ( (pApic->lvt[APIC_LVT_TIMER] & APIC_LVT_TIMER_PERIODIC)
1710 && pApic->initial_count > 0) {
1712 pApic->next_time += (((uint64_t)pApic->initial_count + 1) << pApic->count_shift);
1713 TMTimerSet(pApic->CTX_SUFF(pTimer), pApic->next_time);
1714 pApic->fTimerArmed = true;
1715 apicDoFrequencyHinting(pApic);
1716 Log2(("apicR3TimerCallback: ic=%#x sh=%#x nxt=%#llx\n", pApic->initial_count, pApic->count_shift, pApic->next_time));
1719 pApic->fTimerArmed = false;
1720 pApic->uHintedCountShift = pApic->uHintedInitialCount = 0;
1724 pApic->fTimerArmed = false;
1725 pApic->uHintedCountShift = pApic->uHintedInitialCount = 0;
1731 APICState *pApic = (APICState*)opaque;
1734 SSMR3PutU32(f, pApic->apicbase);
1735 SSMR3PutU32(f, pApic->id);
1736 SSMR3PutU32(f, pApic->phys_id);
1737 SSMR3PutU32(f, pApic->arb_id);
1738 SSMR3PutU32(f, pApic->tpr);
1739 SSMR3PutU32(f, pApic->spurious_vec);
1740 SSMR3PutU8(f, pApic->log_dest);
1741 SSMR3PutU8(f, pApic->dest_mode);
1743 SSMR3PutU32(f, pApic->isr.au32Bitmap[i]);
1744 SSMR3PutU32(f, pApic->tmr.au32Bitmap[i]);
1745 SSMR3PutU32(f, pApic->irr.au32Bitmap[i]);
1748 SSMR3PutU32(f, pApic->lvt[i]);
1750 SSMR3PutU32(f, pApic->esr);
1751 SSMR3PutU32(f, pApic->icr[0]);
1752 SSMR3PutU32(f, pApic->icr[1]);
1753 SSMR3PutU32(f, pApic->divide_conf);
1754 SSMR3PutU32(f, pApic->count_shift);
1755 SSMR3PutU32(f, pApic->initial_count);
1756 SSMR3PutU64(f, pApic->initial_count_load_time);
1757 SSMR3PutU64(f, pApic->next_time);
1759 TMR3TimerSave(pApic->CTX_SUFF(pTimer), f);
1764 APICState *pApic = (APICState*)opaque;
1768 SSMR3GetU32(f, &pApic->apicbase);
1776 pApic->id = val;
1778 pApic->phys_id = 0;
1780 pApic->arb_id = val;
1785 SSMR3GetU32(f, &pApic->id);
1786 SSMR3GetU32(f, &pApic->phys_id);
1787 SSMR3GetU32(f, &pApic->arb_id);
1792 SSMR3GetU32(f, &pApic->tpr);
1793 SSMR3GetU32(f, &pApic->spurious_vec);
1794 SSMR3GetU8(f, &pApic->log_dest);
1795 SSMR3GetU8(f, &pApic->dest_mode);
1797 SSMR3GetU32(f, &pApic->isr.au32Bitmap[i]);
1798 SSMR3GetU32(f, &pApic->tmr.au32Bitmap[i]);
1799 SSMR3GetU32(f, &pApic->irr.au32Bitmap[i]);
1802 SSMR3GetU32(f, &pApic->lvt[i]);
1804 SSMR3GetU32(f, &pApic->esr);
1805 SSMR3GetU32(f, &pApic->icr[0]);
1806 SSMR3GetU32(f, &pApic->icr[1]);
1807 SSMR3GetU32(f, &pApic->divide_conf);
1808 SSMR3GetU32(f, (uint32_t *)&pApic->count_shift);
1809 SSMR3GetU32(f, (uint32_t *)&pApic->initial_count);
1810 SSMR3GetU64(f, (uint64_t *)&pApic->initial_count_load_time);
1811 SSMR3GetU64(f, (uint64_t *)&pApic->next_time);
1813 int rc = TMR3TimerLoad(pApic->CTX_SUFF(pTimer), f);
1815 pApic->uHintedCountShift = pApic->uHintedInitialCount = 0;
1816 pApic->fTimerArmed = TMTimerIsActive(pApic->CTX_SUFF(pTimer));
1817 if (pApic->fTimerArmed)
1818 apicDoFrequencyHinting(pApic);
1829 APICState *pApic = apicGetStateByCurEmt(pDev);
1831 Log(("CPU%d: apicMMIORead at %RGp\n", pApic->phys_id, GCPhysAddr));
1843 && ++pApic->cTPRPatchAttempts < APIC_MAX_PATCH_ATTEMPTS)
1846 pDevIns->pDevHlpGC->pfnPATMSetMMIOPatchInfo(pDevIns, GCPhysAddr, &pApic->tpr);
1858 int rc = apicReadRegister(pDev, pApic, (GCPhysAddr >> 4) & 0xff, &u64Value, VINF_IOM_R3_MMIO_READ, false /*fMsr*/);
1866 APICState *pApic = apicGetStateByCurEmt(pDev);
1868 Log(("CPU%d: apicMMIOWrite at %RGp\n", pApic->phys_id, GCPhysAddr));
1876 return apicWriteRegister(pDev, pApic, (GCPhysAddr >> 4) & 0xff, *(uint32_t const *)pv,
1887 * @param pApic The Local APIC in question.
1890 static uint64_t apicR3InfoReadReg(APICDeviceInfo *pDev, APICState *pApic, uint32_t iReg)
1893 int rc = apicReadRegister(pDev, pApic, iReg, &u64Value, VINF_SUCCESS, true /*fMsr*/);
1902 * @param pApic The Local APIC in question.
1906 static void apicR3DumpVec(APICDeviceInfo *pDev, APICState *pApic, PCDBGFINFOHLP pHlp, uint32_t iStartReg)
1909 pHlp->pfnPrintf(pHlp, "%08x", apicR3InfoReadReg(pDev, pApic, iStartReg + i));
1917 * @param pApic The Local APIC in question.
1921 static void apicR3DumpPending(APICDeviceInfo *pDev, APICState *pApic, PCDBGFINFOHLP pHlp, PCAPIC256BITREG pReg)
1945 * @param pApic The Local APIC in question.
1948 static void apicR3InfoBasic(APICDeviceInfo *pDev, APICState *pApic, PCDBGFINFOHLP pHlp)
1952 pHlp->pfnPrintf(pHlp, "Local APIC at %08llx:\n", pApic->apicbase);
1953 u64 = apicR3InfoReadReg(pDev, pApic, 0x2);
1956 u64 = apicR3InfoReadReg(pDev, pApic, 0x3);
1960 u64 = apicR3InfoReadReg(pDev, pApic, 0x8);
1963 u64 = apicR3InfoReadReg(pDev, pApic, 0xA);
1966 u64 = apicR3InfoReadReg(pDev, pApic, 0xD);
1969 pHlp->pfnPrintf(pHlp, " DFR : %08llx\n", apicR3InfoReadReg(pDev, pApic, 0xE));
1970 u64 = apicR3InfoReadReg(pDev, pApic, 0xF);
1976 apicR3DumpVec(pDev, pApic, pHlp, 0x10);
1977 apicR3DumpPending(pDev, pApic, pHlp, &pApic->isr);
1979 apicR3DumpVec(pDev, pApic, pHlp, 0x20);
1980 apicR3DumpPending(pDev, pApic, pHlp, &pApic->irr);
1988 * @param pApic The Local APIC in question.
1991 static void apicR3InfoLVT(APICDeviceInfo *pDev, APICState *pApic, PCDBGFINFOHLP pHlp)
1999 u64 = apicR3InfoReadReg(pDev, pApic, 0x32);
2005 u64 = apicR3InfoReadReg(pDev, pApic, 0x35);
2014 u64 = apicR3InfoReadReg(pDev, pApic, 0x36);
2030 * @param pApic The Local APIC in question.
2033 static void apicR3InfoTimer(APICDeviceInfo *pDev, APICState *pApic, PCDBGFINFOHLP pHlp)
2036 pHlp->pfnPrintf(pHlp, " Initial count : %08llx\n", apicR3InfoReadReg(pDev, pApic, 0x38));
2037 pHlp->pfnPrintf(pHlp, " Current count : %08llx\n", apicR3InfoReadReg(pDev, pApic, 0x39));
2038 uint64_t u64 = apicR3InfoReadReg(pDev, pApic, 0x3e);
2052 APICState *pApic = apicGetStateByCurEmt(pDev);
2055 apicR3InfoBasic(pDev, pApic, pHlp);
2057 apicR3InfoLVT(pDev, pApic, pHlp);
2059 apicR3InfoTimer(pDev, pApic, pHlp);
2159 APICState *pApic = &pDev->CTX_SUFF(paLapics)[i];
2160 TMTimerStop(pApic->CTX_SUFF(pTimer));
2163 apicR3InitIpi(pDev, pApic);
2166 pApic->arb_id = pApic->id = i;
2167 Assert(pApic->id == pApic->phys_id); /* The two should match again. */
2170 pApic->apicbase = VBOX_MSI_ADDR_BASE | MSR_IA32_APICBASE_ENABLE;
2171 if (pApic->phys_id == 0)
2172 pApic->apicbase |= MSR_IA32_APICBASE_BSP;
2175 apicCpuClearInterrupt(pDev, pApic);
2204 * @param pApic The Local APIC state to init.
2207 static void apicR3StateInit(APICState *pApic, uint8_t id)
2209 memset(pApic, 0, sizeof(*pApic));
2212 pApic->apicbase = VBOX_MSI_ADDR_BASE | MSR_IA32_APICBASE_ENABLE;
2214 pApic->apicbase |= MSR_IA32_APICBASE_BSP;
2217 pApic->lvt[i] = RT_BIT_32(16); /* mask LVT */
2219 pApic->spurious_vec = 0xff;
2220 pApic->phys_id = id;
2221 pApic->id = id;
2406 APICState *pApic = &pDev->paLapicsR3[i];
2407 pApic->pszDesc = MMR3HeapAPrintf(pVM, MM_TAG_PDM_DEVICE_USER, "APIC Timer #%u", i);
2408 rc = PDMDevHlpTMTimerCreate(pDevIns, TMCLOCK_VIRTUAL_SYNC, apicR3TimerCallback, pApic,
2409 TMTIMER_FLAGS_NO_CRIT_SECT, pApic->pszDesc, &pApic->pTimerR3);
2412 pApic->pTimerR0 = TMTimerR0Ptr(pApic->pTimerR3);
2413 pApic->pTimerRC = TMTimerRCPtr(pApic->pTimerR3);
2414 TMR3TimerSetCritSect(pApic->pTimerR3, pDev->pCritSectR3);
2442 APICState *pApic = &pDev->paLapicsR3[i];
2443 PDMDevHlpSTAMRegisterF(pDevIns, &pApic->StatTimerSetInitialCount, STAMTYPE_COUNTER, STAMVISIBILITY_ALWAYS, STAMUNIT_OCCURENCES, "Calls to apicTimerSetInitialCount.", "/Devices/APIC/%u/TimerSetInitialCount", i);
2444 PDMDevHlpSTAMRegisterF(pDevIns, &pApic->StatTimerSetInitialCountArm, STAMTYPE_COUNTER, STAMVISIBILITY_ALWAYS, STAMUNIT_OCCURENCES, "TMTimerSetRelative calls.", "/Devices/APIC/%u/TimerSetInitialCount/Arm", i);
2445 PDMDevHlpSTAMRegisterF(pDevIns, &pApic->StatTimerSetInitialCountDisarm, STAMTYPE_COUNTER, STAMVISIBILITY_ALWAYS, STAMUNIT_OCCURENCES, "TMTimerStop calls.", "/Devices/APIC/%u/TimerSetInitialCount/Disasm", i);
2446 PDMDevHlpSTAMRegisterF(pDevIns, &pApic->StatTimerSetLvt, STAMTYPE_COUNTER, STAMVISIBILITY_ALWAYS, STAMUNIT_OCCURENCES, "Calls to apicTimerSetLvt.", "/Devices/APIC/%u/TimerSetLvt", i);
2447 PDMDevHlpSTAMRegisterF(pDevIns, &pApic->StatTimerSetLvtClearPeriodic, STAMTYPE_COUNTER, STAMVISIBILITY_ALWAYS, STAMUNIT_OCCURENCES, "Clearing APIC_LVT_TIMER_PERIODIC.", "/Devices/APIC/%u/TimerSetLvt/ClearPeriodic", i);
2448 PDMDevHlpSTAMRegisterF(pDevIns, &pApic->StatTimerSetLvtPostponed, STAMTYPE_COUNTER, STAMVISIBILITY_ALWAYS, STAMUNIT_OCCURENCES, "TMTimerStop postponed.", "/Devices/APIC/%u/TimerSetLvt/Postponed", i);
2449 PDMDevHlpSTAMRegisterF(pDevIns, &pApic->StatTimerSetLvtArmed, STAMTYPE_COUNTER, STAMVISIBILITY_ALWAYS, STAMUNIT_OCCURENCES, "TMTimerSet avoided.", "/Devices/APIC/%u/TimerSetLvt/Armed", i);
2450 PDMDevHlpSTAMRegisterF(pDevIns, &pApic->StatTimerSetLvtArm, STAMTYPE_COUNTER, STAMVISIBILITY_ALWAYS, STAMUNIT_OCCURENCES, "TMTimerSet necessary.", "/Devices/APIC/%u/TimerSetLvt/Arm", i);
2451 PDMDevHlpSTAMRegisterF(pDevIns, &pApic->StatTimerSetLvtArmRetries, STAMTYPE_COUNTER, STAMVISIBILITY_ALWAYS, STAMUNIT_OCCURENCES, "TMTimerSet retries.", "/Devices/APIC/%u/TimerSetLvt/ArmRetries", i);
2452 PDMDevHlpSTAMRegisterF(pDevIns, &pApic->StatTimerSetLvtNoRelevantChange,STAMTYPE_COUNTER, STAMVISIBILITY_ALWAYS, STAMUNIT_OCCURENCES, "No relevant flags changed.", "/Devices/APIC/%u/TimerSetLvt/NoRelevantChange", i);