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 <[email protected]>

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/


_______________________________________________
flashrom mailing list
[email protected]
http://www.flashrom.org/mailman/listinfo/flashrom

Reply via email to