[coreboot-gerrit] New patch to review for filo: c439e0d Add support for flash lock on Cougar / Panther Point

Nico Huber (nico.huber@secunet.com) gerrit at coreboot.org
Wed Jul 3 16:17:12 CEST 2013


Nico Huber (nico.huber at secunet.com) just uploaded a new patch set to gerrit, which you can find at http://review.coreboot.org/3597

-gerrit

commit c439e0d2502218ba7ae66837fc8c6ffd7fe6cdfe
Author: Nico Huber <nico.huber at secunet.com>
Date:   Wed Jul 3 15:12:50 2013 +0200

    Add support for flash lock on Cougar / Panther Point
    
    Add PCI IDs for Cougar Point and Panther Point PCHs and lock their
    SPI interface like we do it in coreboot's resume path. We write a
    valid opcode menu but set all flash regions to read only. The regions
    are strapped from the flash descriptor.
    
    Change-Id: Ie5735cff02564822139f45666c1f28b080a9c6d3
    Signed-off-by: Nico Huber <nico.huber at secunet.com>
---
 Config.in       |   1 +
 drivers/intel.c | 101 +++++++++++++++++++++++++++++++++++++++++++++++++++++++-
 2 files changed, 101 insertions(+), 1 deletion(-)

diff --git a/Config.in b/Config.in
index 08ac0ec..cc48bd3 100644
--- a/Config.in
+++ b/Config.in
@@ -196,6 +196,7 @@ config FLASHROM_LOCKDOWN
 
 	        o Intel ICH7 (FWH)
 	        o Intel ICH9 (FWH + SPI)
+	        o Intel Cougar Point / Panther Point PCH (FWH + SPI)
 	        o AMD SB600 (SPI by locking the flash chip itself)
 
 endmenu
diff --git a/drivers/intel.c b/drivers/intel.c
index d2153b7..90811de 100644
--- a/drivers/intel.c
+++ b/drivers/intel.c
@@ -45,10 +45,53 @@
 
 #define ICH9_SPI_HSFS		0x3804
 #define ICH9_SPI_HSFS_FLOCKDN	(1 << 15);
+#define ICH9_SPI_FLASH_REGIONS	5
+#define ICH9_SPI_FREG0		0x3854
+#define ICH9_SPI_FPR0		0x3874
 #define ICH9_SPI_PREOP		0x3894
 #define ICH9_SPI_OPTYPE		0x3896
 #define ICH9_SPI_OPMENU		0x3898
 
+/*
+ * SPI Opcode Menu setup for SPIBAR lockdown
+ * should support most common flash chips.
+ */
+#define SPI_OPMENU_0 0x01 /* WRSR: Write Status Register */
+#define SPI_OPTYPE_0 0x01 /* Write, no address */
+
+#define SPI_OPMENU_1 0x02 /* BYPR: Byte Program */
+#define SPI_OPTYPE_1 0x03 /* Write, address required */
+
+#define SPI_OPMENU_2 0x03 /* READ: Read Data */
+#define SPI_OPTYPE_2 0x02 /* Read, address required */
+
+#define SPI_OPMENU_3 0x05 /* RDSR: Read Status Register */
+#define SPI_OPTYPE_3 0x00 /* Read, no address */
+
+#define SPI_OPMENU_4 0x20 /* SE20: Sector Erase 0x20 */
+#define SPI_OPTYPE_4 0x03 /* Write, address required */
+
+#define SPI_OPMENU_5 0x9f /* RDID: Read ID */
+#define SPI_OPTYPE_5 0x00 /* Read, no address */
+
+#define SPI_OPMENU_6 0xd8 /* BED8: Block Erase 0xd8 */
+#define SPI_OPTYPE_6 0x03 /* Write, address required */
+
+#define SPI_OPMENU_7 0x0b /* FAST: Fast Read */
+#define SPI_OPTYPE_7 0x02 /* Read, address required */
+
+#define SPI_OPMENU_UPPER ((SPI_OPMENU_7 << 24) | (SPI_OPMENU_6 << 16) | \
+			  (SPI_OPMENU_5 << 8) | SPI_OPMENU_4)
+#define SPI_OPMENU_LOWER ((SPI_OPMENU_3 << 24) | (SPI_OPMENU_2 << 16) | \
+			  (SPI_OPMENU_1 << 8) | SPI_OPMENU_0)
+
+#define SPI_OPTYPE ((SPI_OPTYPE_7 << 14) | (SPI_OPTYPE_6 << 12) | \
+		    (SPI_OPTYPE_5 << 10) | (SPI_OPTYPE_4 << 8) |  \
+		    (SPI_OPTYPE_3 << 6) | (SPI_OPTYPE_2 << 4) |	  \
+		    (SPI_OPTYPE_1 << 2) | (SPI_OPTYPE_0))
+
+#define SPI_OPPREFIX ((0x50 << 8) | 0x06) /* EWSR and WREN */
+
 static void lockdown_flash_ich7(void)
 {
 	u8 reg8;
@@ -80,6 +123,24 @@ static void lockdown_flash_ich9_empty_ops(void)
 	RCBA16(ICH9_SPI_HSFS) |= ICH9_SPI_HSFS_FLOCKDN;
 }
 
