Here it is again with the patch actually attached.

Lane Brooks wrote:
Here is the patch again with an updated comment regarding SMP and a signed-off-by line.

Signed-off-by: Lane Brooks <[EMAIL PROTECTED]>

ron minnich wrote:
On 10/2/07, Lane Brooks <[EMAIL PROTECTED]> wrote:
Attached is a patch that enables AMD Geode CS5536 chipset support.  I
have tested it successfully on a MSM800 board from digital logic.  It
does, however, have a few issues that I would like some feedback on.

In my discussions with Marc Jones, Geode systems write protect the BIOS
via RCONFs (cache settings similar to MTRRs). Unlocking requires
changing MSR 0x1808 top byte to 0x22. Reading and writing to the msr,
however, requires instrucitons rdmsr/wrmsr, which are ring0 privileged
instructions so only the kernel can do the read/write.  So my patch uses
the msr kernel module to access these instructions from user space using
the /dev/cpu/0/msr device.

My questions are:
- I do not think this is portable beyond linux.  Is that an issue?
it's not, but it is not really an issue at present.
- My code assumes the msr kernel module is already loaded.  Is there a
way to force a kernel module to load from the C code?  My code does die
gracefully with a message reminding them to load the kernel module if
things fail.
it is possible I think to have udev help with this, but I am not sure.
Graceful failure is certainly a good start.

- It seems like there should be a way to revert the msr back after
flashing is completed to put the bios back in write protect mode.  Is
there a cleanup mechanism available?  Something like disable_flash...
I thought that was in the structure of flashrom. Now that I look, it
seems like we lost it!
I propose this at the end of flashrom:
board_flash_disable(lb_vendor, lb_part);
chipset_flash_disable(chipset);

but we'll need to change some things to make this all work. We need a
penable struct * to use for the disable; no point in searching each
time we touch a chip. or not?

one comment on your patch: you use /dev/cpu/0/msr. This is great for a
single-cpu machine, and will always be fine on  geode. Lots of times,
people use one piece of flashrom to write another. Imagine some future
hacker, in a year or two, who has copied your code for some SMP
system, not understanding why sometimes flashrom fails (i.e. they set
CPU0 msr but end up running on cpu1). We had this very problem when we
were getting graphics going (and, earlier, SMP going). I suggest a
comment as to why the /dev/cpu/0/msr is always safe on geode, but
future hackers beware on SMP. Or something like that.

That's up to you, however :-)

If you had a signed-off-by line, I would ack and commit for you :-)

ron

ron

Index: chipset_enable.c
===================================================================
--- chipset_enable.c	(revision 2816)
+++ chipset_enable.c	(working copy)
@@ -26,6 +26,10 @@
 #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 +222,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;
+	}
+	lseek(fd_msr, 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;
+		}
+		lseek(fd_msr, 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;
@@ -459,6 +511,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. */
-- 
linuxbios mailing list
linuxbios@linuxbios.org
http://www.linuxbios.org/mailman/listinfo/linuxbios

Reply via email to