[flashrom] [PATCH] Fix IDSEL handling in WPCE775X
Carl-Daniel Hailfinger
c-d.hailfinger.devel.2006 at gmx.net
Wed Nov 17 07:54:10 CET 2010
I just noticed that the first patch was corrupt. This one should work.
This patch is for the flashrom-chromium tree.
Fix IDSEL handling in WPCE775X.
- Clean up the code
- Check that SHM window 2 is reachable if FWH communication is used
- IDSEL is 4 bits, use a mask to extract it correctly
- IDSEL setup needs to happen before SHM window 2 is accessed if FWH
communication is used
Signed-off-by: Carl-Daniel Hailfinger <c-d.hailfinger.devel.2006 at gmx.net>
diff --git a/wpce775x.c b/wpce775x.c
index a659893..6a71392 100644
--- a/wpce775x.c
+++ b/wpce775x.c
@@ -164,12 +164,13 @@ static int nuvoton_get_sio_index(uint16_t *port)
/** Call superio to get pre-configured WCB address.
* Read LDN 0x0f (SHM) idx:f8-fb (little-endian).
*/
-static int get_shaw2ba(chipaddr *shaw2ba)
+static int get_shaw2ba(chipaddr *shaw2ba, uint8_t *comm_fwh)
{
uint16_t idx;
uint8_t org_ldn;
uint8_t win_cfg;
uint8_t shm_cfg;
+ int ret = 0;
if (nuvoton_get_sio_index(&idx) < 0)
return -1;
@@ -196,27 +197,40 @@ static int get_shaw2ba(chipaddr *shaw2ba)
*/
win_cfg = sio_read(idx, WPCE775X_WIN_CFG);
if (win_cfg & WPCE775X_WIN_CFG_SHWIN_ACC) {
- uint8_t idsel;
-
/* Make sure shared BIOS memory is enabled */
shm_cfg = sio_read(idx, WPCE775X_SHM_CFG);
- if ((shm_cfg & WPCE775X_SHM_CFG_BIOS_FWH_EN))
- idsel = 0xf;
- else {
+ if (!(shm_cfg & WPCE775X_SHM_CFG_BIOS_FWH_EN)) {
msg_cdbg("Shared BIOS memory is diabled.\n");
msg_cdbg("Please check SHM_CFG:BIOS_FWH_EN.\n");
- goto error;
+ ret = -1;
+ goto out;
}
-
- *shaw2ba &= 0x0fffffff;
- *shaw2ba |= idsel << 28;
+ /* FIXME: Check that this is a FWH capable chipset. */
+ *comm_fwh = 1;
+ /* Check if bit 24-27 are set. Intel ICH will never issue any
+ * LPC firmware memory (FWH) cycles with them cleared.
+ * FWH cycles only have 28 address bits.
+ */
+ if ((*shaw2ba & (0xf << 24)) != 0xf << 24) {
+ msg_cerr("WPCE775X shadow window 2 is outside the "
+ "region addressable with FWH!\n");
+ ret = -1;
+ goto out;
+ }
+ /* FWH cycles are only issued for memory mapped to the top
+ * 16 MB of the 4 GB address space. We could set only the top
+ * 4 bits since those are ignored by the WPCE775X and we checked
+ * bits 24-27 to be 0xf above, but setting the top 8 bits makes
+ * the 16 MB constraint more clear.
+ */
+ *shaw2ba |= 0xff << 24;
+ } else {
+ *comm_fwh = 0;
}
-
- sio_write(idx, NUVOTON_SIOCFG_LDN, org_ldn);
- return 0;
-error:
+
+out:
sio_write(idx, NUVOTON_SIOCFG_LDN, org_ldn);
- return -1;
+ return ret;
}
/* Call superio to get pre-configured fwh_id.
@@ -232,7 +246,8 @@ static int get_fwh_id(uint8_t *fwh_id)
org_ldn = sio_read(idx, NUVOTON_SIOCFG_LDN);
sio_write(idx, NUVOTON_SIOCFG_LDN, NUVOTON_LDN_SHM);
- *fwh_id = sio_read(idx, WPCE775X_SHM_CFG);
+ /* Upper 4 bits of WPCE775X_SHM_CFG store the FWH ID. */
+ *fwh_id = sio_read(idx, WPCE775X_SHM_CFG) >> 4;
sio_write(idx, NUVOTON_SIOCFG_LDN, org_ldn);
return 0;
@@ -402,6 +417,7 @@ int probe_wpce775x(struct flashchip *flash)
uint16_t sio_port;
uint8_t srid;
uint8_t fwh_id;
+ uint8_t comm_fwh = 0;
uint32_t size;
chipaddr original_memory;
uint32_t original_size;
@@ -425,14 +441,29 @@ int probe_wpce775x(struct flashchip *flash)
}
/* get the address of Shadow Window 2. */
- if (get_shaw2ba(&wcb_physical_address) < 0) {
+ if (get_shaw2ba(&wcb_physical_address, &comm_fwh) < 0) {
msg_cdbg("Cannot get the address of Shadow Window 2");
return 0;
}
msg_cdbg("Get the address of WCB(SHA WIN2) at 0x%08x\n",
(uint32_t)wcb_physical_address);
- wcb = (struct wpce775x_wcb *)
- programmer_map_flash_region("WPCE775X WCB",
+
+ /* If we use FWH for Shadow Window 2, we have to set FWH IDSEL in the
+ * chipset before we try to access Shadow Window 2.
+ */
+ if (comm_fwh) {
+ if (get_fwh_id(&fwh_id) < 0) {
+ msg_cdbg("Cannot get fwh_id value.\n");
+ return 0;
+ }
+ msg_cdbg("get fwh_id: 0x%02x\n", fwh_id);
+
+ /* TODO: set fwh_idsel of chipset.
+ * Currently, we employ "-p internal:fwh_idsel=0x0000223e".
+ */
+ }
+
+ wcb = (struct wpce775x_wcb *)physmap("WPCE775X WCB",
wcb_physical_address,
getpagesize() /* min page size */);
msg_cdbg("mapped wcb address: %p for physical addr: 0x%08lx\n", wcb, wcb_physical_address);
@@ -442,15 +473,6 @@ int probe_wpce775x(struct flashchip *flash)
}
memset((void*)wcb, 0, sizeof(*wcb));
- if (get_fwh_id(&fwh_id) < 0) {
- msg_cdbg("Cannot get fwh_id value.\n");
- return 0;
- }
- msg_cdbg("get fwh_id: 0x%02x\n", fwh_id);
-
- /* TODO: set fwh_idsel of chipset.
- Currently, we employ "-p internal:fwh_idsel=0x0000223e". */
-
/* Initialize the parameters of EC SHM component */
if (InitFlash(0x00))
return 0;
--
http://www.hailfinger.org/
More information about the flashrom
mailing list