1 /*
2  * Copyright 2014, General Dynamics C4 Systems
3  *
4  * SPDX-License-Identifier: GPL-2.0-only
5  */
6 
7 #pragma once
8 
9 #define CR0_MONITOR_COPROC  BIT(1)  /* Trap on FPU "WAIT" commands. */
10 #define CR0_EMULATION       BIT(2)  /* Enable OS emulation of FPU. */
11 #define CR0_TASK_SWITCH     BIT(3)  /* Trap on any FPU usage, for lazy FPU. */
12 #define CR0_NUMERIC_ERROR   BIT(5)  /* Internally handle FPU problems. */
13 #define CR0_WRITE_PROTECT   BIT(16) /* Write protection in supervisor mode. */
14 #define CR4_PCE             BIT(8)  /* Performance-Monitoring Counter enable. */
15 #define CR4_OSFXSR          BIT(9)  /* Enable SSE et. al. features. */
16 #define CR4_OSXMMEXCPT      BIT(10) /* Enable SSE exceptions. */
17 #define CR4_OSXSAVE         BIT(18) /* Enavle XSAVE feature set */
18 #define CR4_VMXE            BIT(13) /* Enable VMX mode. */
19 #define CR4_SMEP            BIT(20) /* Supervisor Mode Execution Prevention. */
20 #define CR4_SMAP            BIT(21) /* Supervisor Mode Access Prevention. */
21 
22 #define FLAGS_TF            BIT(8)  /* Trap Flag */
23 #define FLAGS_IF            BIT(9)  /* Interrupt enable Flag */
24 #define FLAGS_HIGH          BIT(1)  /* Bits in the FLAGS register that must be high */
25 #define FLAGS_LOW           (BIT(3) | BIT(5)) /* Bits in the FLAGS register that must be low */
26 #define FLAGS_MASK          MASK(12)/* Only the first 12 bits of the FLAGS are used, rest should be zero */
27 #define FLAGS_USER_DEFAULT  FLAGS_IF | FLAGS_HIGH
28 
29 /* We use a dummy variable to synchronize reads and writes to the control registers.
30  * this allows us to write inline asm blocks that do not have enforced memory
31  * clobbers for ordering. */
32 static unsigned long control_reg_order;
33 
34 #include <mode/machine/cpu_registers.h>
35 
xsetbv(uint32_t reg,uint64_t value)36 static inline void xsetbv(uint32_t reg, uint64_t value)
37 {
38     asm volatile("xsetbv" :: "d"((uint32_t)(value >> 32)), "a"((uint32_t)(value & 0xffffffff)), "c"(reg), "m"(control_reg_order));
39 }
40 
write_xcr0(uint64_t value)41 static inline void write_xcr0(uint64_t value)
42 {
43     xsetbv(0, value);
44 }
45 
46