VirtualBox

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

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

grr

  • 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 54226 2015-02-16 22:52:18Z 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 */
54SUPDECL(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 uint16_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