asm-amd64-x86.h revision d16f75bad381547b34a1f315da059b782f4c21d3
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync/** @file
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync * IPRT - AMD64 and x86 Specific Assembly Functions.
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync */
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync/*
c58f1213e628a545081c70e26c6b67a841cff880vboxsync * Copyright (C) 2006-2013 Oracle Corporation
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync *
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync * This file is part of VirtualBox Open Source Edition (OSE), as
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync * available from http://www.virtualbox.org. This file is free software;
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync * you can redistribute it and/or modify it under the terms of the GNU
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync * General Public License (GPL) as published by the Free Software
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync * Foundation, in version 2 as it comes in the "COPYING" file of the
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync *
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync * The contents of this file may alternatively be used under the terms
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync * of the Common Development and Distribution License Version 1.0
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync * (CDDL) only, as it comes in the "COPYING.CDDL" file of the
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync * VirtualBox OSE distribution, in which case the provisions of the
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync * CDDL are applicable instead of those of the GPL.
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync *
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync * You may elect to license modified versions of this file under the
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync * terms and conditions of either the GPL or the CDDL or both.
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync */
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync#ifndef ___iprt_asm_amd64_x86_h
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync#define ___iprt_asm_amd64_x86_h
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync
2f0d866e126dd288169fed591c259c1c6b4016e5vboxsync#include <iprt/types.h>
52df77333eaa775dd09e7b0c525e726ad75b5effvboxsync#include <iprt/assert.h>
141a285580775ead77d73bb52a63701a5591dc6dvboxsync#if !defined(RT_ARCH_AMD64) && !defined(RT_ARCH_X86)
141a285580775ead77d73bb52a63701a5591dc6dvboxsync# error "Not on AMD64 or x86"
141a285580775ead77d73bb52a63701a5591dc6dvboxsync#endif
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync
2f0d866e126dd288169fed591c259c1c6b4016e5vboxsync#if defined(_MSC_VER) && RT_INLINE_ASM_USES_INTRIN
2f0d866e126dd288169fed591c259c1c6b4016e5vboxsync# include <intrin.h>
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync /* Emit the intrinsics at all optimization levels. */
2f0d866e126dd288169fed591c259c1c6b4016e5vboxsync# pragma intrinsic(_ReadWriteBarrier)
2f0d866e126dd288169fed591c259c1c6b4016e5vboxsync# pragma intrinsic(__cpuid)
2f0d866e126dd288169fed591c259c1c6b4016e5vboxsync# pragma intrinsic(_enable)
2f0d866e126dd288169fed591c259c1c6b4016e5vboxsync# pragma intrinsic(_disable)
2f0d866e126dd288169fed591c259c1c6b4016e5vboxsync# pragma intrinsic(__rdtsc)
2f0d866e126dd288169fed591c259c1c6b4016e5vboxsync# pragma intrinsic(__readmsr)
2f0d866e126dd288169fed591c259c1c6b4016e5vboxsync# pragma intrinsic(__writemsr)
2f0d866e126dd288169fed591c259c1c6b4016e5vboxsync# pragma intrinsic(__outbyte)
2f0d866e126dd288169fed591c259c1c6b4016e5vboxsync# pragma intrinsic(__outbytestring)
2f0d866e126dd288169fed591c259c1c6b4016e5vboxsync# pragma intrinsic(__outword)
2f0d866e126dd288169fed591c259c1c6b4016e5vboxsync# pragma intrinsic(__outwordstring)
2f0d866e126dd288169fed591c259c1c6b4016e5vboxsync# pragma intrinsic(__outdword)
2f0d866e126dd288169fed591c259c1c6b4016e5vboxsync# pragma intrinsic(__outdwordstring)
2f0d866e126dd288169fed591c259c1c6b4016e5vboxsync# pragma intrinsic(__inbyte)
2f0d866e126dd288169fed591c259c1c6b4016e5vboxsync# pragma intrinsic(__inbytestring)
2f0d866e126dd288169fed591c259c1c6b4016e5vboxsync# pragma intrinsic(__inword)
2f0d866e126dd288169fed591c259c1c6b4016e5vboxsync# pragma intrinsic(__inwordstring)
2f0d866e126dd288169fed591c259c1c6b4016e5vboxsync# pragma intrinsic(__indword)
2f0d866e126dd288169fed591c259c1c6b4016e5vboxsync# pragma intrinsic(__indwordstring)
2f0d866e126dd288169fed591c259c1c6b4016e5vboxsync# pragma intrinsic(__invlpg)
2f0d866e126dd288169fed591c259c1c6b4016e5vboxsync# pragma intrinsic(__wbinvd)
2f0d866e126dd288169fed591c259c1c6b4016e5vboxsync# pragma intrinsic(__readcr0)
2f0d866e126dd288169fed591c259c1c6b4016e5vboxsync# pragma intrinsic(__readcr2)
2f0d866e126dd288169fed591c259c1c6b4016e5vboxsync# pragma intrinsic(__readcr3)
2f0d866e126dd288169fed591c259c1c6b4016e5vboxsync# pragma intrinsic(__readcr4)
2f0d866e126dd288169fed591c259c1c6b4016e5vboxsync# pragma intrinsic(__writecr0)
2f0d866e126dd288169fed591c259c1c6b4016e5vboxsync# pragma intrinsic(__writecr3)
2f0d866e126dd288169fed591c259c1c6b4016e5vboxsync# pragma intrinsic(__writecr4)
2f0d866e126dd288169fed591c259c1c6b4016e5vboxsync# pragma intrinsic(__readdr)
2f0d866e126dd288169fed591c259c1c6b4016e5vboxsync# pragma intrinsic(__writedr)
2f0d866e126dd288169fed591c259c1c6b4016e5vboxsync# ifdef RT_ARCH_AMD64
2f0d866e126dd288169fed591c259c1c6b4016e5vboxsync# pragma intrinsic(__readcr8)
2f0d866e126dd288169fed591c259c1c6b4016e5vboxsync# pragma intrinsic(__writecr8)
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync# endif
9ad3427071ba81a2bbf60f5d9a04eb69c147ea6evboxsync# if RT_INLINE_ASM_USES_INTRIN >= 15
9ad3427071ba81a2bbf60f5d9a04eb69c147ea6evboxsync# pragma intrinsic(__readeflags)
9ad3427071ba81a2bbf60f5d9a04eb69c147ea6evboxsync# pragma intrinsic(__writeeflags)
26c76e19c6ae635af16484e15fa73fe74de5acaavboxsync# pragma intrinsic(__rdtscp)
9ad3427071ba81a2bbf60f5d9a04eb69c147ea6evboxsync# endif
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync#endif
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync/** @defgroup grp_rt_asm_amd64_x86 AMD64 and x86 Specific ASM Routines
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync * @ingroup grp_rt_asm
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync * @{
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync */
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync
52df77333eaa775dd09e7b0c525e726ad75b5effvboxsync/** @todo find a more proper place for these structures? */
52df77333eaa775dd09e7b0c525e726ad75b5effvboxsync
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync#pragma pack(1)
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync/** IDTR */
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsynctypedef struct RTIDTR
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync{
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync /** Size of the IDT. */
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync uint16_t cbIdt;
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync /** Address of the IDT. */
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync uintptr_t pIdt;
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync} RTIDTR, *PRTIDTR;
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync#pragma pack()
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync
52df77333eaa775dd09e7b0c525e726ad75b5effvboxsync#pragma pack(1)
52df77333eaa775dd09e7b0c525e726ad75b5effvboxsync/** @internal */
52df77333eaa775dd09e7b0c525e726ad75b5effvboxsynctypedef struct RTIDTRALIGNEDINT
52df77333eaa775dd09e7b0c525e726ad75b5effvboxsync{
52df77333eaa775dd09e7b0c525e726ad75b5effvboxsync /** Alignment padding. */
52df77333eaa775dd09e7b0c525e726ad75b5effvboxsync uint8_t au16Padding[ARCH_BITS == 64 ? 3 : 1];
52df77333eaa775dd09e7b0c525e726ad75b5effvboxsync /** The IDTR structure. */
52df77333eaa775dd09e7b0c525e726ad75b5effvboxsync RTIDTR Idtr;
52df77333eaa775dd09e7b0c525e726ad75b5effvboxsync} RTIDTRALIGNEDINT;
52df77333eaa775dd09e7b0c525e726ad75b5effvboxsync#pragma pack()
52df77333eaa775dd09e7b0c525e726ad75b5effvboxsync
52df77333eaa775dd09e7b0c525e726ad75b5effvboxsync/** Wrapped RTIDTR for preventing misalignment exceptions. */
52df77333eaa775dd09e7b0c525e726ad75b5effvboxsynctypedef union RTIDTRALIGNED
52df77333eaa775dd09e7b0c525e726ad75b5effvboxsync{
52df77333eaa775dd09e7b0c525e726ad75b5effvboxsync /** Try make sure this structure has optimal alignment. */
52df77333eaa775dd09e7b0c525e726ad75b5effvboxsync uint64_t auAlignmentHack[ARCH_BITS == 64 ? 2 : 1];
52df77333eaa775dd09e7b0c525e726ad75b5effvboxsync /** Aligned structure. */
52df77333eaa775dd09e7b0c525e726ad75b5effvboxsync RTIDTRALIGNEDINT s;
52df77333eaa775dd09e7b0c525e726ad75b5effvboxsync} RTIDTRALIGNED;
52df77333eaa775dd09e7b0c525e726ad75b5effvboxsyncAssertCompileSize(RTIDTRALIGNED, ARCH_BITS * 2 / 8);
52df77333eaa775dd09e7b0c525e726ad75b5effvboxsync/** Pointer to a an RTIDTR alignment wrapper. */
52df77333eaa775dd09e7b0c525e726ad75b5effvboxsynctypedef RTIDTRALIGNED *PRIDTRALIGNED;
52df77333eaa775dd09e7b0c525e726ad75b5effvboxsync
52df77333eaa775dd09e7b0c525e726ad75b5effvboxsync
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync#pragma pack(1)
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync/** GDTR */
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsynctypedef struct RTGDTR
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync{
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync /** Size of the GDT. */
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync uint16_t cbGdt;
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync /** Address of the GDT. */
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync uintptr_t pGdt;
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync} RTGDTR, *PRTGDTR;
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync#pragma pack()
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync
52df77333eaa775dd09e7b0c525e726ad75b5effvboxsync#pragma pack(1)
52df77333eaa775dd09e7b0c525e726ad75b5effvboxsync/** @internal */
52df77333eaa775dd09e7b0c525e726ad75b5effvboxsynctypedef struct RTGDTRALIGNEDINT
52df77333eaa775dd09e7b0c525e726ad75b5effvboxsync{
52df77333eaa775dd09e7b0c525e726ad75b5effvboxsync /** Alignment padding. */
52df77333eaa775dd09e7b0c525e726ad75b5effvboxsync uint8_t au16Padding[ARCH_BITS == 64 ? 3 : 1];
52df77333eaa775dd09e7b0c525e726ad75b5effvboxsync /** The GDTR structure. */
52df77333eaa775dd09e7b0c525e726ad75b5effvboxsync RTGDTR Gdtr;
52df77333eaa775dd09e7b0c525e726ad75b5effvboxsync} RTGDTRALIGNEDINT;
52df77333eaa775dd09e7b0c525e726ad75b5effvboxsync#pragma pack()
52df77333eaa775dd09e7b0c525e726ad75b5effvboxsync
52df77333eaa775dd09e7b0c525e726ad75b5effvboxsync/** Wrapped RTGDTR for preventing misalignment exceptions. */
52df77333eaa775dd09e7b0c525e726ad75b5effvboxsynctypedef union RTGDTRALIGNED
52df77333eaa775dd09e7b0c525e726ad75b5effvboxsync{
52df77333eaa775dd09e7b0c525e726ad75b5effvboxsync /** Try make sure this structure has optimal alignment. */
52df77333eaa775dd09e7b0c525e726ad75b5effvboxsync uint64_t auAlignmentHack[ARCH_BITS == 64 ? 2 : 1];
52df77333eaa775dd09e7b0c525e726ad75b5effvboxsync /** Aligned structure. */
52df77333eaa775dd09e7b0c525e726ad75b5effvboxsync RTGDTRALIGNEDINT s;
52df77333eaa775dd09e7b0c525e726ad75b5effvboxsync} RTGDTRALIGNED;
52df77333eaa775dd09e7b0c525e726ad75b5effvboxsyncAssertCompileSize(RTGDTRALIGNED, ARCH_BITS * 2 / 8);
52df77333eaa775dd09e7b0c525e726ad75b5effvboxsync/** Pointer to a an RTGDTR alignment wrapper. */
52df77333eaa775dd09e7b0c525e726ad75b5effvboxsynctypedef RTGDTRALIGNED *PRGDTRALIGNED;
52df77333eaa775dd09e7b0c525e726ad75b5effvboxsync
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync/**
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync * Gets the content of the IDTR CPU register.
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync * @param pIdtr Where to store the IDTR contents.
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync */
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync#if RT_INLINE_ASM_EXTERNAL
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsyncDECLASM(void) ASMGetIDTR(PRTIDTR pIdtr);
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync#else
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsyncDECLINLINE(void) ASMGetIDTR(PRTIDTR pIdtr)
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync{
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync# if RT_INLINE_ASM_GNU_STYLE
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync __asm__ __volatile__("sidt %0" : "=m" (*pIdtr));
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync# else
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync __asm
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync {
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync# ifdef RT_ARCH_AMD64
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync mov rax, [pIdtr]
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync sidt [rax]
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync# else
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync mov eax, [pIdtr]
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync sidt [eax]
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync# endif
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync }
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync# endif
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync}
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync#endif
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync
52df77333eaa775dd09e7b0c525e726ad75b5effvboxsync/**
52df77333eaa775dd09e7b0c525e726ad75b5effvboxsync * Gets the content of the IDTR.LIMIT CPU register.
52df77333eaa775dd09e7b0c525e726ad75b5effvboxsync * @returns IDTR limit.
52df77333eaa775dd09e7b0c525e726ad75b5effvboxsync */
52df77333eaa775dd09e7b0c525e726ad75b5effvboxsync#if RT_INLINE_ASM_EXTERNAL
52df77333eaa775dd09e7b0c525e726ad75b5effvboxsyncDECLASM(uint16_t) ASMGetIdtrLimit(void);
52df77333eaa775dd09e7b0c525e726ad75b5effvboxsync#else
52df77333eaa775dd09e7b0c525e726ad75b5effvboxsyncDECLINLINE(uint16_t) ASMGetIdtrLimit(void)
52df77333eaa775dd09e7b0c525e726ad75b5effvboxsync{
52df77333eaa775dd09e7b0c525e726ad75b5effvboxsync RTIDTRALIGNED TmpIdtr;
52df77333eaa775dd09e7b0c525e726ad75b5effvboxsync# if RT_INLINE_ASM_GNU_STYLE
52df77333eaa775dd09e7b0c525e726ad75b5effvboxsync __asm__ __volatile__("sidt %0" : "=m" (TmpIdtr.s.Idtr));
52df77333eaa775dd09e7b0c525e726ad75b5effvboxsync# else
52df77333eaa775dd09e7b0c525e726ad75b5effvboxsync __asm
52df77333eaa775dd09e7b0c525e726ad75b5effvboxsync {
52df77333eaa775dd09e7b0c525e726ad75b5effvboxsync sidt [TmpIdtr.s.Idtr]
52df77333eaa775dd09e7b0c525e726ad75b5effvboxsync }
52df77333eaa775dd09e7b0c525e726ad75b5effvboxsync# endif
52df77333eaa775dd09e7b0c525e726ad75b5effvboxsync return TmpIdtr.s.Idtr.cbIdt;
52df77333eaa775dd09e7b0c525e726ad75b5effvboxsync}
52df77333eaa775dd09e7b0c525e726ad75b5effvboxsync#endif
52df77333eaa775dd09e7b0c525e726ad75b5effvboxsync
52df77333eaa775dd09e7b0c525e726ad75b5effvboxsync
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync/**
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync * Sets the content of the IDTR CPU register.
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync * @param pIdtr Where to load the IDTR contents from
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync */
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync#if RT_INLINE_ASM_EXTERNAL
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsyncDECLASM(void) ASMSetIDTR(const RTIDTR *pIdtr);
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync#else
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsyncDECLINLINE(void) ASMSetIDTR(const RTIDTR *pIdtr)
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync{
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync# if RT_INLINE_ASM_GNU_STYLE
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync __asm__ __volatile__("lidt %0" : : "m" (*pIdtr));
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync# else
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync __asm
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync {
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync# ifdef RT_ARCH_AMD64
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync mov rax, [pIdtr]
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync lidt [rax]
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync# else
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync mov eax, [pIdtr]
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync lidt [eax]
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync# endif
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync }
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync# endif
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync}
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync#endif
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync/**
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync * Gets the content of the GDTR CPU register.
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync * @param pGdtr Where to store the GDTR contents.
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync */
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync#if RT_INLINE_ASM_EXTERNAL
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsyncDECLASM(void) ASMGetGDTR(PRTGDTR pGdtr);
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync#else
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsyncDECLINLINE(void) ASMGetGDTR(PRTGDTR pGdtr)
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync{
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync# if RT_INLINE_ASM_GNU_STYLE
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync __asm__ __volatile__("sgdt %0" : "=m" (*pGdtr));
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync# else
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync __asm
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync {
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync# ifdef RT_ARCH_AMD64
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync mov rax, [pGdtr]
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync sgdt [rax]
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync# else
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync mov eax, [pGdtr]
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync sgdt [eax]
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync# endif
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync }
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync# endif
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync}
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync#endif
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync
615c2f5544718590f05af51eff75bd1bbac4be54vboxsync
615c2f5544718590f05af51eff75bd1bbac4be54vboxsync/**
615c2f5544718590f05af51eff75bd1bbac4be54vboxsync * Sets the content of the GDTR CPU register.
615c2f5544718590f05af51eff75bd1bbac4be54vboxsync * @param pIdtr Where to load the GDTR contents from
615c2f5544718590f05af51eff75bd1bbac4be54vboxsync */
615c2f5544718590f05af51eff75bd1bbac4be54vboxsync#if RT_INLINE_ASM_EXTERNAL
615c2f5544718590f05af51eff75bd1bbac4be54vboxsyncDECLASM(void) ASMSetGDTR(const RTGDTR *pGdtr);
615c2f5544718590f05af51eff75bd1bbac4be54vboxsync#else
615c2f5544718590f05af51eff75bd1bbac4be54vboxsyncDECLINLINE(void) ASMSetGDTR(const RTGDTR *pGdtr)
615c2f5544718590f05af51eff75bd1bbac4be54vboxsync{
615c2f5544718590f05af51eff75bd1bbac4be54vboxsync# if RT_INLINE_ASM_GNU_STYLE
615c2f5544718590f05af51eff75bd1bbac4be54vboxsync __asm__ __volatile__("lgdt %0" : : "m" (*pGdtr));
615c2f5544718590f05af51eff75bd1bbac4be54vboxsync# else
615c2f5544718590f05af51eff75bd1bbac4be54vboxsync __asm
615c2f5544718590f05af51eff75bd1bbac4be54vboxsync {
615c2f5544718590f05af51eff75bd1bbac4be54vboxsync# ifdef RT_ARCH_AMD64
615c2f5544718590f05af51eff75bd1bbac4be54vboxsync mov rax, [pGdtr]
615c2f5544718590f05af51eff75bd1bbac4be54vboxsync lgdt [rax]
615c2f5544718590f05af51eff75bd1bbac4be54vboxsync# else
615c2f5544718590f05af51eff75bd1bbac4be54vboxsync mov eax, [pGdtr]
615c2f5544718590f05af51eff75bd1bbac4be54vboxsync lgdt [eax]
615c2f5544718590f05af51eff75bd1bbac4be54vboxsync# endif
615c2f5544718590f05af51eff75bd1bbac4be54vboxsync }
615c2f5544718590f05af51eff75bd1bbac4be54vboxsync# endif
615c2f5544718590f05af51eff75bd1bbac4be54vboxsync}
615c2f5544718590f05af51eff75bd1bbac4be54vboxsync#endif
615c2f5544718590f05af51eff75bd1bbac4be54vboxsync
615c2f5544718590f05af51eff75bd1bbac4be54vboxsync
615c2f5544718590f05af51eff75bd1bbac4be54vboxsync
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync/**
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync * Get the cs register.
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync * @returns cs.
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync */
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync#if RT_INLINE_ASM_EXTERNAL
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsyncDECLASM(RTSEL) ASMGetCS(void);
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync#else
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsyncDECLINLINE(RTSEL) ASMGetCS(void)
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync{
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync RTSEL SelCS;
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync# if RT_INLINE_ASM_GNU_STYLE
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync __asm__ __volatile__("movw %%cs, %0\n\t" : "=r" (SelCS));
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync# else
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync __asm
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync {
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync mov ax, cs
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync mov [SelCS], ax
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync }
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync# endif
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync return SelCS;
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync}
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync#endif
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync/**
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync * Get the DS register.
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync * @returns DS.
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync */
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync#if RT_INLINE_ASM_EXTERNAL
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsyncDECLASM(RTSEL) ASMGetDS(void);
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync#else
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsyncDECLINLINE(RTSEL) ASMGetDS(void)
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync{
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync RTSEL SelDS;
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync# if RT_INLINE_ASM_GNU_STYLE
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync __asm__ __volatile__("movw %%ds, %0\n\t" : "=r" (SelDS));
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync# else
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync __asm
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync {
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync mov ax, ds
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync mov [SelDS], ax
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync }
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync# endif
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync return SelDS;
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync}
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync#endif
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync/**
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync * Get the ES register.
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync * @returns ES.
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync */
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync#if RT_INLINE_ASM_EXTERNAL
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsyncDECLASM(RTSEL) ASMGetES(void);
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync#else
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsyncDECLINLINE(RTSEL) ASMGetES(void)
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync{
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync RTSEL SelES;
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync# if RT_INLINE_ASM_GNU_STYLE
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync __asm__ __volatile__("movw %%es, %0\n\t" : "=r" (SelES));
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync# else
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync __asm
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync {
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync mov ax, es
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync mov [SelES], ax
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync }
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync# endif
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync return SelES;
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync}
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync#endif
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync/**
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync * Get the FS register.
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync * @returns FS.
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync */
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync#if RT_INLINE_ASM_EXTERNAL
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsyncDECLASM(RTSEL) ASMGetFS(void);
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync#else
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsyncDECLINLINE(RTSEL) ASMGetFS(void)
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync{
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync RTSEL SelFS;
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync# if RT_INLINE_ASM_GNU_STYLE
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync __asm__ __volatile__("movw %%fs, %0\n\t" : "=r" (SelFS));
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync# else
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync __asm
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync {
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync mov ax, fs
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync mov [SelFS], ax
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync }
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync# endif
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync return SelFS;
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync}
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync# endif
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync/**
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync * Get the GS register.
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync * @returns GS.
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync */
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync#if RT_INLINE_ASM_EXTERNAL
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsyncDECLASM(RTSEL) ASMGetGS(void);
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync#else
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsyncDECLINLINE(RTSEL) ASMGetGS(void)
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync{
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync RTSEL SelGS;
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync# if RT_INLINE_ASM_GNU_STYLE
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync __asm__ __volatile__("movw %%gs, %0\n\t" : "=r" (SelGS));
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync# else
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync __asm
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync {
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync mov ax, gs
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync mov [SelGS], ax
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync }
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync# endif
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync return SelGS;
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync}
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync#endif
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync/**
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync * Get the SS register.
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync * @returns SS.
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync */
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync#if RT_INLINE_ASM_EXTERNAL
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsyncDECLASM(RTSEL) ASMGetSS(void);
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync#else
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsyncDECLINLINE(RTSEL) ASMGetSS(void)
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync{
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync RTSEL SelSS;
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync# if RT_INLINE_ASM_GNU_STYLE
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync __asm__ __volatile__("movw %%ss, %0\n\t" : "=r" (SelSS));
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync# else
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync __asm
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync {
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync mov ax, ss
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync mov [SelSS], ax
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync }
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync# endif
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync return SelSS;
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync}
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync#endif
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync/**
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync * Get the TR register.
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync * @returns TR.
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync */
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync#if RT_INLINE_ASM_EXTERNAL
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsyncDECLASM(RTSEL) ASMGetTR(void);
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync#else
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsyncDECLINLINE(RTSEL) ASMGetTR(void)
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync{
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync RTSEL SelTR;
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync# if RT_INLINE_ASM_GNU_STYLE
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync __asm__ __volatile__("str %w0\n\t" : "=r" (SelTR));
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync# else
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync __asm
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync {
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync str ax
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync mov [SelTR], ax
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync }
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync# endif
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync return SelTR;
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync}
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync#endif
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync
76d3e53889c5a02a3881bd3cfa31509d61cea9d0vboxsync/**
76d3e53889c5a02a3881bd3cfa31509d61cea9d0vboxsync * Get the LDTR register.
76d3e53889c5a02a3881bd3cfa31509d61cea9d0vboxsync * @returns LDTR.
76d3e53889c5a02a3881bd3cfa31509d61cea9d0vboxsync */
76d3e53889c5a02a3881bd3cfa31509d61cea9d0vboxsync#if RT_INLINE_ASM_EXTERNAL
76d3e53889c5a02a3881bd3cfa31509d61cea9d0vboxsyncDECLASM(RTSEL) ASMGetLDTR(void);
76d3e53889c5a02a3881bd3cfa31509d61cea9d0vboxsync#else
76d3e53889c5a02a3881bd3cfa31509d61cea9d0vboxsyncDECLINLINE(RTSEL) ASMGetLDTR(void)
76d3e53889c5a02a3881bd3cfa31509d61cea9d0vboxsync{
76d3e53889c5a02a3881bd3cfa31509d61cea9d0vboxsync RTSEL SelLDTR;
76d3e53889c5a02a3881bd3cfa31509d61cea9d0vboxsync# if RT_INLINE_ASM_GNU_STYLE
76d3e53889c5a02a3881bd3cfa31509d61cea9d0vboxsync __asm__ __volatile__("sldt %w0\n\t" : "=r" (SelLDTR));
76d3e53889c5a02a3881bd3cfa31509d61cea9d0vboxsync# else
76d3e53889c5a02a3881bd3cfa31509d61cea9d0vboxsync __asm
76d3e53889c5a02a3881bd3cfa31509d61cea9d0vboxsync {
76d3e53889c5a02a3881bd3cfa31509d61cea9d0vboxsync sldt ax
76d3e53889c5a02a3881bd3cfa31509d61cea9d0vboxsync mov [SelLDTR], ax
76d3e53889c5a02a3881bd3cfa31509d61cea9d0vboxsync }
76d3e53889c5a02a3881bd3cfa31509d61cea9d0vboxsync# endif
76d3e53889c5a02a3881bd3cfa31509d61cea9d0vboxsync return SelLDTR;
76d3e53889c5a02a3881bd3cfa31509d61cea9d0vboxsync}
76d3e53889c5a02a3881bd3cfa31509d61cea9d0vboxsync#endif
76d3e53889c5a02a3881bd3cfa31509d61cea9d0vboxsync
76d3e53889c5a02a3881bd3cfa31509d61cea9d0vboxsync
109c0d54dc2438e7887f198daefb7e164c8a9dffvboxsync/**
109c0d54dc2438e7887f198daefb7e164c8a9dffvboxsync * Get the access rights for the segment selector.
109c0d54dc2438e7887f198daefb7e164c8a9dffvboxsync *
91b5f2a7d9797385e53af76c22883fa15fd25adfvboxsync * @returns The access rights on success or UINT32_MAX on failure.
109c0d54dc2438e7887f198daefb7e164c8a9dffvboxsync * @param uSel The selector value.
109c0d54dc2438e7887f198daefb7e164c8a9dffvboxsync *
91b5f2a7d9797385e53af76c22883fa15fd25adfvboxsync * @remarks Using UINT32_MAX for failure is chosen because valid access rights
91b5f2a7d9797385e53af76c22883fa15fd25adfvboxsync * always have bits 0:7 as 0 (on both Intel & AMD).
109c0d54dc2438e7887f198daefb7e164c8a9dffvboxsync */
109c0d54dc2438e7887f198daefb7e164c8a9dffvboxsync#if RT_INLINE_ASM_EXTERNAL
62affeb44694facf8de89ef52bb676150f979887vboxsyncDECLASM(uint32_t) ASMGetSegAttr(uint32_t uSel);
109c0d54dc2438e7887f198daefb7e164c8a9dffvboxsync#else
62affeb44694facf8de89ef52bb676150f979887vboxsyncDECLINLINE(uint32_t) ASMGetSegAttr(uint32_t uSel)
109c0d54dc2438e7887f198daefb7e164c8a9dffvboxsync{
109c0d54dc2438e7887f198daefb7e164c8a9dffvboxsync uint32_t uAttr;
109c0d54dc2438e7887f198daefb7e164c8a9dffvboxsync /* LAR only accesses 16-bit of the source operand, but eax for the
109c0d54dc2438e7887f198daefb7e164c8a9dffvboxsync destination operand is required for getting the full 32-bit access rights. */
109c0d54dc2438e7887f198daefb7e164c8a9dffvboxsync# if RT_INLINE_ASM_GNU_STYLE
d8818699735c83c36fc9555f85e6d86b610cdc67vboxsync __asm__ __volatile__("lar %1, %%eax\n\t"
109c0d54dc2438e7887f198daefb7e164c8a9dffvboxsync "jz done%=\n\t"
d8818699735c83c36fc9555f85e6d86b610cdc67vboxsync "movl $0xffffffff, %%eax\n\t"
109c0d54dc2438e7887f198daefb7e164c8a9dffvboxsync "done%=:\n\t"
d8818699735c83c36fc9555f85e6d86b610cdc67vboxsync "movl %%eax, %0\n\t"
109c0d54dc2438e7887f198daefb7e164c8a9dffvboxsync : "=r" (uAttr)
109c0d54dc2438e7887f198daefb7e164c8a9dffvboxsync : "r" (uSel)
109c0d54dc2438e7887f198daefb7e164c8a9dffvboxsync : "cc", "%eax");
109c0d54dc2438e7887f198daefb7e164c8a9dffvboxsync# else
109c0d54dc2438e7887f198daefb7e164c8a9dffvboxsync __asm
109c0d54dc2438e7887f198daefb7e164c8a9dffvboxsync {
d8818699735c83c36fc9555f85e6d86b610cdc67vboxsync lar eax, [uSel]
109c0d54dc2438e7887f198daefb7e164c8a9dffvboxsync jz done
d8818699735c83c36fc9555f85e6d86b610cdc67vboxsync mov eax, 0ffffffffh
109c0d54dc2438e7887f198daefb7e164c8a9dffvboxsync done:
d8818699735c83c36fc9555f85e6d86b610cdc67vboxsync mov [uAttr], eax
109c0d54dc2438e7887f198daefb7e164c8a9dffvboxsync }
109c0d54dc2438e7887f198daefb7e164c8a9dffvboxsync# endif
109c0d54dc2438e7887f198daefb7e164c8a9dffvboxsync return uAttr;
109c0d54dc2438e7887f198daefb7e164c8a9dffvboxsync}
109c0d54dc2438e7887f198daefb7e164c8a9dffvboxsync#endif
109c0d54dc2438e7887f198daefb7e164c8a9dffvboxsync
109c0d54dc2438e7887f198daefb7e164c8a9dffvboxsync
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync/**
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync * Get the [RE]FLAGS register.
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync * @returns [RE]FLAGS.
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync */
9ad3427071ba81a2bbf60f5d9a04eb69c147ea6evboxsync#if RT_INLINE_ASM_EXTERNAL && RT_INLINE_ASM_USES_INTRIN < 15
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsyncDECLASM(RTCCUINTREG) ASMGetFlags(void);
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync#else
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsyncDECLINLINE(RTCCUINTREG) ASMGetFlags(void)
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync{
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync RTCCUINTREG uFlags;
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync# if RT_INLINE_ASM_GNU_STYLE
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync# ifdef RT_ARCH_AMD64
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync __asm__ __volatile__("pushfq\n\t"
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync "popq %0\n\t"
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync : "=r" (uFlags));
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync# else
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync __asm__ __volatile__("pushfl\n\t"
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync "popl %0\n\t"
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync : "=r" (uFlags));
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync# endif
9ad3427071ba81a2bbf60f5d9a04eb69c147ea6evboxsync# elif RT_INLINE_ASM_USES_INTRIN >= 15
9ad3427071ba81a2bbf60f5d9a04eb69c147ea6evboxsync uFlags = __readeflags();
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync# else
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync __asm
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync {
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync# ifdef RT_ARCH_AMD64
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync pushfq
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync pop [uFlags]
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync# else
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync pushfd
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync pop [uFlags]
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync# endif
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync }
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync# endif
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync return uFlags;
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync}
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync#endif
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync/**
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync * Set the [RE]FLAGS register.
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync * @param uFlags The new [RE]FLAGS value.
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync */
9ad3427071ba81a2bbf60f5d9a04eb69c147ea6evboxsync#if RT_INLINE_ASM_EXTERNAL && RT_INLINE_ASM_USES_INTRIN < 15
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsyncDECLASM(void) ASMSetFlags(RTCCUINTREG uFlags);
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync#else
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsyncDECLINLINE(void) ASMSetFlags(RTCCUINTREG uFlags)
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync{
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync# if RT_INLINE_ASM_GNU_STYLE
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync# ifdef RT_ARCH_AMD64
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync __asm__ __volatile__("pushq %0\n\t"
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync "popfq\n\t"
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync : : "g" (uFlags));
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync# else
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync __asm__ __volatile__("pushl %0\n\t"
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync "popfl\n\t"
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync : : "g" (uFlags));
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync# endif
9ad3427071ba81a2bbf60f5d9a04eb69c147ea6evboxsync# elif RT_INLINE_ASM_USES_INTRIN >= 15
9ad3427071ba81a2bbf60f5d9a04eb69c147ea6evboxsync __writeeflags(uFlags);
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync# else
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync __asm
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync {
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync# ifdef RT_ARCH_AMD64
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync push [uFlags]
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync popfq
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync# else
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync push [uFlags]
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync popfd
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync# endif
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync }
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync# endif
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync}
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync#endif
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync/**
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync * Gets the content of the CPU timestamp counter register.
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync *
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync * @returns TSC.
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync */
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync#if RT_INLINE_ASM_EXTERNAL && !RT_INLINE_ASM_USES_INTRIN
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsyncDECLASM(uint64_t) ASMReadTSC(void);
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync#else
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsyncDECLINLINE(uint64_t) ASMReadTSC(void)
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync{
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync RTUINT64U u;
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync# if RT_INLINE_ASM_GNU_STYLE
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync __asm__ __volatile__("rdtsc\n\t" : "=a" (u.s.Lo), "=d" (u.s.Hi));
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync# else
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync# if RT_INLINE_ASM_USES_INTRIN
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync u.u = __rdtsc();
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync# else
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync __asm
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync {
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync rdtsc
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync mov [u.s.Lo], eax
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync mov [u.s.Hi], edx
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync }
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync# endif
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync# endif
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync return u.u;
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync}
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync#endif
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync
26c76e19c6ae635af16484e15fa73fe74de5acaavboxsync/**
26c76e19c6ae635af16484e15fa73fe74de5acaavboxsync * Gets the content of the CPU timestamp counter register and the
26c76e19c6ae635af16484e15fa73fe74de5acaavboxsync * assoicated AUX value.
26c76e19c6ae635af16484e15fa73fe74de5acaavboxsync *
26c76e19c6ae635af16484e15fa73fe74de5acaavboxsync * @returns TSC.
26c76e19c6ae635af16484e15fa73fe74de5acaavboxsync * @param puAux Where to store the AUX value.
26c76e19c6ae635af16484e15fa73fe74de5acaavboxsync */
26c76e19c6ae635af16484e15fa73fe74de5acaavboxsync#if RT_INLINE_ASM_EXTERNAL && RT_INLINE_ASM_USES_INTRIN < 15
26c76e19c6ae635af16484e15fa73fe74de5acaavboxsyncDECLASM(uint64_t) ASMReadTscWithAux(uint32_t *puAux);
26c76e19c6ae635af16484e15fa73fe74de5acaavboxsync#else
26c76e19c6ae635af16484e15fa73fe74de5acaavboxsyncDECLINLINE(uint64_t) ASMReadTscWithAux(uint32_t *puAux)
26c76e19c6ae635af16484e15fa73fe74de5acaavboxsync{
26c76e19c6ae635af16484e15fa73fe74de5acaavboxsync RTUINT64U u;
26c76e19c6ae635af16484e15fa73fe74de5acaavboxsync# if RT_INLINE_ASM_GNU_STYLE
ffaee3d9d3a768954b2b039615d71f25a6b53956vboxsync /* rdtscp is not supported by ancient linux build VM of course :-( */
ffaee3d9d3a768954b2b039615d71f25a6b53956vboxsync /*__asm__ __volatile__("rdtscp\n\t" : "=a" (u.s.Lo), "=d" (u.s.Hi), "=c" (*puAux)); */
ffaee3d9d3a768954b2b039615d71f25a6b53956vboxsync __asm__ __volatile__(".byte 0x0f,0x01,0xf9\n\t" : "=a" (u.s.Lo), "=d" (u.s.Hi), "=c" (*puAux));
26c76e19c6ae635af16484e15fa73fe74de5acaavboxsync# else
26c76e19c6ae635af16484e15fa73fe74de5acaavboxsync# if RT_INLINE_ASM_USES_INTRIN >= 15
26c76e19c6ae635af16484e15fa73fe74de5acaavboxsync u.u = __rdtscp(puAux);
26c76e19c6ae635af16484e15fa73fe74de5acaavboxsync# else
26c76e19c6ae635af16484e15fa73fe74de5acaavboxsync __asm
26c76e19c6ae635af16484e15fa73fe74de5acaavboxsync {
26c76e19c6ae635af16484e15fa73fe74de5acaavboxsync rdtscp
26c76e19c6ae635af16484e15fa73fe74de5acaavboxsync mov [u.s.Lo], eax
26c76e19c6ae635af16484e15fa73fe74de5acaavboxsync mov [u.s.Hi], edx
26c76e19c6ae635af16484e15fa73fe74de5acaavboxsync mov eax, [puAux]
26c76e19c6ae635af16484e15fa73fe74de5acaavboxsync mov [eax], ecx
26c76e19c6ae635af16484e15fa73fe74de5acaavboxsync }
26c76e19c6ae635af16484e15fa73fe74de5acaavboxsync# endif
26c76e19c6ae635af16484e15fa73fe74de5acaavboxsync# endif
26c76e19c6ae635af16484e15fa73fe74de5acaavboxsync return u.u;
26c76e19c6ae635af16484e15fa73fe74de5acaavboxsync}
26c76e19c6ae635af16484e15fa73fe74de5acaavboxsync#endif
26c76e19c6ae635af16484e15fa73fe74de5acaavboxsync
26c76e19c6ae635af16484e15fa73fe74de5acaavboxsync
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync/**
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync * Performs the cpuid instruction returning all registers.
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync *
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync * @param uOperator CPUID operation (eax).
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync * @param pvEAX Where to store eax.
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync * @param pvEBX Where to store ebx.
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync * @param pvECX Where to store ecx.
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync * @param pvEDX Where to store edx.
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync * @remark We're using void pointers to ease the use of special bitfield structures and such.
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync */
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync#if RT_INLINE_ASM_EXTERNAL && !RT_INLINE_ASM_USES_INTRIN
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsyncDECLASM(void) ASMCpuId(uint32_t uOperator, void *pvEAX, void *pvEBX, void *pvECX, void *pvEDX);
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync#else
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsyncDECLINLINE(void) ASMCpuId(uint32_t uOperator, void *pvEAX, void *pvEBX, void *pvECX, void *pvEDX)
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync{
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync# if RT_INLINE_ASM_GNU_STYLE
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync# ifdef RT_ARCH_AMD64
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync RTCCUINTREG uRAX, uRBX, uRCX, uRDX;
4d93fcdfb645b86163cfea77f687172295988d16vboxsync __asm__ __volatile__ ("cpuid\n\t"
4d93fcdfb645b86163cfea77f687172295988d16vboxsync : "=a" (uRAX),
4d93fcdfb645b86163cfea77f687172295988d16vboxsync "=b" (uRBX),
4d93fcdfb645b86163cfea77f687172295988d16vboxsync "=c" (uRCX),
4d93fcdfb645b86163cfea77f687172295988d16vboxsync "=d" (uRDX)
b891b477f403c0a8a1eea185f9bc4ef9c99caf2dvboxsync : "0" (uOperator), "2" (0));
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync *(uint32_t *)pvEAX = (uint32_t)uRAX;
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync *(uint32_t *)pvEBX = (uint32_t)uRBX;
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync *(uint32_t *)pvECX = (uint32_t)uRCX;
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync *(uint32_t *)pvEDX = (uint32_t)uRDX;
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync# else
4d93fcdfb645b86163cfea77f687172295988d16vboxsync __asm__ __volatile__ ("xchgl %%ebx, %1\n\t"
4d93fcdfb645b86163cfea77f687172295988d16vboxsync "cpuid\n\t"
4d93fcdfb645b86163cfea77f687172295988d16vboxsync "xchgl %%ebx, %1\n\t"
4d93fcdfb645b86163cfea77f687172295988d16vboxsync : "=a" (*(uint32_t *)pvEAX),
4d93fcdfb645b86163cfea77f687172295988d16vboxsync "=r" (*(uint32_t *)pvEBX),
4d93fcdfb645b86163cfea77f687172295988d16vboxsync "=c" (*(uint32_t *)pvECX),
4d93fcdfb645b86163cfea77f687172295988d16vboxsync "=d" (*(uint32_t *)pvEDX)
b891b477f403c0a8a1eea185f9bc4ef9c99caf2dvboxsync : "0" (uOperator), "2" (0));
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync# endif
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync# elif RT_INLINE_ASM_USES_INTRIN
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync int aInfo[4];
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync __cpuid(aInfo, uOperator);
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync *(uint32_t *)pvEAX = aInfo[0];
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync *(uint32_t *)pvEBX = aInfo[1];
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync *(uint32_t *)pvECX = aInfo[2];
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync *(uint32_t *)pvEDX = aInfo[3];
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync# else
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync uint32_t uEAX;
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync uint32_t uEBX;
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync uint32_t uECX;
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync uint32_t uEDX;
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync __asm
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync {
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync push ebx
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync mov eax, [uOperator]
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync cpuid
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync mov [uEAX], eax
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync mov [uEBX], ebx
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync mov [uECX], ecx
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync mov [uEDX], edx
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync pop ebx
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync }
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync *(uint32_t *)pvEAX = uEAX;
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync *(uint32_t *)pvEBX = uEBX;
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync *(uint32_t *)pvECX = uECX;
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync *(uint32_t *)pvEDX = uEDX;
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync# endif
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync}
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync#endif
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync/**
3e7e8dae1bd305767a63ff29f1ae8bd8dccb8000vboxsync * Performs the CPUID instruction with EAX and ECX input returning ALL output
3e7e8dae1bd305767a63ff29f1ae8bd8dccb8000vboxsync * registers.
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync *
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync * @param uOperator CPUID operation (eax).
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync * @param uIdxECX ecx index
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync * @param pvEAX Where to store eax.
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync * @param pvEBX Where to store ebx.
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync * @param pvECX Where to store ecx.
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync * @param pvEDX Where to store edx.
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync * @remark We're using void pointers to ease the use of special bitfield structures and such.
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync */
3e7e8dae1bd305767a63ff29f1ae8bd8dccb8000vboxsync#if RT_INLINE_ASM_EXTERNAL || RT_INLINE_ASM_USES_INTRIN
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsyncDECLASM(void) ASMCpuId_Idx_ECX(uint32_t uOperator, uint32_t uIdxECX, void *pvEAX, void *pvEBX, void *pvECX, void *pvEDX);
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync#else
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsyncDECLINLINE(void) ASMCpuId_Idx_ECX(uint32_t uOperator, uint32_t uIdxECX, void *pvEAX, void *pvEBX, void *pvECX, void *pvEDX)
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync{
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync# if RT_INLINE_ASM_GNU_STYLE
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync# ifdef RT_ARCH_AMD64
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync RTCCUINTREG uRAX, uRBX, uRCX, uRDX;
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync __asm__ ("cpuid\n\t"
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync : "=a" (uRAX),
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync "=b" (uRBX),
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync "=c" (uRCX),
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync "=d" (uRDX)
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync : "0" (uOperator),
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync "2" (uIdxECX));
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync *(uint32_t *)pvEAX = (uint32_t)uRAX;
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync *(uint32_t *)pvEBX = (uint32_t)uRBX;
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync *(uint32_t *)pvECX = (uint32_t)uRCX;
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync *(uint32_t *)pvEDX = (uint32_t)uRDX;
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync# else
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync __asm__ ("xchgl %%ebx, %1\n\t"
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync "cpuid\n\t"
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync "xchgl %%ebx, %1\n\t"
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync : "=a" (*(uint32_t *)pvEAX),
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync "=r" (*(uint32_t *)pvEBX),
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync "=c" (*(uint32_t *)pvECX),
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync "=d" (*(uint32_t *)pvEDX)
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync : "0" (uOperator),
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync "2" (uIdxECX));
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync# endif
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync# elif RT_INLINE_ASM_USES_INTRIN
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync int aInfo[4];
3e7e8dae1bd305767a63ff29f1ae8bd8dccb8000vboxsync __cpuidex(aInfo, uOperator, uIdxECX);
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync *(uint32_t *)pvEAX = aInfo[0];
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync *(uint32_t *)pvEBX = aInfo[1];
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync *(uint32_t *)pvECX = aInfo[2];
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync *(uint32_t *)pvEDX = aInfo[3];
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync# else
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync uint32_t uEAX;
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync uint32_t uEBX;
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync uint32_t uECX;
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync uint32_t uEDX;
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync __asm
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync {
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync push ebx
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync mov eax, [uOperator]
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync mov ecx, [uIdxECX]
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync cpuid
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync mov [uEAX], eax
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync mov [uEBX], ebx
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync mov [uECX], ecx
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync mov [uEDX], edx
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync pop ebx
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync }
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync *(uint32_t *)pvEAX = uEAX;
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync *(uint32_t *)pvEBX = uEBX;
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync *(uint32_t *)pvECX = uECX;
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync *(uint32_t *)pvEDX = uEDX;
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync# endif
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync}
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync#endif
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync
1d9b8ac46277d5cbab832794c5cfcce1e0521873vboxsync/**
1d9b8ac46277d5cbab832794c5cfcce1e0521873vboxsync * CPUID variant that initializes all 4 registers before the CPUID instruction.
1d9b8ac46277d5cbab832794c5cfcce1e0521873vboxsync *
1d9b8ac46277d5cbab832794c5cfcce1e0521873vboxsync * @returns The EAX result value.
1d9b8ac46277d5cbab832794c5cfcce1e0521873vboxsync * @param uOperator CPUID operation (eax).
1d9b8ac46277d5cbab832794c5cfcce1e0521873vboxsync * @param uInitEBX The value to assign EBX prior to the CPUID instruction.
1d9b8ac46277d5cbab832794c5cfcce1e0521873vboxsync * @param uInitECX The value to assign ECX prior to the CPUID instruction.
1d9b8ac46277d5cbab832794c5cfcce1e0521873vboxsync * @param uInitEDX The value to assign EDX prior to the CPUID instruction.
1d9b8ac46277d5cbab832794c5cfcce1e0521873vboxsync * @param pvEAX Where to store eax. Optional.
1d9b8ac46277d5cbab832794c5cfcce1e0521873vboxsync * @param pvEBX Where to store ebx. Optional.
1d9b8ac46277d5cbab832794c5cfcce1e0521873vboxsync * @param pvECX Where to store ecx. Optional.
1d9b8ac46277d5cbab832794c5cfcce1e0521873vboxsync * @param pvEDX Where to store edx. Optional.
1d9b8ac46277d5cbab832794c5cfcce1e0521873vboxsync */
1d9b8ac46277d5cbab832794c5cfcce1e0521873vboxsyncDECLASM(uint32_t) ASMCpuIdExSlow(uint32_t uOperator, uint32_t uInitEBX, uint32_t uInitECX, uint32_t uInitEDX,
1d9b8ac46277d5cbab832794c5cfcce1e0521873vboxsync void *pvEAX, void *pvEBX, void *pvECX, void *pvEDX);
1d9b8ac46277d5cbab832794c5cfcce1e0521873vboxsync
1d9b8ac46277d5cbab832794c5cfcce1e0521873vboxsync
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync/**
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync * Performs the cpuid instruction returning ecx and edx.
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync *
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync * @param uOperator CPUID operation (eax).
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync * @param pvECX Where to store ecx.
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync * @param pvEDX Where to store edx.
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync * @remark We're using void pointers to ease the use of special bitfield structures and such.
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync */
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync#if RT_INLINE_ASM_EXTERNAL && !RT_INLINE_ASM_USES_INTRIN
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsyncDECLASM(void) ASMCpuId_ECX_EDX(uint32_t uOperator, void *pvECX, void *pvEDX);
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync#else
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsyncDECLINLINE(void) ASMCpuId_ECX_EDX(uint32_t uOperator, void *pvECX, void *pvEDX)
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync{
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync uint32_t uEBX;
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync ASMCpuId(uOperator, &uOperator, &uEBX, pvECX, pvEDX);
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync}
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync#endif
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync/**
6a89b975ab84f4a47fb86fc27ba6c33c701720cfvboxsync * Performs the cpuid instruction returning eax.
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync *
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync * @param uOperator CPUID operation (eax).
6a89b975ab84f4a47fb86fc27ba6c33c701720cfvboxsync * @returns EAX after cpuid operation.
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync */
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync#if RT_INLINE_ASM_EXTERNAL && !RT_INLINE_ASM_USES_INTRIN
6a89b975ab84f4a47fb86fc27ba6c33c701720cfvboxsyncDECLASM(uint32_t) ASMCpuId_EAX(uint32_t uOperator);
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync#else
6a89b975ab84f4a47fb86fc27ba6c33c701720cfvboxsyncDECLINLINE(uint32_t) ASMCpuId_EAX(uint32_t uOperator)
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync{
6a89b975ab84f4a47fb86fc27ba6c33c701720cfvboxsync RTCCUINTREG xAX;
6a89b975ab84f4a47fb86fc27ba6c33c701720cfvboxsync# if RT_INLINE_ASM_GNU_STYLE
6a89b975ab84f4a47fb86fc27ba6c33c701720cfvboxsync# ifdef RT_ARCH_AMD64
6a89b975ab84f4a47fb86fc27ba6c33c701720cfvboxsync __asm__ ("cpuid"
6a89b975ab84f4a47fb86fc27ba6c33c701720cfvboxsync : "=a" (xAX)
6a89b975ab84f4a47fb86fc27ba6c33c701720cfvboxsync : "0" (uOperator)
6a89b975ab84f4a47fb86fc27ba6c33c701720cfvboxsync : "rbx", "rcx", "rdx");
6a89b975ab84f4a47fb86fc27ba6c33c701720cfvboxsync# elif (defined(PIC) || defined(__PIC__)) && defined(__i386__)
6a89b975ab84f4a47fb86fc27ba6c33c701720cfvboxsync __asm__ ("push %%ebx\n\t"
6a89b975ab84f4a47fb86fc27ba6c33c701720cfvboxsync "cpuid\n\t"
6a89b975ab84f4a47fb86fc27ba6c33c701720cfvboxsync "pop %%ebx\n\t"
6a89b975ab84f4a47fb86fc27ba6c33c701720cfvboxsync : "=a" (xAX)
6a89b975ab84f4a47fb86fc27ba6c33c701720cfvboxsync : "0" (uOperator)
6a89b975ab84f4a47fb86fc27ba6c33c701720cfvboxsync : "ecx", "edx");
6a89b975ab84f4a47fb86fc27ba6c33c701720cfvboxsync# else
6a89b975ab84f4a47fb86fc27ba6c33c701720cfvboxsync __asm__ ("cpuid"
6a89b975ab84f4a47fb86fc27ba6c33c701720cfvboxsync : "=a" (xAX)
6a89b975ab84f4a47fb86fc27ba6c33c701720cfvboxsync : "0" (uOperator)
6a89b975ab84f4a47fb86fc27ba6c33c701720cfvboxsync : "edx", "ecx", "ebx");
6a89b975ab84f4a47fb86fc27ba6c33c701720cfvboxsync# endif
6a89b975ab84f4a47fb86fc27ba6c33c701720cfvboxsync
6a89b975ab84f4a47fb86fc27ba6c33c701720cfvboxsync# elif RT_INLINE_ASM_USES_INTRIN
6a89b975ab84f4a47fb86fc27ba6c33c701720cfvboxsync int aInfo[4];
6a89b975ab84f4a47fb86fc27ba6c33c701720cfvboxsync __cpuid(aInfo, uOperator);
0931358f459881bc01b54d3118e0fc1b9a43bdc3vboxsync xAX = aInfo[0];
6a89b975ab84f4a47fb86fc27ba6c33c701720cfvboxsync
6a89b975ab84f4a47fb86fc27ba6c33c701720cfvboxsync# else
6a89b975ab84f4a47fb86fc27ba6c33c701720cfvboxsync __asm
6a89b975ab84f4a47fb86fc27ba6c33c701720cfvboxsync {
6a89b975ab84f4a47fb86fc27ba6c33c701720cfvboxsync push ebx
6a89b975ab84f4a47fb86fc27ba6c33c701720cfvboxsync mov eax, [uOperator]
6a89b975ab84f4a47fb86fc27ba6c33c701720cfvboxsync cpuid
6a89b975ab84f4a47fb86fc27ba6c33c701720cfvboxsync mov [xAX], eax
6a89b975ab84f4a47fb86fc27ba6c33c701720cfvboxsync pop ebx
6a89b975ab84f4a47fb86fc27ba6c33c701720cfvboxsync }
6a89b975ab84f4a47fb86fc27ba6c33c701720cfvboxsync# endif
6a89b975ab84f4a47fb86fc27ba6c33c701720cfvboxsync return (uint32_t)xAX;
6a89b975ab84f4a47fb86fc27ba6c33c701720cfvboxsync}
6a89b975ab84f4a47fb86fc27ba6c33c701720cfvboxsync#endif
6a89b975ab84f4a47fb86fc27ba6c33c701720cfvboxsync
6a89b975ab84f4a47fb86fc27ba6c33c701720cfvboxsync
6a89b975ab84f4a47fb86fc27ba6c33c701720cfvboxsync/**
6a89b975ab84f4a47fb86fc27ba6c33c701720cfvboxsync * Performs the cpuid instruction returning ebx.
6a89b975ab84f4a47fb86fc27ba6c33c701720cfvboxsync *
6a89b975ab84f4a47fb86fc27ba6c33c701720cfvboxsync * @param uOperator CPUID operation (eax).
6a89b975ab84f4a47fb86fc27ba6c33c701720cfvboxsync * @returns EBX after cpuid operation.
6a89b975ab84f4a47fb86fc27ba6c33c701720cfvboxsync */
6a89b975ab84f4a47fb86fc27ba6c33c701720cfvboxsync#if RT_INLINE_ASM_EXTERNAL && !RT_INLINE_ASM_USES_INTRIN
6a89b975ab84f4a47fb86fc27ba6c33c701720cfvboxsyncDECLASM(uint32_t) ASMCpuId_EBX(uint32_t uOperator);
6a89b975ab84f4a47fb86fc27ba6c33c701720cfvboxsync#else
6a89b975ab84f4a47fb86fc27ba6c33c701720cfvboxsyncDECLINLINE(uint32_t) ASMCpuId_EBX(uint32_t uOperator)
6a89b975ab84f4a47fb86fc27ba6c33c701720cfvboxsync{
6a89b975ab84f4a47fb86fc27ba6c33c701720cfvboxsync RTCCUINTREG xBX;
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync# if RT_INLINE_ASM_GNU_STYLE
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync# ifdef RT_ARCH_AMD64
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync RTCCUINTREG uSpill;
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync __asm__ ("cpuid"
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync : "=a" (uSpill),
6a89b975ab84f4a47fb86fc27ba6c33c701720cfvboxsync "=b" (xBX)
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync : "0" (uOperator)
6a89b975ab84f4a47fb86fc27ba6c33c701720cfvboxsync : "rdx", "rcx");
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync# elif (defined(PIC) || defined(__PIC__)) && defined(__i386__)
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync __asm__ ("push %%ebx\n\t"
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync "cpuid\n\t"
6a89b975ab84f4a47fb86fc27ba6c33c701720cfvboxsync "mov %%ebx, %%edx\n\t"
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync "pop %%ebx\n\t"
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync : "=a" (uOperator),
6a89b975ab84f4a47fb86fc27ba6c33c701720cfvboxsync "=d" (xBX)
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync : "0" (uOperator)
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync : "ecx");
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync# else
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync __asm__ ("cpuid"
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync : "=a" (uOperator),
6a89b975ab84f4a47fb86fc27ba6c33c701720cfvboxsync "=b" (xBX)
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync : "0" (uOperator)
6a89b975ab84f4a47fb86fc27ba6c33c701720cfvboxsync : "edx", "ecx");
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync# endif
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync# elif RT_INLINE_ASM_USES_INTRIN
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync int aInfo[4];
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync __cpuid(aInfo, uOperator);
aede31badacc724e58bbfe5b7e48d4875bd70844vboxsync xBX = aInfo[1];
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync# else
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync __asm
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync {
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync push ebx
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync mov eax, [uOperator]
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync cpuid
6a89b975ab84f4a47fb86fc27ba6c33c701720cfvboxsync mov [xBX], ebx
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync pop ebx
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync }
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync# endif
6a89b975ab84f4a47fb86fc27ba6c33c701720cfvboxsync return (uint32_t)xBX;
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync}
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync#endif
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync/**
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync * Performs the cpuid instruction returning ecx.
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync *
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync * @param uOperator CPUID operation (eax).
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync * @returns ECX after cpuid operation.
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync */
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync#if RT_INLINE_ASM_EXTERNAL && !RT_INLINE_ASM_USES_INTRIN
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsyncDECLASM(uint32_t) ASMCpuId_ECX(uint32_t uOperator);
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync#else
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsyncDECLINLINE(uint32_t) ASMCpuId_ECX(uint32_t uOperator)
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync{
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync RTCCUINTREG xCX;
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync# if RT_INLINE_ASM_GNU_STYLE
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync# ifdef RT_ARCH_AMD64
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync RTCCUINTREG uSpill;
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync __asm__ ("cpuid"
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync : "=a" (uSpill),
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync "=c" (xCX)
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync : "0" (uOperator)
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync : "rbx", "rdx");
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync# elif (defined(PIC) || defined(__PIC__)) && defined(__i386__)
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync __asm__ ("push %%ebx\n\t"
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync "cpuid\n\t"
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync "pop %%ebx\n\t"
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync : "=a" (uOperator),
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync "=c" (xCX)
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync : "0" (uOperator)
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync : "edx");
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync# else
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync __asm__ ("cpuid"
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync : "=a" (uOperator),
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync "=c" (xCX)
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync : "0" (uOperator)
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync : "ebx", "edx");
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync# endif
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync# elif RT_INLINE_ASM_USES_INTRIN
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync int aInfo[4];
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync __cpuid(aInfo, uOperator);
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync xCX = aInfo[2];
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync# else
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync __asm
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync {
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync push ebx
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync mov eax, [uOperator]
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync cpuid
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync mov [xCX], ecx
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync pop ebx
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync }
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync# endif
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync return (uint32_t)xCX;
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync}
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync#endif
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync
6a89b975ab84f4a47fb86fc27ba6c33c701720cfvboxsync/**
6a89b975ab84f4a47fb86fc27ba6c33c701720cfvboxsync * Performs the cpuid instruction returning edx.
6a89b975ab84f4a47fb86fc27ba6c33c701720cfvboxsync *
6a89b975ab84f4a47fb86fc27ba6c33c701720cfvboxsync * @param uOperator CPUID operation (eax).
6a89b975ab84f4a47fb86fc27ba6c33c701720cfvboxsync * @returns EDX after cpuid operation.
6a89b975ab84f4a47fb86fc27ba6c33c701720cfvboxsync */
6a89b975ab84f4a47fb86fc27ba6c33c701720cfvboxsync#if RT_INLINE_ASM_EXTERNAL && !RT_INLINE_ASM_USES_INTRIN
6a89b975ab84f4a47fb86fc27ba6c33c701720cfvboxsyncDECLASM(uint32_t) ASMCpuId_EDX(uint32_t uOperator);
6a89b975ab84f4a47fb86fc27ba6c33c701720cfvboxsync#else
6a89b975ab84f4a47fb86fc27ba6c33c701720cfvboxsyncDECLINLINE(uint32_t) ASMCpuId_EDX(uint32_t uOperator)
6a89b975ab84f4a47fb86fc27ba6c33c701720cfvboxsync{
6a89b975ab84f4a47fb86fc27ba6c33c701720cfvboxsync RTCCUINTREG xDX;
6a89b975ab84f4a47fb86fc27ba6c33c701720cfvboxsync# if RT_INLINE_ASM_GNU_STYLE
6a89b975ab84f4a47fb86fc27ba6c33c701720cfvboxsync# ifdef RT_ARCH_AMD64
6a89b975ab84f4a47fb86fc27ba6c33c701720cfvboxsync RTCCUINTREG uSpill;
6a89b975ab84f4a47fb86fc27ba6c33c701720cfvboxsync __asm__ ("cpuid"
6a89b975ab84f4a47fb86fc27ba6c33c701720cfvboxsync : "=a" (uSpill),
6a89b975ab84f4a47fb86fc27ba6c33c701720cfvboxsync "=d" (xDX)
6a89b975ab84f4a47fb86fc27ba6c33c701720cfvboxsync : "0" (uOperator)
6a89b975ab84f4a47fb86fc27ba6c33c701720cfvboxsync : "rbx", "rcx");
6a89b975ab84f4a47fb86fc27ba6c33c701720cfvboxsync# elif (defined(PIC) || defined(__PIC__)) && defined(__i386__)
6a89b975ab84f4a47fb86fc27ba6c33c701720cfvboxsync __asm__ ("push %%ebx\n\t"
6a89b975ab84f4a47fb86fc27ba6c33c701720cfvboxsync "cpuid\n\t"
6a89b975ab84f4a47fb86fc27ba6c33c701720cfvboxsync "pop %%ebx\n\t"
6a89b975ab84f4a47fb86fc27ba6c33c701720cfvboxsync : "=a" (uOperator),
6a89b975ab84f4a47fb86fc27ba6c33c701720cfvboxsync "=d" (xDX)
6a89b975ab84f4a47fb86fc27ba6c33c701720cfvboxsync : "0" (uOperator)
6a89b975ab84f4a47fb86fc27ba6c33c701720cfvboxsync : "ecx");
6a89b975ab84f4a47fb86fc27ba6c33c701720cfvboxsync# else
6a89b975ab84f4a47fb86fc27ba6c33c701720cfvboxsync __asm__ ("cpuid"
6a89b975ab84f4a47fb86fc27ba6c33c701720cfvboxsync : "=a" (uOperator),
6a89b975ab84f4a47fb86fc27ba6c33c701720cfvboxsync "=d" (xDX)
6a89b975ab84f4a47fb86fc27ba6c33c701720cfvboxsync : "0" (uOperator)
6a89b975ab84f4a47fb86fc27ba6c33c701720cfvboxsync : "ebx", "ecx");
6a89b975ab84f4a47fb86fc27ba6c33c701720cfvboxsync# endif
6a89b975ab84f4a47fb86fc27ba6c33c701720cfvboxsync
6a89b975ab84f4a47fb86fc27ba6c33c701720cfvboxsync# elif RT_INLINE_ASM_USES_INTRIN
6a89b975ab84f4a47fb86fc27ba6c33c701720cfvboxsync int aInfo[4];
6a89b975ab84f4a47fb86fc27ba6c33c701720cfvboxsync __cpuid(aInfo, uOperator);
6a89b975ab84f4a47fb86fc27ba6c33c701720cfvboxsync xDX = aInfo[3];
6a89b975ab84f4a47fb86fc27ba6c33c701720cfvboxsync
6a89b975ab84f4a47fb86fc27ba6c33c701720cfvboxsync# else
6a89b975ab84f4a47fb86fc27ba6c33c701720cfvboxsync __asm
6a89b975ab84f4a47fb86fc27ba6c33c701720cfvboxsync {
6a89b975ab84f4a47fb86fc27ba6c33c701720cfvboxsync push ebx
6a89b975ab84f4a47fb86fc27ba6c33c701720cfvboxsync mov eax, [uOperator]
6a89b975ab84f4a47fb86fc27ba6c33c701720cfvboxsync cpuid
6a89b975ab84f4a47fb86fc27ba6c33c701720cfvboxsync mov [xDX], edx
6a89b975ab84f4a47fb86fc27ba6c33c701720cfvboxsync pop ebx
6a89b975ab84f4a47fb86fc27ba6c33c701720cfvboxsync }
6a89b975ab84f4a47fb86fc27ba6c33c701720cfvboxsync# endif
6a89b975ab84f4a47fb86fc27ba6c33c701720cfvboxsync return (uint32_t)xDX;
6a89b975ab84f4a47fb86fc27ba6c33c701720cfvboxsync}
6a89b975ab84f4a47fb86fc27ba6c33c701720cfvboxsync#endif
6a89b975ab84f4a47fb86fc27ba6c33c701720cfvboxsync
6a89b975ab84f4a47fb86fc27ba6c33c701720cfvboxsync
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync/**
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync * Checks if the current CPU supports CPUID.
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync *
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync * @returns true if CPUID is supported.
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync */
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsyncDECLINLINE(bool) ASMHasCpuId(void)
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync{
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync#ifdef RT_ARCH_AMD64
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync return true; /* ASSUME that all amd64 compatible CPUs have cpuid. */
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync#else /* !RT_ARCH_AMD64 */
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync bool fRet = false;
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync# if RT_INLINE_ASM_GNU_STYLE
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync uint32_t u1;
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync uint32_t u2;
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync __asm__ ("pushf\n\t"
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync "pop %1\n\t"
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync "mov %1, %2\n\t"
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync "xorl $0x200000, %1\n\t"
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync "push %1\n\t"
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync "popf\n\t"
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync "pushf\n\t"
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync "pop %1\n\t"
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync "cmpl %1, %2\n\t"
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync "setne %0\n\t"
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync "push %2\n\t"
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync "popf\n\t"
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync : "=m" (fRet), "=r" (u1), "=r" (u2));
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync# else
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync __asm
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync {
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync pushfd
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync pop eax
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync mov ebx, eax
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync xor eax, 0200000h
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync push eax
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync popfd
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync pushfd
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync pop eax
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync cmp eax, ebx
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync setne fRet
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync push ebx
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync popfd
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync }
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync# endif
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync return fRet;
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync#endif /* !RT_ARCH_AMD64 */
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync}
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync/**
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync * Gets the APIC ID of the current CPU.
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync *
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync * @returns the APIC ID.
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync */
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync#if RT_INLINE_ASM_EXTERNAL && !RT_INLINE_ASM_USES_INTRIN
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsyncDECLASM(uint8_t) ASMGetApicId(void);
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync#else
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsyncDECLINLINE(uint8_t) ASMGetApicId(void)
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync{
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync RTCCUINTREG xBX;
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync# if RT_INLINE_ASM_GNU_STYLE
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync# ifdef RT_ARCH_AMD64
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync RTCCUINTREG uSpill;
4d93fcdfb645b86163cfea77f687172295988d16vboxsync __asm__ __volatile__ ("cpuid"
4d93fcdfb645b86163cfea77f687172295988d16vboxsync : "=a" (uSpill),
4d93fcdfb645b86163cfea77f687172295988d16vboxsync "=b" (xBX)
4d93fcdfb645b86163cfea77f687172295988d16vboxsync : "0" (1)
4d93fcdfb645b86163cfea77f687172295988d16vboxsync : "rcx", "rdx");
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync# elif (defined(PIC) || defined(__PIC__)) && defined(__i386__)
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync RTCCUINTREG uSpill;
4d93fcdfb645b86163cfea77f687172295988d16vboxsync __asm__ __volatile__ ("mov %%ebx,%1\n\t"
4d93fcdfb645b86163cfea77f687172295988d16vboxsync "cpuid\n\t"
4d93fcdfb645b86163cfea77f687172295988d16vboxsync "xchgl %%ebx,%1\n\t"
4d93fcdfb645b86163cfea77f687172295988d16vboxsync : "=a" (uSpill),
a828fbe5454430a560bd0b69e6d1752ad4634c67vboxsync "=rm" (xBX)
4d93fcdfb645b86163cfea77f687172295988d16vboxsync : "0" (1)
4d93fcdfb645b86163cfea77f687172295988d16vboxsync : "ecx", "edx");
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync# else
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync RTCCUINTREG uSpill;
4d93fcdfb645b86163cfea77f687172295988d16vboxsync __asm__ __volatile__ ("cpuid"
4d93fcdfb645b86163cfea77f687172295988d16vboxsync : "=a" (uSpill),
4d93fcdfb645b86163cfea77f687172295988d16vboxsync "=b" (xBX)
4d93fcdfb645b86163cfea77f687172295988d16vboxsync : "0" (1)
4d93fcdfb645b86163cfea77f687172295988d16vboxsync : "ecx", "edx");
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync# endif
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync# elif RT_INLINE_ASM_USES_INTRIN
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync int aInfo[4];
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync __cpuid(aInfo, 1);
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync xBX = aInfo[1];
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync# else
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync __asm
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync {
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync push ebx
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync mov eax, 1
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync cpuid
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync mov [xBX], ebx
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync pop ebx
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync }
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync# endif
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync return (uint8_t)(xBX >> 24);
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync}
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync#endif
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync/**
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync * Tests if it a genuine Intel CPU based on the ASMCpuId(0) output.
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync *
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync * @returns true/false.
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync * @param uEBX EBX return from ASMCpuId(0)
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync * @param uECX ECX return from ASMCpuId(0)
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync * @param uEDX EDX return from ASMCpuId(0)
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync */
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsyncDECLINLINE(bool) ASMIsIntelCpuEx(uint32_t uEBX, uint32_t uECX, uint32_t uEDX)
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync{
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync return uEBX == UINT32_C(0x756e6547)
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync && uECX == UINT32_C(0x6c65746e)
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync && uEDX == UINT32_C(0x49656e69);
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync}
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync/**
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync * Tests if this is a genuine Intel CPU.
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync *
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync * @returns true/false.
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync * @remarks ASSUMES that cpuid is supported by the CPU.
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync */
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsyncDECLINLINE(bool) ASMIsIntelCpu(void)
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync{
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync uint32_t uEAX, uEBX, uECX, uEDX;
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync ASMCpuId(0, &uEAX, &uEBX, &uECX, &uEDX);
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync return ASMIsIntelCpuEx(uEBX, uECX, uEDX);
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync}
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync/**
a0a962c856e508933f3137cb0d583af5c206dc55vboxsync * Tests if it an authentic AMD CPU based on the ASMCpuId(0) output.
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync *
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync * @returns true/false.
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync * @param uEBX EBX return from ASMCpuId(0)
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync * @param uECX ECX return from ASMCpuId(0)
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync * @param uEDX EDX return from ASMCpuId(0)
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync */
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsyncDECLINLINE(bool) ASMIsAmdCpuEx(uint32_t uEBX, uint32_t uECX, uint32_t uEDX)
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync{
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync return uEBX == UINT32_C(0x68747541)
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync && uECX == UINT32_C(0x444d4163)
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync && uEDX == UINT32_C(0x69746e65);
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync}
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync/**
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync * Tests if this is an authentic AMD CPU.
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync *
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync * @returns true/false.
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync * @remarks ASSUMES that cpuid is supported by the CPU.
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync */
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsyncDECLINLINE(bool) ASMIsAmdCpu(void)
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync{
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync uint32_t uEAX, uEBX, uECX, uEDX;
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync ASMCpuId(0, &uEAX, &uEBX, &uECX, &uEDX);
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync return ASMIsAmdCpuEx(uEBX, uECX, uEDX);
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync}
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync
a0a962c856e508933f3137cb0d583af5c206dc55vboxsync/**
a0a962c856e508933f3137cb0d583af5c206dc55vboxsync * Tests if it a centaur hauling VIA CPU based on the ASMCpuId(0) output.
a0a962c856e508933f3137cb0d583af5c206dc55vboxsync *
a0a962c856e508933f3137cb0d583af5c206dc55vboxsync * @returns true/false.
a0a962c856e508933f3137cb0d583af5c206dc55vboxsync * @param uEBX EBX return from ASMCpuId(0).
a0a962c856e508933f3137cb0d583af5c206dc55vboxsync * @param uECX ECX return from ASMCpuId(0).
a0a962c856e508933f3137cb0d583af5c206dc55vboxsync * @param uEDX EDX return from ASMCpuId(0).
a0a962c856e508933f3137cb0d583af5c206dc55vboxsync */
a0a962c856e508933f3137cb0d583af5c206dc55vboxsyncDECLINLINE(bool) ASMIsViaCentaurCpuEx(uint32_t uEBX, uint32_t uECX, uint32_t uEDX)
a0a962c856e508933f3137cb0d583af5c206dc55vboxsync{
a0a962c856e508933f3137cb0d583af5c206dc55vboxsync return uEBX == UINT32_C(0x746e6543)
a0a962c856e508933f3137cb0d583af5c206dc55vboxsync && uECX == UINT32_C(0x736c7561)
a0a962c856e508933f3137cb0d583af5c206dc55vboxsync && uEDX == UINT32_C(0x48727561);
a0a962c856e508933f3137cb0d583af5c206dc55vboxsync}
a0a962c856e508933f3137cb0d583af5c206dc55vboxsync
a0a962c856e508933f3137cb0d583af5c206dc55vboxsync
a0a962c856e508933f3137cb0d583af5c206dc55vboxsync/**
a0a962c856e508933f3137cb0d583af5c206dc55vboxsync * Tests if this is a centaur hauling VIA CPU.
a0a962c856e508933f3137cb0d583af5c206dc55vboxsync *
a0a962c856e508933f3137cb0d583af5c206dc55vboxsync * @returns true/false.
a0a962c856e508933f3137cb0d583af5c206dc55vboxsync * @remarks ASSUMES that cpuid is supported by the CPU.
a0a962c856e508933f3137cb0d583af5c206dc55vboxsync */
a0a962c856e508933f3137cb0d583af5c206dc55vboxsyncDECLINLINE(bool) ASMIsViaCentaurCpu(void)
a0a962c856e508933f3137cb0d583af5c206dc55vboxsync{
a0a962c856e508933f3137cb0d583af5c206dc55vboxsync uint32_t uEAX, uEBX, uECX, uEDX;
a0a962c856e508933f3137cb0d583af5c206dc55vboxsync ASMCpuId(0, &uEAX, &uEBX, &uECX, &uEDX);
a0a962c856e508933f3137cb0d583af5c206dc55vboxsync return ASMIsAmdCpuEx(uEBX, uECX, uEDX);
a0a962c856e508933f3137cb0d583af5c206dc55vboxsync}
a0a962c856e508933f3137cb0d583af5c206dc55vboxsync
a0a962c856e508933f3137cb0d583af5c206dc55vboxsync
a0a962c856e508933f3137cb0d583af5c206dc55vboxsync/**
a0a962c856e508933f3137cb0d583af5c206dc55vboxsync * Checks whether ASMCpuId_EAX(0x00000000) indicates a valid range.
a0a962c856e508933f3137cb0d583af5c206dc55vboxsync *
a0a962c856e508933f3137cb0d583af5c206dc55vboxsync *
a0a962c856e508933f3137cb0d583af5c206dc55vboxsync * @returns true/false.
a0a962c856e508933f3137cb0d583af5c206dc55vboxsync * @param uEAX The EAX value of CPUID leaf 0x00000000.
a0a962c856e508933f3137cb0d583af5c206dc55vboxsync *
a0a962c856e508933f3137cb0d583af5c206dc55vboxsync * @note This only succeeds if there are at least two leaves in the range.
a0a962c856e508933f3137cb0d583af5c206dc55vboxsync * @remarks The upper range limit is just some half reasonable value we've
a0a962c856e508933f3137cb0d583af5c206dc55vboxsync * picked out of thin air.
a0a962c856e508933f3137cb0d583af5c206dc55vboxsync */
a0a962c856e508933f3137cb0d583af5c206dc55vboxsyncDECLINLINE(bool) ASMIsValidStdRange(uint32_t uEAX)
a0a962c856e508933f3137cb0d583af5c206dc55vboxsync{
a0a962c856e508933f3137cb0d583af5c206dc55vboxsync return uEAX >= UINT32_C(0x00000001) && uEAX <= UINT32_C(0x000fffff);
a0a962c856e508933f3137cb0d583af5c206dc55vboxsync}
a0a962c856e508933f3137cb0d583af5c206dc55vboxsync
a0a962c856e508933f3137cb0d583af5c206dc55vboxsync
a0a962c856e508933f3137cb0d583af5c206dc55vboxsync/**
a0a962c856e508933f3137cb0d583af5c206dc55vboxsync * Checks whether ASMCpuId_EAX(0x80000000) indicates a valid range.
a0a962c856e508933f3137cb0d583af5c206dc55vboxsync *
a0a962c856e508933f3137cb0d583af5c206dc55vboxsync * This only succeeds if there are at least two leaves in the range.
a0a962c856e508933f3137cb0d583af5c206dc55vboxsync *
a0a962c856e508933f3137cb0d583af5c206dc55vboxsync * @returns true/false.
a0a962c856e508933f3137cb0d583af5c206dc55vboxsync * @param uEAX The EAX value of CPUID leaf 0x80000000.
a0a962c856e508933f3137cb0d583af5c206dc55vboxsync *
a0a962c856e508933f3137cb0d583af5c206dc55vboxsync * @note This only succeeds if there are at least two leaves in the range.
a0a962c856e508933f3137cb0d583af5c206dc55vboxsync * @remarks The upper range limit is just some half reasonable value we've
a0a962c856e508933f3137cb0d583af5c206dc55vboxsync * picked out of thin air.
a0a962c856e508933f3137cb0d583af5c206dc55vboxsync */
a0a962c856e508933f3137cb0d583af5c206dc55vboxsyncDECLINLINE(bool) ASMIsValidExtRange(uint32_t uEAX)
a0a962c856e508933f3137cb0d583af5c206dc55vboxsync{
a0a962c856e508933f3137cb0d583af5c206dc55vboxsync return uEAX >= UINT32_C(0x80000001) && uEAX <= UINT32_C(0x800fffff);
a0a962c856e508933f3137cb0d583af5c206dc55vboxsync}
a0a962c856e508933f3137cb0d583af5c206dc55vboxsync
a0a962c856e508933f3137cb0d583af5c206dc55vboxsync
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync/**
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync * Extracts the CPU family from ASMCpuId(1) or ASMCpuId(0x80000001)
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync *
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync * @returns Family.
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync * @param uEAX EAX return from ASMCpuId(1) or ASMCpuId(0x80000001).
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync */
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsyncDECLINLINE(uint32_t) ASMGetCpuFamily(uint32_t uEAX)
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync{
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync return ((uEAX >> 8) & 0xf) == 0xf
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync ? ((uEAX >> 20) & 0x7f) + 0xf
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync : ((uEAX >> 8) & 0xf);
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync}
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync/**
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync * Extracts the CPU model from ASMCpuId(1) or ASMCpuId(0x80000001), Intel variant.
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync *
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync * @returns Model.
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync * @param uEAX EAX from ASMCpuId(1) or ASMCpuId(0x80000001).
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync */
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsyncDECLINLINE(uint32_t) ASMGetCpuModelIntel(uint32_t uEAX)
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync{
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync return ((uEAX >> 8) & 0xf) == 0xf || (((uEAX >> 8) & 0xf) == 0x6) /* family! */
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync ? ((uEAX >> 4) & 0xf) | ((uEAX >> 12) & 0xf0)
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync : ((uEAX >> 4) & 0xf);
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync}
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync/**
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync * Extracts the CPU model from ASMCpuId(1) or ASMCpuId(0x80000001), AMD variant.
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync *
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync * @returns Model.
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync * @param uEAX EAX from ASMCpuId(1) or ASMCpuId(0x80000001).
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync */
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsyncDECLINLINE(uint32_t) ASMGetCpuModelAMD(uint32_t uEAX)
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync{
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync return ((uEAX >> 8) & 0xf) == 0xf
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync ? ((uEAX >> 4) & 0xf) | ((uEAX >> 12) & 0xf0)
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync : ((uEAX >> 4) & 0xf);
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync}
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync/**
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync * Extracts the CPU model from ASMCpuId(1) or ASMCpuId(0x80000001)
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync *
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync * @returns Model.
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync * @param uEAX EAX from ASMCpuId(1) or ASMCpuId(0x80000001).
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync * @param fIntel Whether it's an intel CPU. Use ASMIsIntelCpuEx() or ASMIsIntelCpu().
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync */
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsyncDECLINLINE(uint32_t) ASMGetCpuModel(uint32_t uEAX, bool fIntel)
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync{
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync return ((uEAX >> 8) & 0xf) == 0xf || (((uEAX >> 8) & 0xf) == 0x6 && fIntel) /* family! */
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync ? ((uEAX >> 4) & 0xf) | ((uEAX >> 12) & 0xf0)
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync : ((uEAX >> 4) & 0xf);
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync}
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync/**
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync * Extracts the CPU stepping from ASMCpuId(1) or ASMCpuId(0x80000001)
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync *
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync * @returns Model.
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync * @param uEAX EAX from ASMCpuId(1) or ASMCpuId(0x80000001).
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync */
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsyncDECLINLINE(uint32_t) ASMGetCpuStepping(uint32_t uEAX)
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync{
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync return uEAX & 0xf;
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync}
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync/**
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync * Get cr0.
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync * @returns cr0.
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync */
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync#if RT_INLINE_ASM_EXTERNAL && !RT_INLINE_ASM_USES_INTRIN
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsyncDECLASM(RTCCUINTREG) ASMGetCR0(void);
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync#else
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsyncDECLINLINE(RTCCUINTREG) ASMGetCR0(void)
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync{
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync RTCCUINTREG uCR0;
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync# if RT_INLINE_ASM_USES_INTRIN
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync uCR0 = __readcr0();
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync# elif RT_INLINE_ASM_GNU_STYLE
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync# ifdef RT_ARCH_AMD64
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync __asm__ __volatile__("movq %%cr0, %0\t\n" : "=r" (uCR0));
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync# else
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync __asm__ __volatile__("movl %%cr0, %0\t\n" : "=r" (uCR0));
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync# endif
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync# else
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync __asm
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync {
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync# ifdef RT_ARCH_AMD64
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync mov rax, cr0
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync mov [uCR0], rax
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync# else
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync mov eax, cr0
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync mov [uCR0], eax
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync# endif
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync }
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync# endif
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync return uCR0;
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync}
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync#endif
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync/**
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync * Sets the CR0 register.
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync * @param uCR0 The new CR0 value.
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync */
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync#if RT_INLINE_ASM_EXTERNAL && !RT_INLINE_ASM_USES_INTRIN
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsyncDECLASM(void) ASMSetCR0(RTCCUINTREG uCR0);
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync#else
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsyncDECLINLINE(void) ASMSetCR0(RTCCUINTREG uCR0)
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync{
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync# if RT_INLINE_ASM_USES_INTRIN
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync __writecr0(uCR0);
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync# elif RT_INLINE_ASM_GNU_STYLE
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync# ifdef RT_ARCH_AMD64
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync __asm__ __volatile__("movq %0, %%cr0\n\t" :: "r" (uCR0));
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync# else
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync __asm__ __volatile__("movl %0, %%cr0\n\t" :: "r" (uCR0));
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync# endif
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync# else
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync __asm
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync {
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync# ifdef RT_ARCH_AMD64
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync mov rax, [uCR0]
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync mov cr0, rax
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync# else
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync mov eax, [uCR0]
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync mov cr0, eax
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync# endif
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync }
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync# endif
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync}
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync#endif
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync/**
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync * Get cr2.
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync * @returns cr2.
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync */
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync#if RT_INLINE_ASM_EXTERNAL && !RT_INLINE_ASM_USES_INTRIN
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsyncDECLASM(RTCCUINTREG) ASMGetCR2(void);
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync#else
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsyncDECLINLINE(RTCCUINTREG) ASMGetCR2(void)
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync{
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync RTCCUINTREG uCR2;
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync# if RT_INLINE_ASM_USES_INTRIN
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync uCR2 = __readcr2();
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync# elif RT_INLINE_ASM_GNU_STYLE
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync# ifdef RT_ARCH_AMD64
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync __asm__ __volatile__("movq %%cr2, %0\t\n" : "=r" (uCR2));
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync# else
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync __asm__ __volatile__("movl %%cr2, %0\t\n" : "=r" (uCR2));
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync# endif
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync# else
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync __asm
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync {
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync# ifdef RT_ARCH_AMD64
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync mov rax, cr2
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync mov [uCR2], rax
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync# else
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync mov eax, cr2
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync mov [uCR2], eax
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync# endif
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync }
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync# endif
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync return uCR2;
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync}
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync#endif
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync/**
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync * Sets the CR2 register.
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync * @param uCR2 The new CR0 value.
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync */
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync#if RT_INLINE_ASM_EXTERNAL
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsyncDECLASM(void) ASMSetCR2(RTCCUINTREG uCR2);
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync#else
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsyncDECLINLINE(void) ASMSetCR2(RTCCUINTREG uCR2)
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync{
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync# if RT_INLINE_ASM_GNU_STYLE
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync# ifdef RT_ARCH_AMD64
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync __asm__ __volatile__("movq %0, %%cr2\n\t" :: "r" (uCR2));
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync# else
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync __asm__ __volatile__("movl %0, %%cr2\n\t" :: "r" (uCR2));
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync# endif
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync# else
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync __asm
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync {
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync# ifdef RT_ARCH_AMD64
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync mov rax, [uCR2]
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync mov cr2, rax
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync# else
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync mov eax, [uCR2]
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync mov cr2, eax
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync# endif
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync }
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync# endif
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync}
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync#endif
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync/**
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync * Get cr3.
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync * @returns cr3.
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync */
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync#if RT_INLINE_ASM_EXTERNAL && !RT_INLINE_ASM_USES_INTRIN
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsyncDECLASM(RTCCUINTREG) ASMGetCR3(void);
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync#else
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsyncDECLINLINE(RTCCUINTREG) ASMGetCR3(void)
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync{
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync RTCCUINTREG uCR3;
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync# if RT_INLINE_ASM_USES_INTRIN
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync uCR3 = __readcr3();
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync# elif RT_INLINE_ASM_GNU_STYLE
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync# ifdef RT_ARCH_AMD64
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync __asm__ __volatile__("movq %%cr3, %0\t\n" : "=r" (uCR3));
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync# else
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync __asm__ __volatile__("movl %%cr3, %0\t\n" : "=r" (uCR3));
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync# endif
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync# else
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync __asm
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync {
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync# ifdef RT_ARCH_AMD64
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync mov rax, cr3
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync mov [uCR3], rax
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync# else
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync mov eax, cr3
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync mov [uCR3], eax
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync# endif
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync }
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync# endif
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync return uCR3;
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync}
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync#endif
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync/**
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync * Sets the CR3 register.
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync *
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync * @param uCR3 New CR3 value.
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync */
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync#if RT_INLINE_ASM_EXTERNAL && !RT_INLINE_ASM_USES_INTRIN
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsyncDECLASM(void) ASMSetCR3(RTCCUINTREG uCR3);
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync#else
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsyncDECLINLINE(void) ASMSetCR3(RTCCUINTREG uCR3)
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync{
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync# if RT_INLINE_ASM_USES_INTRIN
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync __writecr3(uCR3);
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync# elif RT_INLINE_ASM_GNU_STYLE
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync# ifdef RT_ARCH_AMD64
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync __asm__ __volatile__("movq %0, %%cr3\n\t" : : "r" (uCR3));
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync# else
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync __asm__ __volatile__("movl %0, %%cr3\n\t" : : "r" (uCR3));
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync# endif
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync# else
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync __asm
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync {
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync# ifdef RT_ARCH_AMD64
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync mov rax, [uCR3]
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync mov cr3, rax
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync# else
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync mov eax, [uCR3]
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync mov cr3, eax
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync# endif
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync }
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync# endif
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync}
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync#endif
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync/**
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync * Reloads the CR3 register.
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync */
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync#if RT_INLINE_ASM_EXTERNAL && !RT_INLINE_ASM_USES_INTRIN
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsyncDECLASM(void) ASMReloadCR3(void);
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync#else
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsyncDECLINLINE(void) ASMReloadCR3(void)
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync{
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync# if RT_INLINE_ASM_USES_INTRIN
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync __writecr3(__readcr3());
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync# elif RT_INLINE_ASM_GNU_STYLE
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync RTCCUINTREG u;
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync# ifdef RT_ARCH_AMD64
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync __asm__ __volatile__("movq %%cr3, %0\n\t"
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync "movq %0, %%cr3\n\t"
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync : "=r" (u));
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync# else
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync __asm__ __volatile__("movl %%cr3, %0\n\t"
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync "movl %0, %%cr3\n\t"
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync : "=r" (u));
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync# endif
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync# else
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync __asm
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync {
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync# ifdef RT_ARCH_AMD64
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync mov rax, cr3
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync mov cr3, rax
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync# else
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync mov eax, cr3
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync mov cr3, eax
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync# endif
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync }
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync# endif
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync}
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync#endif
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync/**
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync * Get cr4.
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync * @returns cr4.
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync */
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync#if RT_INLINE_ASM_EXTERNAL && !RT_INLINE_ASM_USES_INTRIN
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsyncDECLASM(RTCCUINTREG) ASMGetCR4(void);
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync#else
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsyncDECLINLINE(RTCCUINTREG) ASMGetCR4(void)
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync{
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync RTCCUINTREG uCR4;
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync# if RT_INLINE_ASM_USES_INTRIN
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync uCR4 = __readcr4();
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync# elif RT_INLINE_ASM_GNU_STYLE
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync# ifdef RT_ARCH_AMD64
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync __asm__ __volatile__("movq %%cr4, %0\t\n" : "=r" (uCR4));
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync# else
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync __asm__ __volatile__("movl %%cr4, %0\t\n" : "=r" (uCR4));
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync# endif
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync# else
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync __asm
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync {
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync# ifdef RT_ARCH_AMD64
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync mov rax, cr4
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync mov [uCR4], rax
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync# else
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync push eax /* just in case */
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync /*mov eax, cr4*/
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync _emit 0x0f
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync _emit 0x20
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync _emit 0xe0
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync mov [uCR4], eax
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync pop eax
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync# endif
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync }
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync# endif
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync return uCR4;
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync}
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync#endif
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync/**
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync * Sets the CR4 register.
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync *
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync * @param uCR4 New CR4 value.
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync */
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync#if RT_INLINE_ASM_EXTERNAL && !RT_INLINE_ASM_USES_INTRIN
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsyncDECLASM(void) ASMSetCR4(RTCCUINTREG uCR4);
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync#else
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsyncDECLINLINE(void) ASMSetCR4(RTCCUINTREG uCR4)
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync{
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync# if RT_INLINE_ASM_USES_INTRIN
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync __writecr4(uCR4);
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync# elif RT_INLINE_ASM_GNU_STYLE
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync# ifdef RT_ARCH_AMD64
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync __asm__ __volatile__("movq %0, %%cr4\n\t" : : "r" (uCR4));
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync# else
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync __asm__ __volatile__("movl %0, %%cr4\n\t" : : "r" (uCR4));
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync# endif
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync# else
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync __asm
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync {
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync# ifdef RT_ARCH_AMD64
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync mov rax, [uCR4]
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync mov cr4, rax
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync# else
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync mov eax, [uCR4]
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync _emit 0x0F
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync _emit 0x22
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync _emit 0xE0 /* mov cr4, eax */
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync# endif
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync }
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync# endif
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync}
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync#endif
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync/**
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync * Get cr8.
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync * @returns cr8.
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync * @remark The lock prefix hack for access from non-64-bit modes is NOT used and 0 is returned.
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync */
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync#if RT_INLINE_ASM_EXTERNAL && !RT_INLINE_ASM_USES_INTRIN
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsyncDECLASM(RTCCUINTREG) ASMGetCR8(void);
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync#else
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsyncDECLINLINE(RTCCUINTREG) ASMGetCR8(void)
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync{
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync# ifdef RT_ARCH_AMD64
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync RTCCUINTREG uCR8;
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync# if RT_INLINE_ASM_USES_INTRIN
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync uCR8 = __readcr8();
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync# elif RT_INLINE_ASM_GNU_STYLE
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync __asm__ __volatile__("movq %%cr8, %0\t\n" : "=r" (uCR8));
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync# else
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync __asm
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync {
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync mov rax, cr8
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync mov [uCR8], rax
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync }
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync# endif
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync return uCR8;
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync# else /* !RT_ARCH_AMD64 */
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync return 0;
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync# endif /* !RT_ARCH_AMD64 */
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync}
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync#endif
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync
7a33455519f76382026197f01d5cac3f6a98ed51vboxsync/**
7a33455519f76382026197f01d5cac3f6a98ed51vboxsync * Get XCR0 (eXtended feature Control Register 0).
7a33455519f76382026197f01d5cac3f6a98ed51vboxsync * @returns xcr0.
7a33455519f76382026197f01d5cac3f6a98ed51vboxsync */
7a33455519f76382026197f01d5cac3f6a98ed51vboxsyncDECLASM(uint64_t) ASMGetXcr0(void);
7a33455519f76382026197f01d5cac3f6a98ed51vboxsync
7a33455519f76382026197f01d5cac3f6a98ed51vboxsync/**
7a33455519f76382026197f01d5cac3f6a98ed51vboxsync * Sets the XCR0 register.
7a33455519f76382026197f01d5cac3f6a98ed51vboxsync * @param uXcr0 The new XCR0 value.
7a33455519f76382026197f01d5cac3f6a98ed51vboxsync */
7a33455519f76382026197f01d5cac3f6a98ed51vboxsyncDECLASM(void) ASMSetXcr0(uint64_t uXcr0);
7a33455519f76382026197f01d5cac3f6a98ed51vboxsync
d16f75bad381547b34a1f315da059b782f4c21d3vboxsync/**
d16f75bad381547b34a1f315da059b782f4c21d3vboxsync * Save extended CPU state.
d16f75bad381547b34a1f315da059b782f4c21d3vboxsync * @param pXStateArea Where to save the state.
d16f75bad381547b34a1f315da059b782f4c21d3vboxsync * @param fComponents Which state components to save.
d16f75bad381547b34a1f315da059b782f4c21d3vboxsync */
d16f75bad381547b34a1f315da059b782f4c21d3vboxsyncDECLASM(void) ASMXSave(PX86XSAVEAREA pXStateArea, uint64_t fComponents);
d16f75bad381547b34a1f315da059b782f4c21d3vboxsync
d16f75bad381547b34a1f315da059b782f4c21d3vboxsync/**
d16f75bad381547b34a1f315da059b782f4c21d3vboxsync * Loads extended CPU state.
d16f75bad381547b34a1f315da059b782f4c21d3vboxsync * @param pXStateArea Where to load the state from.
d16f75bad381547b34a1f315da059b782f4c21d3vboxsync * @param fComponents Which state components to load.
d16f75bad381547b34a1f315da059b782f4c21d3vboxsync */
d16f75bad381547b34a1f315da059b782f4c21d3vboxsyncDECLASM(void) ASMXLoad(PCX86XSAVEAREA pXStateArea, uint64_t fComponents);
d16f75bad381547b34a1f315da059b782f4c21d3vboxsync
7a33455519f76382026197f01d5cac3f6a98ed51vboxsync
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync/**
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync * Enables interrupts (EFLAGS.IF).
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync */
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync#if RT_INLINE_ASM_EXTERNAL && !RT_INLINE_ASM_USES_INTRIN
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsyncDECLASM(void) ASMIntEnable(void);
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync#else
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsyncDECLINLINE(void) ASMIntEnable(void)
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync{
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync# if RT_INLINE_ASM_GNU_STYLE
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync __asm("sti\n");
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync# elif RT_INLINE_ASM_USES_INTRIN
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync _enable();
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync# else
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync __asm sti
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync# endif
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync}
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync#endif
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync/**
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync * Disables interrupts (!EFLAGS.IF).
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync */
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync#if RT_INLINE_ASM_EXTERNAL && !RT_INLINE_ASM_USES_INTRIN
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsyncDECLASM(void) ASMIntDisable(void);
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync#else
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsyncDECLINLINE(void) ASMIntDisable(void)
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync{
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync# if RT_INLINE_ASM_GNU_STYLE
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync __asm("cli\n");
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync# elif RT_INLINE_ASM_USES_INTRIN
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync _disable();
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync# else
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync __asm cli
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync# endif
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync}
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync#endif
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync/**
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync * Disables interrupts and returns previous xFLAGS.
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync */
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync#if RT_INLINE_ASM_EXTERNAL && !RT_INLINE_ASM_USES_INTRIN
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsyncDECLASM(RTCCUINTREG) ASMIntDisableFlags(void);
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync#else
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsyncDECLINLINE(RTCCUINTREG) ASMIntDisableFlags(void)
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync{
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync RTCCUINTREG xFlags;
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync# if RT_INLINE_ASM_GNU_STYLE
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync# ifdef RT_ARCH_AMD64
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync __asm__ __volatile__("pushfq\n\t"
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync "cli\n\t"
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync "popq %0\n\t"
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync : "=r" (xFlags));
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync# else
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync __asm__ __volatile__("pushfl\n\t"
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync "cli\n\t"
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync "popl %0\n\t"
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync : "=r" (xFlags));
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync# endif
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync# elif RT_INLINE_ASM_USES_INTRIN && !defined(RT_ARCH_X86)
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync xFlags = ASMGetFlags();
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync _disable();
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync# else
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync __asm {
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync pushfd
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync cli
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync pop [xFlags]
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync }
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync# endif
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync return xFlags;
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync}
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync#endif
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync/**
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync * Are interrupts enabled?
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync *
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync * @returns true / false.
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync */
f1967d85ca97034356c41befdb31d67c042a2e14vboxsyncDECLINLINE(bool) ASMIntAreEnabled(void)
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync{
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync RTCCUINTREG uFlags = ASMGetFlags();
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync return uFlags & 0x200 /* X86_EFL_IF */ ? true : false;
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync}
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync/**
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync * Halts the CPU until interrupted.
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync */
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync#if RT_INLINE_ASM_EXTERNAL
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsyncDECLASM(void) ASMHalt(void);
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync#else
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsyncDECLINLINE(void) ASMHalt(void)
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync{
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync# if RT_INLINE_ASM_GNU_STYLE
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync __asm__ __volatile__("hlt\n\t");
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync# else
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync __asm {
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync hlt
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync }
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync# endif
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync}
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync#endif
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync/**
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync * Reads a machine specific register.
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync *
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync * @returns Register content.
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync * @param uRegister Register to read.
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync */
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync#if RT_INLINE_ASM_EXTERNAL && !RT_INLINE_ASM_USES_INTRIN
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsyncDECLASM(uint64_t) ASMRdMsr(uint32_t uRegister);
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync#else
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsyncDECLINLINE(uint64_t) ASMRdMsr(uint32_t uRegister)
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync{
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync RTUINT64U u;
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync# if RT_INLINE_ASM_GNU_STYLE
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync __asm__ __volatile__("rdmsr\n\t"
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync : "=a" (u.s.Lo),
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync "=d" (u.s.Hi)
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync : "c" (uRegister));
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync# elif RT_INLINE_ASM_USES_INTRIN
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync u.u = __readmsr(uRegister);
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync# else
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync __asm
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync {
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync mov ecx, [uRegister]
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync rdmsr
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync mov [u.s.Lo], eax
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync mov [u.s.Hi], edx
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync }
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync# endif
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync return u.u;
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync}
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync#endif
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync/**
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync * Writes a machine specific register.
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync *
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync * @returns Register content.
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync * @param uRegister Register to write to.
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync * @param u64Val Value to write.
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync */
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync#if RT_INLINE_ASM_EXTERNAL && !RT_INLINE_ASM_USES_INTRIN
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsyncDECLASM(void) ASMWrMsr(uint32_t uRegister, uint64_t u64Val);
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync#else
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsyncDECLINLINE(void) ASMWrMsr(uint32_t uRegister, uint64_t u64Val)
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync{
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync RTUINT64U u;
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync u.u = u64Val;
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync# if RT_INLINE_ASM_GNU_STYLE
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync __asm__ __volatile__("wrmsr\n\t"
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync ::"a" (u.s.Lo),
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync "d" (u.s.Hi),
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync "c" (uRegister));
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync# elif RT_INLINE_ASM_USES_INTRIN
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync __writemsr(uRegister, u.u);
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync# else
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync __asm
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync {
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync mov ecx, [uRegister]
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync mov edx, [u.s.Hi]
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync mov eax, [u.s.Lo]
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync wrmsr
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync }
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync# endif
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync}
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync#endif
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync
9c5875d62215e6a088a86658e5553af6b8401f1cvboxsync/**
9c5875d62215e6a088a86658e5553af6b8401f1cvboxsync * Reads a machine specific register, extended version (for AMD).
9c5875d62215e6a088a86658e5553af6b8401f1cvboxsync *
9c5875d62215e6a088a86658e5553af6b8401f1cvboxsync * @returns Register content.
9c5875d62215e6a088a86658e5553af6b8401f1cvboxsync * @param uRegister Register to read.
9c5875d62215e6a088a86658e5553af6b8401f1cvboxsync * @param uXDI RDI/EDI value.
9c5875d62215e6a088a86658e5553af6b8401f1cvboxsync */
9c5875d62215e6a088a86658e5553af6b8401f1cvboxsync#if RT_INLINE_ASM_EXTERNAL
9c5875d62215e6a088a86658e5553af6b8401f1cvboxsyncDECLASM(uint64_t) ASMRdMsrEx(uint32_t uRegister, RTCCUINTREG uXDI);
9c5875d62215e6a088a86658e5553af6b8401f1cvboxsync#else
9c5875d62215e6a088a86658e5553af6b8401f1cvboxsyncDECLINLINE(uint64_t) ASMRdMsrEx(uint32_t uRegister, RTCCUINTREG uXDI)
9c5875d62215e6a088a86658e5553af6b8401f1cvboxsync{
9c5875d62215e6a088a86658e5553af6b8401f1cvboxsync RTUINT64U u;
9c5875d62215e6a088a86658e5553af6b8401f1cvboxsync# if RT_INLINE_ASM_GNU_STYLE
9c5875d62215e6a088a86658e5553af6b8401f1cvboxsync __asm__ __volatile__("rdmsr\n\t"
9c5875d62215e6a088a86658e5553af6b8401f1cvboxsync : "=a" (u.s.Lo),
9c5875d62215e6a088a86658e5553af6b8401f1cvboxsync "=d" (u.s.Hi)
9c5875d62215e6a088a86658e5553af6b8401f1cvboxsync : "c" (uRegister),
9c5875d62215e6a088a86658e5553af6b8401f1cvboxsync "D" (uXDI));
9c5875d62215e6a088a86658e5553af6b8401f1cvboxsync
9c5875d62215e6a088a86658e5553af6b8401f1cvboxsync# else
9c5875d62215e6a088a86658e5553af6b8401f1cvboxsync __asm
9c5875d62215e6a088a86658e5553af6b8401f1cvboxsync {
9c5875d62215e6a088a86658e5553af6b8401f1cvboxsync mov ecx, [uRegister]
9c5875d62215e6a088a86658e5553af6b8401f1cvboxsync xchg edi, [uXDI]
9c5875d62215e6a088a86658e5553af6b8401f1cvboxsync rdmsr
9c5875d62215e6a088a86658e5553af6b8401f1cvboxsync mov [u.s.Lo], eax
9c5875d62215e6a088a86658e5553af6b8401f1cvboxsync mov [u.s.Hi], edx
9c5875d62215e6a088a86658e5553af6b8401f1cvboxsync xchg edi, [uXDI]
9c5875d62215e6a088a86658e5553af6b8401f1cvboxsync }
9c5875d62215e6a088a86658e5553af6b8401f1cvboxsync# endif
9c5875d62215e6a088a86658e5553af6b8401f1cvboxsync
9c5875d62215e6a088a86658e5553af6b8401f1cvboxsync return u.u;
9c5875d62215e6a088a86658e5553af6b8401f1cvboxsync}
9c5875d62215e6a088a86658e5553af6b8401f1cvboxsync#endif
9c5875d62215e6a088a86658e5553af6b8401f1cvboxsync
9c5875d62215e6a088a86658e5553af6b8401f1cvboxsync
9c5875d62215e6a088a86658e5553af6b8401f1cvboxsync/**
9c5875d62215e6a088a86658e5553af6b8401f1cvboxsync * Writes a machine specific register, extended version (for AMD).
9c5875d62215e6a088a86658e5553af6b8401f1cvboxsync *
9c5875d62215e6a088a86658e5553af6b8401f1cvboxsync * @returns Register content.
9c5875d62215e6a088a86658e5553af6b8401f1cvboxsync * @param uRegister Register to write to.
9c5875d62215e6a088a86658e5553af6b8401f1cvboxsync * @param uXDI RDI/EDI value.
9c5875d62215e6a088a86658e5553af6b8401f1cvboxsync * @param u64Val Value to write.
9c5875d62215e6a088a86658e5553af6b8401f1cvboxsync */
9c5875d62215e6a088a86658e5553af6b8401f1cvboxsync#if RT_INLINE_ASM_EXTERNAL
9c5875d62215e6a088a86658e5553af6b8401f1cvboxsyncDECLASM(void) ASMWrMsrEx(uint32_t uRegister, RTCCUINTREG uXDI, uint64_t u64Val);
9c5875d62215e6a088a86658e5553af6b8401f1cvboxsync#else
9c5875d62215e6a088a86658e5553af6b8401f1cvboxsyncDECLINLINE(void) ASMWrMsrEx(uint32_t uRegister, RTCCUINTREG uXDI, uint64_t u64Val)
9c5875d62215e6a088a86658e5553af6b8401f1cvboxsync{
9c5875d62215e6a088a86658e5553af6b8401f1cvboxsync RTUINT64U u;
9c5875d62215e6a088a86658e5553af6b8401f1cvboxsync
9c5875d62215e6a088a86658e5553af6b8401f1cvboxsync u.u = u64Val;
9c5875d62215e6a088a86658e5553af6b8401f1cvboxsync# if RT_INLINE_ASM_GNU_STYLE
9c5875d62215e6a088a86658e5553af6b8401f1cvboxsync __asm__ __volatile__("wrmsr\n\t"
9c5875d62215e6a088a86658e5553af6b8401f1cvboxsync ::"a" (u.s.Lo),
9c5875d62215e6a088a86658e5553af6b8401f1cvboxsync "d" (u.s.Hi),
9c5875d62215e6a088a86658e5553af6b8401f1cvboxsync "c" (uRegister),
9c5875d62215e6a088a86658e5553af6b8401f1cvboxsync "D" (uXDI));
9c5875d62215e6a088a86658e5553af6b8401f1cvboxsync
9c5875d62215e6a088a86658e5553af6b8401f1cvboxsync# else
9c5875d62215e6a088a86658e5553af6b8401f1cvboxsync __asm
9c5875d62215e6a088a86658e5553af6b8401f1cvboxsync {
9c5875d62215e6a088a86658e5553af6b8401f1cvboxsync mov ecx, [uRegister]
9c5875d62215e6a088a86658e5553af6b8401f1cvboxsync xchg edi, [uXDI]
9c5875d62215e6a088a86658e5553af6b8401f1cvboxsync mov edx, [u.s.Hi]
9c5875d62215e6a088a86658e5553af6b8401f1cvboxsync mov eax, [u.s.Lo]
9c5875d62215e6a088a86658e5553af6b8401f1cvboxsync wrmsr
9c5875d62215e6a088a86658e5553af6b8401f1cvboxsync xchg edi, [uXDI]
9c5875d62215e6a088a86658e5553af6b8401f1cvboxsync }
9c5875d62215e6a088a86658e5553af6b8401f1cvboxsync# endif
9c5875d62215e6a088a86658e5553af6b8401f1cvboxsync}
9c5875d62215e6a088a86658e5553af6b8401f1cvboxsync#endif
9c5875d62215e6a088a86658e5553af6b8401f1cvboxsync
9c5875d62215e6a088a86658e5553af6b8401f1cvboxsync
9c5875d62215e6a088a86658e5553af6b8401f1cvboxsync
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync/**
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync * Reads low part of a machine specific register.
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync *
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync * @returns Register content.
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync * @param uRegister Register to read.
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync */
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync#if RT_INLINE_ASM_EXTERNAL && !RT_INLINE_ASM_USES_INTRIN
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsyncDECLASM(uint32_t) ASMRdMsr_Low(uint32_t uRegister);
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync#else
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsyncDECLINLINE(uint32_t) ASMRdMsr_Low(uint32_t uRegister)
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync{
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync uint32_t u32;
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync# if RT_INLINE_ASM_GNU_STYLE
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync __asm__ __volatile__("rdmsr\n\t"
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync : "=a" (u32)
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync : "c" (uRegister)
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync : "edx");
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync# elif RT_INLINE_ASM_USES_INTRIN
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync u32 = (uint32_t)__readmsr(uRegister);
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync#else
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync __asm
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync {
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync mov ecx, [uRegister]
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync rdmsr
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync mov [u32], eax
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync }
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync# endif
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync return u32;
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync}
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync#endif
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync/**
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync * Reads high part of a machine specific register.
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync *
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync * @returns Register content.
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync * @param uRegister Register to read.
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync */
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync#if RT_INLINE_ASM_EXTERNAL && !RT_INLINE_ASM_USES_INTRIN
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsyncDECLASM(uint32_t) ASMRdMsr_High(uint32_t uRegister);
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync#else
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsyncDECLINLINE(uint32_t) ASMRdMsr_High(uint32_t uRegister)
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync{
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync uint32_t u32;
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync# if RT_INLINE_ASM_GNU_STYLE
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync __asm__ __volatile__("rdmsr\n\t"
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync : "=d" (u32)
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync : "c" (uRegister)
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync : "eax");
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync# elif RT_INLINE_ASM_USES_INTRIN
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync u32 = (uint32_t)(__readmsr(uRegister) >> 32);
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync# else
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync __asm
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync {
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync mov ecx, [uRegister]
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync rdmsr
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync mov [u32], edx
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync }
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync# endif
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync return u32;
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync}
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync#endif
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync/**
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync * Gets dr0.
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync *
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync * @returns dr0.
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync */
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync#if RT_INLINE_ASM_EXTERNAL && !RT_INLINE_ASM_USES_INTRIN
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsyncDECLASM(RTCCUINTREG) ASMGetDR0(void);
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync#else
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsyncDECLINLINE(RTCCUINTREG) ASMGetDR0(void)
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync{
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync RTCCUINTREG uDR0;
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync# if RT_INLINE_ASM_USES_INTRIN
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync uDR0 = __readdr(0);
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync# elif RT_INLINE_ASM_GNU_STYLE
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync# ifdef RT_ARCH_AMD64
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync __asm__ __volatile__("movq %%dr0, %0\n\t" : "=r" (uDR0));
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync# else
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync __asm__ __volatile__("movl %%dr0, %0\n\t" : "=r" (uDR0));
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync# endif
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync# else
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync __asm
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync {
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync# ifdef RT_ARCH_AMD64
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync mov rax, dr0
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync mov [uDR0], rax
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync# else
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync mov eax, dr0
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync mov [uDR0], eax
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync# endif
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync }
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync# endif
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync return uDR0;
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync}
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync#endif
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync/**
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync * Gets dr1.
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync *
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync * @returns dr1.
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync */
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync#if RT_INLINE_ASM_EXTERNAL && !RT_INLINE_ASM_USES_INTRIN
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsyncDECLASM(RTCCUINTREG) ASMGetDR1(void);
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync#else
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsyncDECLINLINE(RTCCUINTREG) ASMGetDR1(void)
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync{
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync RTCCUINTREG uDR1;
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync# if RT_INLINE_ASM_USES_INTRIN
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync uDR1 = __readdr(1);
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync# elif RT_INLINE_ASM_GNU_STYLE
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync# ifdef RT_ARCH_AMD64
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync __asm__ __volatile__("movq %%dr1, %0\n\t" : "=r" (uDR1));
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync# else
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync __asm__ __volatile__("movl %%dr1, %0\n\t" : "=r" (uDR1));
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync# endif
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync# else
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync __asm
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync {
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync# ifdef RT_ARCH_AMD64
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync mov rax, dr1
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync mov [uDR1], rax
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync# else
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync mov eax, dr1
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync mov [uDR1], eax
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync# endif
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync }
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync# endif
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync return uDR1;
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync}
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync#endif
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync/**
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync * Gets dr2.
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync *
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync * @returns dr2.
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync */
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync#if RT_INLINE_ASM_EXTERNAL && !RT_INLINE_ASM_USES_INTRIN
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsyncDECLASM(RTCCUINTREG) ASMGetDR2(void);
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync#else
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsyncDECLINLINE(RTCCUINTREG) ASMGetDR2(void)
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync{
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync RTCCUINTREG uDR2;
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync# if RT_INLINE_ASM_USES_INTRIN
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync uDR2 = __readdr(2);
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync# elif RT_INLINE_ASM_GNU_STYLE
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync# ifdef RT_ARCH_AMD64
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync __asm__ __volatile__("movq %%dr2, %0\n\t" : "=r" (uDR2));
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync# else
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync __asm__ __volatile__("movl %%dr2, %0\n\t" : "=r" (uDR2));
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync# endif
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync# else
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync __asm
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync {
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync# ifdef RT_ARCH_AMD64
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync mov rax, dr2
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync mov [uDR2], rax
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync# else
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync mov eax, dr2
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync mov [uDR2], eax
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync# endif
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync }
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync# endif
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync return uDR2;
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync}
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync#endif
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync/**
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync * Gets dr3.
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync *
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync * @returns dr3.
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync */
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync#if RT_INLINE_ASM_EXTERNAL && !RT_INLINE_ASM_USES_INTRIN
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsyncDECLASM(RTCCUINTREG) ASMGetDR3(void);
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync#else
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsyncDECLINLINE(RTCCUINTREG) ASMGetDR3(void)
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync{
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync RTCCUINTREG uDR3;
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync# if RT_INLINE_ASM_USES_INTRIN
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync uDR3 = __readdr(3);
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync# elif RT_INLINE_ASM_GNU_STYLE
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync# ifdef RT_ARCH_AMD64
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync __asm__ __volatile__("movq %%dr3, %0\n\t" : "=r" (uDR3));
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync# else
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync __asm__ __volatile__("movl %%dr3, %0\n\t" : "=r" (uDR3));
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync# endif
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync# else
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync __asm
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync {
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync# ifdef RT_ARCH_AMD64
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync mov rax, dr3
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync mov [uDR3], rax
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync# else
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync mov eax, dr3
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync mov [uDR3], eax
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync# endif
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync }
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync# endif
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync return uDR3;
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync}
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync#endif
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync/**
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync * Gets dr6.
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync *
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync * @returns dr6.
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync */
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync#if RT_INLINE_ASM_EXTERNAL && !RT_INLINE_ASM_USES_INTRIN
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsyncDECLASM(RTCCUINTREG) ASMGetDR6(void);
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync#else
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsyncDECLINLINE(RTCCUINTREG) ASMGetDR6(void)
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync{
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync RTCCUINTREG uDR6;
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync# if RT_INLINE_ASM_USES_INTRIN
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync uDR6 = __readdr(6);
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync# elif RT_INLINE_ASM_GNU_STYLE
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync# ifdef RT_ARCH_AMD64
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync __asm__ __volatile__("movq %%dr6, %0\n\t" : "=r" (uDR6));
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync# else
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync __asm__ __volatile__("movl %%dr6, %0\n\t" : "=r" (uDR6));
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync# endif
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync# else
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync __asm
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync {
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync# ifdef RT_ARCH_AMD64
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync mov rax, dr6
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync mov [uDR6], rax
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync# else
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync mov eax, dr6
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync mov [uDR6], eax
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync# endif
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync }
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync# endif
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync return uDR6;
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync}
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync#endif
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync/**
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync * Reads and clears DR6.
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync *
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync * @returns DR6.
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync */
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync#if RT_INLINE_ASM_EXTERNAL && !RT_INLINE_ASM_USES_INTRIN
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsyncDECLASM(RTCCUINTREG) ASMGetAndClearDR6(void);
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync#else
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsyncDECLINLINE(RTCCUINTREG) ASMGetAndClearDR6(void)
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync{
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync RTCCUINTREG uDR6;
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync# if RT_INLINE_ASM_USES_INTRIN
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync uDR6 = __readdr(6);
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync __writedr(6, 0xffff0ff0U); /* 31-16 and 4-11 are 1's, 12 and 63-31 are zero. */
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync# elif RT_INLINE_ASM_GNU_STYLE
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync RTCCUINTREG uNewValue = 0xffff0ff0U;/* 31-16 and 4-11 are 1's, 12 and 63-31 are zero. */
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync# ifdef RT_ARCH_AMD64
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync __asm__ __volatile__("movq %%dr6, %0\n\t"
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync "movq %1, %%dr6\n\t"
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync : "=r" (uDR6)
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync : "r" (uNewValue));
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync# else
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync __asm__ __volatile__("movl %%dr6, %0\n\t"
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync "movl %1, %%dr6\n\t"
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync : "=r" (uDR6)
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync : "r" (uNewValue));
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync# endif
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync# else
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync __asm
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync {
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync# ifdef RT_ARCH_AMD64
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync mov rax, dr6
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync mov [uDR6], rax
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync mov rcx, rax
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync mov ecx, 0ffff0ff0h; /* 31-16 and 4-11 are 1's, 12 and 63-31 are zero. */
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync mov dr6, rcx
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync# else
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync mov eax, dr6
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync mov [uDR6], eax
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync mov ecx, 0ffff0ff0h; /* 31-16 and 4-11 are 1's, 12 is zero. */
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync mov dr6, ecx
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync# endif
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync }
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync# endif
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync return uDR6;
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync}
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync#endif
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync/**
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync * Gets dr7.
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync *
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync * @returns dr7.
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync */
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync#if RT_INLINE_ASM_EXTERNAL && !RT_INLINE_ASM_USES_INTRIN
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsyncDECLASM(RTCCUINTREG) ASMGetDR7(void);
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync#else
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsyncDECLINLINE(RTCCUINTREG) ASMGetDR7(void)
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync{
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync RTCCUINTREG uDR7;
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync# if RT_INLINE_ASM_USES_INTRIN
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync uDR7 = __readdr(7);
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync# elif RT_INLINE_ASM_GNU_STYLE
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync# ifdef RT_ARCH_AMD64
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync __asm__ __volatile__("movq %%dr7, %0\n\t" : "=r" (uDR7));
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync# else
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync __asm__ __volatile__("movl %%dr7, %0\n\t" : "=r" (uDR7));
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync# endif
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync# else
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync __asm
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync {
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync# ifdef RT_ARCH_AMD64
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync mov rax, dr7
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync mov [uDR7], rax
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync# else
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync mov eax, dr7
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync mov [uDR7], eax
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync# endif
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync }
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync# endif
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync return uDR7;
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync}
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync#endif
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync/**
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync * Sets dr0.
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync *
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync * @param uDRVal Debug register value to write
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync */
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync#if RT_INLINE_ASM_EXTERNAL && !RT_INLINE_ASM_USES_INTRIN
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsyncDECLASM(void) ASMSetDR0(RTCCUINTREG uDRVal);
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync#else
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsyncDECLINLINE(void) ASMSetDR0(RTCCUINTREG uDRVal)
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync{
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync# if RT_INLINE_ASM_USES_INTRIN
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync __writedr(0, uDRVal);
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync# elif RT_INLINE_ASM_GNU_STYLE
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync# ifdef RT_ARCH_AMD64
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync __asm__ __volatile__("movq %0, %%dr0\n\t" : : "r" (uDRVal));
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync# else
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync __asm__ __volatile__("movl %0, %%dr0\n\t" : : "r" (uDRVal));
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync# endif
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync# else
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync __asm
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync {
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync# ifdef RT_ARCH_AMD64
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync mov rax, [uDRVal]
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync mov dr0, rax
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync# else
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync mov eax, [uDRVal]
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync mov dr0, eax
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync# endif
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync }
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync# endif
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync}
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync#endif
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync/**
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync * Sets dr1.
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync *
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync * @param uDRVal Debug register value to write
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync */
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync#if RT_INLINE_ASM_EXTERNAL && !RT_INLINE_ASM_USES_INTRIN
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsyncDECLASM(void) ASMSetDR1(RTCCUINTREG uDRVal);
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync#else
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsyncDECLINLINE(void) ASMSetDR1(RTCCUINTREG uDRVal)
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync{
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync# if RT_INLINE_ASM_USES_INTRIN
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync __writedr(1, uDRVal);
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync# elif RT_INLINE_ASM_GNU_STYLE
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync# ifdef RT_ARCH_AMD64
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync __asm__ __volatile__("movq %0, %%dr1\n\t" : : "r" (uDRVal));
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync# else
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync __asm__ __volatile__("movl %0, %%dr1\n\t" : : "r" (uDRVal));
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync# endif
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync# else
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync __asm
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync {
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync# ifdef RT_ARCH_AMD64
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync mov rax, [uDRVal]
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync mov dr1, rax
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync# else
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync mov eax, [uDRVal]
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync mov dr1, eax
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync# endif
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync }
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync# endif
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync}
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync#endif
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync/**
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync * Sets dr2.
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync *
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync * @param uDRVal Debug register value to write
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync */
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync#if RT_INLINE_ASM_EXTERNAL && !RT_INLINE_ASM_USES_INTRIN
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsyncDECLASM(void) ASMSetDR2(RTCCUINTREG uDRVal);
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync#else
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsyncDECLINLINE(void) ASMSetDR2(RTCCUINTREG uDRVal)
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync{
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync# if RT_INLINE_ASM_USES_INTRIN
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync __writedr(2, uDRVal);
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync# elif RT_INLINE_ASM_GNU_STYLE
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync# ifdef RT_ARCH_AMD64
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync __asm__ __volatile__("movq %0, %%dr2\n\t" : : "r" (uDRVal));
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync# else
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync __asm__ __volatile__("movl %0, %%dr2\n\t" : : "r" (uDRVal));
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync# endif
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync# else
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync __asm
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync {
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync# ifdef RT_ARCH_AMD64
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync mov rax, [uDRVal]
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync mov dr2, rax
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync# else
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync mov eax, [uDRVal]
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync mov dr2, eax
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync# endif
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync }
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync# endif
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync}
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync#endif
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync/**
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync * Sets dr3.
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync *
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync * @param uDRVal Debug register value to write
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync */
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync#if RT_INLINE_ASM_EXTERNAL && !RT_INLINE_ASM_USES_INTRIN
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsyncDECLASM(void) ASMSetDR3(RTCCUINTREG uDRVal);
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync#else
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsyncDECLINLINE(void) ASMSetDR3(RTCCUINTREG uDRVal)
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync{
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync# if RT_INLINE_ASM_USES_INTRIN
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync __writedr(3, uDRVal);
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync# elif RT_INLINE_ASM_GNU_STYLE
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync# ifdef RT_ARCH_AMD64
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync __asm__ __volatile__("movq %0, %%dr3\n\t" : : "r" (uDRVal));
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync# else
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync __asm__ __volatile__("movl %0, %%dr3\n\t" : : "r" (uDRVal));
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync# endif
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync# else
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync __asm
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync {
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync# ifdef RT_ARCH_AMD64
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync mov rax, [uDRVal]
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync mov dr3, rax
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync# else
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync mov eax, [uDRVal]
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync mov dr3, eax
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync# endif
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync }
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync# endif
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync}
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync#endif
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync/**
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync * Sets dr6.
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync *
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync * @param uDRVal Debug register value to write
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync */
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync#if RT_INLINE_ASM_EXTERNAL && !RT_INLINE_ASM_USES_INTRIN
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsyncDECLASM(void) ASMSetDR6(RTCCUINTREG uDRVal);
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync#else
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsyncDECLINLINE(void) ASMSetDR6(RTCCUINTREG uDRVal)
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync{
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync# if RT_INLINE_ASM_USES_INTRIN
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync __writedr(6, uDRVal);
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync# elif RT_INLINE_ASM_GNU_STYLE
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync# ifdef RT_ARCH_AMD64
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync __asm__ __volatile__("movq %0, %%dr6\n\t" : : "r" (uDRVal));
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync# else
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync __asm__ __volatile__("movl %0, %%dr6\n\t" : : "r" (uDRVal));
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync# endif
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync# else
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync __asm
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync {
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync# ifdef RT_ARCH_AMD64
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync mov rax, [uDRVal]
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync mov dr6, rax
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync# else
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync mov eax, [uDRVal]
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync mov dr6, eax
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync# endif
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync }
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync# endif
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync}
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync#endif
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync/**
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync * Sets dr7.
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync *
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync * @param uDRVal Debug register value to write
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync */
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync#if RT_INLINE_ASM_EXTERNAL && !RT_INLINE_ASM_USES_INTRIN
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsyncDECLASM(void) ASMSetDR7(RTCCUINTREG uDRVal);
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync#else
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsyncDECLINLINE(void) ASMSetDR7(RTCCUINTREG uDRVal)
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync{
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync# if RT_INLINE_ASM_USES_INTRIN
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync __writedr(7, uDRVal);
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync# elif RT_INLINE_ASM_GNU_STYLE
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync# ifdef RT_ARCH_AMD64
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync __asm__ __volatile__("movq %0, %%dr7\n\t" : : "r" (uDRVal));
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync# else
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync __asm__ __volatile__("movl %0, %%dr7\n\t" : : "r" (uDRVal));
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync# endif
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync# else
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync __asm
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync {
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync# ifdef RT_ARCH_AMD64
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync mov rax, [uDRVal]
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync mov dr7, rax
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync# else
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync mov eax, [uDRVal]
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync mov dr7, eax
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync# endif
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync }
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync# endif
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync}
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync#endif
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync/**
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync * Writes a 8-bit unsigned integer to an I/O port, ordered.
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync *
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync * @param Port I/O port to write to.
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync * @param u8 8-bit integer to write.
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync */
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync#if RT_INLINE_ASM_EXTERNAL && !RT_INLINE_ASM_USES_INTRIN
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsyncDECLASM(void) ASMOutU8(RTIOPORT Port, uint8_t u8);
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync#else
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsyncDECLINLINE(void) ASMOutU8(RTIOPORT Port, uint8_t u8)
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync{
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync# if RT_INLINE_ASM_GNU_STYLE
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync __asm__ __volatile__("outb %b1, %w0\n\t"
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync :: "Nd" (Port),
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync "a" (u8));
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync# elif RT_INLINE_ASM_USES_INTRIN
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync __outbyte(Port, u8);
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync# else
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync __asm
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync {
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync mov dx, [Port]
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync mov al, [u8]
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync out dx, al
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync }
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync# endif
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync}
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync#endif
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync/**
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync * Reads a 8-bit unsigned integer from an I/O port, ordered.
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync *
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync * @returns 8-bit integer.
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync * @param Port I/O port to read from.
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync */
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync#if RT_INLINE_ASM_EXTERNAL && !RT_INLINE_ASM_USES_INTRIN
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsyncDECLASM(uint8_t) ASMInU8(RTIOPORT Port);
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync#else
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsyncDECLINLINE(uint8_t) ASMInU8(RTIOPORT Port)
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync{
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync uint8_t u8;
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync# if RT_INLINE_ASM_GNU_STYLE
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync __asm__ __volatile__("inb %w1, %b0\n\t"
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync : "=a" (u8)
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync : "Nd" (Port));
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync# elif RT_INLINE_ASM_USES_INTRIN
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync u8 = __inbyte(Port);
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync# else
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync __asm
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync {
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync mov dx, [Port]
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync in al, dx
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync mov [u8], al
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync }
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync# endif
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync return u8;
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync}
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync#endif
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync/**
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync * Writes a 16-bit unsigned integer to an I/O port, ordered.
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync *
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync * @param Port I/O port to write to.
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync * @param u16 16-bit integer to write.
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync */
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync#if RT_INLINE_ASM_EXTERNAL && !RT_INLINE_ASM_USES_INTRIN
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsyncDECLASM(void) ASMOutU16(RTIOPORT Port, uint16_t u16);
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync#else
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsyncDECLINLINE(void) ASMOutU16(RTIOPORT Port, uint16_t u16)
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync{
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync# if RT_INLINE_ASM_GNU_STYLE
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync __asm__ __volatile__("outw %w1, %w0\n\t"
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync :: "Nd" (Port),
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync "a" (u16));
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync# elif RT_INLINE_ASM_USES_INTRIN
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync __outword(Port, u16);
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync# else
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync __asm
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync {
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync mov dx, [Port]
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync mov ax, [u16]
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync out dx, ax
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync }
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync# endif
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync}
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync#endif
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync/**
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync * Reads a 16-bit unsigned integer from an I/O port, ordered.
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync *
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync * @returns 16-bit integer.
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync * @param Port I/O port to read from.
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync */
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync#if RT_INLINE_ASM_EXTERNAL && !RT_INLINE_ASM_USES_INTRIN
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsyncDECLASM(uint16_t) ASMInU16(RTIOPORT Port);
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync#else
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsyncDECLINLINE(uint16_t) ASMInU16(RTIOPORT Port)
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync{
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync uint16_t u16;
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync# if RT_INLINE_ASM_GNU_STYLE
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync __asm__ __volatile__("inw %w1, %w0\n\t"
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync : "=a" (u16)
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync : "Nd" (Port));
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync# elif RT_INLINE_ASM_USES_INTRIN
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync u16 = __inword(Port);
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync# else
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync __asm
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync {
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync mov dx, [Port]
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync in ax, dx
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync mov [u16], ax
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync }
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync# endif
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync return u16;
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync}
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync#endif
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync/**
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync * Writes a 32-bit unsigned integer to an I/O port, ordered.
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync *
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync * @param Port I/O port to write to.
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync * @param u32 32-bit integer to write.
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync */
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync#if RT_INLINE_ASM_EXTERNAL && !RT_INLINE_ASM_USES_INTRIN
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsyncDECLASM(void) ASMOutU32(RTIOPORT Port, uint32_t u32);
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync#else
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsyncDECLINLINE(void) ASMOutU32(RTIOPORT Port, uint32_t u32)
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync{
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync# if RT_INLINE_ASM_GNU_STYLE
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync __asm__ __volatile__("outl %1, %w0\n\t"
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync :: "Nd" (Port),
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync "a" (u32));
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync# elif RT_INLINE_ASM_USES_INTRIN
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync __outdword(Port, u32);
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync# else
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync __asm
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync {
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync mov dx, [Port]
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync mov eax, [u32]
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync out dx, eax
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync }
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync# endif
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync}
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync#endif
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync/**
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync * Reads a 32-bit unsigned integer from an I/O port, ordered.
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync *
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync * @returns 32-bit integer.
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync * @param Port I/O port to read from.
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync */
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync#if RT_INLINE_ASM_EXTERNAL && !RT_INLINE_ASM_USES_INTRIN
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsyncDECLASM(uint32_t) ASMInU32(RTIOPORT Port);
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync#else
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsyncDECLINLINE(uint32_t) ASMInU32(RTIOPORT Port)
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync{
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync uint32_t u32;
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync# if RT_INLINE_ASM_GNU_STYLE
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync __asm__ __volatile__("inl %w1, %0\n\t"
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync : "=a" (u32)
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync : "Nd" (Port));
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync# elif RT_INLINE_ASM_USES_INTRIN
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync u32 = __indword(Port);
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync# else
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync __asm
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync {
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync mov dx, [Port]
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync in eax, dx
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync mov [u32], eax
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync }
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync# endif
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync return u32;
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync}
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync#endif
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync/**
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync * Writes a string of 8-bit unsigned integer items to an I/O port, ordered.
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync *
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync * @param Port I/O port to write to.
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync * @param pau8 Pointer to the string buffer.
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync * @param c The number of items to write.
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync */
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync#if RT_INLINE_ASM_EXTERNAL && !RT_INLINE_ASM_USES_INTRIN
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsyncDECLASM(void) ASMOutStrU8(RTIOPORT Port, uint8_t const *pau8, size_t c);
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync#else
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsyncDECLINLINE(void) ASMOutStrU8(RTIOPORT Port, uint8_t const *pau8, size_t c)
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync{
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync# if RT_INLINE_ASM_GNU_STYLE
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync __asm__ __volatile__("rep; outsb\n\t"
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync : "+S" (pau8),
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync "+c" (c)
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync : "d" (Port));
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync# elif RT_INLINE_ASM_USES_INTRIN
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync __outbytestring(Port, (unsigned char *)pau8, (unsigned long)c);
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync# else
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync __asm
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync {
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync mov dx, [Port]
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync mov ecx, [c]
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync mov eax, [pau8]
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync xchg esi, eax
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync rep outsb
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync xchg esi, eax
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync }
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync# endif
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync}
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync#endif
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync/**
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync * Reads a string of 8-bit unsigned integer items from an I/O port, ordered.
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync *
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync * @param Port I/O port to read from.
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync * @param pau8 Pointer to the string buffer (output).
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync * @param c The number of items to read.
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync */
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync#if RT_INLINE_ASM_EXTERNAL && !RT_INLINE_ASM_USES_INTRIN
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsyncDECLASM(void) ASMInStrU8(RTIOPORT Port, uint8_t *pau8, size_t c);
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync#else
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsyncDECLINLINE(void) ASMInStrU8(RTIOPORT Port, uint8_t *pau8, size_t c)
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync{
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync# if RT_INLINE_ASM_GNU_STYLE
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync __asm__ __volatile__("rep; insb\n\t"
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync : "+D" (pau8),
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync "+c" (c)
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync : "d" (Port));
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync# elif RT_INLINE_ASM_USES_INTRIN
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync __inbytestring(Port, pau8, (unsigned long)c);
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync# else
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync __asm
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync {
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync mov dx, [Port]
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync mov ecx, [c]
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync mov eax, [pau8]
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync xchg edi, eax
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync rep insb
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync xchg edi, eax
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync }
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync# endif
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync}
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync#endif
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync/**
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync * Writes a string of 16-bit unsigned integer items to an I/O port, ordered.
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync *
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync * @param Port I/O port to write to.
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync * @param pau16 Pointer to the string buffer.
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync * @param c The number of items to write.
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync */
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync#if RT_INLINE_ASM_EXTERNAL && !RT_INLINE_ASM_USES_INTRIN
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsyncDECLASM(void) ASMOutStrU16(RTIOPORT Port, uint16_t const *pau16, size_t c);
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync#else
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsyncDECLINLINE(void) ASMOutStrU16(RTIOPORT Port, uint16_t const *pau16, size_t c)
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync{
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync# if RT_INLINE_ASM_GNU_STYLE
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync __asm__ __volatile__("rep; outsw\n\t"
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync : "+S" (pau16),
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync "+c" (c)
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync : "d" (Port));
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync# elif RT_INLINE_ASM_USES_INTRIN
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync __outwordstring(Port, (unsigned short *)pau16, (unsigned long)c);
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync# else
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync __asm
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync {
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync mov dx, [Port]
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync mov ecx, [c]
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync mov eax, [pau16]
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync xchg esi, eax
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync rep outsw
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync xchg esi, eax
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync }
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync# endif
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync}
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync#endif
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync/**
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync * Reads a string of 16-bit unsigned integer items from an I/O port, ordered.
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync *
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync * @param Port I/O port to read from.
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync * @param pau16 Pointer to the string buffer (output).
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync * @param c The number of items to read.
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync */
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync#if RT_INLINE_ASM_EXTERNAL && !RT_INLINE_ASM_USES_INTRIN
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsyncDECLASM(void) ASMInStrU16(RTIOPORT Port, uint16_t *pau16, size_t c);
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync#else
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsyncDECLINLINE(void) ASMInStrU16(RTIOPORT Port, uint16_t *pau16, size_t c)
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync{
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync# if RT_INLINE_ASM_GNU_STYLE
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync __asm__ __volatile__("rep; insw\n\t"
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync : "+D" (pau16),
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync "+c" (c)
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync : "d" (Port));
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync# elif RT_INLINE_ASM_USES_INTRIN
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync __inwordstring(Port, pau16, (unsigned long)c);
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync# else
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync __asm
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync {
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync mov dx, [Port]
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync mov ecx, [c]
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync mov eax, [pau16]
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync xchg edi, eax
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync rep insw
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync xchg edi, eax
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync }
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync# endif
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync}
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync#endif
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync/**
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync * Writes a string of 32-bit unsigned integer items to an I/O port, ordered.
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync *
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync * @param Port I/O port to write to.
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync * @param pau32 Pointer to the string buffer.
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync * @param c The number of items to write.
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync */
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync#if RT_INLINE_ASM_EXTERNAL && !RT_INLINE_ASM_USES_INTRIN
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsyncDECLASM(void) ASMOutStrU32(RTIOPORT Port, uint32_t const *pau32, size_t c);
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync#else
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsyncDECLINLINE(void) ASMOutStrU32(RTIOPORT Port, uint32_t const *pau32, size_t c)
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync{
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync# if RT_INLINE_ASM_GNU_STYLE
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync __asm__ __volatile__("rep; outsl\n\t"
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync : "+S" (pau32),
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync "+c" (c)
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync : "d" (Port));
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync# elif RT_INLINE_ASM_USES_INTRIN
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync __outdwordstring(Port, (unsigned long *)pau32, (unsigned long)c);
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync# else
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync __asm
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync {
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync mov dx, [Port]
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync mov ecx, [c]
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync mov eax, [pau32]
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync xchg esi, eax
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync rep outsd
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync xchg esi, eax
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync }
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync# endif
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync}
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync#endif
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync/**
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync * Reads a string of 32-bit unsigned integer items from an I/O port, ordered.
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync *
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync * @param Port I/O port to read from.
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync * @param pau32 Pointer to the string buffer (output).
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync * @param c The number of items to read.
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync */
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync#if RT_INLINE_ASM_EXTERNAL && !RT_INLINE_ASM_USES_INTRIN
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsyncDECLASM(void) ASMInStrU32(RTIOPORT Port, uint32_t *pau32, size_t c);
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync#else
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsyncDECLINLINE(void) ASMInStrU32(RTIOPORT Port, uint32_t *pau32, size_t c)
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync{
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync# if RT_INLINE_ASM_GNU_STYLE
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync __asm__ __volatile__("rep; insl\n\t"
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync : "+D" (pau32),
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync "+c" (c)
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync : "d" (Port));
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync# elif RT_INLINE_ASM_USES_INTRIN
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync __indwordstring(Port, (unsigned long *)pau32, (unsigned long)c);
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync# else
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync __asm
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync {
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync mov dx, [Port]
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync mov ecx, [c]
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync mov eax, [pau32]
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync xchg edi, eax
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync rep insd
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync xchg edi, eax
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync }
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync# endif
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync}
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync#endif
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync/**
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync * Invalidate page.
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync *
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync * @param pv Address of the page to invalidate.
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync */
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync#if RT_INLINE_ASM_EXTERNAL && !RT_INLINE_ASM_USES_INTRIN
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsyncDECLASM(void) ASMInvalidatePage(void *pv);
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync#else
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsyncDECLINLINE(void) ASMInvalidatePage(void *pv)
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync{
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync# if RT_INLINE_ASM_USES_INTRIN
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync __invlpg(pv);
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync# elif RT_INLINE_ASM_GNU_STYLE
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync __asm__ __volatile__("invlpg %0\n\t"
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync : : "m" (*(uint8_t *)pv));
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync# else
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync __asm
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync {
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync# ifdef RT_ARCH_AMD64
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync mov rax, [pv]
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync invlpg [rax]
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync# else
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync mov eax, [pv]
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync invlpg [eax]
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync# endif
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync }
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync# endif
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync}
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync#endif
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync/**
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync * Write back the internal caches and invalidate them.
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync */
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync#if RT_INLINE_ASM_EXTERNAL && !RT_INLINE_ASM_USES_INTRIN
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsyncDECLASM(void) ASMWriteBackAndInvalidateCaches(void);
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync#else
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsyncDECLINLINE(void) ASMWriteBackAndInvalidateCaches(void)
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync{
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync# if RT_INLINE_ASM_USES_INTRIN
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync __wbinvd();
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync# elif RT_INLINE_ASM_GNU_STYLE
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync __asm__ __volatile__("wbinvd");
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync# else
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync __asm
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync {
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync wbinvd
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync }
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync# endif
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync}
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync#endif
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync/**
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync * Invalidate internal and (perhaps) external caches without first
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync * flushing dirty cache lines. Use with extreme care.
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync */
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync#if RT_INLINE_ASM_EXTERNAL
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsyncDECLASM(void) ASMInvalidateInternalCaches(void);
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync#else
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsyncDECLINLINE(void) ASMInvalidateInternalCaches(void)
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync{
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync# if RT_INLINE_ASM_GNU_STYLE
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync __asm__ __volatile__("invd");
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync# else
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync __asm
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync {
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync invd
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync }
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync# endif
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync}
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync#endif
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync/**
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync * Memory load/store fence, waits for any pending writes and reads to complete.
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync * Requires the X86_CPUID_FEATURE_EDX_SSE2 CPUID bit set.
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync */
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsyncDECLINLINE(void) ASMMemoryFenceSSE2(void)
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync{
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync#if RT_INLINE_ASM_GNU_STYLE
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync __asm__ __volatile__ (".byte 0x0f,0xae,0xf0\n\t");
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync#elif RT_INLINE_ASM_USES_INTRIN
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync _mm_mfence();
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync#else
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync __asm
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync {
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync _emit 0x0f
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync _emit 0xae
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync _emit 0xf0
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync }
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync#endif
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync}
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync/**
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync * Memory store fence, waits for any writes to complete.
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync * Requires the X86_CPUID_FEATURE_EDX_SSE CPUID bit set.
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync */
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsyncDECLINLINE(void) ASMWriteFenceSSE(void)
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync{
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync#if RT_INLINE_ASM_GNU_STYLE
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync __asm__ __volatile__ (".byte 0x0f,0xae,0xf8\n\t");
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync#elif RT_INLINE_ASM_USES_INTRIN
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync _mm_sfence();
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync#else
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync __asm
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync {
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync _emit 0x0f
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync _emit 0xae
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync _emit 0xf8
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync }
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync#endif
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync}
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync/**
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync * Memory load fence, waits for any pending reads to complete.
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync * Requires the X86_CPUID_FEATURE_EDX_SSE2 CPUID bit set.
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync */
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsyncDECLINLINE(void) ASMReadFenceSSE2(void)
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync{
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync#if RT_INLINE_ASM_GNU_STYLE
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync __asm__ __volatile__ (".byte 0x0f,0xae,0xe8\n\t");
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync#elif RT_INLINE_ASM_USES_INTRIN
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync _mm_lfence();
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync#else
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync __asm
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync {
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync _emit 0x0f
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync _emit 0xae
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync _emit 0xe8
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync }
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync#endif
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync}
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync/** @} */
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync#endif
831acea16fc15fff2cf90a217d02eea69bf27a40vboxsync