[flashrom] [PATCH 2/2] Add support for AMD Geode's MSR on OpenBSD.

Stefan Tauner stefan.tauner at student.tuwien.ac.at
Sat Apr 13 01:53:46 CEST 2013


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 at student.tuwien.ac.at>
---
 physmap.c |   94 ++++++++++++++++++++++++++++++++++++++++++++++++++++++-------
 1 file changed, 84 insertions(+), 10 deletions(-)

diff --git a/physmap.c b/physmap.c
index 4ebfb06..b6a9163 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.msr = 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,7 @@ void cleanup_cpu_msr(void)
 	fd_msr = -1;
 }
 
-#else
-
-#if defined(__MACH__) && defined(__APPLE__)
+#elif defined(__MACH__) && defined(__APPLE__)
 int setup_cpu_msr(int cpu)
 {
 	// Always succeed for now
@@ -494,6 +569,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 +592,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
-- 
Kind regards, Stefan Tauner





More information about the flashrom mailing list