geode_msr.c revision 621ff18c
1/* 2 * Copyright (c) 2008 Advanced Micro Devices, Inc. 3 * 4 * Permission is hereby granted, free of charge, to any person obtaining a 5 * copy of this software and associated documentation files (the "Software"), 6 * to deal in the Software without restriction, including without limitation 7 * the rights to use, copy, modify, merge, publish, distribute, sublicense, 8 * and/or sell copies of the Software, and to permit persons to whom the 9 * Software is furnished to do so, subject to the following conditions: 10 * 11 * The above copyright notice and this permission notice shall be included in 12 * all copies or substantial portions of the Software. 13 * 14 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 15 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 16 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 17 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 18 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 19 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER 20 * DEALINGS IN THE SOFTWARE. 21 * 22 * Neither the name of the Advanced Micro Devices, Inc. nor the names of its 23 * contributors may be used to endorse or promote products derived from this 24 * software without specific prior written permission. 25 */ 26 27#ifdef HAVE_CONFIG_H 28#include "config.h" 29#endif 30 31#include <stdio.h> 32#include <unistd.h> 33#include <fcntl.h> 34#include <sys/types.h> 35#include <errno.h> 36 37#ifdef __OpenBSD__ 38#include <sys/ioctl.h> 39#include <machine/amdmsr.h> 40#endif 41 42#include "os.h" 43#include "geode.h" 44 45#ifdef __OpenBSD__ 46#define _PATH_MSRDEV "/dev/amdmsr" 47#define X_PRIVSEP 48#else 49#define _PATH_MSRDEV "/dev/cpu/0/msr" 50#endif 51 52static int 53_msr_open(void) 54{ 55 static int msrfd = 0; 56 57 if (msrfd == 0) { 58#ifdef X_PRIVSEP 59 msrfd = priv_open_device(_PATH_MSRDEV); 60#else 61 msrfd = open(_PATH_MSRDEV, O_RDWR); 62#endif 63 if (msrfd == -1) 64 FatalError("Unable to open %s: %s\n", _PATH_MSRDEV, 65 strerror(errno)); 66 } 67 68 return msrfd; 69} 70 71int 72GeodeReadMSR(unsigned long addr, unsigned long *lo, unsigned long *hi) 73{ 74#ifdef __OpenBSD__ 75 struct amdmsr_req req; 76 int fd = _msr_open(); 77 78 req.addr = addr; 79 80 if (ioctl(fd, RDMSR, &req) == -1) 81 FatalError("Unable to read MSR at address %0x06x: %s\n", addr, 82 strerror(errno)); 83 84 *hi = req.val >> 32; 85 *lo = req.val & 0xffffffff; 86#else 87 unsigned int data[2]; 88 int fd = _msr_open(); 89 int ret; 90 91 if (fd == -1) 92 return -1; 93 94 ret = lseek(fd, (off_t) addr, SEEK_SET); 95 96 if (ret == -1) 97 return -1; 98 99 ret = read(fd, (void *) data, sizeof(data)); 100 101 if (ret != 8) 102 return -1; 103 104 *hi = data[1]; 105 *lo = data[0]; 106#endif 107 return 0; 108} 109 110int 111GeodeWriteMSR(unsigned long addr, unsigned long lo, unsigned long hi) 112{ 113#ifdef __OpenBSD__ 114 struct amdmsr_req req; 115 int fd = _msr_open(); 116 117 req.addr = addr; 118 req.val = (u_int64_t) hi << 32 | (u_int64_t)lo; 119 120 if (ioctl(fd, WRMSR, &req) == -1) 121 FatalError("Unable to write MSR at address 0x%06x: %s\n", addr, 122 strerror(errno)); 123#else 124 unsigned int data[2]; 125 int fd = _msr_open(); 126 127 if (fd == -1) 128 return -1; 129 130 if (lseek(fd, (off_t) addr, SEEK_SET) == -1) 131 return -1; 132 133 data[0] = lo; 134 data[1] = hi; 135 136 if (write(fd, (void *) data, 8) != 8) 137 return -1; 138#endif 139 return 0; 140} 141