1 | // SPDX-License-Identifier: GPL-3.0-or-later |
2 | |
3 | #include "mos/x86/tasks/fpu_context.h" |
4 | |
5 | #include "mos/misc/setup.h" |
6 | #include "mos/mm/slab.h" |
7 | #include "mos/platform/platform.h" |
8 | #include "mos/syslog/printk.h" |
9 | #include "mos/tasks/task_types.h" |
10 | |
11 | #include <mos_stdlib.h> |
12 | |
13 | slab_t *xsave_area_slab = NULL; |
14 | |
15 | static void setup_xsave_slab(void) |
16 | { |
17 | xsave_area_slab = kmemcache_create(name: "x86.xsave" , ent_size: platform_info->arch_info.xsave_size); |
18 | } |
19 | |
20 | MOS_INIT(SLAB_AUTOINIT, setup_xsave_slab); |
21 | |
22 | static const u64 RFBM = ~0ULL; |
23 | const reg32_t low = RFBM & 0xFFFFFFFF; |
24 | const reg32_t high = RFBM >> 32; |
25 | |
26 | void x86_xsave_thread(thread_t *thread) |
27 | { |
28 | if (!thread || thread->mode == THREAD_MODE_KERNEL) |
29 | return; // no, kernel threads don't have these |
30 | |
31 | if (!thread->platform_options.xsaveptr) |
32 | return; // this happens when the thread is being execve'd |
33 | |
34 | pr_dcont(scheduler, "saved." ); |
35 | __asm__ volatile("xsave %0" ::"m" (*thread->platform_options.xsaveptr), "a" (low), "d" (high)); |
36 | } |
37 | |
38 | void x86_xrstor_thread(thread_t *thread) |
39 | { |
40 | if (!thread || thread->mode == THREAD_MODE_KERNEL) |
41 | return; // no, kernel threads don't have these |
42 | |
43 | if (!thread->platform_options.xsaveptr) |
44 | return; // this happens when the thread is being execve'd |
45 | |
46 | pr_dcont(scheduler, "restored." ); |
47 | __asm__ volatile("xrstor %0" ::"m" (*thread->platform_options.xsaveptr), "a" (low), "d" (high)); |
48 | } |
49 | |