Author: stefanct
Date: Thu Oct 20 14:57:14 2011
New Revision: 1452
URL: http://flashrom.org/trac/flashrom/changeset/1452

Log:
ichspi: add (partially) dead support code for Intel Hardware Sequencing

This was done to ease the review. Another patch will hook up (and
explain) this code later.

Signed-off-by: Stefan Tauner <[email protected]>
Acked-by: Carl-Daniel Hailfinger <[email protected]>

Modified:
   trunk/ich_descriptors.c
   trunk/ich_descriptors.h
   trunk/ichspi.c

Modified: trunk/ich_descriptors.c
==============================================================================
--- trunk/ich_descriptors.c     Fri Oct 14 22:33:14 2011        (r1451)
+++ trunk/ich_descriptors.c     Thu Oct 20 14:57:14 2011        (r1452)
@@ -213,6 +213,34 @@
        msg_pdbg2("\n");
 }
 
+/** Returns the integer representation of the component density with index
+idx in bytes or 0 if a correct size can not be determined. */
+int getFCBA_component_density(const struct ich_descriptors *desc, uint8_t idx)
+{
+       uint8_t size_enc;
+       
+       switch(idx) {
+       case 0:
+               size_enc = desc->component.comp1_density;
+               break;
+       case 1:
+               if (desc->content.NC == 0)
+                       return 0;
+               size_enc = desc->component.comp2_density;
+               break;
+       default:
+               msg_perr("Only ICH SPI component index 0 or 1 are supported "
+                        "yet.\n");
+               return 0;
+       }
+       if (size_enc > 5) {
+               msg_perr("Density of ICH SPI component with index %d is "
+                        "invalid. Encoded density is 0x%x.\n", idx, size_enc);
+               return 0;
+       }
+       return (1 << (19 + size_enc));
+}
+
 static uint32_t read_descriptor_reg(uint8_t section, uint16_t offset, void 
*spibar)
 {
        uint32_t control = 0;

Modified: trunk/ich_descriptors.h
==============================================================================
--- trunk/ich_descriptors.h     Fri Oct 14 22:33:14 2011        (r1451)
+++ trunk/ich_descriptors.h     Thu Oct 20 14:57:14 2011        (r1452)
@@ -255,6 +255,7 @@
 void prettyprint_ich_descriptor_master(const struct ich_desc_master *master);
 
 int read_ich_descriptors_via_fdo(void *spibar, struct ich_descriptors *desc);
+int getFCBA_component_density(const struct ich_descriptors *desc, uint8_t idx);
 
 #endif /* __ICH_DESCRIPTORS_H__ */
 #endif /* defined(__i386__) || defined(__x86_64__) */

Modified: trunk/ichspi.c
==============================================================================
--- trunk/ichspi.c      Fri Oct 14 22:33:14 2011        (r1451)
+++ trunk/ichspi.c      Thu Oct 20 14:57:14 2011        (r1452)
@@ -26,6 +26,7 @@
 #if defined(__i386__) || defined(__x86_64__)
 
 #include <string.h>
+#include <stdlib.h>
 #include "flash.h"
 #include "programmer.h"
 #include "spi.h"
@@ -1080,6 +1081,77 @@
        return result;
 }
 
