From 3664647a25f31a26993433dcb6754484f58a9a62 Mon Sep 17 00:00:00 2001 From: Arthur Heymans Date: Mon, 22 Jan 2018 14:42:18 +0100 Subject: sb/intel/i82801gx: Add the option to lock the platform This allows to lock down spi among other things Mostly copied from bd82x6x. Tested on Intel DG41WV with the MRC_CACHE driver write protecting the mrc_cache region. Change-Id: If9c3a6118f4586d51c093edec896c347ba904b8f Signed-off-by: Arthur Heymans Reviewed-on: https://review.coreboot.org/23358 Tested-by: build bot (Jenkins) Reviewed-by: Patrick Georgi --- src/southbridge/intel/i82801gx/Kconfig | 1 + src/southbridge/intel/i82801gx/i82801gx.h | 47 +++++++++++++++++++++++++++++++ src/southbridge/intel/i82801gx/lpc.c | 35 +++++++++++++++++++++++ 3 files changed, 83 insertions(+) (limited to 'src/southbridge/intel') diff --git a/src/southbridge/intel/i82801gx/Kconfig b/src/southbridge/intel/i82801gx/Kconfig index 9fd19ed324..2670d23c9d 100644 --- a/src/southbridge/intel/i82801gx/Kconfig +++ b/src/southbridge/intel/i82801gx/Kconfig @@ -26,6 +26,7 @@ config SOUTHBRIDGE_INTEL_I82801GX select SOUTHBRIDGE_INTEL_COMMON_GPIO select SOUTHBRIDGE_INTEL_COMMON_SMBUS select SOUTHBRIDGE_INTEL_COMMON_SPI + select HAVE_INTEL_CHIPSET_LOCKDOWN if SOUTHBRIDGE_INTEL_I82801GX diff --git a/src/southbridge/intel/i82801gx/i82801gx.h b/src/southbridge/intel/i82801gx/i82801gx.h index 1038bafdab..36c79eb5d1 100644 --- a/src/southbridge/intel/i82801gx/i82801gx.h +++ b/src/southbridge/intel/i82801gx/i82801gx.h @@ -368,6 +368,53 @@ int southbridge_detect_s3_resume(void); #define DEVACT_STS 0x44 #define SS_CNT 0x50 #define C3_RES 0x54 +#define TCO1_CNT 0x68 + +/* SPIBAR + * + * SPI Opcode Menu setup for SPIBAR lockdown + * should support most common flash chips. + */ + +#define PREOP 0x54 +#define OPTYPE 0x56 +#define OPMENU 0x58 + +#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 */ #endif /* __ACPI__ */ #endif /* SOUTHBRIDGE_INTEL_I82801GX_I82801GX_H */ diff --git a/src/southbridge/intel/i82801gx/lpc.c b/src/southbridge/intel/i82801gx/lpc.c index ab426ab86c..acc57a7dfb 100644 --- a/src/southbridge/intel/i82801gx/lpc.c +++ b/src/southbridge/intel/i82801gx/lpc.c @@ -645,6 +645,40 @@ static void i82801gx_lpc_read_resources(struct device *dev) } } +#define SPIBAR16(x) RCBA16(0x3020 + x) +#define SPIBAR32(x) RCBA32(0x3020 + x) + +static void lpc_final(struct device *dev) +{ + u16 tco1_cnt; + + if (!IS_ENABLED(CONFIG_INTEL_CHIPSET_LOCKDOWN)) + return; + + SPIBAR16(PREOP) = SPI_OPPREFIX; + /* Set SPI opcode menu */ + SPIBAR16(OPTYPE) = SPI_OPTYPE; + SPIBAR32(OPMENU) = SPI_OPMENU_LOWER; + SPIBAR32(OPMENU + 4) = SPI_OPMENU_UPPER; + + /* Lock SPIBAR */ + SPIBAR16(0) = SPIBAR16(0) | (1 << 15); + + /* BIOS Interface Lockdown */ + RCBA32(0x3410) |= 1 << 0; + + /* Global SMI Lock */ + pci_or_config16(dev, GEN_PMCON_1, 1 << 4); + + /* TCO_Lock */ + tco1_cnt = inw(DEFAULT_PMBASE + 0x60 + TCO1_CNT); + tco1_cnt |= (1 << 12); /* TCO lock */ + outw(tco1_cnt, DEFAULT_PMBASE + 0x60 + TCO1_CNT); + + /* Indicate finalize step with post code */ + outb(POST_OS_BOOT, 0x80); +} + static void set_subsystem(struct device *dev, unsigned int vendor, unsigned int device) { @@ -698,6 +732,7 @@ static struct device_operations device_ops = { .scan_bus = scan_lpc_bus, .enable = i82801gx_enable, .ops_pci = &pci_ops, + .final = lpc_final, }; /* 27b0: 82801GH (ICH7 DH) */ -- cgit v1.2.3