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