summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorCarl-Daniel Hailfinger <c-d.hailfinger.devel.2006@gmx.net>2011-07-25 22:44:09 +0000
committerCarl-Daniel Hailfinger <c-d.hailfinger.devel.2006@gmx.net>2011-07-25 22:44:09 +0000
commit46fa068fa21353efe41d9b41092817f7a6f5a4aa (patch)
tree654a61e99fb535a698754d3f0a1da437fb95d645
parenta07438302eac1eb8eb6831366d2e36dd14489f4b (diff)
downloadast2050-flashrom-46fa068fa21353efe41d9b41092817f7a6f5a4aa.zip
ast2050-flashrom-46fa068fa21353efe41d9b41092817f7a6f5a4aa.tar.gz
Fix ICH FWH IDSEL setting with the fwh_idsel= internal programmer parameter
The code took 32 bits of input and wrote them to an 48 bit register, duplicating some values. Document the fwh_idsel= parameter in the man page. Corresponding to flashrom svn r1389. Signed-off-by: Carl-Daniel Hailfinger <c-d.hailfinger.devel.2006@gmx.net> Acked-by: Stefan Tauner <stefan.tauner@alumni.tuwien.ac.at>
-rw-r--r--chipset_enable.c34
-rw-r--r--flashrom.817
2 files changed, 44 insertions, 7 deletions
diff --git a/chipset_enable.c b/chipset_enable.c
index b31639a..21990f6 100644
--- a/chipset_enable.c
+++ b/chipset_enable.c
@@ -30,6 +30,8 @@
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
+#include <inttypes.h>
+#include <errno.h>
#include "flash.h"
#include "programmer.h"
@@ -311,15 +313,33 @@ static int enable_flash_ich_dc(struct pci_dev *dev, const char *name)
idsel = extract_programmer_param("fwh_idsel");
if (idsel && strlen(idsel)) {
- fwh_conf = (uint32_t)strtoul(idsel, NULL, 0);
-
- /* FIXME: Need to undo this on shutdown. */
- msg_pinfo("\nSetting IDSEL=0x%x for top 16 MB", fwh_conf);
- rpci_write_long(dev, 0xd0, fwh_conf);
- rpci_write_word(dev, 0xd4, fwh_conf);
+ uint64_t fwh_idsel_old;
+ uint64_t fwh_idsel;
+ errno = 0;
+ /* Base 16, nothing else makes sense. */
+ fwh_idsel = (uint64_t)strtoull(idsel, NULL, 16);
+ if (errno) {
+ msg_perr("Error: fwh_idsel= specified, but value could "
+ "not be converted.\n");
+ goto idsel_garbage_out;
+ }
+ if (fwh_idsel & 0xffff000000000000ULL) {
+ msg_perr("Error: fwh_idsel= specified, but value had "
+ "unusued bits set.\n");
+ goto idsel_garbage_out;
+ }
+ fwh_idsel_old = pci_read_long(dev, 0xd0);
+ fwh_idsel_old <<= 16;
+ fwh_idsel_old |= pci_read_word(dev, 0xd4);
+ msg_pdbg("\nSetting IDSEL from 0x%012" PRIx64 " to "
+ "0x%012" PRIx64 " for top 16 MB.", fwh_idsel_old,
+ fwh_idsel);
+ rpci_write_long(dev, 0xd0, (fwh_idsel >> 16) & 0xffffffff);
+ rpci_write_word(dev, 0xd4, fwh_idsel & 0xffff);
/* FIXME: Decode settings are not changed. */
} else if (idsel) {
- msg_perr("Error: idsel= specified, but no number given.\n");
+ msg_perr("Error: fwh_idsel= specified, but no value given.\n");
+idsel_garbage_out:
free(idsel);
/* FIXME: Return failure here once internal_init() starts
* to care about the return value of the chipset enable.
diff --git a/flashrom.8 b/flashrom.8
index 2814d8c..2834570 100644
--- a/flashrom.8
+++ b/flashrom.8
@@ -299,6 +299,23 @@ is the I/O port number (must be a multiple of 8). In the unlikely case
flashrom doesn't detect an active IT87 LPC<->SPI bridge, please send a bug
report so we can diagnose the problem.
.sp
+If you have an Intel chipset with an ICH6 or later southbridge and if you want
+to set specific IDSEL values for a non-default flash chip or an embedded
+controller (EC), you can use the
+.sp
+.B " flashrom \-p internal:fwh_idsel=value"
+.sp
+syntax where value is the 48-bit hexadecimal raw value to be written in the
+IDSEL registers of the Intel southbridge. The upper 32 bits use one hex digit
+each per 512 kB range between 0xffc00000 and 0xffffffff, and the lower 16 bits
+use one hex digit each per 1024 kB range between 0xff400000 and 0xff7fffff.
+The rightmost hex digit corresponds with the lowest address range. All address
+ranges have a corresponding sister range 4 MB below with identical IDSEL
+settings. The default value for ICH7 is given in the example below.
+.sp
+Example:
+.B "flashrom \-p internal:fwh_idsel=0x001122334567"
+.sp
Using flashrom on laptops is dangerous and may easily make your hardware
unusable (see also the
.B BUGS
OpenPOWER on IntegriCloud