Changeset 25459 in vbox for trunk/src/VBox/HostDrivers/Support
- Timestamp:
- Dec 17, 2009 12:49:43 PM (15 years ago)
- svn:sync-xref-src-repo-rev:
- 56123
- Location:
- trunk/src/VBox/HostDrivers/Support
- Files:
-
- 2 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/HostDrivers/Support/SUPDrv.c
r25434 r25459 2771 2771 2772 2772 /** 2773 * (Re-)initializes the per-cpu structure prior to starting or resuming the GIP 2774 * updating. 2775 * 2776 * @param pGipCpu The per CPU structure for this CPU. 2777 * @param u64NanoTS The current time. 2778 */ 2779 static void supdrvGipReInitCpu(PSUPGIPCPU pGipCpu, uint64_t u64NanoTS) 2780 { 2781 pGipCpu->u64TSC = ASMReadTSC() - pGipCpu->u32UpdateIntervalTSC; 2782 pGipCpu->u64NanoTS = u64NanoTS; 2783 } 2784 2785 2786 /** 2787 * Set the current TSC and NanoTS value for the CPU. 2788 * 2789 * @param idCpu The CPU ID. Unused - we have to use the APIC ID. 2790 * @param pvUser1 Pointer to the ring-0 GIP mapping. 2791 * @param pvUser2 Pointer to the variable holding the current time. 2792 */ 2793 static DECLCALLBACK(void) supdrvGipReInitCpuCallback(RTCPUID idCpu, void *pvUser1, void *pvUser2) 2794 { 2795 PSUPGLOBALINFOPAGE pGip = (PSUPGLOBALINFOPAGE)pvUser1; 2796 unsigned iCpu = ASMGetApicId(); 2797 2798 if (RT_LIKELY(iCpu < RT_ELEMENTS(pGip->aCPUs))) 2799 supdrvGipReInitCpu(&pGip->aCPUs[iCpu], *(uint64_t *)pvUser2); 2800 2801 NOREF(pvUser2); 2802 NOREF(idCpu); 2803 } 2804 2805 2806 /** 2773 2807 * Maps the GIP into userspace and/or get the physical address of the GIP. 2774 2808 * … … 2829 2863 { 2830 2864 PSUPGLOBALINFOPAGE pGipR0 = pDevExt->pGip; 2865 uint64_t u64NanoTS; 2831 2866 unsigned i; 2832 2867 2833 2868 LogFlow(("SUPR0GipMap: Resumes GIP updating\n")); 2834 2869 2835 for (i = 0; i < RT_ELEMENTS(pGipR0->aCPUs); i++) 2836 ASMAtomicXchgU32(&pGipR0->aCPUs[i].u32TransactionId, pGipR0->aCPUs[i].u32TransactionId & ~(GIP_UPDATEHZ_RECALC_FREQ * 2 - 1)); 2837 ASMAtomicXchgU64(&pGipR0->u64NanoTSLastUpdateHz, 0); 2870 if (pGipR0->aCPUs[0].u32TransactionId != 2 /* not the first time */) 2871 { 2872 for (i = 0; i < RT_ELEMENTS(pGipR0->aCPUs); i++) 2873 ASMAtomicUoWriteU32(&pGipR0->aCPUs[i].u32TransactionId, 2874 (pGipR0->aCPUs[i].u32TransactionId + GIP_UPDATEHZ_RECALC_FREQ * 2) 2875 & ~(GIP_UPDATEHZ_RECALC_FREQ * 2 - 1)); 2876 ASMAtomicWriteU64(&pGipR0->u64NanoTSLastUpdateHz, 0); 2877 } 2878 2879 u64NanoTS = RTTimeSystemNanoTS() - pGipR0->u32UpdateIntervalNS; 2880 if ( pGipR0->u32Mode == SUPGIPMODE_SYNC_TSC 2881 || RTMpGetOnlineCount() == 1) 2882 supdrvGipReInitCpu(&pGipR0->aCPUs[0], u64NanoTS); 2883 else 2884 RTMpOnAll(supdrvGipReInitCpuCallback, pGipR0, &u64NanoTS); 2838 2885 2839 2886 rc = RTTimerStart(pDevExt->pGipTimer, 0); … … 4463 4510 uint64_t NanoTS = RTTimeSystemNanoTS(); 4464 4511 4465 supdrvGipUpdate(pDevExt->pGip, NanoTS, u64TSC );4512 supdrvGipUpdate(pDevExt->pGip, NanoTS, u64TSC, iTick); 4466 4513 4467 4514 ASMSetFlags(fOldFlags); … … 4484 4531 /** @todo reset the transaction number and whatnot when iTick == 1. */ 4485 4532 if (pDevExt->idGipMaster == idCpu) 4486 supdrvGipUpdate(pDevExt->pGip, NanoTS, u64TSC );4533 supdrvGipUpdate(pDevExt->pGip, NanoTS, u64TSC, iTick); 4487 4534 else 4488 supdrvGipUpdatePerCpu(pDevExt->pGip, NanoTS, u64TSC, ASMGetApicId() );4535 supdrvGipUpdatePerCpu(pDevExt->pGip, NanoTS, u64TSC, ASMGetApicId(), iTick); 4489 4536 4490 4537 ASMSetFlags(fOldFlags); … … 4577 4624 /* 4578 4625 * We don't know the following values until we've executed updates. 4579 * So, we'll just insert very high values. 4626 * So, we'll just pretend it's a 4 GHz CPU and adjust the history it on 4627 * the 2nd timer callout. 4580 4628 */ 4581 pGip->aCPUs[i].u64CpuHz = _4G + 1; 4582 pGip->aCPUs[i].u32UpdateIntervalTSC = _2G / 4; 4583 pGip->aCPUs[i].au32TSCHistory[0] = _2G / 4; 4584 pGip->aCPUs[i].au32TSCHistory[1] = _2G / 4; 4585 pGip->aCPUs[i].au32TSCHistory[2] = _2G / 4; 4586 pGip->aCPUs[i].au32TSCHistory[3] = _2G / 4; 4587 pGip->aCPUs[i].au32TSCHistory[4] = _2G / 4; 4588 pGip->aCPUs[i].au32TSCHistory[5] = _2G / 4; 4589 pGip->aCPUs[i].au32TSCHistory[6] = _2G / 4; 4590 pGip->aCPUs[i].au32TSCHistory[7] = _2G / 4; 4629 pGip->aCPUs[i].u64CpuHz = _4G + 1; /* tstGIP-2 depends on this. */ 4630 pGip->aCPUs[i].u32UpdateIntervalTSC 4631 = pGip->aCPUs[i].au32TSCHistory[0] 4632 = pGip->aCPUs[i].au32TSCHistory[1] 4633 = pGip->aCPUs[i].au32TSCHistory[2] 4634 = pGip->aCPUs[i].au32TSCHistory[3] 4635 = pGip->aCPUs[i].au32TSCHistory[4] 4636 = pGip->aCPUs[i].au32TSCHistory[5] 4637 = pGip->aCPUs[i].au32TSCHistory[6] 4638 = pGip->aCPUs[i].au32TSCHistory[7] 4639 = /*pGip->aCPUs[i].u64CpuHz*/ _4G / uUpdateHz; 4591 4640 } 4592 4641 … … 4725 4774 * @param u64NanoTS The current time stamp. 4726 4775 * @param u64TSC The current TSC. 4727 */ 4728 static void supdrvGipDoUpdateCpu(PSUPGLOBALINFOPAGE pGip, PSUPGIPCPU pGipCpu, uint64_t u64NanoTS, uint64_t u64TSC) 4776 * @param iTick The current timer tick. 4777 */ 4778 static void supdrvGipDoUpdateCpu(PSUPGLOBALINFOPAGE pGip, PSUPGIPCPU pGipCpu, uint64_t u64NanoTS, uint64_t u64TSC, uint64_t iTick) 4729 4779 { 4730 4780 uint64_t u64TSCDelta; … … 4733 4783 unsigned iTSCHistoryHead; 4734 4784 uint64_t u64CpuHz; 4785 uint32_t u32TransactionId; 4735 4786 4736 4787 /* Delta between this and the previous update. */ 4737 pGipCpu->u32UpdateIntervalNS = (uint32_t)(u64NanoTS - pGipCpu->u64NanoTS);4788 ASMAtomicUoWriteU32(&pGipCpu->u32PrevUpdateIntervalNS, (uint32_t)(u64NanoTS - pGipCpu->u64NanoTS)); 4738 4789 4739 4790 /* … … 4756 4807 4757 4808 /* 4809 * On the 2nd and 3rd callout, reset the history with the current TSC 4810 * interval since the values entered by supdrvGipInit are totally off. 4811 * The interval on the 1st callout completely unreliable, the 2nd is a bit 4812 * better, while the 3rd should be most reliable. 4813 */ 4814 u32TransactionId = pGipCpu->u32TransactionId; 4815 if (RT_UNLIKELY( ( u32TransactionId == 5 4816 || u32TransactionId == 7) 4817 && ( iTick == 2 4818 || iTick == 3) )) 4819 { 4820 unsigned i; 4821 for (i = 0; i < RT_ELEMENTS(pGipCpu->au32TSCHistory); i++) 4822 ASMAtomicUoWriteU32(&pGipCpu->au32TSCHistory[i], (uint32_t)u64TSCDelta); 4823 } 4824 4825 /* 4758 4826 * TSC History. 4759 4827 */ 4760 4828 Assert(RT_ELEMENTS(pGipCpu->au32TSCHistory) == 8); 4761 4762 4829 iTSCHistoryHead = (pGipCpu->iTSCHistoryHead + 1) & 7; 4763 4830 ASMAtomicXchgU32(&pGipCpu->iTSCHistoryHead, iTSCHistoryHead); … … 4815 4882 * Updates the GIP. 4816 4883 * 4817 * @param pGip Pointer to the GIP. 4818 * @param u64NanoTS The current nanosecond timesamp. 4819 * @param u64TSC The current TSC timesamp. 4820 */ 4821 void VBOXCALL supdrvGipUpdate(PSUPGLOBALINFOPAGE pGip, uint64_t u64NanoTS, uint64_t u64TSC) 4884 * @param pGip Pointer to the GIP. 4885 * @param u64NanoTS The current nanosecond timesamp. 4886 * @param u64TSC The current TSC timesamp. 4887 * @param iTick The current timer tick. 4888 */ 4889 void VBOXCALL supdrvGipUpdate(PSUPGLOBALINFOPAGE pGip, uint64_t u64NanoTS, uint64_t u64TSC, uint64_t iTick) 4822 4890 { 4823 4891 /* … … 4830 4898 { 4831 4899 unsigned iCpu = ASMGetApicId(); 4832 if (RT_ LIKELY(iCpu >= RT_ELEMENTS(pGip->aCPUs)))4900 if (RT_UNLIKELY(iCpu >= RT_ELEMENTS(pGip->aCPUs))) 4833 4901 return; 4834 4902 pGipCpu = &pGip->aCPUs[iCpu]; … … 4870 4938 * Update the data. 4871 4939 */ 4872 supdrvGipDoUpdateCpu(pGip, pGipCpu, u64NanoTS, u64TSC );4940 supdrvGipDoUpdateCpu(pGip, pGipCpu, u64NanoTS, u64TSC, iTick); 4873 4941 4874 4942 /* … … 4882 4950 * Updates the per cpu GIP data for the calling cpu. 4883 4951 * 4884 * @param pGip Pointer to the GIP. 4885 * @param u64NanoTS The current nanosecond timesamp. 4886 * @param u64TSC The current TSC timesamp. 4887 * @param iCpu The CPU index. 4888 */ 4889 void VBOXCALL supdrvGipUpdatePerCpu(PSUPGLOBALINFOPAGE pGip, uint64_t u64NanoTS, uint64_t u64TSC, unsigned iCpu) 4952 * @param pGip Pointer to the GIP. 4953 * @param u64NanoTS The current nanosecond timesamp. 4954 * @param u64TSC The current TSC timesamp. 4955 * @param iCpu The CPU index. 4956 * @param iTick The current timer tick. 4957 */ 4958 void VBOXCALL supdrvGipUpdatePerCpu(PSUPGLOBALINFOPAGE pGip, uint64_t u64NanoTS, uint64_t u64TSC, unsigned iCpu, uint64_t iTick) 4890 4959 { 4891 4960 PSUPGIPCPU pGipCpu; … … 4909 4978 * Update the data. 4910 4979 */ 4911 supdrvGipDoUpdateCpu(pGip, pGipCpu, u64NanoTS, u64TSC );4980 supdrvGipDoUpdateCpu(pGip, pGipCpu, u64NanoTS, u64TSC, iTick); 4912 4981 4913 4982 /* -
trunk/src/VBox/HostDrivers/Support/SUPDrvInternal.h
r25336 r25459 716 716 int VBOXCALL supdrvGipInit(PSUPDRVDEVEXT pDevExt, PSUPGLOBALINFOPAGE pGip, RTHCPHYS HCPhys, uint64_t u64NanoTS, unsigned uUpdateHz); 717 717 void VBOXCALL supdrvGipTerm(PSUPGLOBALINFOPAGE pGip); 718 void VBOXCALL supdrvGipUpdate(PSUPGLOBALINFOPAGE pGip, uint64_t u64NanoTS, uint64_t u64TSC );719 void VBOXCALL supdrvGipUpdatePerCpu(PSUPGLOBALINFOPAGE pGip, uint64_t u64NanoTS, uint64_t u64TSC, unsigned iCpu );718 void VBOXCALL supdrvGipUpdate(PSUPGLOBALINFOPAGE pGip, uint64_t u64NanoTS, uint64_t u64TSC, uint64_t iTick); 719 void VBOXCALL supdrvGipUpdatePerCpu(PSUPGLOBALINFOPAGE pGip, uint64_t u64NanoTS, uint64_t u64TSC, unsigned iCpu, uint64_t iTick); 720 720 bool VBOXCALL supdrvDetermineAsyncTsc(uint64_t *pu64DiffCores); 721 721
Note:
See TracChangeset
for help on using the changeset viewer.