+#if 0
+/* Sets FLA in FADDR to (addr & 0x01FFFFFF) without touching other bits. */
+static void ich_hwseq_set_addr(uint32_t addr)
+{
+       uint32_t addr_old = REGREAD32(ICH9_REG_FADDR) & ~0x01FFFFFF;
+       REGWRITE32(ICH9_REG_FADDR, (addr & 0x01FFFFFF) | addr_old);
+}
+
+/* Sets FADDR.FLA to 'addr' and returns the erase block size in bytes
+ * of the block containing this address. May return nonsense if the address is
+ * not valid. The erase block size for a specific address depends on the flash
+ * partition layout as specified by FPB and the partition properties as defined
+ * by UVSCC and LVSCC respectively. An alternative to implement this method
+ * would be by querying FPB and the respective VSCC register directly.
+ */
+static uint32_t ich_hwseq_get_erase_block_size(unsigned int addr)
+{
+       uint8_t enc_berase;
+       static const uint32_t const dec_berase[4] = {
+               256,
+               4 * 1024,
+               8 * 1024,
+               64 * 1024
+       };
+
+       ich_hwseq_set_addr(addr);
+       enc_berase = (REGREAD16(ICH9_REG_HSFS) & HSFS_BERASE) >>
+                    HSFS_BERASE_OFF;
+       return dec_berase[enc_berase];
+}
+
+/* Polls for Cycle Done Status, Flash Cycle Error or timeout in 8 us intervals.
+   Resets all error flags in HSFS.
+   Returns 0 if the cycle completes successfully without errors within
+   timeout us, 1 on errors. */
+static int ich_hwseq_wait_for_cycle_complete(unsigned int timeout,
+                                            unsigned int len)
+{
+       uint16_t hsfs;
+       uint32_t addr;
+
+       timeout /= 8; /* scale timeout duration to counter */
+       while ((((hsfs = REGREAD16(ICH9_REG_HSFS)) &
+                (HSFS_FDONE | HSFS_FCERR)) == 0) &&
+              --timeout) {
+               programmer_delay(8);
+       }
+       REGWRITE16(ICH9_REG_HSFS, REGREAD16(ICH9_REG_HSFS));
+       if (!timeout) {
+               addr = REGREAD32(ICH9_REG_FADDR) & 0x01FFFFFF;
+               msg_perr("Timeout error between offset 0x%08x and "
+                        "0x%08x + %d (=0x%08x)!\n",
+                        addr, addr, len - 1, addr + len - 1);
+               prettyprint_ich9_reg_hsfs(hsfs);
+               prettyprint_ich9_reg_hsfc(REGREAD16(ICH9_REG_HSFC));
+               return 1;
+       }
+
+       if (hsfs & HSFS_FCERR) {
+               addr = REGREAD32(ICH9_REG_FADDR) & 0x01FFFFFF;
+               msg_perr("Transaction error between offset 0x%08x and "
+                        "0x%08x (=0x%08x + %d)!\n",
+                        addr, addr + len - 1, addr, len - 1);
+               prettyprint_ich9_reg_hsfs(hsfs);
+               prettyprint_ich9_reg_hsfc(REGREAD16(ICH9_REG_HSFC));
+               return 1;
+       }
+       return 0;
+}
+#endif
+
 static int ich_spi_send_multicommand(struct spi_command *cmds)
 {
        int ret = 0;
@@ -1250,21 +1322,18 @@
        uint8_t old, new;
        uint16_t spibar_offset, tmp2;
        uint32_t tmp;
-       int ichspi_desc = 0;
+       int desc_valid = 0;
 
        switch (ich_generation) {
        case 7:
-               register_spi_programmer(&spi_programmer_ich7);
                spibar_offset = 0x3020;
                break;
        case 8:
-               register_spi_programmer(&spi_programmer_ich9);
                spibar_offset = 0x3020;
                break;
        case 9:
        case 10:
        default:                /* Future version might behave the same */
-               register_spi_programmer(&spi_programmer_ich9);
                spibar_offset = 0x3800;
                break;
        }
@@ -1275,8 +1344,8 @@
        /* Assign Virtual Address */
        ich_spibar = rcrb + spibar_offset;
 
-       switch (spi_programmer->type) {
-       case SPI_CONTROLLER_ICH7:
+       switch (ich_generation) {
+       case 7:
                msg_pdbg("0x00: 0x%04x     (SPIS)\n",
                             mmio_readw(ich_spibar + 0));
                msg_pdbg("0x02: 0x%04x     (SPIC)\n",
@@ -1313,9 +1382,13 @@
                        ichspi_lock = 1;
                }
                ich_set_bbar(ich_generation, 0);
+               register_spi_programmer(&spi_programmer_ich7);
                ich_init_opcodes();
                break;
-       case SPI_CONTROLLER_ICH9:
+       case 8:
+       case 9:
+       case 10:
+       default:                /* Future version might behave the same */
                tmp2 = mmio_readw(ich_spibar + ICH9_REG_HSFS);
                msg_pdbg("0x04: 0x%04x (HSFS)\n", tmp2);
                prettyprint_ich9_reg_hsfs(tmp2);
@@ -1324,8 +1397,8 @@
                        ichspi_lock = 1;
                }
                if (tmp2 & HSFS_FDV)
-                       ichspi_desc = 1;
-               if (!(tmp2 & HSFS_FDOPSS) && ichspi_desc)
+                       desc_valid = 1;
+               if (!(tmp2 & HSFS_FDOPSS) && desc_valid)
                        msg_pinfo("The Flash Descriptor Security Override "
                                  "Strap-Pin is set. Restrictions implied\n"
                                  "by the FRAP and FREG registers are NOT in "
@@ -1400,18 +1473,16 @@
                }
 
                msg_pdbg("\n");
-               if (ichspi_desc) {
+               if (desc_valid) {
                        struct ich_descriptors desc = {{ 0 }};
                        if (read_ich_descriptors_via_fdo(ich_spibar, &desc) ==
                            ICH_RET_OK)
                                prettyprint_ich_descriptors(CHIPSET_ICH_UNKNOWN,
                                                            &desc);
                }
+               register_spi_programmer(&spi_programmer_ich9);
                ich_init_opcodes();
                break;
-       default:
-               /* Nothing */
-               break;
        }
 
        old = pci_read_byte(dev, 0xdc);

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

Reply via email to