Author: stefanct Date: Sat Jul 13 23:18:32 2013 New Revision: 1696 URL: http://flashrom.org/trac/flashrom/changeset/1696
Log: Add support for AMD Geode's MSR on OpenBSD.
Previously the default implementation was used, which always failed. On other systems than the Geode the code is not equal to that anymore, but should not explode because setup_cpu_msr() returns an error and therefore no other MSR functions should be called.
Signed-off-by: Stefan Tauner stefan.tauner@student.tuwien.ac.at Tested-by Leonardo Guardati leonardo@guardati.it Acked-by: Stefan Tauner stefan.tauner@student.tuwien.ac.at Acked-by: Carl-Daniel Hailfinger c-d.hailfinger.devel.2006@gmx.net
Modified: trunk/physmap.c
Modified: trunk/physmap.c ============================================================================== --- trunk/physmap.c Sat Jul 13 22:55:33 2013 (r1695) +++ trunk/physmap.c Sat Jul 13 23:18:32 2013 (r1696) @@ -282,6 +282,8 @@ PHYSMAP_RO); }
+/* MSR abstraction implementations for Linux, OpenBSD, FreeBSD/Dragonfly, OSX, libpayload + * and a non-working default implemenation on the bottom. See also hwaccess.h for some (re)declarations. */ #if defined(__i386__) || defined(__x86_64__)
#ifdef __linux__ @@ -381,8 +383,83 @@ /* Clear MSR file descriptor. */ fd_msr = -1; } -#else -#if defined(__FreeBSD__) || defined(__FreeBSD_kernel__) || defined(__DragonFly__) +#elif defined(__OpenBSD__) /* This does only work for certain AMD Geode LX systems see amdmsr(4). */ +#include <sys/ioctl.h> +#include <machine/amdmsr.h> + +static int fd_msr = -1; + +msr_t rdmsr(int addr) +{ + struct amdmsr_req args; + + msr_t msr = { 0xffffffff, 0xffffffff }; + + args.addr = (uint32_t)addr; + + if (ioctl(fd_msr, RDMSR, &args) < 0) { + msg_perr("Error while executing RDMSR ioctl: %s\n", strerror(errno)); + close(fd_msr); + exit(1); + } + + msr.lo = args.val & 0xffffffff; + msr.hi = args.val >> 32; + + return msr; +} + +int wrmsr(int addr, msr_t msr) +{ + struct amdmsr_req args; + + args.addr = addr; + args.val = (((uint64_t)msr.hi) << 32) | msr.lo; + + if (ioctl(fd_msr, WRMSR, &args) < 0) { + msg_perr("Error while executing WRMSR ioctl: %s\n", strerror(errno)); + close(fd_msr); + exit(1); + } + + return 0; +} + +int setup_cpu_msr(int cpu) +{ + char msrfilename[64]; + memset(msrfilename, 0, sizeof(msrfilename)); + snprintf(msrfilename, sizeof(msrfilename), "/dev/amdmsr"); + + if (fd_msr != -1) { + msg_pinfo("MSR was already initialized\n"); + return -1; + } + + fd_msr = open(msrfilename, O_RDWR); + + if (fd_msr < 0) { + msg_perr("Error while opening %s: %s\n", msrfilename, strerror(errno)); + return -1; + } + + return 0; +} + +void cleanup_cpu_msr(void) +{ + if (fd_msr == -1) { + msg_pinfo("No MSR initialized.\n"); + return; + } + + close(fd_msr); + + /* Clear MSR file descriptor. */ + fd_msr = -1; +} + +#elif defined(__FreeBSD__) || defined(__FreeBSD_kernel__) || defined(__DragonFly__) #include <sys/ioctl.h>
typedef struct { @@ -465,9 +542,8 @@ fd_msr = -1; }
-#else - -#if defined(__MACH__) && defined(__APPLE__) +#elif defined(__MACH__) && defined(__APPLE__) +/* rdmsr() and wrmsr() are provided by DirectHW which needs neither setup nor cleanup. */ int setup_cpu_msr(int cpu) { // Always succeed for now @@ -494,6 +570,7 @@ return 0; } #else +/* default MSR implementation */ msr_t rdmsr(int addr) { msr_t ret = { 0xffffffff, 0xffffffff }; @@ -516,9 +593,7 @@ { // Nothing, yet. } -#endif -#endif -#endif -#else +#endif // OS switches for MSR code +#else // x86 /* Does MSR exist on non-x86 architectures? */ -#endif +#endif // arch switches for MSR code