Attention is currently required from: Hsuan Ting Chen.

Hsuan-ting Chen would like Hsuan Ting Chen to review this change.

View Change

ichspi.c: Add support for region 9 and beyond in Meteor Lake

Since Meteor Lake, configuring region access for FREG9 and higher is
necessary. This configuration is determined using BIOS_BM registers:

BIOS_BM_RAP (Offset 0x118): BIOS Master Read Access Permissions.
Each bit [15:0] corresponds to a region [15:0].
A set bit grants BIOS master read access.

BIOS_BM_WAP (Offset 0x11c): BIOS Master Write Access Permissions.
Each bit [15:0] corresponds to a region [15:0].
A set bit grants BIOS master write/erase access.

BUG=b:319773700, b:304439294
BUG=b:319336080
TEST=On MTL, use flashrom -VV to see correct FREG9 access
TEST=On ADL, use flashrom -VV to see not break anything

Change-Id: I1e06e7b3d470423a6014e623826d9234fdebfbf9
Signed-off-by: roccochen@chromium.com <roccochen@chromium.org>
---
M ichspi.c
1 file changed, 63 insertions(+), 12 deletions(-)

git pull ssh://review.coreboot.org:29418/flashrom refs/changes/57/81357/1
diff --git a/ichspi.c b/ichspi.c
index bee5ec9..8e98de5 100644
--- a/ichspi.c
+++ b/ichspi.c
@@ -153,6 +153,9 @@
#define ICH9_FADDR_FLA 0x01ffffff
#define ICH9_REG_FDATA0 0x10 /* 64 Bytes */

+#define ICH_REG_BIOS_BM_RAP 0x118 /* 16 Bits BIOS Master Read Access Permissions */
+#define ICH_REG_BIOS_BM_WAP 0x11c /* 16 Bits BIOS Master Write Access Permissions */
+
#define ICH9_REG_FRAP 0x50 /* 32 Bytes Flash Region Access Permissions */
#define ICH9_REG_FREG0 0x54 /* 32 Bytes Flash Region 0 */

@@ -1834,8 +1837,58 @@
"read-write", "write-only", "read-only", "locked"
};

+static void ich_get_bios_region_access(uint32_t *region_read_access,
+ uint32_t *region_write_access)
+{
+ uint32_t tmp;
+ *region_read_access = 0;
+ *region_write_access = 0;
+
+ switch (ich_generation) {
+ case CHIPSET_METEOR_LAKE:
+ /*
+ * Starting from Meteor Lake, we need to fetch the region
+ * read/write access permissions from the BIOS_BM registers
+ * because we need to support FREG9 or above.
+ */
+ *region_read_access = mmio_readw(ich_spibar + ICH_REG_BIOS_BM_RAP);
+ *region_write_access = mmio_readw(ich_spibar + ICH_REG_BIOS_BM_WAP);
+ break;
+
+ default:
+ /*
+ * FRAP - Flash Regions Access Permissions Register
+ * Bit Descriptions:
+ * 31:24 BIOS Master Write Access Grant (BMWAG)
+ * 23:16 BIOS Master Read Access Grant (BMRAG)
+ * 15:8 BIOS Region Write Access (BRWA)
+ * 7:0 BIOS Region Read Access (BRRA)
+ */
+ tmp = mmio_readl(ich_spibar + ICH9_REG_FRAP);
+ msg_pdbg("0x50: 0x%08"PRIx32" (FRAP)\n", tmp);
+ msg_pdbg("BMWAG 0x%02"PRIx32", ", ICH_BMWAG(tmp));
+ msg_pdbg("BMRAG 0x%02"PRIx32", ", ICH_BMRAG(tmp));
+ msg_pdbg("BRWA 0x%02"PRIx32", ", ICH_BRWA(tmp));
+ msg_pdbg("BRRA 0x%02"PRIx32"\n", ICH_BRRA(tmp));
+
+ *region_read_access = ICH_BRRA(tmp);
+ *region_write_access = ICH_BRWA(tmp);
+ break;
+ }
+}
+
+inline static unsigned int ich_get_defined_region_count(void) {
+ switch (ich_generation) {
+ case CHIPSET_METEOR_LAKE:
+ return 16;
+ default:
+ return 8;
+ }
+}
+
static enum ich_access_protection ich9_handle_frap(struct fd_region *fd_regions,
- uint32_t frap, unsigned int i)
+ uint32_t region_read_access,
+ uint32_t region_write_access, unsigned int i)
{
static const char *const region_names[] = {
"Flash Descriptor", "BIOS", "Management Engine",
@@ -1863,12 +1916,12 @@
}
msg_pdbg("0x%02X: 0x%08"PRIx32" ", offset, freg);

- if (i < 8) {
- rwperms_idx = (((ICH_BRWA(frap) >> i) & 1) << 1) |
- (((ICH_BRRA(frap) >> i) & 1) << 0);
+ if (i < ich_get_defined_region_count()) {
+ rwperms_idx = (((region_write_access >> i) & 1) << 1) |
+ (((region_read_access >> i) & 1) << 0);
rwperms = access_perms_to_protection[rwperms_idx];
} else {
- /* Datasheets don't define any access bits for regions > 7. We
+ /* Datasheets might not define all the access bits for regions. We
can't rely on the actual descriptor settings either as there
are several overrides for them (those by other masters are
not even readable by us, *shrug*). */
@@ -2175,16 +2228,14 @@
}

if (desc_valid) {
- tmp = mmio_readl(spibar + ICH9_REG_FRAP);
- msg_pdbg("0x50: 0x%08"PRIx32" (FRAP)\n", tmp);
- msg_pdbg("BMWAG 0x%02"PRIx32", ", ICH_BMWAG(tmp));
- msg_pdbg("BMRAG 0x%02"PRIx32", ", ICH_BMRAG(tmp));
- msg_pdbg("BRWA 0x%02"PRIx32", ", ICH_BRWA(tmp));
- msg_pdbg("BRRA 0x%02"PRIx32"\n", ICH_BRRA(tmp));
+ unsigned int region_read_access, region_write_access;
+ ich_get_bios_region_access(&region_read_access, &region_write_access);

/* Handle FREGx and FRAP registers */
for (i = 0; i < num_freg; i++)
- ich_spi_rw_restricted |= ich9_handle_frap(hwseq_data.fd_regions, tmp, i);
+ ich_spi_rw_restricted |= ich9_handle_frap(hwseq_data.fd_regions,
+ region_read_access,
+ region_write_access, i);
if (ich_spi_rw_restricted)
msg_pinfo("Not all flash regions are freely accessible by flashrom. This is "
"most likely\ndue to an active ME. Please see "

To view, visit change 81357. To unsubscribe, or for help writing mail filters, visit settings.

Gerrit-Project: flashrom
Gerrit-Branch: main
Gerrit-Change-Id: I1e06e7b3d470423a6014e623826d9234fdebfbf9
Gerrit-Change-Number: 81357
Gerrit-PatchSet: 1
Gerrit-Owner: Hsuan-ting Chen <roccochen@google.com>
Gerrit-Reviewer: Hsuan Ting Chen <roccochen@chromium.org>
Gerrit-Attention: Hsuan Ting Chen <roccochen@chromium.org>
Gerrit-MessageType: newchange