/** @file
GCC inline implementation of BaseLib processor specific functions.
Copyright (c) 2006 - 2010, Intel Corporation. All rights reserved.<BR>
Portions copyright (c) 2008 - 2009, Apple Inc. All rights reserved.<BR>
This program and the accompanying materials
are licensed and made available under the terms and conditions of the BSD License
which accompanies this distribution. The full text of the license may be found at
THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
**/
#include "BaseLibInternals.h"
/**
Used to serialize load and store operations.
All loads and stores that proceed calls to this function are guaranteed to be
globally visible when this function returns.
**/
)
{
// This is a little bit of overkill and it is more about the compiler that it is
// actually processor synchronization. This is like the _ReadWriteBarrier
// Microsoft specific intrinsic
}
/**
Enables CPU interrupts.
Enables CPU interrupts.
**/
)
{
}
/**
Disables CPU interrupts.
Disables CPU interrupts.
**/
)
{
}
/**
Requests CPU to pause for a short period of time.
Requests CPU to pause for a short period of time. Typically used in MP
systems to prevent memory starvation while waiting for a spin lock.
**/
CpuPause (
)
{
}
/**
Generates a breakpoint on the CPU.
Generates a breakpoint on the CPU. The breakpoint must be implemented such
that code can resume normal execution after the breakpoint.
**/
)
{
}
/**
Returns a 64-bit Machine Specific Register(MSR).
Reads and returns the 64-bit MSR specified by Index. No parameter checking is
performed on Index, and some Index values may cause CPU exceptions. The
caller must either guarantee that Index is valid, or the caller must set up
exception handlers to catch the exceptions. This function is only available
on IA-32 and X64.
@param Index The 32-bit MSR index to read.
@return The value of the MSR identified by Index.
**/
)
{
"rdmsr"
);
return Data;
}
/**
Writes a 64-bit value to a Machine Specific Register(MSR), and returns the
value.
Writes the 64-bit value specified by Value to the MSR specified by Index. The
64-bit value written to the MSR is returned. No parameter checking is
performed on Index or Value, and some of these may cause CPU exceptions. The
caller must either guarantee that Index and Value are valid, or the caller
must establish proper exception handlers. This function is only available on
IA-32 and X64.
@param Index The 32-bit MSR index to write.
@param Value The 64-bit value to write to the MSR.
@return Value
**/
)
{
"wrmsr"
:
: "c" (Index),
"A" (Value)
);
return Value;
}
/**
Reads the current value of the EFLAGS register.
Reads and returns the current value of the EFLAGS register. This function is
only available on IA-32 and X64. This returns a 32-bit value on IA-32 and a
64-bit value on X64.
@return EFLAGS on IA-32 or RFLAGS on X64.
**/
)
{
"pushfl \n\t"
"popl %0 "
: "=r" (Eflags)
);
return Eflags;
}
/**
Reads the current value of the Control Register 0 (CR0).
Reads and returns the current value of CR0. This function is only available
on IA-32 and X64. This returns a 32-bit value on IA-32 and a 64-bit value on
X64.
@return The value of the Control Register 0 (CR0).
**/
)
{
"movl %%cr0,%0"
: "=a" (Data)
);
return Data;
}
/**
Reads the current value of the Control Register 2 (CR2).
Reads and returns the current value of CR2. This function is only available
on IA-32 and X64. This returns a 32-bit value on IA-32 and a 64-bit value on
X64.
@return The value of the Control Register 2 (CR2).
**/
)
{
"movl %%cr2, %0"
: "=r" (Data)
);
return Data;
}
/**
Reads the current value of the Control Register 3 (CR3).
Reads and returns the current value of CR3. This function is only available
on IA-32 and X64. This returns a 32-bit value on IA-32 and a 64-bit value on
X64.
@return The value of the Control Register 3 (CR3).
**/
)
{
"movl %%cr3, %0"
: "=r" (Data)
);
return Data;
}
/**
Reads the current value of the Control Register 4 (CR4).
Reads and returns the current value of CR4. This function is only available
on IA-32 and X64. This returns a 32-bit value on IA-32 and a 64-bit value on
X64.
@return The value of the Control Register 4 (CR4).
**/
)
{
"movl %%cr4, %0"
: "=a" (Data)
);
return Data;
}
/**
Writes a value to Control Register 0 (CR0).
Writes and returns a new value to CR0. This function is only available on
IA-32 and X64. This writes a 32-bit value on IA-32 and a 64-bit value on X64.
@param Cr0 The value to write to CR0.
@return The value written to CR0.
**/
)
{
"movl %0, %%cr0"
:
: "r" (Cr0)
);
return Cr0;
}
/**
Writes a value to Control Register 2 (CR2).
Writes and returns a new value to CR2. This function is only available on
IA-32 and X64. This writes a 32-bit value on IA-32 and a 64-bit value on X64.
@param Cr2 The value to write to CR2.
@return The value written to CR2.
**/
)
{
"movl %0, %%cr2"
:
: "r" (Cr2)
);
return Cr2;
}
/**
Writes a value to Control Register 3 (CR3).
Writes and returns a new value to CR3. This function is only available on
IA-32 and X64. This writes a 32-bit value on IA-32 and a 64-bit value on X64.
@param Cr3 The value to write to CR3.
@return The value written to CR3.
**/
)
{
"movl %0, %%cr3"
:
: "r" (Cr3)
);
return Cr3;
}
/**
Writes a value to Control Register 4 (CR4).
Writes and returns a new value to CR4. This function is only available on
IA-32 and X64. This writes a 32-bit value on IA-32 and a 64-bit value on X64.
@param Cr4 The value to write to CR4.
@return The value written to CR4.
**/
)
{
"movl %0, %%cr4"
:
: "r" (Cr4)
);
return Cr4;
}
/**
Reads the current value of Debug Register 0 (DR0).
Reads and returns the current value of DR0. This function is only available
on IA-32 and X64. This returns a 32-bit value on IA-32 and a 64-bit value on
X64.
@return The value of Debug Register 0 (DR0).
**/
)
{
"movl %%dr0, %0"
: "=r" (Data)
);
return Data;
}
/**
Reads the current value of Debug Register 1 (DR1).
Reads and returns the current value of DR1. This function is only available
on IA-32 and X64. This returns a 32-bit value on IA-32 and a 64-bit value on
X64.
@return The value of Debug Register 1 (DR1).
**/
)
{
"movl %%dr1, %0"
: "=r" (Data)
);
return Data;
}
/**
Reads the current value of Debug Register 2 (DR2).
Reads and returns the current value of DR2. This function is only available
on IA-32 and X64. This returns a 32-bit value on IA-32 and a 64-bit value on
X64.
@return The value of Debug Register 2 (DR2).
**/
)
{
"movl %%dr2, %0"
: "=r" (Data)
);
return Data;
}
/**
Reads the current value of Debug Register 3 (DR3).
Reads and returns the current value of DR3. This function is only available
on IA-32 and X64. This returns a 32-bit value on IA-32 and a 64-bit value on
X64.
@return The value of Debug Register 3 (DR3).
**/
)
{
"movl %%dr3, %0"
: "=r" (Data)
);
return Data;
}
/**
Reads the current value of Debug Register 4 (DR4).
Reads and returns the current value of DR4. This function is only available
on IA-32 and X64. This returns a 32-bit value on IA-32 and a 64-bit value on
X64.
@return The value of Debug Register 4 (DR4).
**/
)
{
"movl %%dr4, %0"
: "=r" (Data)
);
return Data;
}
/**
Reads the current value of Debug Register 5 (DR5).
Reads and returns the current value of DR5. This function is only available
on IA-32 and X64. This returns a 32-bit value on IA-32 and a 64-bit value on
X64.
@return The value of Debug Register 5 (DR5).
**/
)
{
"movl %%dr5, %0"
: "=r" (Data)
);
return Data;
}
/**
Reads the current value of Debug Register 6 (DR6).
Reads and returns the current value of DR6. This function is only available
on IA-32 and X64. This returns a 32-bit value on IA-32 and a 64-bit value on
X64.
@return The value of Debug Register 6 (DR6).
**/
)
{
"movl %%dr6, %0"
: "=r" (Data)
);
return Data;
}
/**
Reads the current value of Debug Register 7 (DR7).
Reads and returns the current value of DR7. This function is only available
on IA-32 and X64. This returns a 32-bit value on IA-32 and a 64-bit value on
X64.
@return The value of Debug Register 7 (DR7).
**/
)
{
"movl %%dr7, %0"
: "=r" (Data)
);
return Data;
}
/**
Writes a value to Debug Register 0 (DR0).
Writes and returns a new value to DR0. This function is only available on
IA-32 and X64. This writes a 32-bit value on IA-32 and a 64-bit value on X64.
@param Dr0 The value to write to Dr0.
@return The value written to Debug Register 0 (DR0).
**/
)
{
"movl %0, %%dr0"
:
: "r" (Dr0)
);
return Dr0;
}
/**
Writes a value to Debug Register 1 (DR1).
Writes and returns a new value to DR1. This function is only available on
IA-32 and X64. This writes a 32-bit value on IA-32 and a 64-bit value on X64.
@param Dr1 The value to write to Dr1.
@return The value written to Debug Register 1 (DR1).
**/
)
{
"movl %0, %%dr1"
:
: "r" (Dr1)
);
return Dr1;
}
/**
Writes a value to Debug Register 2 (DR2).
Writes and returns a new value to DR2. This function is only available on
IA-32 and X64. This writes a 32-bit value on IA-32 and a 64-bit value on X64.
@param Dr2 The value to write to Dr2.
@return The value written to Debug Register 2 (DR2).
**/
)
{
"movl %0, %%dr2"
:
: "r" (Dr2)
);
return Dr2;
}
/**
Writes a value to Debug Register 3 (DR3).
Writes and returns a new value to DR3. This function is only available on
IA-32 and X64. This writes a 32-bit value on IA-32 and a 64-bit value on X64.
@param Dr3 The value to write to Dr3.
@return The value written to Debug Register 3 (DR3).
**/
)
{
"movl %0, %%dr3"
:
: "r" (Dr3)
);
return Dr3;
}
/**
Writes a value to Debug Register 4 (DR4).
Writes and returns a new value to DR4. This function is only available on
IA-32 and X64. This writes a 32-bit value on IA-32 and a 64-bit value on X64.
@param Dr4 The value to write to Dr4.
@return The value written to Debug Register 4 (DR4).
**/
)
{
"movl %0, %%dr4"
:
: "r" (Dr4)
);
return Dr4;
}
/**
Writes a value to Debug Register 5 (DR5).
Writes and returns a new value to DR5. This function is only available on
IA-32 and X64. This writes a 32-bit value on IA-32 and a 64-bit value on X64.
@param Dr5 The value to write to Dr5.
@return The value written to Debug Register 5 (DR5).
**/
)
{
"movl %0, %%dr5"
:
: "r" (Dr5)
);
return Dr5;
}
/**
Writes a value to Debug Register 6 (DR6).
Writes and returns a new value to DR6. This function is only available on
IA-32 and X64. This writes a 32-bit value on IA-32 and a 64-bit value on X64.
@param Dr6 The value to write to Dr6.
@return The value written to Debug Register 6 (DR6).
**/
)
{
"movl %0, %%dr6"
:
: "r" (Dr6)
);
return Dr6;
}
/**
Writes a value to Debug Register 7 (DR7).
Writes and returns a new value to DR7. This function is only available on
IA-32 and X64. This writes a 32-bit value on IA-32 and a 64-bit value on X64.
@param Dr7 The value to write to Dr7.
@return The value written to Debug Register 7 (DR7).
**/
)
{
"movl %0, %%dr7"
:
: "r" (Dr7)
);
return Dr7;
}
/**
Reads the current value of Code Segment Register (CS).
Reads and returns the current value of CS. This function is only available on
IA-32 and X64.
@return The current value of CS.
**/
)
{
"mov %%cs, %0"
:"=a" (Data)
);
return Data;
}
/**
Reads the current value of Data Segment Register (DS).
Reads and returns the current value of DS. This function is only available on
IA-32 and X64.
@return The current value of DS.
**/
)
{
"mov %%ds, %0"
:"=a" (Data)
);
return Data;
}
/**
Reads the current value of Extra Segment Register (ES).
Reads and returns the current value of ES. This function is only available on
IA-32 and X64.
@return The current value of ES.
**/
)
{
"mov %%es, %0"
:"=a" (Data)
);
return Data;
}
/**
Reads the current value of FS Data Segment Register (FS).
Reads and returns the current value of FS. This function is only available on
IA-32 and X64.
@return The current value of FS.
**/
)
{
"mov %%fs, %0"
:"=a" (Data)
);
return Data;
}
/**
Reads the current value of GS Data Segment Register (GS).
Reads and returns the current value of GS. This function is only available on
IA-32 and X64.
@return The current value of GS.
**/
)
{
"mov %%gs, %0"
:"=a" (Data)
);
return Data;
}
/**
Reads the current value of Stack Segment Register (SS).
Reads and returns the current value of SS. This function is only available on
IA-32 and X64.
@return The current value of SS.
**/
)
{
"mov %%ds, %0"
:"=a" (Data)
);
return Data;
}
/**
Reads the current value of Task Register (TR).
Reads and returns the current value of TR. This function is only available on
IA-32 and X64.
@return The current value of TR.
**/
)
{
"str %0"
: "=a" (Data)
);
return Data;
}
/**
Reads the current Global Descriptor Table Register(GDTR) descriptor.
Reads and returns the current GDTR descriptor and returns it in Gdtr. This
function is only available on IA-32 and X64.
@param Gdtr The pointer to a GDTR descriptor.
**/
)
{
"sgdt %0"
: "=m" (*Gdtr)
);
}
/**
Writes the current Global Descriptor Table Register (GDTR) descriptor.
Writes and the current GDTR descriptor specified by Gdtr. This function is
only available on IA-32 and X64.
@param Gdtr The pointer to a GDTR descriptor.
**/
)
{
"lgdt %0"
:
: "m" (*Gdtr)
);
}
/**
Reads the current Interrupt Descriptor Table Register(GDTR) descriptor.
Reads and returns the current IDTR descriptor and returns it in Idtr. This
function is only available on IA-32 and X64.
@param Idtr The pointer to a IDTR descriptor.
**/
)
{
"sidt %0"
: "=m" (*Idtr)
);
}
/**
Writes the current Interrupt Descriptor Table Register(GDTR) descriptor.
Writes the current IDTR descriptor and returns it in Idtr. This function is
only available on IA-32 and X64.
@param Idtr The pointer to a IDTR descriptor.
**/
)
{
"lidt %0"
:
: "m" (*Idtr)
);
}
/**
Reads the current Local Descriptor Table Register(LDTR) selector.
Reads and returns the current 16-bit LDTR descriptor value. This function is
only available on IA-32 and X64.
@return The current selector of LDT.
**/
)
{
"sldt %0"
);
return Data;
}
/**
Writes the current Local Descriptor Table Register (GDTR) selector.
Writes and the current LDTR descriptor specified by Ldtr. This function is
only available on IA-32 and X64.
@param Ldtr 16-bit LDTR selector value.
**/
)
{
"lldtw %0"
:
);
}
/**
Buffer. Buffer must be aligned on a 16-byte boundary. This function is only
available on IA-32 and X64.
**/
)
{
"fxsave %0"
:
);
}
/**
by Buffer. Buffer must be aligned on a 16-byte boundary. This function is
only available on IA-32 and X64.
**/
)
{
"fxrstor %0"
:
);
}
/**
Reads the current value of 64-bit MMX Register #0 (MM0).
Reads and returns the current value of MM0. This function is only available
on IA-32 and X64.
@return The current value of MM0.
**/
)
{
"push %%eax \n\t"
"push %%eax \n\t"
"movq %%mm0, (%%esp)\n\t"
"pop %%eax \n\t"
"pop %%edx \n\t"
);
return Data;
}
/**
Reads the current value of 64-bit MMX Register #1 (MM1).
Reads and returns the current value of MM1. This function is only available
on IA-32 and X64.
@return The current value of MM1.
**/
)
{
"push %%eax \n\t"
"push %%eax \n\t"
"movq %%mm1, (%%esp)\n\t"
"pop %%eax \n\t"
"pop %%edx \n\t"
);
return Data;
}
/**
Reads the current value of 64-bit MMX Register #2 (MM2).
Reads and returns the current value of MM2. This function is only available
on IA-32 and X64.
@return The current value of MM2.
**/
)
{
"push %%eax \n\t"
"push %%eax \n\t"
"movq %%mm2, (%%esp)\n\t"
"pop %%eax \n\t"
"pop %%edx \n\t"
);
return Data;
}
/**
Reads the current value of 64-bit MMX Register #3 (MM3).
Reads and returns the current value of MM3. This function is only available
on IA-32 and X64.
@return The current value of MM3.
**/
)
{
"push %%eax \n\t"
"push %%eax \n\t"
"movq %%mm3, (%%esp)\n\t"
"pop %%eax \n\t"
"pop %%edx \n\t"
);
return Data;
}
/**
Reads the current value of 64-bit MMX Register #4 (MM4).
Reads and returns the current value of MM4. This function is only available
on IA-32 and X64.
@return The current value of MM4.
**/
)
{
"push %%eax \n\t"
"push %%eax \n\t"
"movq %%mm4, (%%esp)\n\t"
"pop %%eax \n\t"
"pop %%edx \n\t"
);
return Data;
}
/**
Reads the current value of 64-bit MMX Register #5 (MM5).
Reads and returns the current value of MM5. This function is only available
on IA-32 and X64.
@return The current value of MM5.
**/
)
{
"push %%eax \n\t"
"push %%eax \n\t"
"movq %%mm5, (%%esp)\n\t"
"pop %%eax \n\t"
"pop %%edx \n\t"
);
return Data;
}
/**
Reads the current value of 64-bit MMX Register #6 (MM6).
Reads and returns the current value of MM6. This function is only available
on IA-32 and X64.
@return The current value of MM6.
**/
)
{
"push %%eax \n\t"
"push %%eax \n\t"
"movq %%mm6, (%%esp)\n\t"
"pop %%eax \n\t"
"pop %%edx \n\t"
);
return Data;
}
/**
Reads the current value of 64-bit MMX Register #7 (MM7).
Reads and returns the current value of MM7. This function is only available
on IA-32 and X64.
@return The current value of MM7.
**/
)
{
"push %%eax \n\t"
"push %%eax \n\t"
"movq %%mm7, (%%esp)\n\t"
"pop %%eax \n\t"
"pop %%edx \n\t"
);
return Data;
}
/**
Writes the current value of 64-bit MMX Register #0 (MM0).
Writes the current value of MM0. This function is only available on IA32 and
X64.
@param Value The 64-bit value to write to MM0.
**/
)
{
"movq %0, %%mm0" // %0
:
: "m" (Value)
);
}
/**
Writes the current value of 64-bit MMX Register #1 (MM1).
Writes the current value of MM1. This function is only available on IA32 and
X64.
@param Value The 64-bit value to write to MM1.
**/
)
{
"movq %0, %%mm1" // %0
:
: "m" (Value)
);
}
/**
Writes the current value of 64-bit MMX Register #2 (MM2).
Writes the current value of MM2. This function is only available on IA32 and
X64.
@param Value The 64-bit value to write to MM2.
**/
)
{
"movq %0, %%mm2" // %0
:
: "m" (Value)
);
}
/**
Writes the current value of 64-bit MMX Register #3 (MM3).
Writes the current value of MM3. This function is only available on IA32 and
X64.
@param Value The 64-bit value to write to MM3.
**/
)
{
"movq %0, %%mm3" // %0
:
: "m" (Value)
);
}
/**
Writes the current value of 64-bit MMX Register #4 (MM4).
Writes the current value of MM4. This function is only available on IA32 and
X64.
@param Value The 64-bit value to write to MM4.
**/
)
{
"movq %0, %%mm4" // %0
:
: "m" (Value)
);
}
/**
Writes the current value of 64-bit MMX Register #5 (MM5).
Writes the current value of MM5. This function is only available on IA32 and
X64.
@param Value The 64-bit value to write to MM5.
**/
)
{
"movq %0, %%mm5" // %0
:
: "m" (Value)
);
}
/**
Writes the current value of 64-bit MMX Register #6 (MM6).
Writes the current value of MM6. This function is only available on IA32 and
X64.
@param Value The 64-bit value to write to MM6.
**/
)
{
"movq %0, %%mm6" // %0
:
: "m" (Value)
);
}
/**
Writes the current value of 64-bit MMX Register #7 (MM7).
Writes the current value of MM7. This function is only available on IA32 and
X64.
@param Value The 64-bit value to write to MM7.
**/
)
{
"movq %0, %%mm7" // %0
:
: "m" (Value)
);
}
/**
Reads the current value of Time Stamp Counter (TSC).
Reads and returns the current value of TSC. This function is only available
on IA-32 and X64.
@return The current value of TSC
**/
)
{
"rdtsc"
: "=A" (Data)
);
return Data;
}
/**
Reads the current value of a Performance Counter (PMC).
Reads and returns the current value of performance counter specified by
Index. This function is only available on IA-32 and X64.
@param Index The 32-bit Performance Counter index to read.
@return The value of the PMC specified by Index.
**/
)
{
"rdpmc"
: "=A" (Data)
: "c" (Index)
);
return Data;
}
/**
Executes a WBINVD instruction.
Executes a WBINVD instruction. This function is only available on IA-32 and
X64.
**/
)
{
}
/**
Executes a INVD instruction.
Executes a INVD instruction. This function is only available on IA-32 and
X64.
**/
AsmInvd (
)
{
}
/**
Flushes a cache line from all the instruction and data caches within the
coherency domain of the CPU.
Flushed the cache line specified by LinearAddress, and returns LinearAddress.
This function is only available on IA-32 and X64.
@param LinearAddress The address of the cache line to flush. If the CPU is
in a physical addressing mode, then LinearAddress is a
physical address. If the CPU is in a virtual
addressing mode, then LinearAddress is a virtual
address.
@return LinearAddress
**/
VOID *
)
{
"clflush (%0)"
: "+a" (LinearAddress)
:
: "memory"
);
return LinearAddress;
}