1 /*
2  * Copyright (c) 2019 Intel Corp.
3  * SPDX-License-Identifier: Apache-2.0
4  */
5 
6 #ifndef ZEPHYR_INCLUDE_ARCH_X86_MSR_H_
7 #define ZEPHYR_INCLUDE_ARCH_X86_MSR_H_
8 
9 /*
10  * Model specific registers (MSR).  Access with z_x86_msr_read/write().
11  */
12 
13 #define X86_TIME_STAMP_COUNTER_MSR	0x00000010
14 
15 #define X86_SPEC_CTRL_MSR		0x00000048
16 #define X86_SPEC_CTRL_MSR_IBRS		BIT(0)
17 #define X86_SPEC_CTRL_MSR_SSBD		BIT(2)
18 
19 #define X86_APIC_BASE_MSR		0x0000001b
20 #define X86_APIC_BASE_MSR_X2APIC	BIT(10)
21 
22 #define X86_MTRR_DEF_TYPE_MSR		0x000002ff
23 #define X86_MTRR_DEF_TYPE_MSR_ENABLE	BIT(11)
24 
25 #define X86_X2APIC_BASE_MSR		0x00000800 /* .. thru 0x00000BFF */
26 
27 #define X86_EFER_MSR			0xC0000080U
28 #define X86_EFER_MSR_SCE		BIT(0)
29 #define X86_EFER_MSR_LME		BIT(8)
30 #define X86_EFER_MSR_NXE		BIT(11)
31 
32 /* STAR 31:0   Unused in long mode
33  *      47:32  Kernel CS (SS = CS+8)
34  *      63:48  User CS (SS = CS+8)
35  */
36 #define X86_STAR_MSR			0xC0000081U
37 
38 /* Location for system call entry point */
39 #define X86_LSTAR_MSR			0xC0000082U
40 
41 /* Low 32 bits in this MSR are the SYSCALL mask applied to EFLAGS */
42 #define X86_FMASK_MSR			0xC0000084U
43 
44 #define X86_FS_BASE			0xC0000100U
45 #define X86_GS_BASE			0xC0000101U
46 #define X86_KERNEL_GS_BASE		0xC0000102U
47 
48 #ifndef _ASMLANGUAGE
49 #ifdef __cplusplus
50 extern "C" {
51 #endif
52 
53 /*
54  * z_x86_msr_write() is shared between 32- and 64-bit implementations, but
55  * due to ABI differences with long return values, z_x86_msr_read() is not.
56  */
57 
z_x86_msr_write(unsigned int msr,uint64_t data)58 static inline void z_x86_msr_write(unsigned int msr, uint64_t data)
59 {
60 	uint32_t high = data >> 32;
61 	uint32_t low = data & 0xFFFFFFFFU;
62 
63 	__asm__ volatile ("wrmsr" : : "c"(msr), "a"(low), "d"(high));
64 }
65 
66 #ifdef CONFIG_X86_64
67 
z_x86_msr_read(unsigned int msr)68 static inline uint64_t z_x86_msr_read(unsigned int msr)
69 {
70 	union {
71 		struct {
72 			uint32_t lo;
73 			uint32_t hi;
74 		};
75 		uint64_t value;
76 	} rv;
77 
78 	__asm__ volatile ("rdmsr" : "=a" (rv.lo), "=d" (rv.hi) : "c" (msr));
79 
80 	return rv.value;
81 }
82 
83 #else
84 
z_x86_msr_read(unsigned int msr)85 static inline uint64_t z_x86_msr_read(unsigned int msr)
86 {
87 	uint64_t ret;
88 
89 	__asm__ volatile("rdmsr" : "=A" (ret) : "c" (msr));
90 
91 	return ret;
92 }
93 
94 #endif
95 
96 #ifdef __cplusplus
97 }
98 #endif
99 #endif /* _ASMLANGUAGE */
100 
101 #endif /* ZEPHYR_INCLUDE_ARCH_X86_MSR_H_ */
102