1 /* 2 * Copyright (c) 2019 Intel Corporation 3 * SPDX-License-Identifier: Apache-2.0 4 */ 5 6 #ifndef ZEPHYR_INCLUDE_ARCH_X86_INTEL64_THREAD_H_ 7 #define ZEPHYR_INCLUDE_ARCH_X86_INTEL64_THREAD_H_ 8 9 #define X86_THREAD_FLAG_ALL 0x01 /* _thread_arch.flags: entire state saved */ 10 11 /* 12 * GDT selectors - these must agree with the GDT layout in locore.S. 13 */ 14 15 #define X86_KERNEL_CS_32 0x08 /* 32-bit kernel code */ 16 #define X86_KERNEL_DS_32 0x10 /* 32-bit kernel data */ 17 #define X86_KERNEL_CS 0x18 /* 64-bit kernel code */ 18 #define X86_KERNEL_DS 0x20 /* 64-bit kernel data */ 19 #define X86_USER_CS_32 0x28 /* 32-bit user data (unused) */ 20 #define X86_USER_DS 0x30 /* 64-bit user mode data */ 21 #define X86_USER_CS 0x38 /* 64-bit user mode code */ 22 23 /* Value programmed into bits 63:32 of STAR MSR with proper segment 24 * descriptors for implementing user mode with syscall/sysret 25 */ 26 #define X86_STAR_UPPER ((X86_USER_CS_32 << 16) | X86_KERNEL_CS) 27 28 #define X86_KERNEL_CPU0_TR 0x40 /* 64-bit task state segment */ 29 #define X86_KERNEL_CPU1_TR 0x50 /* 64-bit task state segment */ 30 #define X86_KERNEL_CPU2_TR 0x60 /* 64-bit task state segment */ 31 #define X86_KERNEL_CPU3_TR 0x70 /* 64-bit task state segment */ 32 33 /* 34 * Some SSE definitions. Ideally these will ultimately be shared with 32-bit. 35 */ 36 37 #define X86_FXSAVE_SIZE 512 /* size and alignment of buffer ... */ 38 #define X86_FXSAVE_ALIGN 16 /* ... for FXSAVE/FXRSTOR ops */ 39 40 /* MXCSR Control and Status Register for SIMD floating-point operations. 41 * Set default value 1F80H according to the Intel(R) 64 and IA-32 Manual. 42 * Disable denormals-are-zeros mode. 43 */ 44 #define X86_MXCSR_SANE 0x1f80 45 46 #ifndef _ASMLANGUAGE 47 48 #include <zephyr/types.h> 49 #include <arch/x86/mmustructs.h> 50 51 /* 52 * 64-bit Task State Segment. One defined per CPU. 53 */ 54 55 struct x86_tss64 { 56 /* 57 * Architecturally-defined portion. It is somewhat tedious to 58 * enumerate each member specifically (rather than using arrays) 59 * but we need to get (some of) their offsets from assembly. 60 */ 61 62 uint8_t reserved0[4]; 63 64 uint64_t rsp0; /* privileged stacks */ 65 uint64_t rsp1; 66 uint64_t rsp2; 67 68 uint8_t reserved[8]; 69 70 uint64_t ist1; /* interrupt stacks */ 71 uint64_t ist2; 72 uint64_t ist3; 73 uint64_t ist4; 74 uint64_t ist5; 75 uint64_t ist6; 76 uint64_t ist7; 77 78 uint8_t reserved1[10]; 79 80 uint16_t iomapb; /* offset to I/O base */ 81 82 /* 83 * Zephyr specific portion. Stash per-CPU data here for convenience. 84 */ 85 86 struct _cpu *cpu; 87 #ifdef CONFIG_USERSPACE 88 /* Privilege mode stack pointer value when doing a system call */ 89 char *psp; 90 91 /* Storage area for user mode stack pointer when doing a syscall */ 92 char *usp; 93 #endif /* CONFIG_USERSPACE */ 94 } __packed __aligned(8); 95 96 typedef struct x86_tss64 x86_tss64_t; 97 98 /* 99 * The _callee_saved registers are unconditionally saved/restored across 100 * context switches; the _thread_arch registers are only preserved when 101 * the thread is interrupted. _arch_thread.flags tells __resume when to 102 * cheat and only restore the first set. For more details see locore.S. 103 */ 104 105 struct _callee_saved { 106 uint64_t rsp; 107 uint64_t rbx; 108 uint64_t rbp; 109 uint64_t r12; 110 uint64_t r13; 111 uint64_t r14; 112 uint64_t r15; 113 uint64_t rip; 114 uint64_t rflags; 115 }; 116 117 typedef struct _callee_saved _callee_saved_t; 118 119 struct _thread_arch { 120 uint8_t flags; 121 122 #ifdef CONFIG_USERSPACE 123 #ifndef CONFIG_X86_COMMON_PAGE_TABLE 124 /* Physical address of the page tables used by this thread */ 125 uintptr_t ptables; 126 #endif /* CONFIG_X86_COMMON_PAGE_TABLE */ 127 128 /* Initial privilege mode stack pointer when doing a system call. 129 * Un-set for supervisor threads. 130 */ 131 char *psp; 132 133 /* SS and CS selectors for this thread when restoring context */ 134 uint64_t ss; 135 uint64_t cs; 136 #endif 137 138 uint64_t rax; 139 uint64_t rcx; 140 uint64_t rdx; 141 uint64_t rsi; 142 uint64_t rdi; 143 uint64_t r8; 144 uint64_t r9; 145 uint64_t r10; 146 uint64_t r11; 147 char __aligned(X86_FXSAVE_ALIGN) sse[X86_FXSAVE_SIZE]; 148 }; 149 150 typedef struct _thread_arch _thread_arch_t; 151 152 #endif /* _ASMLANGUAGE */ 153 154 #endif /* ZEPHYR_INCLUDE_ARCH_X86_INTEL64_THREAD_H_ */ 155