kernel/x86_64: AVX support

xsave or xsavec are supported.
breaks vregs compatibility.
change the thread structure object cache alignment to 64
the xsave fpu_state size isn't defined, it is for instance 832 here, thus I picked 1024.

Change-Id: I4a0cab0bc42c1d37f24dcafb8259f8ff24a330d2
Reviewed-on: https://review.haiku-os.org/c/haiku/+/2849
Reviewed-by: Adrien Destugues <[email protected]>
This commit is contained in:
Jérôme Duval
2020-06-03 06:16:48 +00:00
committed by Adrien Destugues
parent 734c1e0491
commit 9495126984
10 changed files with 191 additions and 27 deletions
+13 -1
View File
@@ -89,6 +89,18 @@ struct fpu_state {
unsigned char _reserved_416_511[96];
};
struct xstate_hdr {
unsigned long bv;
unsigned long xcomp_bv;
unsigned char _reserved[48];
};
struct savefpu {
struct fpu_state fp_fxsave;
struct xstate_hdr fp_xstate;
unsigned long fp_ymm[16][2];
};
struct vregs {
unsigned long rax;
unsigned long rbx;
@@ -110,7 +122,7 @@ struct vregs {
unsigned long rip;
unsigned long rflags;
struct fpu_state fpu;
struct savefpu fpu;
};
@@ -22,6 +22,8 @@
#define ALTCODEPATCH_TAG_STAC 1
#define ALTCODEPATCH_TAG_CLAC 2
#define ALTCODEPATCH_TAG_XSAVE 3
#define ALTCODEPATCH_TAG_XRSTOR 4
#ifdef _ASSEMBLER
@@ -354,9 +354,15 @@
#define IA32_CR4_GLOBAL_PAGES (1UL << 7)
#define CR4_OS_FXSR (1UL << 9)
#define CR4_OS_XMM_EXCEPTION (1UL << 10)
#define IA32_CR4_OSXSAVE (1UL << 18)
#define IA32_CR4_SMEP (1UL << 20)
#define IA32_CR4_SMAP (1UL << 21)
// Extended Control Register XCR0 flags
#define IA32_XCR0_X87 (1UL << 0)
#define IA32_XCR0_SSE (1UL << 1)
#define IA32_XCR0_AVX (1UL << 2)
// page fault error codes (http://wiki.osdev.org/Page_Fault)
#define PGFAULT_P 0x01 // Protection violation
#define PGFAULT_W 0x02 // Write
@@ -547,6 +553,16 @@ struct intel_microcode_extended_signature {
#define clear_ac() \
__asm__ volatile (ASM_CLAC : : : "memory")
#define xgetbv(reg) ({ \
uint32 low, high; \
__asm__ volatile ("xgetbv" : "=a" (low), "=d" (high), "c" (reg)); \
(low | (uint64)high << 32); \
})
#define xsetbv(reg, value) { \
uint32 low = value; uint32 high = value >> 32; \
__asm__ volatile ("xsetbv" : : "a" (low), "d" (high), "c" (reg)); }
#define out8(value,port) \
__asm__ ("outb %%al,%%dx" : : "a" (value), "d" (port))
@@ -53,8 +53,13 @@ struct arch_thread {
struct farcall interrupt_stack;
#endif
#ifndef __x86_64__
// 512 byte floating point save point - this must be 16 byte aligned
uint8 fpu_state[512] _ALIGNED(16);
#else
// floating point save point - this must be 64 byte aligned for xsave
uint8 fpu_state[1024] _ALIGNED(64);
#endif
addr_t GetFramePointer() const;
} _ALIGNED(16);