diff options
author | Martin Roth <martinroth@google.com> | 2017-11-16 16:00:53 -0700 |
---|---|---|
committer | Martin Roth <martinroth@google.com> | 2017-11-19 01:44:07 +0000 |
commit | 241391841e3aac76bb1cca282a9ed7ba192827f3 (patch) | |
tree | e6d26a4c4ce9b23d7539a92d5ed7b2c234da6d61 /src/vendorcode/amd | |
parent | 6c623ca5655b273269701f212fb12118029d78e2 (diff) |
vendorcode/amd/pi/00670F00: Remove dependency on amd/include dir
Copy the two headers used by the Stoney BinaryPI implementation into
the 00670F00 directory so that any changes that are made to them don't
affect other platforms.
BUG=b:67299330
TEST=Build
Change-Id: I5d37fac72871f2617c4be45c151741436cbfce96
Signed-off-by: Martin Roth <martinroth@google.com>
Reviewed-on: https://review.coreboot.org/22498
Tested-by: build bot (Jenkins) <no-reply@coreboot.org>
Reviewed-by: Aaron Durbin <adurbin@chromium.org>
Diffstat (limited to 'src/vendorcode/amd')
-rw-r--r-- | src/vendorcode/amd/pi/00670F00/Makefile.inc | 2 | ||||
-rw-r--r-- | src/vendorcode/amd/pi/00670F00/Porting.h | 302 | ||||
-rw-r--r-- | src/vendorcode/amd/pi/00670F00/agesa_headers.h | 2 | ||||
-rw-r--r-- | src/vendorcode/amd/pi/00670F00/gcc-intrin.h | 629 |
4 files changed, 933 insertions, 2 deletions
diff --git a/src/vendorcode/amd/pi/00670F00/Makefile.inc b/src/vendorcode/amd/pi/00670F00/Makefile.inc index bd00ea3b72..3fb78709e1 100644 --- a/src/vendorcode/amd/pi/00670F00/Makefile.inc +++ b/src/vendorcode/amd/pi/00670F00/Makefile.inc @@ -33,7 +33,7 @@ ifeq ($(CONFIG_SOC_AMD_STONEYRIDGE_FP4)$(CONFIG_SOC_AMD_STONEYRIDGE_FT4),y) AGESA_ROOT = $(call strip_quotes,$(CONFIG_AGESA_BINARY_PI_VENDORCODE_PATH)) -AGESA_INC = -I$(obj) -I$(src)/vendorcode/amd/include +AGESA_INC = -I$(obj) AGESA_INC += -I$(src)/mainboard/$(MAINBOARDDIR) AGESA_INC += -I$(AGESA_ROOT)/binaryPI diff --git a/src/vendorcode/amd/pi/00670F00/Porting.h b/src/vendorcode/amd/pi/00670F00/Porting.h new file mode 100644 index 0000000000..ed1a9c707e --- /dev/null +++ b/src/vendorcode/amd/pi/00670F00/Porting.h @@ -0,0 +1,302 @@ +/* $NoKeywords:$ */ +/** + * @file + * + * Describes compiler dependencies - to support several compile time environments + * + * Contains compiler environment porting descriptions + * + * @xrefitem bom "File Content Label" "Release Content" + * @e project: AGESA + * @e sub-project: Includes + * @e \$Revision: 44324 $ @e \$Date: 2010-12-22 03:16:51 -0600 (Wed, 22 Dec 2010) $ + */ +/***************************************************************************** + * + * Copyright (c) 2008 - 2013, Advanced Micro Devices, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of Advanced Micro Devices, Inc. nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL ADVANCED MICRO DEVICES, INC. BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + ***************************************************************************/ + +#ifndef _PORTING_H_ +#define _PORTING_H_ + +#if defined (_MSC_VER) + #include <intrin.h> + void _disable (void); + void _enable (void); + #pragma warning(disable: 4103 4001 4733) + #pragma intrinsic (_disable, _enable) + #pragma warning(push) + // ----------------------------------------------------------------------- + // Define a code_seg MACRO + // + #define MAKE_AS_A_STRING(arg) #arg + + #define CODE_GROUP(arg) __pragma (code_seg (MAKE_AS_A_STRING (.t##arg))) + + #define RDATA_GROUP(arg) __pragma (const_seg (MAKE_AS_A_STRING (.d##arg))) + #define FUNC_ATTRIBUTE(arg) __declspec(arg) + //#include <intrin.h> // MS has built-in functions + + #if _MSC_VER < 900 + // ----------------------------------------------------------------------- + // Assume MSVC 1.52C (16-bit) + // + // NOTE: When using MSVC 1.52C use the following command line: + // + // CL.EXE /G3 /AL /O1i /Fa <FILENAME.C> + // + // This will produce 32-bit code in USE16 segment that is optimized for code + // size. + typedef void VOID; + + // Create the universal 32, 16, and 8-bit data types + typedef unsigned long UINTN; + typedef long INT32; + typedef unsigned long UINT32; + typedef int INT16; + typedef unsigned int UINT16; + typedef char INT8; + typedef unsigned char UINT8; + typedef char CHAR8; + typedef unsigned short CHAR16; + + /// struct for 16-bit environment handling of 64-bit value + typedef struct _UINT64 { + IN OUT UINT32 lo; ///< lower 32-bits of 64-bit value + IN OUT UINT32 hi; ///< highest 32-bits of 64-bit value + } UINT64; + + // Create the Boolean type + #define TRUE 1 + #define FALSE 0 + typedef unsigned char BOOLEAN; + + #define CONST const + #define STATIC static + #define VOLATILE volatile + #define CALLCONV __pascal + #define ROMDATA __based( __segname( "_CODE" ) ) + #define _16BYTE_ALIGN __declspec(align(16)) + #define _8BYTE_ALIGN __declspec(align(8)) + #define _4BYTE_ALIGN __declspec(align(4)) + #define _2BYTE_ALIGN __declspec(align(2)) + #define _1BYTE_ALIGN __declspec(align(1)) + + // Force tight packing of structures + // Note: Entire AGESA (Project / Solution) will be using pragma pack 1 + #pragma warning( disable : 4103 ) // Disable '#pragma pack' in .h warning + #pragma pack(1) + + // Disable WORD->BYTE automatic conversion warnings. Example: + // BYTE LocalByte; + // void MyFunc(BYTE val); + // + // MyFunc(LocalByte*2+1); // Warning, automatic conversion + // + // The problem is any time math is performed on a BYTE, it is converted to a + // WORD by MSVC 1.52c, and then when it is converted back to a BYTE, a warning + // is generated. Disable warning C4761 + #pragma warning( disable : 4761 ) + + #else + // ----------------------------------------------------------------------- + // Assume a 32-bit MSVC++ + // + // Disable the following warnings: + // 4100 - 'identifier' : unreferenced formal parameter + // 4276 - 'function' : no prototype provided; assumed no parameters + // 4214 - non standard extension used : bit field types other than int + // 4001 - nonstandard extension 'single line comment' was used + // 4142 - benign redefinition of type for following declaration + // - typedef char INT8 + #if defined (_M_IX86) + #pragma warning (disable: 4100 4276 4214 4001 4142 4305 4306) + + #ifndef VOID + typedef void VOID; + #endif + // Create the universal 32, 16, and 8-bit data types + #ifndef UINTN + typedef unsigned __w64 UINTN; + #endif + typedef __int64 INT64; + typedef unsigned __int64 UINT64; + typedef int INT32; + typedef unsigned int UINT32; + typedef short INT16; + typedef unsigned short UINT16; + typedef char INT8; + typedef unsigned char UINT8; + typedef char CHAR8; + typedef unsigned short CHAR16; + + // Create the Boolean type + #ifndef TRUE + #define TRUE 1 + #endif + #ifndef FALSE + #define FALSE 0 + #endif + typedef unsigned char BOOLEAN; + + // Force tight packing of structures + // Note: Entire AGESA (Project / Solution) will be using pragma pack 1 + #pragma pack(1) + + #define CONST const + #define STATIC static + #define VOLATILE volatile + #define CALLCONV + #define ROMDATA + #define _16BYTE_ALIGN __declspec(align(64)) + #define _8BYTE_ALIGN __declspec(align(8)) + #define _4BYTE_ALIGN __declspec(align(4)) + #define _2BYTE_ALIGN __declspec(align(2)) + #define _1BYTE_ALIGN __declspec(align(1)) + //Support for variadic macros was introduced in Visual C++ 2005. + #if _MSC_VER >= 1400 + #define VA_ARGS_SUPPORTED + #endif + // 64 bit of compiler + #else + #pragma warning (disable: 4100 4276 4214 4001 4142 4305 4306 4366) + + #ifndef VOID + typedef void VOID; + #endif + // Create the universal 32, 16, and 8-bit data types + #ifndef UINTN + typedef unsigned __int64 UINTN; + #endif + typedef __int64 INT64; + typedef unsigned __int64 UINT64; + typedef int INT32; + typedef unsigned int UINT32; + typedef short INT16; + typedef unsigned short UINT16; + typedef char INT8; + typedef unsigned char UINT8; + typedef char CHAR8; + typedef unsigned short CHAR16; + + // Create the Boolean type + #ifndef TRUE + #define TRUE 1 + #endif + #ifndef FALSE + #define FALSE 0 + #endif + typedef unsigned char BOOLEAN; + #define _16BYTE_ALIGN __declspec(align(16)) + #define _8BYTE_ALIGN __declspec(align(8)) + #define _4BYTE_ALIGN __declspec(align(4)) + #define _2BYTE_ALIGN __declspec(align(2)) + #define _1BYTE_ALIGN __declspec(align(1)) + // Force tight packing of structures + // Note: Entire AGESA (Project / Solution) will be using pragma pack 1 + #pragma pack(1) + + #define CONST const + #define STATIC static + #define VOLATILE volatile + #define CALLCONV + #define ROMDATA + #endif + #endif + // ----------------------------------------------------------------------- + // End of MS compiler versions + +#elif defined __GNUC__ + + #include <stdint.h> + + #define IN + #define OUT + #define STATIC static + #define VOLATILE volatile + #define TRUE 1 + #define FALSE 0 + #define CONST const + #define ROMDATA + #define CALLCONV + #define _16BYTE_ALIGN __attribute__((aligned (16))) + #define _8BYTE_ALIGN __attribute__((aligned (8))) + #define _4BYTE_ALIGN __attribute__((aligned (4))) + #define _2BYTE_ALIGN __attribute__((aligned (2))) + #define _1BYTE_ALIGN __attribute__((aligned (1))) + + typedef uintptr_t UINTN; + typedef int64_t INT64; + typedef uint64_t UINT64; + typedef int32_t INT32; + typedef uint32_t UINT32; + typedef int16_t INT16; + typedef uint16_t UINT16; + typedef int8_t INT8; + typedef uint8_t UINT8; + typedef char CHAR8; + typedef unsigned short CHAR16; + typedef unsigned char BOOLEAN; + typedef void VOID; + +#define CODE_GROUP(arg) +#define RDATA_GROUP(arg) + +#pragma pack(1) + +#define FUNC_ATTRIBUTE(arg) __attribute__((arg)) +#define MAKE_AS_A_STRING(arg) #arg +#include <stddef.h> +#include <gcc-intrin.h> + +#include <assert.h> +//#include <console/console.h> +//#include <commonlib/loglevel.h> + +#ifndef NULL + #define NULL ((void *)0) +#endif + +#else + // ----------------------------------------------------------------------- + // Unknown or unsupported compiler + // + #error "Unknown compiler in use" +#endif + +// ----------------------------------------------------------------------- +// Common definitions for all compilers +// + +//Support forward reference construct +#define AGESA_FORWARD_DECLARATION(x) typedef struct _##x x + +// The following are use in conformance to the UEFI style guide +#define IN +#define OUT + +#endif // _PORTING_H_ diff --git a/src/vendorcode/amd/pi/00670F00/agesa_headers.h b/src/vendorcode/amd/pi/00670F00/agesa_headers.h index d93b73f163..721da3f89c 100644 --- a/src/vendorcode/amd/pi/00670F00/agesa_headers.h +++ b/src/vendorcode/amd/pi/00670F00/agesa_headers.h @@ -17,7 +17,7 @@ #define __AGESA_HEADERS_H__ #pragma pack(push) -#include <Porting.h> +#include "Porting.h" #include "AGESA.h" #include "AMD.h" diff --git a/src/vendorcode/amd/pi/00670F00/gcc-intrin.h b/src/vendorcode/amd/pi/00670F00/gcc-intrin.h new file mode 100644 index 0000000000..44e91d28b6 --- /dev/null +++ b/src/vendorcode/amd/pi/00670F00/gcc-intrin.h @@ -0,0 +1,629 @@ +/* + * Copyright (c) 2011, Advanced Micro Devices, Inc. All rights reserved. + * Copyright (c) 2014, Edward O'Callaghan <eocallaghan@alterapraxis.com> + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of Advanced Micro Devices, Inc. nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL ADVANCED MICRO DEVICES, INC. BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + */ + +#if defined (__GNUC__) +#include <stdint.h> +/* I/O intrin functions. */ +static __inline__ __attribute__((always_inline)) uint8_t __inbyte(uint16_t Port) +{ + uint8_t value; + + __asm__ __volatile__ ( + "in %1, %0" + : "=a" (value) + : "Nd" (Port) + ); + + return value; +} + +static __inline__ __attribute__((always_inline)) uint16_t __inword(uint16_t Port) +{ + uint16_t value; + + __asm__ __volatile__ ( + "in %1, %0" + : "=a" (value) + : "Nd" (Port) + ); + + return value; +} + +static __inline__ __attribute__((always_inline)) uint32_t __indword(uint16_t Port) +{ + uint32_t value; + + __asm__ __volatile__ ( + "in %1, %0" + : "=a" (value) + : "Nd" (Port) + ); + return value; + +} + +static __inline__ __attribute__((always_inline)) void __outbyte(uint16_t Port,uint8_t Data) +{ + __asm__ __volatile__ ( + "out %0, %1" + : + : "a" (Data), "Nd" (Port) + ); +} + +static __inline__ __attribute__((always_inline)) void __outword(uint16_t Port,uint16_t Data) +{ + __asm__ __volatile__ ( + "out %0, %1" + : + : "a" (Data), "Nd" (Port) + ); +} + +static __inline__ __attribute__((always_inline)) void __outdword(uint16_t Port,uint32_t Data) +{ + __asm__ __volatile__ ( + "out %0, %1" + : + : "a" (Data), "Nd" (Port) + ); +} + +static __inline__ __attribute__((always_inline)) void __inbytestring(uint16_t Port,uint8_t *Buffer,unsigned long Count) +{ + __asm__ __volatile__ ( + "rep ; insb" + : "+D" (Buffer), "+c" (Count) + : "d"(Port) + ); +} + +static __inline__ __attribute__((always_inline)) void __inwordstring(uint16_t Port,uint16_t *Buffer,unsigned long Count) +{ + __asm__ __volatile__ ( + "rep ; insw" + : "+D" (Buffer), "+c" (Count) + : "d"(Port) + ); +} + +static __inline__ __attribute__((always_inline)) void __indwordstring(uint16_t Port,unsigned long *Buffer,unsigned long Count) +{ + __asm__ __volatile__ ( + "rep ; insl" + : "+D" (Buffer), "+c" (Count) + : "d"(Port) + ); +} + +static __inline__ __attribute__((always_inline)) void __outbytestring(uint16_t Port,uint8_t *Buffer,unsigned long Count) +{ + __asm__ __volatile__ ( + "rep ; outsb" + : "+S" (Buffer), "+c" (Count) + : "d"(Port) + ); +} + +static __inline__ __attribute__((always_inline)) void __outwordstring(uint16_t Port,uint16_t *Buffer,unsigned long Count) +{ + __asm__ __volatile__ ( + "rep ; outsw" + : "+S" (Buffer), "+c" (Count) + : "d"(Port) + ); +} + +static __inline__ __attribute__((always_inline)) void __outdwordstring(uint16_t Port,unsigned long *Buffer,unsigned long Count) +{ + __asm__ __volatile__ ( + "rep ; outsl" + : "+S" (Buffer), "+c" (Count) + : "d"(Port) + ); +} + +static __inline__ __attribute__((always_inline)) unsigned long __readdr0(void) +{ + unsigned long value; + __asm__ __volatile__ ( + "mov %%dr0, %[value]" + : [value] "=r" (value) + ); + return value; +} + +static __inline__ __attribute__((always_inline)) unsigned long __readdr1(void) +{ + unsigned long value; + __asm__ __volatile__ ( + "mov %%dr1, %[value]" + : [value] "=r" (value) + ); + return value; +} + +static __inline__ __attribute__((always_inline)) unsigned long __readdr2(void) +{ + unsigned long value; + __asm__ __volatile__ ( + "mov %%dr2, %[value]" + : [value] "=r" (value) + ); + return value; +} + +static __inline__ __attribute__((always_inline)) unsigned long __readdr3(void) +{ + unsigned long value; + __asm__ __volatile__ ( + "mov %%dr3, %[value]" + : [value] "=r" (value) + ); + return value; +} + +static __inline__ __attribute__((always_inline)) unsigned long __readdr7(void) +{ + unsigned long value; + __asm__ __volatile__ ( + "mov %%dr7, %[value]" + : [value] "=r" (value) + ); + return value; +} + +static __inline__ __attribute__((always_inline)) unsigned long __readdr(unsigned long reg) +{ + switch (reg){ + case 0: + return __readdr0 (); + break; + + case 1: + return __readdr1 (); + break; + + case 2: + return __readdr2 (); + break; + + case 3: + return __readdr3 (); + break; + + case 7: + return __readdr7 (); + break; + + default: + return -1; + } +} + +static __inline__ __attribute__((always_inline)) void __writedr0(unsigned long Data) +{ + __asm__ __volatile__ ( + "mov %0, %%dr0" + : + : "r" (Data) + ); +} + +static __inline__ __attribute__((always_inline)) void __writedr1(unsigned long Data) +{ + __asm__ __volatile__ ( + "mov %0, %%dr1" + : + : "r" (Data) + ); +} + +static __inline__ __attribute__((always_inline)) void __writedr2(unsigned long Data) +{ + __asm__ __volatile__ ( + "mov %0, %%dr2" + : + : "r" (Data) + ); +} + +static __inline__ __attribute__((always_inline)) void __writedr3(unsigned long Data) +{ + __asm__ __volatile__ ( + "mov %0, %%dr3" + : + : "r" (Data) + ); +} + +static __inline__ __attribute__((always_inline)) void __writedr7(unsigned long Data) +{ + __asm__ __volatile__ ( + "mov %0, %%dr7" + : + : "r" (Data) + ); +} + +static __inline__ __attribute__((always_inline)) void __writedr(unsigned long reg, unsigned long Data) +{ + switch (reg){ + case 0: + __writedr0 (Data); + break; + + case 1: + __writedr1 (Data); + break; + + case 2: + __writedr2 (Data); + break; + + case 3: + __writedr3 (Data); + break; + + case 7: + __writedr7 (Data); + break; + + default: + ; + } +} + +static __inline__ __attribute__((always_inline)) unsigned long __readcr0(void) +{ + unsigned long value; + __asm__ __volatile__ ( + "mov %%cr0, %[value]" + : [value] "=r" (value)); + return value; +} + +static __inline__ __attribute__((always_inline)) unsigned long __readcr2(void) +{ + unsigned long value; + __asm__ __volatile__ ( + "mov %%cr2, %[value]" + : [value] "=r" (value)); + return value; +} + +static __inline__ __attribute__((always_inline)) unsigned long __readcr3(void) +{ + unsigned long value; + __asm__ __volatile__ ( + "mov %%cr3, %[value]" + : [value] "=r" (value)); + return value; +} + +static __inline__ __attribute__((always_inline)) unsigned long __readcr4(void) +{ + unsigned long value; + __asm__ __volatile__ ( + "mov %%cr4, %[value]" + : [value] "=r" (value)); + return value; +} + +static __inline__ __attribute__((always_inline)) unsigned long __readcr8(void) +{ + unsigned long value; + __asm__ __volatile__ ( + "mov %%cr8, %[value]" + : [value] "=r" (value)); + return value; +} + +static __inline__ __attribute__((always_inline)) unsigned long __readcr(unsigned long reg) +{ + switch (reg){ + case 0: + return __readcr0 (); + break; + + case 2: + return __readcr2 (); + break; + + case 3: + return __readcr3 (); + break; + + case 4: + return __readcr4 (); + break; + + case 8: + return __readcr8 (); + break; + + default: + return -1; + } +} + +static __inline__ __attribute__((always_inline)) void __writecr0(unsigned long Data) +{ + __asm__ __volatile__ ( + "mov %0, %%cr0" + : + : "r" (Data) + : "memory" + ); +} + +static __inline__ __attribute__((always_inline)) void __writecr2(unsigned long Data) +{ + __asm__ __volatile__ ( + "mov %0, %%cr2" + : + : "r" (Data) + ); +} + +static __inline__ __attribute__((always_inline)) void __writecr3(unsigned long Data) +{ + __asm__ __volatile__ ( + "mov %0, %%cr3" + : + : "r" (Data) + ); +} + +static __inline__ __attribute__((always_inline)) void __writecr4(unsigned long Data) +{ + __asm__ __volatile__ ( + "mov %0, %%cr4" + : + : "r" (Data) + ); +} + +static __inline__ __attribute__((always_inline)) void __writecr8(unsigned long Data) +{ + __asm__ __volatile__ ( + "mov %0, %%cr8" + : + : "r" (Data) + ); +} + +static __inline__ __attribute__((always_inline)) void __writecr(unsigned long reg, unsigned long Data) +{ + switch (reg){ + case 0: + __writecr0 (Data); + break; + + case 2: + __writecr2 (Data); + break; + + case 3: + __writecr3 (Data); + break; + + case 4: + __writecr4 (Data); + break; + + case 8: + __writecr8 (Data); + break; + + default: + ; + } +} + +static __inline__ __attribute__((always_inline)) UINT64 __readmsr(UINT32 msr) +{ + UINT64 retval; + __asm__ __volatile__( + "rdmsr" + : "=A" (retval) + : "c" (msr) + ); + return retval; +} + +static __inline__ __attribute__((always_inline)) void __writemsr (UINT32 msr, UINT64 Value) +{ + __asm__ __volatile__ ( + "wrmsr" + : + : "c" (msr), "A" (Value) + ); +} + +#if !defined(__clang__) +static __inline__ __attribute__((always_inline)) UINT64 __rdtsc(void) +{ + UINT64 retval; + __asm__ __volatile__ ( + "rdtsc" + : "=A" (retval)); + return retval; +} +#endif + +static __inline__ __attribute__((always_inline)) void __cpuid(int CPUInfo[], const int InfoType) +{ + __asm__ __volatile__( + "cpuid" + :"=a" (CPUInfo[0]), "=b" (CPUInfo[1]), "=c" (CPUInfo[2]), "=d" (CPUInfo[3]) + : "a" (InfoType) + ); +} + + +static __inline__ __attribute__((always_inline)) void _disable(void) +{ + __asm__ __volatile__ ("cli"); +} + + +static __inline__ __attribute__((always_inline)) void _enable(void) +{ + __asm__ __volatile__ ("sti"); +} + + +static __inline__ __attribute__((always_inline)) void __halt(void) +{ + __asm__ __volatile__ ("hlt"); +} + + +static __inline__ __attribute__((always_inline)) void __debugbreak(void) +{ + __asm__ __volatile__ ("int3"); +} + +static __inline__ __attribute__((always_inline)) void __invd(void) +{ + __asm__ __volatile__ ("invd"); +} + +static __inline__ __attribute__((always_inline)) void __wbinvd(void) +{ + __asm__ __volatile__ ("wbinvd"); +} + +static __inline__ __attribute__((always_inline)) void __lidt(void *Source) +{ + __asm__ __volatile__("lidt %0" : : "m"(*(short*)Source)); +} + +static __inline__ __attribute__((always_inline)) void +__writefsbyte(const unsigned long Offset, const uint8_t Data) +{ + __asm__ ("movb %[Data], %%fs:%a[Offset]" + : + : [Offset] "ir" (Offset), [Data] "iq" (Data)); +} + +static __inline__ __attribute__((always_inline)) void +__writefsword(const unsigned long Offset, const uint16_t Data) +{ + __asm__ ("movw %[Data], %%fs:%a[Offset]" + : + : [Offset] "ir" (Offset), [Data] "ir" (Data)); +} + +static __inline__ __attribute__((always_inline)) void +__writefsdword(const unsigned long Offset, const uint32_t Data) +{ + __asm__ ("movl %[Data], %%fs:%a[Offset]" + : + : [Offset] "ir" (Offset), [Data] "ir" (Data)); +} + +static __inline__ __attribute__((always_inline)) uint8_t +__readfsbyte(const unsigned long Offset) +{ + unsigned char value; + __asm__ ("movb %%fs:%a[Offset], %[value]" + : [value] "=q" (value) + : [Offset] "ir" (Offset)); + return value; +} + +static __inline__ __attribute__((always_inline)) uint16_t +__readfsword(const unsigned long Offset) +{ + unsigned short value; + __asm__ ("movw %%fs:%a[Offset], %[value]" + : [value] "=q" (value) + : [Offset] "ir" (Offset)); + return value; +} + +static __inline__ __attribute__((always_inline)) uint32_t +__readfsdword(unsigned long Offset) +{ + unsigned long value; + __asm__ ("mov %%fs:%a[Offset], %[value]" + : [value] "=r" (value) + : [Offset] "ir" (Offset)); + return value; +} + +#ifdef __SSE3__ +typedef long long __v2di __attribute__((__vector_size__ (16))); +typedef long long __m128i __attribute__((__vector_size__ (16), __may_alias__)); + +static __inline__ __attribute__((always_inline)) void _mm_stream_si128_fs2 (void *__A, __m128i __B) +{ + __asm__(".byte 0x64"); // fs prefix +#if defined(__clang__) + __builtin_nontemporal_store((__v2di)__B, (__v2di *)__A); +#else + __builtin_ia32_movntdq ((__v2di *)__A, (__v2di)__B); +#endif +} + +static __inline__ __attribute__((always_inline)) void _mm_stream_si128_fs (void *__A, void *__B) +{ + __m128i data; + data = (__m128i) __builtin_ia32_lddqu ((char const *)__B); + _mm_stream_si128_fs2 (__A, data); +} + +static __inline__ __attribute__((always_inline)) void _mm_clflush_fs (void *__A) +{ + __asm__(".byte 0x64"); // fs prefix + __builtin_ia32_clflush (__A); +} + +#if !defined(__clang__) +static __inline __attribute__(( __always_inline__)) void _mm_mfence (void) +{ + __builtin_ia32_mfence (); +} +#else +void _mm_mfence(void); +#endif + +#if !defined(__clang__) +static __inline __attribute__(( __always_inline__)) void _mm_sfence (void) +{ + __builtin_ia32_sfence (); +} +#else +void _mm_sfence(void); +#endif +#endif /* __SSE3__ */ + +#endif /* defined (__GNUC__) */ |