summaryrefslogtreecommitdiffstats
path: root/physmap.c
diff options
context:
space:
mode:
authorStefan Tauner <stefan.tauner@alumni.tuwien.ac.at>2013-07-13 21:18:32 +0000
committerStefan Tauner <stefan.tauner@alumni.tuwien.ac.at>2013-07-13 21:18:32 +0000
commit6bf5fe78f1064b56275056b2a90ea4e1c34e42be (patch)
treead79544266cff3bbc268ad3d5eaade252b0dad46 /physmap.c
parent95b4b6d9f64f15a9077c61bfc4a903370ab415a6 (diff)
downloadast2050-flashrom-6bf5fe78f1064b56275056b2a90ea4e1c34e42be.zip
ast2050-flashrom-6bf5fe78f1064b56275056b2a90ea4e1c34e42be.tar.gz
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. Corresponding to flashrom svn r1696. Signed-off-by: Stefan Tauner <stefan.tauner@alumni.tuwien.ac.at> Tested-by Leonardo Guardati <leonardo@guardati.it> Acked-by: Stefan Tauner <stefan.tauner@alumni.tuwien.ac.at> Acked-by: Carl-Daniel Hailfinger <c-d.hailfinger.devel.2006@gmx.net>
Diffstat (limited to 'physmap.c')
-rw-r--r--physmap.c95
1 files changed, 85 insertions, 10 deletions
diff --git a/physmap.c b/physmap.c
index 4ebfb06..3c3f27b 100644
--- a/physmap.c
+++ b/physmap.c
@@ -282,6 +282,8 @@ void *physmap_try_ro(const char *descr, unsigned long phys_addr, size_t len)
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 @@ void cleanup_cpu_msr(void)
/* 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 @@ void cleanup_cpu_msr(void)
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 @@ int libpayload_wrmsr(int addr, msr_t msr)
return 0;
}
#else
+/* default MSR implementation */
msr_t rdmsr(int addr)
{
msr_t ret = { 0xffffffff, 0xffffffff };
@@ -516,9 +593,7 @@ void cleanup_cpu_msr(void)
{
// 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
OpenPOWER on IntegriCloud