xref: /aosp_15_r20/external/flashrom/hwaccess_x86_msr.c (revision 0d6140be3aa665ecc836e8907834fcd3e3b018fc)
1*0d6140beSAndroid Build Coastguard Worker /*
2*0d6140beSAndroid Build Coastguard Worker  * This file is part of the flashrom project.
3*0d6140beSAndroid Build Coastguard Worker  *
4*0d6140beSAndroid Build Coastguard Worker  * Copyright (C) 2009 Peter Stuge <[email protected]>
5*0d6140beSAndroid Build Coastguard Worker  * Copyright (C) 2009 coresystems GmbH
6*0d6140beSAndroid Build Coastguard Worker  * Copyright (C) 2010 Carl-Daniel Hailfinger
7*0d6140beSAndroid Build Coastguard Worker  * Copyright (C) 2010 Rudolf Marek <[email protected]>
8*0d6140beSAndroid Build Coastguard Worker  *
9*0d6140beSAndroid Build Coastguard Worker  * This program is free software; you can redistribute it and/or modify
10*0d6140beSAndroid Build Coastguard Worker  * it under the terms of the GNU General Public License as published by
11*0d6140beSAndroid Build Coastguard Worker  * the Free Software Foundation; version 2 of the License.
12*0d6140beSAndroid Build Coastguard Worker  *
13*0d6140beSAndroid Build Coastguard Worker  * This program is distributed in the hope that it will be useful,
14*0d6140beSAndroid Build Coastguard Worker  * but WITHOUT ANY WARRANTY; without even the implied warranty of
15*0d6140beSAndroid Build Coastguard Worker  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16*0d6140beSAndroid Build Coastguard Worker  * GNU General Public License for more details.
17*0d6140beSAndroid Build Coastguard Worker  */
18*0d6140beSAndroid Build Coastguard Worker 
19*0d6140beSAndroid Build Coastguard Worker /* MSR abstraction implementations for Linux, OpenBSD, FreeBSD/Dragonfly, OSX, libpayload
20*0d6140beSAndroid Build Coastguard Worker  * and a non-working default implementation on the bottom.
21*0d6140beSAndroid Build Coastguard Worker  */
22*0d6140beSAndroid Build Coastguard Worker 
23*0d6140beSAndroid Build Coastguard Worker #include "hwaccess_x86_msr.h"
24*0d6140beSAndroid Build Coastguard Worker #include "flash.h"
25*0d6140beSAndroid Build Coastguard Worker 
26*0d6140beSAndroid Build Coastguard Worker #ifdef __linux__
27*0d6140beSAndroid Build Coastguard Worker /*
28*0d6140beSAndroid Build Coastguard Worker  * Reading and writing to MSRs, however requires instructions rdmsr/wrmsr,
29*0d6140beSAndroid Build Coastguard Worker  * which are ring0 privileged instructions so only the kernel can do the
30*0d6140beSAndroid Build Coastguard Worker  * read/write. This function, therefore, requires that the msr kernel module
31*0d6140beSAndroid Build Coastguard Worker  * be loaded to access these instructions from user space using device
32*0d6140beSAndroid Build Coastguard Worker  * /dev/cpu/0/msr.
33*0d6140beSAndroid Build Coastguard Worker  */
34*0d6140beSAndroid Build Coastguard Worker 
35*0d6140beSAndroid Build Coastguard Worker #include <stdint.h>
36*0d6140beSAndroid Build Coastguard Worker #include <stdlib.h>
37*0d6140beSAndroid Build Coastguard Worker #include <errno.h>
38*0d6140beSAndroid Build Coastguard Worker #include <fcntl.h>
39*0d6140beSAndroid Build Coastguard Worker #include <string.h>
40*0d6140beSAndroid Build Coastguard Worker #include <unistd.h>
41*0d6140beSAndroid Build Coastguard Worker 
42*0d6140beSAndroid Build Coastguard Worker static int fd_msr = -1;
43*0d6140beSAndroid Build Coastguard Worker 
msr_read(int addr)44*0d6140beSAndroid Build Coastguard Worker msr_t msr_read(int addr)
45*0d6140beSAndroid Build Coastguard Worker {
46*0d6140beSAndroid Build Coastguard Worker 	uint32_t buf[2];
47*0d6140beSAndroid Build Coastguard Worker 	msr_t msr = { 0xffffffff, 0xffffffff };
48*0d6140beSAndroid Build Coastguard Worker 
49*0d6140beSAndroid Build Coastguard Worker 	if (lseek(fd_msr, (off_t) addr, SEEK_SET) == -1) {
50*0d6140beSAndroid Build Coastguard Worker 		msg_perr("Could not lseek() MSR: %s\n", strerror(errno));
51*0d6140beSAndroid Build Coastguard Worker 		close(fd_msr);
52*0d6140beSAndroid Build Coastguard Worker 		exit(1);
53*0d6140beSAndroid Build Coastguard Worker 	}
54*0d6140beSAndroid Build Coastguard Worker 
55*0d6140beSAndroid Build Coastguard Worker 	if (read(fd_msr, buf, 8) == 8) {
56*0d6140beSAndroid Build Coastguard Worker 		msr.lo = buf[0];
57*0d6140beSAndroid Build Coastguard Worker 		msr.hi = buf[1];
58*0d6140beSAndroid Build Coastguard Worker 		return msr;
59*0d6140beSAndroid Build Coastguard Worker 	}
60*0d6140beSAndroid Build Coastguard Worker 
61*0d6140beSAndroid Build Coastguard Worker 	if (errno != EIO) {
62*0d6140beSAndroid Build Coastguard Worker 		// A severe error.
63*0d6140beSAndroid Build Coastguard Worker 		msg_perr("Could not read() MSR: %s\n", strerror(errno));
64*0d6140beSAndroid Build Coastguard Worker 		close(fd_msr);
65*0d6140beSAndroid Build Coastguard Worker 		exit(1);
66*0d6140beSAndroid Build Coastguard Worker 	}
67*0d6140beSAndroid Build Coastguard Worker 
68*0d6140beSAndroid Build Coastguard Worker 	return msr;
69*0d6140beSAndroid Build Coastguard Worker }
70*0d6140beSAndroid Build Coastguard Worker 
msr_write(int addr,msr_t msr)71*0d6140beSAndroid Build Coastguard Worker int msr_write(int addr, msr_t msr)
72*0d6140beSAndroid Build Coastguard Worker {
73*0d6140beSAndroid Build Coastguard Worker 	uint32_t buf[2];
74*0d6140beSAndroid Build Coastguard Worker 	buf[0] = msr.lo;
75*0d6140beSAndroid Build Coastguard Worker 	buf[1] = msr.hi;
76*0d6140beSAndroid Build Coastguard Worker 
77*0d6140beSAndroid Build Coastguard Worker 	if (lseek(fd_msr, (off_t) addr, SEEK_SET) == -1) {
78*0d6140beSAndroid Build Coastguard Worker 		msg_perr("Could not lseek() MSR: %s\n", strerror(errno));
79*0d6140beSAndroid Build Coastguard Worker 		close(fd_msr);
80*0d6140beSAndroid Build Coastguard Worker 		exit(1);
81*0d6140beSAndroid Build Coastguard Worker 	}
82*0d6140beSAndroid Build Coastguard Worker 
83*0d6140beSAndroid Build Coastguard Worker 	if (write(fd_msr, buf, 8) != 8 && errno != EIO) {
84*0d6140beSAndroid Build Coastguard Worker 		msg_perr("Could not write() MSR: %s\n", strerror(errno));
85*0d6140beSAndroid Build Coastguard Worker 		close(fd_msr);
86*0d6140beSAndroid Build Coastguard Worker 		exit(1);
87*0d6140beSAndroid Build Coastguard Worker 	}
88*0d6140beSAndroid Build Coastguard Worker 
89*0d6140beSAndroid Build Coastguard Worker 	/* Some MSRs must not be written. */
90*0d6140beSAndroid Build Coastguard Worker 	if (errno == EIO)
91*0d6140beSAndroid Build Coastguard Worker 		return -1;
92*0d6140beSAndroid Build Coastguard Worker 
93*0d6140beSAndroid Build Coastguard Worker 	return 0;
94*0d6140beSAndroid Build Coastguard Worker }
95*0d6140beSAndroid Build Coastguard Worker 
msr_setup(int cpu)96*0d6140beSAndroid Build Coastguard Worker int msr_setup(int cpu)
97*0d6140beSAndroid Build Coastguard Worker {
98*0d6140beSAndroid Build Coastguard Worker 	char msrfilename[64] = { 0 };
99*0d6140beSAndroid Build Coastguard Worker 	snprintf(msrfilename, sizeof(msrfilename), "/dev/cpu/%d/msr", cpu);
100*0d6140beSAndroid Build Coastguard Worker 
101*0d6140beSAndroid Build Coastguard Worker 	if (fd_msr != -1) {
102*0d6140beSAndroid Build Coastguard Worker 		msg_pinfo("MSR was already initialized\n");
103*0d6140beSAndroid Build Coastguard Worker 		return -1;
104*0d6140beSAndroid Build Coastguard Worker 	}
105*0d6140beSAndroid Build Coastguard Worker 
106*0d6140beSAndroid Build Coastguard Worker 	fd_msr = open(msrfilename, O_RDWR);
107*0d6140beSAndroid Build Coastguard Worker 
108*0d6140beSAndroid Build Coastguard Worker 	if (fd_msr < 0) {
109*0d6140beSAndroid Build Coastguard Worker 		msg_perr("Error while opening %s: %s\n", msrfilename, strerror(errno));
110*0d6140beSAndroid Build Coastguard Worker 		msg_pinfo("Did you run 'modprobe msr'?\n");
111*0d6140beSAndroid Build Coastguard Worker 		return -1;
112*0d6140beSAndroid Build Coastguard Worker 	}
113*0d6140beSAndroid Build Coastguard Worker 
114*0d6140beSAndroid Build Coastguard Worker 	return 0;
115*0d6140beSAndroid Build Coastguard Worker }
116*0d6140beSAndroid Build Coastguard Worker 
msr_cleanup(void)117*0d6140beSAndroid Build Coastguard Worker void msr_cleanup(void)
118*0d6140beSAndroid Build Coastguard Worker {
119*0d6140beSAndroid Build Coastguard Worker 	if (fd_msr == -1) {
120*0d6140beSAndroid Build Coastguard Worker 		msg_pinfo("No MSR initialized.\n");
121*0d6140beSAndroid Build Coastguard Worker 		return;
122*0d6140beSAndroid Build Coastguard Worker 	}
123*0d6140beSAndroid Build Coastguard Worker 
124*0d6140beSAndroid Build Coastguard Worker 	close(fd_msr);
125*0d6140beSAndroid Build Coastguard Worker 
126*0d6140beSAndroid Build Coastguard Worker 	/* Clear MSR file descriptor. */
127*0d6140beSAndroid Build Coastguard Worker 	fd_msr = -1;
128*0d6140beSAndroid Build Coastguard Worker }
129*0d6140beSAndroid Build Coastguard Worker #elif defined(__OpenBSD__) && defined (__i386__) /* This does only work for certain AMD Geode LX systems see amdmsr(4). */
130*0d6140beSAndroid Build Coastguard Worker #include <stdlib.h>
131*0d6140beSAndroid Build Coastguard Worker #include <stdint.h>
132*0d6140beSAndroid Build Coastguard Worker #include <stdio.h>
133*0d6140beSAndroid Build Coastguard Worker #include <string.h>
134*0d6140beSAndroid Build Coastguard Worker #include <errno.h>
135*0d6140beSAndroid Build Coastguard Worker #include <fcntl.h>
136*0d6140beSAndroid Build Coastguard Worker #include <unistd.h>
137*0d6140beSAndroid Build Coastguard Worker #include <sys/ioctl.h>
138*0d6140beSAndroid Build Coastguard Worker #include <machine/amdmsr.h>
139*0d6140beSAndroid Build Coastguard Worker 
140*0d6140beSAndroid Build Coastguard Worker static int fd_msr = -1;
141*0d6140beSAndroid Build Coastguard Worker 
msr_read(int addr)142*0d6140beSAndroid Build Coastguard Worker msr_t msr_read(int addr)
143*0d6140beSAndroid Build Coastguard Worker {
144*0d6140beSAndroid Build Coastguard Worker 	struct amdmsr_req args;
145*0d6140beSAndroid Build Coastguard Worker 
146*0d6140beSAndroid Build Coastguard Worker 	msr_t msr = { 0xffffffff, 0xffffffff };
147*0d6140beSAndroid Build Coastguard Worker 
148*0d6140beSAndroid Build Coastguard Worker 	args.addr = (uint32_t)addr;
149*0d6140beSAndroid Build Coastguard Worker 
150*0d6140beSAndroid Build Coastguard Worker 	if (ioctl(fd_msr, RDMSR, &args) < 0) {
151*0d6140beSAndroid Build Coastguard Worker 		msg_perr("Error while executing RDMSR ioctl: %s\n", strerror(errno));
152*0d6140beSAndroid Build Coastguard Worker 		close(fd_msr);
153*0d6140beSAndroid Build Coastguard Worker 		exit(1);
154*0d6140beSAndroid Build Coastguard Worker 	}
155*0d6140beSAndroid Build Coastguard Worker 
156*0d6140beSAndroid Build Coastguard Worker 	msr.lo = args.val & 0xffffffff;
157*0d6140beSAndroid Build Coastguard Worker 	msr.hi = args.val >> 32;
158*0d6140beSAndroid Build Coastguard Worker 
159*0d6140beSAndroid Build Coastguard Worker 	return msr;
160*0d6140beSAndroid Build Coastguard Worker }
161*0d6140beSAndroid Build Coastguard Worker 
msr_write(int addr,msr_t msr)162*0d6140beSAndroid Build Coastguard Worker int msr_write(int addr, msr_t msr)
163*0d6140beSAndroid Build Coastguard Worker {
164*0d6140beSAndroid Build Coastguard Worker 	struct amdmsr_req args;
165*0d6140beSAndroid Build Coastguard Worker 
166*0d6140beSAndroid Build Coastguard Worker 	args.addr = addr;
167*0d6140beSAndroid Build Coastguard Worker 	args.val = (((uint64_t)msr.hi) << 32) | msr.lo;
168*0d6140beSAndroid Build Coastguard Worker 
169*0d6140beSAndroid Build Coastguard Worker 	if (ioctl(fd_msr, WRMSR, &args) < 0) {
170*0d6140beSAndroid Build Coastguard Worker 		msg_perr("Error while executing WRMSR ioctl: %s\n", strerror(errno));
171*0d6140beSAndroid Build Coastguard Worker 		close(fd_msr);
172*0d6140beSAndroid Build Coastguard Worker 		exit(1);
173*0d6140beSAndroid Build Coastguard Worker 	}
174*0d6140beSAndroid Build Coastguard Worker 
175*0d6140beSAndroid Build Coastguard Worker 	return 0;
176*0d6140beSAndroid Build Coastguard Worker }
177*0d6140beSAndroid Build Coastguard Worker 
msr_setup(int cpu)178*0d6140beSAndroid Build Coastguard Worker int msr_setup(int cpu)
179*0d6140beSAndroid Build Coastguard Worker {
180*0d6140beSAndroid Build Coastguard Worker 	char msrfilename[64] = { 0 };
181*0d6140beSAndroid Build Coastguard Worker 	snprintf(msrfilename, sizeof(msrfilename), "/dev/amdmsr");
182*0d6140beSAndroid Build Coastguard Worker 
183*0d6140beSAndroid Build Coastguard Worker 	if (fd_msr != -1) {
184*0d6140beSAndroid Build Coastguard Worker 		msg_pinfo("MSR was already initialized\n");
185*0d6140beSAndroid Build Coastguard Worker 		return -1;
186*0d6140beSAndroid Build Coastguard Worker 	}
187*0d6140beSAndroid Build Coastguard Worker 
188*0d6140beSAndroid Build Coastguard Worker 	fd_msr = open(msrfilename, O_RDWR);
189*0d6140beSAndroid Build Coastguard Worker 
190*0d6140beSAndroid Build Coastguard Worker 	if (fd_msr < 0) {
191*0d6140beSAndroid Build Coastguard Worker 		msg_perr("Error while opening %s: %s\n", msrfilename, strerror(errno));
192*0d6140beSAndroid Build Coastguard Worker 		return -1;
193*0d6140beSAndroid Build Coastguard Worker 	}
194*0d6140beSAndroid Build Coastguard Worker 
195*0d6140beSAndroid Build Coastguard Worker 	return 0;
196*0d6140beSAndroid Build Coastguard Worker }
197*0d6140beSAndroid Build Coastguard Worker 
msr_cleanup(void)198*0d6140beSAndroid Build Coastguard Worker void msr_cleanup(void)
199*0d6140beSAndroid Build Coastguard Worker {
200*0d6140beSAndroid Build Coastguard Worker 	if (fd_msr == -1) {
201*0d6140beSAndroid Build Coastguard Worker 		msg_pinfo("No MSR initialized.\n");
202*0d6140beSAndroid Build Coastguard Worker 		return;
203*0d6140beSAndroid Build Coastguard Worker 	}
204*0d6140beSAndroid Build Coastguard Worker 
205*0d6140beSAndroid Build Coastguard Worker 	close(fd_msr);
206*0d6140beSAndroid Build Coastguard Worker 
207*0d6140beSAndroid Build Coastguard Worker 	/* Clear MSR file descriptor. */
208*0d6140beSAndroid Build Coastguard Worker 	fd_msr = -1;
209*0d6140beSAndroid Build Coastguard Worker }
210*0d6140beSAndroid Build Coastguard Worker 
211*0d6140beSAndroid Build Coastguard Worker #elif defined(__FreeBSD__) || defined(__FreeBSD_kernel__) || defined(__DragonFly__)
212*0d6140beSAndroid Build Coastguard Worker #include <stdint.h>
213*0d6140beSAndroid Build Coastguard Worker #include <stdlib.h>
214*0d6140beSAndroid Build Coastguard Worker #include <errno.h>
215*0d6140beSAndroid Build Coastguard Worker #include <fcntl.h>
216*0d6140beSAndroid Build Coastguard Worker #include <string.h>
217*0d6140beSAndroid Build Coastguard Worker #include <unistd.h>
218*0d6140beSAndroid Build Coastguard Worker 
219*0d6140beSAndroid Build Coastguard Worker #include <sys/ioctl.h>
220*0d6140beSAndroid Build Coastguard Worker 
221*0d6140beSAndroid Build Coastguard Worker typedef struct {
222*0d6140beSAndroid Build Coastguard Worker 	int msr;
223*0d6140beSAndroid Build Coastguard Worker 	uint64_t data;
224*0d6140beSAndroid Build Coastguard Worker } cpu_msr_args_t;
225*0d6140beSAndroid Build Coastguard Worker #define CPU_RDMSR _IOWR('c', 1, cpu_msr_args_t)
226*0d6140beSAndroid Build Coastguard Worker #define CPU_WRMSR _IOWR('c', 2, cpu_msr_args_t)
227*0d6140beSAndroid Build Coastguard Worker 
228*0d6140beSAndroid Build Coastguard Worker static int fd_msr = -1;
229*0d6140beSAndroid Build Coastguard Worker 
msr_read(int addr)230*0d6140beSAndroid Build Coastguard Worker msr_t msr_read(int addr)
231*0d6140beSAndroid Build Coastguard Worker {
232*0d6140beSAndroid Build Coastguard Worker 	cpu_msr_args_t args;
233*0d6140beSAndroid Build Coastguard Worker 
234*0d6140beSAndroid Build Coastguard Worker 	msr_t msr = { 0xffffffff, 0xffffffff };
235*0d6140beSAndroid Build Coastguard Worker 
236*0d6140beSAndroid Build Coastguard Worker 	args.msr = addr;
237*0d6140beSAndroid Build Coastguard Worker 
238*0d6140beSAndroid Build Coastguard Worker 	if (ioctl(fd_msr, CPU_RDMSR, &args) < 0) {
239*0d6140beSAndroid Build Coastguard Worker 		msg_perr("Error while executing CPU_RDMSR ioctl: %s\n", strerror(errno));
240*0d6140beSAndroid Build Coastguard Worker 		close(fd_msr);
241*0d6140beSAndroid Build Coastguard Worker 		exit(1);
242*0d6140beSAndroid Build Coastguard Worker 	}
243*0d6140beSAndroid Build Coastguard Worker 
244*0d6140beSAndroid Build Coastguard Worker 	msr.lo = args.data & 0xffffffff;
245*0d6140beSAndroid Build Coastguard Worker 	msr.hi = args.data >> 32;
246*0d6140beSAndroid Build Coastguard Worker 
247*0d6140beSAndroid Build Coastguard Worker 	return msr;
248*0d6140beSAndroid Build Coastguard Worker }
249*0d6140beSAndroid Build Coastguard Worker 
msr_write(int addr,msr_t msr)250*0d6140beSAndroid Build Coastguard Worker int msr_write(int addr, msr_t msr)
251*0d6140beSAndroid Build Coastguard Worker {
252*0d6140beSAndroid Build Coastguard Worker 	cpu_msr_args_t args;
253*0d6140beSAndroid Build Coastguard Worker 
254*0d6140beSAndroid Build Coastguard Worker 	args.msr = addr;
255*0d6140beSAndroid Build Coastguard Worker 	args.data = (((uint64_t)msr.hi) << 32) | msr.lo;
256*0d6140beSAndroid Build Coastguard Worker 
257*0d6140beSAndroid Build Coastguard Worker 	if (ioctl(fd_msr, CPU_WRMSR, &args) < 0) {
258*0d6140beSAndroid Build Coastguard Worker 		msg_perr("Error while executing CPU_WRMSR ioctl: %s\n", strerror(errno));
259*0d6140beSAndroid Build Coastguard Worker 		close(fd_msr);
260*0d6140beSAndroid Build Coastguard Worker 		exit(1);
261*0d6140beSAndroid Build Coastguard Worker 	}
262*0d6140beSAndroid Build Coastguard Worker 
263*0d6140beSAndroid Build Coastguard Worker 	return 0;
264*0d6140beSAndroid Build Coastguard Worker }
265*0d6140beSAndroid Build Coastguard Worker 
msr_setup(int cpu)266*0d6140beSAndroid Build Coastguard Worker int msr_setup(int cpu)
267*0d6140beSAndroid Build Coastguard Worker {
268*0d6140beSAndroid Build Coastguard Worker 	char msrfilename[64] = { 0 };
269*0d6140beSAndroid Build Coastguard Worker 	snprintf(msrfilename, sizeof(msrfilename), "/dev/cpu%d", cpu);
270*0d6140beSAndroid Build Coastguard Worker 
271*0d6140beSAndroid Build Coastguard Worker 	if (fd_msr != -1) {
272*0d6140beSAndroid Build Coastguard Worker 		msg_pinfo("MSR was already initialized\n");
273*0d6140beSAndroid Build Coastguard Worker 		return -1;
274*0d6140beSAndroid Build Coastguard Worker 	}
275*0d6140beSAndroid Build Coastguard Worker 
276*0d6140beSAndroid Build Coastguard Worker 	fd_msr = open(msrfilename, O_RDWR);
277*0d6140beSAndroid Build Coastguard Worker 
278*0d6140beSAndroid Build Coastguard Worker 	if (fd_msr < 0) {
279*0d6140beSAndroid Build Coastguard Worker 		msg_perr("Error while opening %s: %s\n", msrfilename, strerror(errno));
280*0d6140beSAndroid Build Coastguard Worker 		msg_pinfo("Did you install ports/sysutils/devcpu?\n");
281*0d6140beSAndroid Build Coastguard Worker 		return -1;
282*0d6140beSAndroid Build Coastguard Worker 	}
283*0d6140beSAndroid Build Coastguard Worker 
284*0d6140beSAndroid Build Coastguard Worker 	return 0;
285*0d6140beSAndroid Build Coastguard Worker }
286*0d6140beSAndroid Build Coastguard Worker 
msr_cleanup(void)287*0d6140beSAndroid Build Coastguard Worker void msr_cleanup(void)
288*0d6140beSAndroid Build Coastguard Worker {
289*0d6140beSAndroid Build Coastguard Worker 	if (fd_msr == -1) {
290*0d6140beSAndroid Build Coastguard Worker 		msg_pinfo("No MSR initialized.\n");
291*0d6140beSAndroid Build Coastguard Worker 		return;
292*0d6140beSAndroid Build Coastguard Worker 	}
293*0d6140beSAndroid Build Coastguard Worker 
294*0d6140beSAndroid Build Coastguard Worker 	close(fd_msr);
295*0d6140beSAndroid Build Coastguard Worker 
296*0d6140beSAndroid Build Coastguard Worker 	/* Clear MSR file descriptor. */
297*0d6140beSAndroid Build Coastguard Worker 	fd_msr = -1;
298*0d6140beSAndroid Build Coastguard Worker }
299*0d6140beSAndroid Build Coastguard Worker 
300*0d6140beSAndroid Build Coastguard Worker #elif defined(__MACH__) && defined(__APPLE__)
301*0d6140beSAndroid Build Coastguard Worker /*
302*0d6140beSAndroid Build Coastguard Worker  * DirectHW has identical, but conflicting typedef for msr_t. We redefine msr_t
303*0d6140beSAndroid Build Coastguard Worker  * to directhw_msr_t for DirectHW.
304*0d6140beSAndroid Build Coastguard Worker  * rdmsr() and wrmsr() are provided by DirectHW and need neither setup nor cleanup.
305*0d6140beSAndroid Build Coastguard Worker  */
306*0d6140beSAndroid Build Coastguard Worker #define msr_t directhw_msr_t
307*0d6140beSAndroid Build Coastguard Worker #include <DirectHW/DirectHW.h>
308*0d6140beSAndroid Build Coastguard Worker #undef msr_t
309*0d6140beSAndroid Build Coastguard Worker 
msr_read(int addr)310*0d6140beSAndroid Build Coastguard Worker msr_t msr_read(int addr)
311*0d6140beSAndroid Build Coastguard Worker {
312*0d6140beSAndroid Build Coastguard Worker 	directhw_msr_t msr;
313*0d6140beSAndroid Build Coastguard Worker 	msr = rdmsr(addr);
314*0d6140beSAndroid Build Coastguard Worker 	return (msr_t){msr.hi, msr.lo};
315*0d6140beSAndroid Build Coastguard Worker }
316*0d6140beSAndroid Build Coastguard Worker 
msr_write(int addr,msr_t msr)317*0d6140beSAndroid Build Coastguard Worker int msr_write(int addr, msr_t msr)
318*0d6140beSAndroid Build Coastguard Worker {
319*0d6140beSAndroid Build Coastguard Worker 	return wrmsr(addr, (directhw_msr_t){msr.hi, msr.lo});
320*0d6140beSAndroid Build Coastguard Worker }
321*0d6140beSAndroid Build Coastguard Worker 
msr_setup(int cpu)322*0d6140beSAndroid Build Coastguard Worker int msr_setup(int cpu)
323*0d6140beSAndroid Build Coastguard Worker {
324*0d6140beSAndroid Build Coastguard Worker 	// Always succeed for now
325*0d6140beSAndroid Build Coastguard Worker 	return 0;
326*0d6140beSAndroid Build Coastguard Worker }
327*0d6140beSAndroid Build Coastguard Worker 
msr_cleanup(void)328*0d6140beSAndroid Build Coastguard Worker void msr_cleanup(void)
329*0d6140beSAndroid Build Coastguard Worker {
330*0d6140beSAndroid Build Coastguard Worker 	// Nothing, yet.
331*0d6140beSAndroid Build Coastguard Worker }
332*0d6140beSAndroid Build Coastguard Worker #elif defined(__LIBPAYLOAD__)
333*0d6140beSAndroid Build Coastguard Worker #include <arch/msr.h>
334*0d6140beSAndroid Build Coastguard Worker 
msr_read(int addr)335*0d6140beSAndroid Build Coastguard Worker msr_t msr_read(int addr)
336*0d6140beSAndroid Build Coastguard Worker {
337*0d6140beSAndroid Build Coastguard Worker 	msr_t msr;
338*0d6140beSAndroid Build Coastguard Worker 	unsigned long long val = _rdmsr(addr);
339*0d6140beSAndroid Build Coastguard Worker 	msr.lo = val & 0xffffffff;
340*0d6140beSAndroid Build Coastguard Worker 	msr.hi = val >> 32;
341*0d6140beSAndroid Build Coastguard Worker 	return msr;
342*0d6140beSAndroid Build Coastguard Worker }
343*0d6140beSAndroid Build Coastguard Worker 
msr_write(int addr,msr_t msr)344*0d6140beSAndroid Build Coastguard Worker int msr_write(int addr, msr_t msr)
345*0d6140beSAndroid Build Coastguard Worker {
346*0d6140beSAndroid Build Coastguard Worker 	_wrmsr(addr, msr.lo | ((unsigned long long)msr.hi << 32));
347*0d6140beSAndroid Build Coastguard Worker 	return 0;
348*0d6140beSAndroid Build Coastguard Worker }
349*0d6140beSAndroid Build Coastguard Worker 
msr_setup(int cpu)350*0d6140beSAndroid Build Coastguard Worker int msr_setup(int cpu)
351*0d6140beSAndroid Build Coastguard Worker {
352*0d6140beSAndroid Build Coastguard Worker 	return 0;
353*0d6140beSAndroid Build Coastguard Worker }
354*0d6140beSAndroid Build Coastguard Worker 
msr_cleanup(void)355*0d6140beSAndroid Build Coastguard Worker void msr_cleanup(void)
356*0d6140beSAndroid Build Coastguard Worker {
357*0d6140beSAndroid Build Coastguard Worker }
358*0d6140beSAndroid Build Coastguard Worker #else
359*0d6140beSAndroid Build Coastguard Worker /* default MSR implementation */
msr_read(int addr)360*0d6140beSAndroid Build Coastguard Worker msr_t msr_read(int addr)
361*0d6140beSAndroid Build Coastguard Worker {
362*0d6140beSAndroid Build Coastguard Worker 	msr_t ret = { 0xffffffff, 0xffffffff };
363*0d6140beSAndroid Build Coastguard Worker 
364*0d6140beSAndroid Build Coastguard Worker 	return ret;
365*0d6140beSAndroid Build Coastguard Worker }
366*0d6140beSAndroid Build Coastguard Worker 
msr_write(int addr,msr_t msr)367*0d6140beSAndroid Build Coastguard Worker int msr_write(int addr, msr_t msr)
368*0d6140beSAndroid Build Coastguard Worker {
369*0d6140beSAndroid Build Coastguard Worker 	return -1;
370*0d6140beSAndroid Build Coastguard Worker }
371*0d6140beSAndroid Build Coastguard Worker 
msr_setup(int cpu)372*0d6140beSAndroid Build Coastguard Worker int msr_setup(int cpu)
373*0d6140beSAndroid Build Coastguard Worker {
374*0d6140beSAndroid Build Coastguard Worker 	msg_pinfo("No MSR support for your OS yet.\n");
375*0d6140beSAndroid Build Coastguard Worker 	return -1;
376*0d6140beSAndroid Build Coastguard Worker }
377*0d6140beSAndroid Build Coastguard Worker 
msr_cleanup(void)378*0d6140beSAndroid Build Coastguard Worker void msr_cleanup(void)
379*0d6140beSAndroid Build Coastguard Worker {
380*0d6140beSAndroid Build Coastguard Worker 	// Nothing, yet.
381*0d6140beSAndroid Build Coastguard Worker }
382*0d6140beSAndroid Build Coastguard Worker #endif // OS switches for MSR code
383