Flashrom support for AMD Geode CS5536
Attached is a patch that enables AMD Geode CS5536 chipset support. I
have tested it successfully on a MSM800 board from digital logic.
Corresponding to flashrom svn r160 and coreboot v2 svn r2967.
Signed-off-by: Lane Brooks <lbrooks@mit.edu>
Acked-by: Jordan Crouse <jordan.crouse@amd.com>
diff --git a/chipset_enable.c b/chipset_enable.c
index 63996da..87929f5 100644
--- a/chipset_enable.c
+++ b/chipset_enable.c
@@ -23,9 +23,15 @@
* Contains the chipset specific flash enables.
*/
+#define _LARGEFILE64_SOURCE
+
#include <stdio.h>
#include <pci/pci.h>
#include <stdlib.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+#include <unistd.h>
#include "flash.h"
static int enable_flash_ali_m1533(struct pci_dev *dev, char *name)
@@ -218,6 +224,54 @@
return 0;
}
+static int enable_flash_cs5536(struct pci_dev *dev, char *name)
+{
+ int fd_msr;
+ unsigned char buf[8];
+ unsigned int addr = 0x1808;
+
+ /* Geode systems write protect the BIOS via RCONFs (cache
+ * settings similar to MTRRs). To unlock, change MSR 0x1808
+ * top byte to 0x22. Reading and writing to msr, however
+ * requires instrucitons rdmsr/wrmsr, which are ring0 privileged
+ * instructions so only the kernel can do the read/write. This
+ * function, therefore, requires that the msr kernel module be
+ * loaded to access these instructions from user space using
+ * device /dev/cpu/0/msr. This hard-coded driver location
+ * could have potential problems on SMP machines since it
+ * assumes cpu0, but it is safe on the geode which is not SMP.
+ *
+ * This is probably not portable beyond linux.
+ */
+
+ fd_msr = open("/dev/cpu/0/msr", O_RDONLY);
+ if (!fd_msr) {
+ perror("open msr");
+ return -1;
+ }
+ lseek64(fd_msr, (off64_t) addr, SEEK_SET);
+ read(fd_msr, buf, 8);
+ close(fd_msr);
+ if (buf[7] != 0x22) {
+ printf("Enabling Geode MSR to write to flash.\n");
+ buf[7] = 0x22;
+ fd_msr = open("/dev/cpu/0/msr", O_WRONLY);
+ if (!fd_msr) {
+ perror("open msr");
+ return -1;
+ }
+ lseek64(fd_msr, (off64_t) addr, SEEK_SET);
+ if (write(fd_msr, buf, 8) < 0) {
+ perror("msr write");
+ printf
+ ("Cannot write to MSR. Make sure msr kernel is loaded: 'modprobe msr'\n");
+ return -1;
+ }
+ close(fd_msr);
+ }
+ return 0;
+}
+
static int enable_flash_sc1100(struct pci_dev *dev, char *name)
{
uint8_t new;
@@ -460,6 +514,7 @@
{0x1078, 0x0100, "CS5530/CS5530A", enable_flash_cs5530},
{0x100b, 0x0510, "SC1100", enable_flash_sc1100},
{0x1039, 0x0008, "SIS5595", enable_flash_sis5595},
+ {0x1022, 0x2080, "AMD GEODE CS5536", enable_flash_cs5536},
{0x1022, 0x7468, "AMD8111", enable_flash_amd8111},
{0x10B9, 0x1533, "ALi M1533", enable_flash_ali_m1533},
/* this fallthrough looks broken. */