Currently we are using mxcsr register with the bit 6 DAZ enabled. When the denormals-are-zeros flag is set, the processor converts all denormal source operands to a zero with the sign of the original operand before performing any computations on them. It causes bugs in the SIMD XMM registers computation like #38646 I suggest to disable Denormals-Are-Zeros flag and mask division-by-zero exception. Set value to the default 1F80H according to the Intel(R) 64 and IA-32 Architectures Software Developer's Manual. Fix will let all x86 boards perform SIMD computation using XMM registers in the correct way. Fixes #38646 Signed-off-by: Maksim Masalski <maksim.masalski@intel.com>
155 lines
3.9 KiB
C
155 lines
3.9 KiB
C
/*
|
|
* Copyright (c) 2019 Intel Corporation
|
|
* SPDX-License-Identifier: Apache-2.0
|
|
*/
|
|
|
|
#ifndef ZEPHYR_INCLUDE_ARCH_X86_INTEL64_THREAD_H_
|
|
#define ZEPHYR_INCLUDE_ARCH_X86_INTEL64_THREAD_H_
|
|
|
|
#define X86_THREAD_FLAG_ALL 0x01 /* _thread_arch.flags: entire state saved */
|
|
|
|
/*
|
|
* GDT selectors - these must agree with the GDT layout in locore.S.
|
|
*/
|
|
|
|
#define X86_KERNEL_CS_32 0x08 /* 32-bit kernel code */
|
|
#define X86_KERNEL_DS_32 0x10 /* 32-bit kernel data */
|
|
#define X86_KERNEL_CS 0x18 /* 64-bit kernel code */
|
|
#define X86_KERNEL_DS 0x20 /* 64-bit kernel data */
|
|
#define X86_USER_CS_32 0x28 /* 32-bit user data (unused) */
|
|
#define X86_USER_DS 0x30 /* 64-bit user mode data */
|
|
#define X86_USER_CS 0x38 /* 64-bit user mode code */
|
|
|
|
/* Value programmed into bits 63:32 of STAR MSR with proper segment
|
|
* descriptors for implementing user mode with syscall/sysret
|
|
*/
|
|
#define X86_STAR_UPPER ((X86_USER_CS_32 << 16) | X86_KERNEL_CS)
|
|
|
|
#define X86_KERNEL_CPU0_TR 0x40 /* 64-bit task state segment */
|
|
#define X86_KERNEL_CPU1_TR 0x50 /* 64-bit task state segment */
|
|
#define X86_KERNEL_CPU2_TR 0x60 /* 64-bit task state segment */
|
|
#define X86_KERNEL_CPU3_TR 0x70 /* 64-bit task state segment */
|
|
|
|
/*
|
|
* Some SSE definitions. Ideally these will ultimately be shared with 32-bit.
|
|
*/
|
|
|
|
#define X86_FXSAVE_SIZE 512 /* size and alignment of buffer ... */
|
|
#define X86_FXSAVE_ALIGN 16 /* ... for FXSAVE/FXRSTOR ops */
|
|
|
|
/* MXCSR Control and Status Register for SIMD floating-point operations.
|
|
* Set default value 1F80H according to the Intel(R) 64 and IA-32 Manual.
|
|
* Disable denormals-are-zeros mode.
|
|
*/
|
|
#define X86_MXCSR_SANE 0x1f80
|
|
|
|
#ifndef _ASMLANGUAGE
|
|
|
|
#include <zephyr/types.h>
|
|
#include <arch/x86/mmustructs.h>
|
|
|
|
/*
|
|
* 64-bit Task State Segment. One defined per CPU.
|
|
*/
|
|
|
|
struct x86_tss64 {
|
|
/*
|
|
* Architecturally-defined portion. It is somewhat tedious to
|
|
* enumerate each member specifically (rather than using arrays)
|
|
* but we need to get (some of) their offsets from assembly.
|
|
*/
|
|
|
|
uint8_t reserved0[4];
|
|
|
|
uint64_t rsp0; /* privileged stacks */
|
|
uint64_t rsp1;
|
|
uint64_t rsp2;
|
|
|
|
uint8_t reserved[8];
|
|
|
|
uint64_t ist1; /* interrupt stacks */
|
|
uint64_t ist2;
|
|
uint64_t ist3;
|
|
uint64_t ist4;
|
|
uint64_t ist5;
|
|
uint64_t ist6;
|
|
uint64_t ist7;
|
|
|
|
uint8_t reserved1[10];
|
|
|
|
uint16_t iomapb; /* offset to I/O base */
|
|
|
|
/*
|
|
* Zephyr specific portion. Stash per-CPU data here for convenience.
|
|
*/
|
|
|
|
struct _cpu *cpu;
|
|
#ifdef CONFIG_USERSPACE
|
|
/* Privilege mode stack pointer value when doing a system call */
|
|
char *psp;
|
|
|
|
/* Storage area for user mode stack pointer when doing a syscall */
|
|
char *usp;
|
|
#endif /* CONFIG_USERSPACE */
|
|
} __packed __aligned(8);
|
|
|
|
typedef struct x86_tss64 x86_tss64_t;
|
|
|
|
/*
|
|
* The _callee_saved registers are unconditionally saved/restored across
|
|
* context switches; the _thread_arch registers are only preserved when
|
|
* the thread is interrupted. _arch_thread.flags tells __resume when to
|
|
* cheat and only restore the first set. For more details see locore.S.
|
|
*/
|
|
|
|
struct _callee_saved {
|
|
uint64_t rsp;
|
|
uint64_t rbx;
|
|
uint64_t rbp;
|
|
uint64_t r12;
|
|
uint64_t r13;
|
|
uint64_t r14;
|
|
uint64_t r15;
|
|
uint64_t rip;
|
|
uint64_t rflags;
|
|
};
|
|
|
|
typedef struct _callee_saved _callee_saved_t;
|
|
|
|
struct _thread_arch {
|
|
uint8_t flags;
|
|
|
|
#ifdef CONFIG_USERSPACE
|
|
#ifndef CONFIG_X86_COMMON_PAGE_TABLE
|
|
/* Physical address of the page tables used by this thread */
|
|
uintptr_t ptables;
|
|
#endif /* CONFIG_X86_COMMON_PAGE_TABLE */
|
|
|
|
/* Initial privilege mode stack pointer when doing a system call.
|
|
* Un-set for supervisor threads.
|
|
*/
|
|
char *psp;
|
|
|
|
/* SS and CS selectors for this thread when restoring context */
|
|
uint64_t ss;
|
|
uint64_t cs;
|
|
#endif
|
|
|
|
uint64_t rax;
|
|
uint64_t rcx;
|
|
uint64_t rdx;
|
|
uint64_t rsi;
|
|
uint64_t rdi;
|
|
uint64_t r8;
|
|
uint64_t r9;
|
|
uint64_t r10;
|
|
uint64_t r11;
|
|
char __aligned(X86_FXSAVE_ALIGN) sse[X86_FXSAVE_SIZE];
|
|
};
|
|
|
|
typedef struct _thread_arch _thread_arch_t;
|
|
|
|
#endif /* _ASMLANGUAGE */
|
|
|
|
#endif /* ZEPHYR_INCLUDE_ARCH_X86_INTEL64_THREAD_H_ */
|