cpum.h revision aa9c1381743c6022507a480a1848f6cb597f1c98
/** @file
* CPUM - CPU Monitor(/ Manager).
*/
/*
* Copyright (C) 2006-2007 Sun Microsystems, Inc.
*
* This file is part of VirtualBox Open Source Edition (OSE), as
* available from http://www.virtualbox.org. This file is free software;
* General Public License (GPL) as published by the Free Software
* Foundation, in version 2 as it comes in the "COPYING" file of the
* VirtualBox OSE distribution. VirtualBox OSE is distributed in the
* hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
*
* The contents of this file may alternatively be used under the terms
* of the Common Development and Distribution License Version 1.0
* (CDDL) only, as it comes in the "COPYING.CDDL" file of the
* VirtualBox OSE distribution, in which case the provisions of the
* CDDL are applicable instead of those of the GPL.
*
* You may elect to license modified versions of this file under the
* terms and conditions of either the GPL or the CDDL or both.
*
* Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa
* Clara, CA 95054 USA or visit http://www.sun.com if you need
* additional information or have any questions.
*/
#ifndef ___VBox_cpum_h
#define ___VBox_cpum_h
/** @defgroup grp_cpum The CPU Monitor(/Manager) API
* @{
*/
/**
* Selector hidden registers.
*/
typedef struct CPUMSELREGHID
{
/** Base register.
*
* Long mode remarks:
* - Unused in long mode for CS, DS, ES, SS
* - 32 bits for FS & GS; FS(GS)_BASE msr used for the base address
* - 64 bits for TR & LDTR
*/
/** Limit (expanded). */
/** Flags.
* This is the high 32-bit word of the descriptor entry.
* Only the flags, dpl and type are used. */
/**
* The sysenter register set.
*/
typedef struct CPUMSYSENTER
{
/** Ring 0 cs.
* This value + 8 is the Ring 0 ss.
* This value + 16 is the Ring 3 cs.
* This value + 24 is the Ring 3 ss.
*/
/** Ring 0 eip. */
/** Ring 0 esp. */
} CPUMSYSENTER;
/**
* CPU context core.
*/
#pragma pack(1)
typedef struct CPUMCTXCORE
{
union
{
};
union
{
};
union
{
};
union
{
};
union
{
};
union
{
};
union
{
};
union
{
};
/* Note: lss esp, [] in the switcher needs some space, so we reserve it here instead of relying on the exact esp & ss layout as before. */
union
{
};
union
{
};
/** Hidden selector registers.
* @{ */
/** @} */
} CPUMCTXCORE;
#pragma pack()
/**
* CPU context.
*/
#pragma pack(1)
typedef struct CPUMCTX
{
/** FPU state. (16-byte alignment)
* @todo This doesn't have to be in X86FXSTATE on CPUs without fxsr - we need a type for the
* actual format or convert it (waste of time). */
/** CPUMCTXCORE Part.
* @{ */
union
{
};
union
{
};
union
{
};
union
{
};
union
{
};
union
{
};
union
{
};
union
{
};
/* Note: lss esp, [] in the switcher needs some space, so we reserve it here instead of relying on the exact esp & ss layout as before (prevented us from using a union with rsp). */
union
{
};
union
{
};
/** Hidden selector registers.
* @{ */
/** @} */
/** @} */
/** Control registers.
* @{ */
/** @} */
/** Debug registers.
* @{ */
/* DR8-15 are currently not supported */
/** @} */
/** Global Descriptor Table register. */
/** Interrupt Descriptor Table register. */
/** The task register.
* Only the guest context uses all the members. */
/** The task register.
* Only the guest context uses all the members. */
/** The sysenter msr registers.
* This member is not used by the hypervisor context. */
/** System MSRs.
* @{ */
/** @} */
/** Hidden selector registers.
* @{ */
/** @} */
/* padding to get 32byte aligned size */
} CPUMCTX;
#pragma pack()
/**
* Gets the CPUMCTXCORE part of a CPUMCTX.
*/
/**
* The register set returned by a CPUID operation.
*/
typedef struct CPUMCPUID
{
} CPUMCPUID;
/** Pointer to a CPUID leaf. */
typedef CPUMCPUID *PCPUMCPUID;
/** Pointer to a const CPUID leaf. */
typedef const CPUMCPUID *PCCPUMCPUID;
/**
* CPUID feature to set or clear.
*/
typedef enum CPUMCPUIDFEATURE
{
/** The APIC feature bit. (Std+Ext) */
/** The PAE feature bit. (Std+Ext) */
/** The NXE feature bit. (Ext) */
/** The LONG MODE feature bit. (Ext) */
/*
* CPU Vendor.
*/
typedef enum CPUMCPUVENDOR
{
/** 32bit hackishness. */
CPUMCPUVENDOR_32BIT_HACK = 0x7fffffff
/** @name Guest Register Getters.
* @{ */
CPUMDECL(void) CPUMGetGuestCpuId(PVM pVM, uint32_t iLeaf, uint32_t *pEax, uint32_t *pEbx, uint32_t *pEcx, uint32_t *pEdx);
/** @} */
/** @name Guest Register Setters.
* @{ */
/** @} */
/** @name Misc Guest Predicate Functions.
* @{ */
/**
* Tests if the guest is running in real mode or not.
*
* @returns true if in real mode, otherwise false.
* @param pVM The VM handle.
*/
{
}
/**
* Tests if the guest is running in protected or not.
*
* @returns true if in protected mode, otherwise false.
* @param pVM The VM handle.
*/
{
}
/**
* Tests if the guest is running in paged protected or not.
*
* @returns true if in paged protected mode, otherwise false.
* @param pVM The VM handle.
*/
{
}
/**
* Tests if the guest is running in long mode or not.
*
* @returns true if in long mode, otherwise false.
* @param pVM The VM handle.
*/
{
}
/**
* Tests if the guest is running in 16 bits paged protected or not.
*
* @returns true if in paged protected mode, otherwise false.
* @param pVM The VM handle.
*/
/**
* Tests if the guest is running in 32 bits paged protected or not.
*
* @returns true if in paged protected mode, otherwise false.
* @param pVM The VM handle.
*/
/**
* Tests if the guest is running in 64 bits mode or not.
*
* @returns true if in 64 bits protected mode, otherwise false.
* @param pVM The VM handle.
* @param pCtx Current CPU context
*/
{
if (!CPUMIsGuestInLongMode(pVM))
return false;
}
/**
* Tests if the guest is running in 64 bits mode or not.
*
* @returns true if in 64 bits protected mode, otherwise false.
* @param pVM The VM handle.
* @param pCtx Current CPU context
*/
{
return false;
}
/**
* Gets the CPU vendor
*
* @returns CPU vendor
* @param pVM The VM handle.
*/
/** @} */
/** @name Hypervisor Register Getters.
* @{ */
#if 0 /* these are not correct. */
#endif
/** This register is only saved on fatal traps. */
/** This register is only saved on fatal traps. */
/** This register is only saved on fatal traps. */
/** @} */
/** @name Hypervisor Register Setters.
* @{ */
/** @} */
/**
* Sets or resets an alternative hypervisor context core.
*
* This is called when we get a hypervisor trap set switch the context
* core with the trap frame on the stack. It is called again to reset
* back to the default context core when resuming hypervisor execution.
*
* @param pVM The VM handle.
* @param pCtxCore Pointer to the alternative context core or NULL
* to go back to the default context core.
*/
/**
* Queries the pointer to the internal CPUMCTX structure
*
* @returns VBox status code.
* @param pVM Handle to the virtual machine.
* @param ppCtx Receives the CPUMCTX pointer when successful.
*/
/**
* Queries the pointer to the internal CPUMCTX structure for the hypervisor.
*
* @returns VBox status code.
* @param pVM Handle to the virtual machine.
* @param ppCtx Receives the hyper CPUMCTX pointer when successful.
*/
/**
* Gets the pointer to the internal CPUMCTXCORE structure.
* This is only for reading in order to save a few calls.
*
* @param pVM Handle to the virtual machine.
*/
/**
* Gets the pointer to the internal CPUMCTXCORE structure for the hypervisor.
* This is only for reading in order to save a few calls.
*
* @param pVM Handle to the virtual machine.
*/
/**
* Sets the guest context core registers.
*
* @param pVM Handle to the virtual machine.
* @param pCtxCore The new context core values.
*/
/**
* Transforms the guest CPU state to raw-ring mode.
*
* This function will change the any of the cs and ss register with DPL=0 to DPL=1.
*
* @returns VBox status. (recompiler failure)
* @param pVM VM handle.
* @param pCtxCore The context core (for trap usage).
* @see @ref pg_raw
*/
/**
* Transforms the guest CPU state from raw-ring mode to correct values.
*
* This function will change any selector registers with DPL=1 to DPL=0.
*
* @returns Adjusted rc.
* @param pVM VM handle.
* @param rc Raw mode return code
* @param pCtxCore The context core (for trap usage).
* @see @ref pg_raw
*/
/**
* Gets the EFLAGS while we're in raw-mode.
*
* @returns The eflags.
* @param pVM The VM handle.
* @param pCtxCore The context core.
*/
/**
* Updates the EFLAGS while we're in raw-mode.
*
* @param pVM The VM handle.
* @param pCtxCore The context core.
* @param eflags The new EFLAGS value.
*/
/**
*
* This function will change any selector registers with DPL=1 to DPL=0.
*
* @returns VBox status code.
* @param pVM VM handle.
*/
/**
*
* @returns VBox status code.
* @param pVM VM handle.
*/
/** @name Changed flags
* These flags are used to keep track of which important register that
* have been changed since last they were reset. The only one allowed
* to clear them is REM!
* @{
*/
#define CPUM_CHANGED_FPU_REM RT_BIT(0)
/** @} */
/**
* Gets and resets the changed flags (CPUM_CHANGED_*).
*
* @returns The changed flags.
* @param pVM VM handle.
*/
/**
* Sets the specified changed flags (CPUM_CHANGED_*).
*
* @param pVM The VM handle.
*/
/**
* Checks if the CPU supports the FXSAVE and FXRSTOR instruction.
* @returns true if supported.
* @returns false if not supported.
* @param pVM The VM handle.
*/
/**
* Checks if the host OS uses the SYSENTER / SYSEXIT instructions.
* @returns true if used.
* @returns false if not used.
* @param pVM The VM handle.
*/
/**
* Checks if the host OS uses the SYSCALL / SYSRET instructions.
* @returns true if used.
* @returns false if not used.
* @param pVM The VM handle.
*/
/**
* @returns true if we did.
* @returns false if not.
* @param pVM The VM handle.
*/
/**
* @param pVM The VM handle.
*/
/**
* Checks if the hidden selector registers are valid
* @returns true if they are.
* @returns false if not.
* @param pVM The VM handle.
*/
/**
* Checks if the hidden selector registers are valid
* @param pVM The VM handle.
* @param fValid Valid or not
*/
/**
* Get the current privilege level of the guest.
*
* @returns cpl
* @param pVM VM Handle.
* @param pRegFrame Trap register frame.
*/
/**
* CPU modes.
*/
typedef enum CPUMMODE
{
/** The usual invalid zero entry. */
CPUMMODE_INVALID = 0,
/** Real mode. */
/** Protected mode (32-bit). */
/** Long mode (64-bit). */
} CPUMMODE;
/**
* Gets the current guest CPU mode.
*
* If paging mode is what you need, check out PGMGetGuestMode().
*
* @returns The CPU mode.
* @param pVM The VM handle.
*/
#ifdef IN_RING3
/** @defgroup grp_cpum_r3 The CPU Monitor(/Manager) API
* @ingroup grp_cpum
* @{
*/
/**
* Initializes the CPUM.
*
* @returns VBox status code.
* @param pVM The VM to operate on.
*/
/**
* Applies relocations to data and code managed by this
* component. This function will be called at init and
* whenever the VMM need to relocate it self inside the GC.
*
* The CPUM will update the addresses used by the switcher.
*
* @param pVM The VM.
*/
/**
* Terminates the CPUM.
*
* Termination means cleaning up and freeing all resources,
* the VM it self is at this point powered off or suspended.
*
* @returns VBox status code.
* @param pVM The VM to operate on.
*/
/**
* Resets the CPU.
*
* @param pVM The VM handle.
*/
/**
* Queries the pointer to the internal CPUMCTX structure
*
* @returns VBox status code.
* @param pVM Handle to the virtual machine.
* @param ppCtx Receives the CPUMCTX GC pointer when successful.
*/
#ifdef DEBUG
/**
* Debug helper - Saves guest context on raw mode entry (for fatal dump)
*
* @internal
*/
#endif
/**
* API for controlling a few of the CPU features found in CR4.
*
* Currently only X86_CR4_TSD is accepted as input.
*
* @returns VBox status code.
*
* @param pVM The VM handle.
* @param fOr The CR4 OR mask.
* @param fAnd The CR4 AND mask.
*/
/** @} */
#endif
#ifdef IN_GC
/** @defgroup grp_cpum_gc The CPU Monitor(/Manager) API
* @ingroup grp_cpum
* @{
*/
/**
* Assumes a trap stack frame has already been setup on the guest's stack!
*
* @param selCS Code selector of handler
* @param pHandler GC virtual address of handler
* @param eflags Callee's EFLAGS
* @param selSS Stack selector for handler
* @param pEsp Stack address for handler
*
* This function does not return!
*
*/
DECLASM(void) CPUMGCCallGuestTrapHandler(PCPUMCTXCORE pRegFrame, uint32_t selCS, RTRCPTR pHandler, uint32_t eflags, uint32_t selSS, RTRCPTR pEsp);
/**
* Performs an iret to V86 code
* Assumes a trap stack frame has already been setup on the guest's stack!
*
*
* This function does not return!
*/
/** @} */
#endif
#ifdef IN_RING0
/** @defgroup grp_cpum_r0 The CPU Monitor(/Manager) API
* @ingroup grp_cpum
* @{
*/
/**
* Does Ring-0 CPUM initialization.
*
* This is mainly to check that the Host CPU mode is compatible
* with VBox.
*
* @returns VBox status code.
* @param pVM The VM to operate on.
*/
/** @} */
#endif
/** @} */
#endif