[flashrom] [commit] r1452 - trunk

repository service svn at flashrom.org
Thu Oct 20 14:57:14 CEST 2011


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 <stefan.tauner at student.tuwien.ac.at>
Acked-by: Carl-Daniel Hailfinger <c-d.hailfinger.devel.2006 at gmx.net>

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);




More information about the flashrom mailing list