timesupA.mac revision c0e374304cebe77219b2abc0b6796e72e452c4dd
b8e299dddd091ae24e0c08c45d91b8f937bd14d2vboxsync; IPRT - Time using SUPLib, the Assembly Code Template.
b8e299dddd091ae24e0c08c45d91b8f937bd14d2vboxsync; Copyright (C) 2006-2014 Oracle Corporation
b8e299dddd091ae24e0c08c45d91b8f937bd14d2vboxsync; This file is part of VirtualBox Open Source Edition (OSE), as
b8e299dddd091ae24e0c08c45d91b8f937bd14d2vboxsync; available from http://www.virtualbox.org. This file is free software;
b8e299dddd091ae24e0c08c45d91b8f937bd14d2vboxsync; you can redistribute it and/or modify it under the terms of the GNU
b8e299dddd091ae24e0c08c45d91b8f937bd14d2vboxsync; General Public License (GPL) as published by the Free Software
b8e299dddd091ae24e0c08c45d91b8f937bd14d2vboxsync; Foundation, in version 2 as it comes in the "COPYING" file of the
b8e299dddd091ae24e0c08c45d91b8f937bd14d2vboxsync; VirtualBox OSE distribution. VirtualBox OSE is distributed in the
b8e299dddd091ae24e0c08c45d91b8f937bd14d2vboxsync; hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
b8e299dddd091ae24e0c08c45d91b8f937bd14d2vboxsync; The contents of this file may alternatively be used under the terms
b8e299dddd091ae24e0c08c45d91b8f937bd14d2vboxsync; of the Common Development and Distribution License Version 1.0
b8e299dddd091ae24e0c08c45d91b8f937bd14d2vboxsync; (CDDL) only, as it comes in the "COPYING.CDDL" file of the
b8e299dddd091ae24e0c08c45d91b8f937bd14d2vboxsync; VirtualBox OSE distribution, in which case the provisions of the
b8e299dddd091ae24e0c08c45d91b8f937bd14d2vboxsync; CDDL are applicable instead of those of the GPL.
b8e299dddd091ae24e0c08c45d91b8f937bd14d2vboxsync; You may elect to license modified versions of this file under the
b8e299dddd091ae24e0c08c45d91b8f937bd14d2vboxsync; terms and conditions of either the GPL or the CDDL or both.
b8e299dddd091ae24e0c08c45d91b8f937bd14d2vboxsync%ifdef RT_ARCH_X86
b8e299dddd091ae24e0c08c45d91b8f937bd14d2vboxsync; The x86 assembly implementation of the assembly routines.
b8e299dddd091ae24e0c08c45d91b8f937bd14d2vboxsync; @returns Nanosecond timestamp.
b8e299dddd091ae24e0c08c45d91b8f937bd14d2vboxsync; @param pData Pointer to the nanosecond timestamp data.
b8e299dddd091ae24e0c08c45d91b8f937bd14d2vboxsyncBEGINPROC rtTimeNanoTSInternalAsm
b8e299dddd091ae24e0c08c45d91b8f937bd14d2vboxsync ; Variable definitions.
b8e299dddd091ae24e0c08c45d91b8f937bd14d2vboxsync%define pData [ebp + 08h]
b8e299dddd091ae24e0c08c45d91b8f937bd14d2vboxsync%define u64RetNanoTS_Hi [ebp - 04h]
b8e299dddd091ae24e0c08c45d91b8f937bd14d2vboxsync%define u64RetNanoTS [ebp - 08h]
b8e299dddd091ae24e0c08c45d91b8f937bd14d2vboxsync%define u32UpdateIntervalNS [ebp - 0ch]
b8e299dddd091ae24e0c08c45d91b8f937bd14d2vboxsync%define u32UpdateIntervalTSC [ebp - 10h]
b8e299dddd091ae24e0c08c45d91b8f937bd14d2vboxsync%define u64TSC_Hi [ebp - 14h]
b8e299dddd091ae24e0c08c45d91b8f937bd14d2vboxsync%define u64TSC [ebp - 18h]
b8e299dddd091ae24e0c08c45d91b8f937bd14d2vboxsync%define u64CurNanoTS_Hi [ebp - 1ch]
b8e299dddd091ae24e0c08c45d91b8f937bd14d2vboxsync%define u64CurNanoTS [ebp - 20h]
b8e299dddd091ae24e0c08c45d91b8f937bd14d2vboxsync%define u64PrevNanoTS_Hi [ebp - 24h]
b8e299dddd091ae24e0c08c45d91b8f937bd14d2vboxsync%define u64PrevNanoTS [ebp - 28h]
b8e299dddd091ae24e0c08c45d91b8f937bd14d2vboxsync%define u32TransactionId [ebp - 2ch]
b8e299dddd091ae24e0c08c45d91b8f937bd14d2vboxsync%define u32ApicIdPlus [ebp - 30h]
b8e299dddd091ae24e0c08c45d91b8f937bd14d2vboxsync%define TmpVar [ebp - 34h]
b8e299dddd091ae24e0c08c45d91b8f937bd14d2vboxsync%define SavedEBX [ebp - 38h]
b8e299dddd091ae24e0c08c45d91b8f937bd14d2vboxsync%define SavedEDI [ebp - 3ch]
b8e299dddd091ae24e0c08c45d91b8f937bd14d2vboxsync%define SavedESI [ebp - 40h]
b8e299dddd091ae24e0c08c45d91b8f937bd14d2vboxsync mov ebp, esp
b8e299dddd091ae24e0c08c45d91b8f937bd14d2vboxsync sub esp, 40h
b8e299dddd091ae24e0c08c45d91b8f937bd14d2vboxsync mov SavedEBX, ebx
b8e299dddd091ae24e0c08c45d91b8f937bd14d2vboxsync mov SavedEDI, edi
b8e299dddd091ae24e0c08c45d91b8f937bd14d2vboxsync mov SavedESI, esi
b8e299dddd091ae24e0c08c45d91b8f937bd14d2vboxsync ;; Read the GIP data and the previous value.
b8e299dddd091ae24e0c08c45d91b8f937bd14d2vboxsync ; Load pGip and calc pGipCPU, setting u32ApicIdPlus if necessary.
b8e299dddd091ae24e0c08c45d91b8f937bd14d2vboxsync%ifdef IMPORTED_SUPLIB
b8e299dddd091ae24e0c08c45d91b8f937bd14d2vboxsync %ifdef IN_RING0
b8e299dddd091ae24e0c08c45d91b8f937bd14d2vboxsync mov esi, IMP(g_SUPGlobalInfoPage)
b8e299dddd091ae24e0c08c45d91b8f937bd14d2vboxsync mov esi, IMP(g_pSUPGlobalInfoPage)
b8e299dddd091ae24e0c08c45d91b8f937bd14d2vboxsync mov esi, [esi]
b8e299dddd091ae24e0c08c45d91b8f937bd14d2vboxsync mov esi, [NAME(g_pSUPGlobalInfoPage)]
b8e299dddd091ae24e0c08c45d91b8f937bd14d2vboxsync or esi, esi
b8e299dddd091ae24e0c08c45d91b8f937bd14d2vboxsync jz .Rediscover
b8e299dddd091ae24e0c08c45d91b8f937bd14d2vboxsync cmp dword [esi + SUPGLOBALINFOPAGE.u32Magic], SUPGLOBALINFOPAGE_MAGIC
b8e299dddd091ae24e0c08c45d91b8f937bd14d2vboxsync jne .Rediscover
b8e299dddd091ae24e0c08c45d91b8f937bd14d2vboxsync%ifdef ASYNC_GIP
b8e299dddd091ae24e0c08c45d91b8f937bd14d2vboxsync ; u8ApicId = ASMGetApicId();
b8e299dddd091ae24e0c08c45d91b8f937bd14d2vboxsync cpuid ; expensive
b8e299dddd091ae24e0c08c45d91b8f937bd14d2vboxsync %ifdef NEED_TRANSACTION_ID
b8e299dddd091ae24e0c08c45d91b8f937bd14d2vboxsync mov u32ApicIdPlus, ebx
b8e299dddd091ae24e0c08c45d91b8f937bd14d2vboxsync ; pGipCpu = &pGip->aCPU[pGip->aiCpuFromApicId[u8ApicId]];
b8e299dddd091ae24e0c08c45d91b8f937bd14d2vboxsync shr ebx, 24
b8e299dddd091ae24e0c08c45d91b8f937bd14d2vboxsync movzx ebx, word [esi + ebx * 2 + SUPGLOBALINFOPAGE.aiCpuFromApicId]
b8e299dddd091ae24e0c08c45d91b8f937bd14d2vboxsync mov eax, SUPGIPCPU_size
b8e299dddd091ae24e0c08c45d91b8f937bd14d2vboxsync lea edi, [esi + eax + SUPGLOBALINFOPAGE.aCPUs] ; edi == &pGip->aCPU[u8ApicId];
b8e299dddd091ae24e0c08c45d91b8f937bd14d2vboxsync lea edi, [esi + SUPGLOBALINFOPAGE.aCPUs] ; edi == &pGip->aCPU[0];
b8e299dddd091ae24e0c08c45d91b8f937bd14d2vboxsync%ifdef NEED_TRANSACTION_ID
b8e299dddd091ae24e0c08c45d91b8f937bd14d2vboxsync ; Serialized loading of u32TransactionId.
b8e299dddd091ae24e0c08c45d91b8f937bd14d2vboxsync mov u32TransactionId, ebx
b8e299dddd091ae24e0c08c45d91b8f937bd14d2vboxsync %ifdef USE_LFENCE
b8e299dddd091ae24e0c08c45d91b8f937bd14d2vboxsync lock xor dword TmpVar, 0
b8e299dddd091ae24e0c08c45d91b8f937bd14d2vboxsync ; Load the data and TSC.
b8e299dddd091ae24e0c08c45d91b8f937bd14d2vboxsync mov eax, [esi + SUPGLOBALINFOPAGE.u32UpdateIntervalNS]
b8e299dddd091ae24e0c08c45d91b8f937bd14d2vboxsync mov u32UpdateIntervalNS, eax ; esi is now free
b8e299dddd091ae24e0c08c45d91b8f937bd14d2vboxsync mov u32UpdateIntervalTSC, edx
b8e299dddd091ae24e0c08c45d91b8f937bd14d2vboxsync SupTscDeltaApply edi ; Apply inter-cpu TSC-delta to have the normalized TSC value in edx:eax
b8e299dddd091ae24e0c08c45d91b8f937bd14d2vboxsync mov ecx, [edi + SUPGIPCPU.u64NanoTS]
b8e299dddd091ae24e0c08c45d91b8f937bd14d2vboxsync mov u64CurNanoTS, ecx
b8e299dddd091ae24e0c08c45d91b8f937bd14d2vboxsync mov esi, [edi + SUPGIPCPU.u64NanoTS + 4]
b8e299dddd091ae24e0c08c45d91b8f937bd14d2vboxsync mov u64CurNanoTS_Hi, esi
mov ebx, [edi + SUPGIPCPU.u64TSC]
mov ecx, [edi + SUPGIPCPU.u64TSC + 4]
; This serializes load/save. And with the dependency on the
mov esi, [esi + RTTIMENANOTSDATA.pu64Prev]
mov esi, [edi + SUPGIPCPU.u32TransactionId]
mov esi, [esi + RTTIMENANOTSDATA.pu64Prev]
inc dword [esi + RTTIMENANOTSDATA.cExpired]
inc dword [esi + RTTIMENANOTSDATA.c1nsSteps]
call dword [eax + RTTIMENANOTSDATA.pfnBad]
lock inc dword [edi + RTTIMENANOTSDATA.cUpdateRaces]
call [eax + RTTIMENANOTSDATA.pfnRediscover]
mov pGip, [rel NAME(g_pSUPGlobalInfoPage) wrt ..gotpcrel]
cmp dword [pGip + SUPGLOBALINFOPAGE.u32Magic], SUPGLOBALINFOPAGE_MAGIC
movzx eax, word [pGip + rbx * 2 + SUPGLOBALINFOPAGE.aiCpuFromApicId]
lea pGipCPU, [pGip + rax + SUPGLOBALINFOPAGE.aCPUs]
lea pGipCPU, [pGip + SUPGLOBALINFOPAGE.aCPUs]
mov u32TransactionId, [pGipCPU + SUPGIPCPU.u32TransactionId]
mov u32UpdateIntervalNS, [pGip + SUPGLOBALINFOPAGE.u32UpdateIntervalNS] ; before u64TSC
mov u32UpdateIntervalTSC, [pGipCPU + SUPGIPCPU.u32UpdateIntervalTSC]
mov u64PrevNanoTS, [pData + RTTIMENANOTSDATA.pu64Prev]
mov u64CurNanoTS, [pGipCPU + SUPGIPCPU.u64NanoTS]
mov u64TSC, [pGipCPU + SUPGIPCPU.u64TSC]
cmp u32TransactionId, [pGipCPU + SUPGIPCPU.u32TransactionId]
mov rbx, [pData + RTTIMENANOTSDATA.pu64Prev]
inc dword [pData + RTTIMENANOTSDATA.cExpired]
inc dword [pData + RTTIMENANOTSDATA.c1nsSteps]
call qword [pData + RTTIMENANOTSDATA.pfnBad]
lock inc dword [pData + RTTIMENANOTSDATA.cUpdateRaces]
call [pData + RTTIMENANOTSDATA.pfnRediscover]