VirtualBox

source: vbox/trunk/src/VBox/HostDrivers/Support/SUPLibAll.cpp@ 54224

Last change on this file since 54224 was 54224, checked in by vboxsync, 10 years ago

SUP,IPRT: Started as a build fix ended up as a cleanup (mostly untested as I'm windows). We'll keep SUP_IOCTL_TSC_READ for the purpose of dealing with the i64TSCDelta == INT64_MAX in SUPReadTsc/SUPReadTscWithDelta. Moved the excessive inline code from sup.h to SUPLibAll.cpp (new file) and SUPDrv.c (apply delta). Don't bother too much about trying to share code between SUPLibAll.cpp and SUPDrv.c/++ as the SUPReadTsc[WithDelta] scenario does not care about knowing when things goes bad, it just needs a TSC that is as good as we can get. The SUPDrv.c code on the other hand probably needs other kind of status codes, assertions and whatnot to be better off with its own version of the code. Remove the now unused assembly macro for applying the delta - the way the delta is applied will not change, period, so better just document it instead.

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 4.3 KB
Line 
1/* $Id: SUPLibAll.cpp 54224 2015-02-16 22:41:32Z vboxsync $ */
2/** @file
3 * VirtualBox Support Library - All Contexts Code.
4 */
5
6/*
7 * Copyright (C) 2006-2014 Oracle Corporation
8 *
9 * This file is part of VirtualBox Open Source Edition (OSE), as
10 * available from http://www.virtualbox.org. This file is free software;
11 * you can redistribute it and/or modify it under the terms of the GNU
12 * General Public License (GPL) as published by the Free Software
13 * Foundation, in version 2 as it comes in the "COPYING" file of the
14 * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
15 * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
16 *
17 * The contents of this file may alternatively be used under the terms
18 * of the Common Development and Distribution License Version 1.0
19 * (CDDL) only, as it comes in the "COPYING.CDDL" file of the
20 * VirtualBox OSE distribution, in which case the provisions of the
21 * CDDL are applicable instead of those of the GPL.
22 *
23 * You may elect to license modified versions of this file under the
24 * terms and conditions of either the GPL or the CDDL or both.
25 */
26
27/*******************************************************************************
28* Header Files *
29*******************************************************************************/
30#include <VBox/sup.h>
31#ifdef IN_RING0
32# include <iprt/mp.h>
33#endif
34#if defined(RT_ARCH_AMD64) || defined(RT_ARCH_X86)
35# include <iprt/asm-amd64-x86.h>
36#endif
37
38
39#if defined(RT_ARCH_AMD64) || defined(RT_ARCH_X86)
40
41/**
42 * The slow case for SUPReadTsc where we need to apply deltas.
43 *
44 * Must only be called when deltas are applicable, so please do not call it
45 * directly.
46 *
47 * @returns TSC with delta applied.
48 *
49 * @remarks May be called with interrupts disabled in ring-0! This is why the
50 * ring-0 code doesn't attempt to figure the delta.
51 *
52 * @internal
53 */
54DECLINLINE(uint64_t) SUPReadTscWithDelta(void)
55{
56 PSUPGLOBALINFOPAGE pGip = g_pSUPGlobalInfoPage;
57 Assert(GIP_ARE_TSC_DELTAS_APPLICABLE(pGip));
58
59 /** @todo Check out the rdtscp optimization, ASMGetApicId is very expensive. */
60
61# ifdef IN_RING3
62 /*
63 * Read the TSC and delta.
64 */
65 uint32_t cTries = 0;
66 for (;;)
67 {
68 uint8_t idApic = ASMGetApicId();
69 uint64_t uTsc = ASMReadTSC();
70 int64_t iTscDelta = pGip->aCPUs[pGip->aiCpuFromApicId[idApic]].i64TSCDelta;
71 if (RT_LIKELY( idApic == ASMGetApicId()
72 || cTries >= 10))
73 {
74 /*
75 * If the delta is valid, apply it.
76 */
77 if (RT_LIKELY(iTscDelta != INT64_MAX))
78 return uTsc - iTscDelta;
79
80 /*
81 * The delta needs calculating, call supdrv to get the TSC.
82 */
83 int rc = SUPR3ReadTsc(&uTsc, NULL);
84 if (RT_SUCCESS(rc))
85 return uTsc;
86 AssertMsgFailed(("SUPR3ReadTsc -> %Rrc\n", rc));
87
88 /* That didn't work, just return something half useful... */
89 return ASMReadTSC();
90 }
91 cTries++;
92 }
93# else
94 /*
95 * Read the TSC and delta.
96 */
97 RTCCUINTREG uFlags = ASMIntDisableFlags();
98# ifdef IN_RING0
99 int iCpuSet = RTMpCpuIdToSetIndex(RTMpCpuId());
100 uint16_t iGipCpu = (unsigned)iCpuSet < RT_ELEMENTS(pGip->aiCpuFromCpuSetIdx)
101 ? pGip->aiCpuFromCpuSetIdx[iCpuSet] : UINT16_MAX;
102# else
103 uint8_t idApic = ASMGetApicId(); /** @todo this could probably be eliminated in RC if we really wanted to... */
104 uint16_t iGipCpu = (unsigned)idApic < RT_ELEMENTS(pGip->aiCpuFromApicId) /* for the future */
105 ? pGip->aiCpuFromApicId[idApic] : UINT16_MAX;
106# endif
107 int64_t iTscDelta = (unsigned)iGipCpu < pGip->cCpus ? pGip->aCPUs[iGipCpu].i64TSCDelta : INT64_MAX;
108 uint64_t uTsc = ASMReadTSC();
109 ASMSetFlags(uFlags);
110
111 /*
112 * If the delta is valid, apply it, otherwise ignore it (really shouldn't
113 * happen in these contexts!).
114 */
115 if (RT_LIKELY(iTscDelta != INT64_MAX))
116 return uTsc - iTscDelta;
117# ifdef IN_RING0
118 AssertMsgFailed(("iCpuSet=%d (%#x) iGipCpu=%#x\n", iCpuSet, iCpuSet, iGipCpu));
119# else
120 AssertMsgFailed(("idApic=%#x iGipCpu=%#x\n", idApic, iGipCpu));
121# endif
122 return uTsc;
123# endif
124}
125
126#endif /* RT_ARCH_AMD64 || RT_ARCH_X86 */
127
Note: See TracBrowser for help on using the repository browser.

© 2024 Oracle Support Privacy / Do Not Sell My Info Terms of Use Trademark Policy Automated Access Etiquette