xref: /openbmc/u-boot/arch/x86/include/asm/msr.h (revision 98568f0fa96bca77382ec6fdf06852ada559c2bf)
1*98568f0fSGraeme Russ /*
2*98568f0fSGraeme Russ  * Taken from the linux kernel file of the same name
3*98568f0fSGraeme Russ  *
4*98568f0fSGraeme Russ  * (C) Copyright 2012
5*98568f0fSGraeme Russ  * Graeme Russ, <graeme.russ@gmail.com>
6*98568f0fSGraeme Russ  *
7*98568f0fSGraeme Russ  * This program is free software; you can redistribute it and/or
8*98568f0fSGraeme Russ  * modify it under the terms of the GNU General Public License as
9*98568f0fSGraeme Russ  * published by the Free Software Foundation; either version 2 of
10*98568f0fSGraeme Russ  * the License, or (at your option) any later version.
11*98568f0fSGraeme Russ  *
12*98568f0fSGraeme Russ  * This program is distributed in the hope that it will be useful,
13*98568f0fSGraeme Russ  * but WITHOUT ANY WARRANTY; without even the implied warranty of
14*98568f0fSGraeme Russ  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15*98568f0fSGraeme Russ  * GNU General Public License for more details.
16*98568f0fSGraeme Russ  *
17*98568f0fSGraeme Russ  * You should have received a copy of the GNU General Public License
18*98568f0fSGraeme Russ  * along with this program; if not, write to the Free Software
19*98568f0fSGraeme Russ  * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
20*98568f0fSGraeme Russ  * MA 02111-1307 USA
21*98568f0fSGraeme Russ  */
22*98568f0fSGraeme Russ 
23*98568f0fSGraeme Russ #ifndef _ASM_X86_MSR_H
24*98568f0fSGraeme Russ #define _ASM_X86_MSR_H
25*98568f0fSGraeme Russ 
26*98568f0fSGraeme Russ #include <asm/msr-index.h>
27*98568f0fSGraeme Russ 
28*98568f0fSGraeme Russ #ifndef __ASSEMBLY__
29*98568f0fSGraeme Russ 
30*98568f0fSGraeme Russ #include <linux/types.h>
31*98568f0fSGraeme Russ #include <linux/ioctl.h>
32*98568f0fSGraeme Russ 
33*98568f0fSGraeme Russ #define X86_IOC_RDMSR_REGS	_IOWR('c', 0xA0, __u32[8])
34*98568f0fSGraeme Russ #define X86_IOC_WRMSR_REGS	_IOWR('c', 0xA1, __u32[8])
35*98568f0fSGraeme Russ 
36*98568f0fSGraeme Russ #ifdef __KERNEL__
37*98568f0fSGraeme Russ 
38*98568f0fSGraeme Russ #include <asm/errno.h>
39*98568f0fSGraeme Russ 
40*98568f0fSGraeme Russ struct msr {
41*98568f0fSGraeme Russ 	union {
42*98568f0fSGraeme Russ 		struct {
43*98568f0fSGraeme Russ 			u32 l;
44*98568f0fSGraeme Russ 			u32 h;
45*98568f0fSGraeme Russ 		};
46*98568f0fSGraeme Russ 		u64 q;
47*98568f0fSGraeme Russ 	};
48*98568f0fSGraeme Russ };
49*98568f0fSGraeme Russ 
50*98568f0fSGraeme Russ struct msr_info {
51*98568f0fSGraeme Russ 	u32 msr_no;
52*98568f0fSGraeme Russ 	struct msr reg;
53*98568f0fSGraeme Russ 	struct msr *msrs;
54*98568f0fSGraeme Russ 	int err;
55*98568f0fSGraeme Russ };
56*98568f0fSGraeme Russ 
57*98568f0fSGraeme Russ struct msr_regs_info {
58*98568f0fSGraeme Russ 	u32 *regs;
59*98568f0fSGraeme Russ 	int err;
60*98568f0fSGraeme Russ };
61*98568f0fSGraeme Russ 
62*98568f0fSGraeme Russ static inline unsigned long long native_read_tscp(unsigned int *aux)
63*98568f0fSGraeme Russ {
64*98568f0fSGraeme Russ 	unsigned long low, high;
65*98568f0fSGraeme Russ 	asm volatile(".byte 0x0f,0x01,0xf9"
66*98568f0fSGraeme Russ 		     : "=a" (low), "=d" (high), "=c" (*aux));
67*98568f0fSGraeme Russ 	return low | ((u64)high << 32);
68*98568f0fSGraeme Russ }
69*98568f0fSGraeme Russ 
70*98568f0fSGraeme Russ /*
71*98568f0fSGraeme Russ  * both i386 and x86_64 returns 64-bit value in edx:eax, but gcc's "A"
72*98568f0fSGraeme Russ  * constraint has different meanings. For i386, "A" means exactly
73*98568f0fSGraeme Russ  * edx:eax, while for x86_64 it doesn't mean rdx:rax or edx:eax. Instead,
74*98568f0fSGraeme Russ  * it means rax *or* rdx.
75*98568f0fSGraeme Russ  */
76*98568f0fSGraeme Russ #ifdef CONFIG_X86_64
77*98568f0fSGraeme Russ #define DECLARE_ARGS(val, low, high)	unsigned low, high
78*98568f0fSGraeme Russ #define EAX_EDX_VAL(val, low, high)	((low) | ((u64)(high) << 32))
79*98568f0fSGraeme Russ #define EAX_EDX_ARGS(val, low, high)	"a" (low), "d" (high)
80*98568f0fSGraeme Russ #define EAX_EDX_RET(val, low, high)	"=a" (low), "=d" (high)
81*98568f0fSGraeme Russ #else
82*98568f0fSGraeme Russ #define DECLARE_ARGS(val, low, high)	unsigned long long val
83*98568f0fSGraeme Russ #define EAX_EDX_VAL(val, low, high)	(val)
84*98568f0fSGraeme Russ #define EAX_EDX_ARGS(val, low, high)	"A" (val)
85*98568f0fSGraeme Russ #define EAX_EDX_RET(val, low, high)	"=A" (val)
86*98568f0fSGraeme Russ #endif
87*98568f0fSGraeme Russ 
88*98568f0fSGraeme Russ static inline unsigned long long native_read_msr(unsigned int msr)
89*98568f0fSGraeme Russ {
90*98568f0fSGraeme Russ 	DECLARE_ARGS(val, low, high);
91*98568f0fSGraeme Russ 
92*98568f0fSGraeme Russ 	asm volatile("rdmsr" : EAX_EDX_RET(val, low, high) : "c" (msr));
93*98568f0fSGraeme Russ 	return EAX_EDX_VAL(val, low, high);
94*98568f0fSGraeme Russ }
95*98568f0fSGraeme Russ 
96*98568f0fSGraeme Russ static inline void native_write_msr(unsigned int msr,
97*98568f0fSGraeme Russ 				    unsigned low, unsigned high)
98*98568f0fSGraeme Russ {
99*98568f0fSGraeme Russ 	asm volatile("wrmsr" : : "c" (msr), "a"(low), "d" (high) : "memory");
100*98568f0fSGraeme Russ }
101*98568f0fSGraeme Russ 
102*98568f0fSGraeme Russ extern unsigned long long native_read_tsc(void);
103*98568f0fSGraeme Russ 
104*98568f0fSGraeme Russ extern int native_rdmsr_safe_regs(u32 regs[8]);
105*98568f0fSGraeme Russ extern int native_wrmsr_safe_regs(u32 regs[8]);
106*98568f0fSGraeme Russ 
107*98568f0fSGraeme Russ static inline unsigned long long native_read_pmc(int counter)
108*98568f0fSGraeme Russ {
109*98568f0fSGraeme Russ 	DECLARE_ARGS(val, low, high);
110*98568f0fSGraeme Russ 
111*98568f0fSGraeme Russ 	asm volatile("rdpmc" : EAX_EDX_RET(val, low, high) : "c" (counter));
112*98568f0fSGraeme Russ 	return EAX_EDX_VAL(val, low, high);
113*98568f0fSGraeme Russ }
114*98568f0fSGraeme Russ 
115*98568f0fSGraeme Russ #ifdef CONFIG_PARAVIRT
116*98568f0fSGraeme Russ #include <asm/paravirt.h>
117*98568f0fSGraeme Russ #else
118*98568f0fSGraeme Russ #include <errno.h>
119*98568f0fSGraeme Russ /*
120*98568f0fSGraeme Russ  * Access to machine-specific registers (available on 586 and better only)
121*98568f0fSGraeme Russ  * Note: the rd* operations modify the parameters directly (without using
122*98568f0fSGraeme Russ  * pointer indirection), this allows gcc to optimize better
123*98568f0fSGraeme Russ  */
124*98568f0fSGraeme Russ 
125*98568f0fSGraeme Russ #define rdmsr(msr, val1, val2)					\
126*98568f0fSGraeme Russ do {								\
127*98568f0fSGraeme Russ 	u64 __val = native_read_msr((msr));			\
128*98568f0fSGraeme Russ 	(void)((val1) = (u32)__val);				\
129*98568f0fSGraeme Russ 	(void)((val2) = (u32)(__val >> 32));			\
130*98568f0fSGraeme Russ } while (0)
131*98568f0fSGraeme Russ 
132*98568f0fSGraeme Russ static inline void wrmsr(unsigned msr, unsigned low, unsigned high)
133*98568f0fSGraeme Russ {
134*98568f0fSGraeme Russ 	native_write_msr(msr, low, high);
135*98568f0fSGraeme Russ }
136*98568f0fSGraeme Russ 
137*98568f0fSGraeme Russ #define rdmsrl(msr, val)			\
138*98568f0fSGraeme Russ 	((val) = native_read_msr((msr)))
139*98568f0fSGraeme Russ 
140*98568f0fSGraeme Russ #define wrmsrl(msr, val)						\
141*98568f0fSGraeme Russ 	native_write_msr((msr), (u32)((u64)(val)), (u32)((u64)(val) >> 32))
142*98568f0fSGraeme Russ 
143*98568f0fSGraeme Russ /* rdmsr with exception handling */
144*98568f0fSGraeme Russ #define rdmsr_safe(msr, p1, p2)					\
145*98568f0fSGraeme Russ ({								\
146*98568f0fSGraeme Russ 	int __err;						\
147*98568f0fSGraeme Russ 	u64 __val = native_read_msr_safe((msr), &__err);	\
148*98568f0fSGraeme Russ 	(*p1) = (u32)__val;					\
149*98568f0fSGraeme Russ 	(*p2) = (u32)(__val >> 32);				\
150*98568f0fSGraeme Russ 	__err;							\
151*98568f0fSGraeme Russ })
152*98568f0fSGraeme Russ 
153*98568f0fSGraeme Russ static inline int rdmsrl_amd_safe(unsigned msr, unsigned long long *p)
154*98568f0fSGraeme Russ {
155*98568f0fSGraeme Russ 	u32 gprs[8] = { 0 };
156*98568f0fSGraeme Russ 	int err;
157*98568f0fSGraeme Russ 
158*98568f0fSGraeme Russ 	gprs[1] = msr;
159*98568f0fSGraeme Russ 	gprs[7] = 0x9c5a203a;
160*98568f0fSGraeme Russ 
161*98568f0fSGraeme Russ 	err = native_rdmsr_safe_regs(gprs);
162*98568f0fSGraeme Russ 
163*98568f0fSGraeme Russ 	*p = gprs[0] | ((u64)gprs[2] << 32);
164*98568f0fSGraeme Russ 
165*98568f0fSGraeme Russ 	return err;
166*98568f0fSGraeme Russ }
167*98568f0fSGraeme Russ 
168*98568f0fSGraeme Russ static inline int wrmsrl_amd_safe(unsigned msr, unsigned long long val)
169*98568f0fSGraeme Russ {
170*98568f0fSGraeme Russ 	u32 gprs[8] = { 0 };
171*98568f0fSGraeme Russ 
172*98568f0fSGraeme Russ 	gprs[0] = (u32)val;
173*98568f0fSGraeme Russ 	gprs[1] = msr;
174*98568f0fSGraeme Russ 	gprs[2] = val >> 32;
175*98568f0fSGraeme Russ 	gprs[7] = 0x9c5a203a;
176*98568f0fSGraeme Russ 
177*98568f0fSGraeme Russ 	return native_wrmsr_safe_regs(gprs);
178*98568f0fSGraeme Russ }
179*98568f0fSGraeme Russ 
180*98568f0fSGraeme Russ static inline int rdmsr_safe_regs(u32 regs[8])
181*98568f0fSGraeme Russ {
182*98568f0fSGraeme Russ 	return native_rdmsr_safe_regs(regs);
183*98568f0fSGraeme Russ }
184*98568f0fSGraeme Russ 
185*98568f0fSGraeme Russ static inline int wrmsr_safe_regs(u32 regs[8])
186*98568f0fSGraeme Russ {
187*98568f0fSGraeme Russ 	return native_wrmsr_safe_regs(regs);
188*98568f0fSGraeme Russ }
189*98568f0fSGraeme Russ 
190*98568f0fSGraeme Russ #define rdtscl(low)						\
191*98568f0fSGraeme Russ 	((low) = (u32)__native_read_tsc())
192*98568f0fSGraeme Russ 
193*98568f0fSGraeme Russ #define rdtscll(val)						\
194*98568f0fSGraeme Russ 	((val) = __native_read_tsc())
195*98568f0fSGraeme Russ 
196*98568f0fSGraeme Russ #define rdpmc(counter, low, high)			\
197*98568f0fSGraeme Russ do {							\
198*98568f0fSGraeme Russ 	u64 _l = native_read_pmc((counter));		\
199*98568f0fSGraeme Russ 	(low)  = (u32)_l;				\
200*98568f0fSGraeme Russ 	(high) = (u32)(_l >> 32);			\
201*98568f0fSGraeme Russ } while (0)
202*98568f0fSGraeme Russ 
203*98568f0fSGraeme Russ #define rdtscp(low, high, aux)					\
204*98568f0fSGraeme Russ do {                                                            \
205*98568f0fSGraeme Russ 	unsigned long long _val = native_read_tscp(&(aux));     \
206*98568f0fSGraeme Russ 	(low) = (u32)_val;                                      \
207*98568f0fSGraeme Russ 	(high) = (u32)(_val >> 32);                             \
208*98568f0fSGraeme Russ } while (0)
209*98568f0fSGraeme Russ 
210*98568f0fSGraeme Russ #define rdtscpll(val, aux) (val) = native_read_tscp(&(aux))
211*98568f0fSGraeme Russ 
212*98568f0fSGraeme Russ #endif	/* !CONFIG_PARAVIRT */
213*98568f0fSGraeme Russ 
214*98568f0fSGraeme Russ 
215*98568f0fSGraeme Russ #define checking_wrmsrl(msr, val) wrmsr_safe((msr), (u32)(val),		\
216*98568f0fSGraeme Russ 					     (u32)((val) >> 32))
217*98568f0fSGraeme Russ 
218*98568f0fSGraeme Russ #define write_tsc(val1, val2) wrmsr(MSR_IA32_TSC, (val1), (val2))
219*98568f0fSGraeme Russ 
220*98568f0fSGraeme Russ #define write_rdtscp_aux(val) wrmsr(MSR_TSC_AUX, (val), 0)
221*98568f0fSGraeme Russ 
222*98568f0fSGraeme Russ struct msr *msrs_alloc(void);
223*98568f0fSGraeme Russ void msrs_free(struct msr *msrs);
224*98568f0fSGraeme Russ 
225*98568f0fSGraeme Russ #ifdef CONFIG_SMP
226*98568f0fSGraeme Russ int rdmsr_on_cpu(unsigned int cpu, u32 msr_no, u32 *l, u32 *h);
227*98568f0fSGraeme Russ int wrmsr_on_cpu(unsigned int cpu, u32 msr_no, u32 l, u32 h);
228*98568f0fSGraeme Russ void rdmsr_on_cpus(const struct cpumask *mask, u32 msr_no, struct msr *msrs);
229*98568f0fSGraeme Russ void wrmsr_on_cpus(const struct cpumask *mask, u32 msr_no, struct msr *msrs);
230*98568f0fSGraeme Russ int rdmsr_safe_on_cpu(unsigned int cpu, u32 msr_no, u32 *l, u32 *h);
231*98568f0fSGraeme Russ int wrmsr_safe_on_cpu(unsigned int cpu, u32 msr_no, u32 l, u32 h);
232*98568f0fSGraeme Russ int rdmsr_safe_regs_on_cpu(unsigned int cpu, u32 regs[8]);
233*98568f0fSGraeme Russ int wrmsr_safe_regs_on_cpu(unsigned int cpu, u32 regs[8]);
234*98568f0fSGraeme Russ 
235*98568f0fSGraeme Russ #endif  /* CONFIG_SMP */
236*98568f0fSGraeme Russ #endif /* __KERNEL__ */
237*98568f0fSGraeme Russ #endif /* __ASSEMBLY__ */
238*98568f0fSGraeme Russ #endif /* _ASM_X86_MSR_H */
239