+static void lockdown_flash_ich9_lock_regions(void)
+{
+	/* Lock SPI interface with the opcodes coreboot uses */
+	RCBA16(ICH9_SPI_PREOP)  = SPI_OPPREFIX;
+	RCBA16(ICH9_SPI_OPTYPE) = SPI_OPTYPE;
+	RCBA32(ICH9_SPI_OPMENU + 0) = SPI_OPMENU_LOWER;
+	RCBA32(ICH9_SPI_OPMENU + 4) = SPI_OPMENU_UPPER;
+
+	/* Copy flash regions from FREG0-4 to FPR0-4
+	   and enable write protection bit31 */
+	int i;
+	for (i = 0; i < (4 * ICH9_SPI_FLASH_REGIONS); i += 4)
+		RCBA32(ICH9_SPI_FPR0 + i) =
+			RCBA32(ICH9_SPI_FREG0 + i) | (1 << 31);
+
+	RCBA16(ICH9_SPI_HSFS) |= ICH9_SPI_HSFS_FLOCKDN;
+}
+
 int intel_lockdown_flash(void)
 {
 	const u32 reg32 = pci_read_config32(PCI_DEV(0,0x1f, 0), 0);
@@ -106,8 +167,46 @@ int intel_lockdown_flash(void)
 		   of setting up any write protection. */
 		lockdown_flash_ich9_empty_ops();
 		break;
+
+		/* Cougar Point */
+	case 0x1c448086:
+	case 0x1c468086:
+	case 0x1c478086:
+	case 0x1c498086:
+	case 0x1c4a8086:
+	case 0x1c4b8086:
+	case 0x1c4c8086:
+	case 0x1c4d8086:
+	case 0x1c4e8086:
+	case 0x1c4f8086:
+	case 0x1c508086:
+	case 0x1c528086:
+	case 0x1c548086:
+	case 0x1c568086:
+	case 0x1c5c8086:
+		/* Panther Point */
+	case 0x1e448086:
+	case 0x1e468086:
+	case 0x1e478086:
+	case 0x1e488086:
+	case 0x1e498086:
+	case 0x1e4a8086:
+	case 0x1e538086:
+	case 0x1e558086:
+	case 0x1e568086:
+	case 0x1e578086:
+	case 0x1e588086:
+	case 0x1e598086:
+	case 0x1e5d8086:
+	case 0x1e5e8086:
+	case 0x1e5f8086:
+		lockdown_flash_ich7();
+		/* Since Cougar Point, coreboot uses flash regions,
+		   lock them and set up static SPI opcodes. */
+		lockdown_flash_ich9_lock_regions();
+		break;
 	default:
-		debug("Not an ICH7 or ICH9 southbridge\n");
+		debug("Not a supported ICH or PCH southbridge\n");
 		return -1;
 	}
 



More information about the coreboot-gerrit mailing list