summaryrefslogtreecommitdiff
path: root/src/vendorcode/amd/pi
diff options
context:
space:
mode:
authorMartin Roth <martinroth@google.com>2017-11-16 16:00:53 -0700
committerMartin Roth <martinroth@google.com>2017-11-19 01:44:07 +0000
commit241391841e3aac76bb1cca282a9ed7ba192827f3 (patch)
treee6d26a4c4ce9b23d7539a92d5ed7b2c234da6d61 /src/vendorcode/amd/pi
parent6c623ca5655b273269701f212fb12118029d78e2 (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/pi')
-rw-r--r--src/vendorcode/amd/pi/00670F00/Makefile.inc2
-rw-r--r--src/vendorcode/amd/pi/00670F00/Porting.h302
-rw-r--r--src/vendorcode/amd/pi/00670F00/agesa_headers.h2
-rw-r--r--src/vendorcode/amd/pi/00670F00/gcc-intrin.h629
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__) */