mirror of
https://review.coreboot.org/flashrom.git
synced 2025-04-26 22:52:34 +02:00
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. Move CHIPSET_METEOR_LAKE to the bottom of the ich_chipset list to ensure that all the newer chipsets in the future will use BIOS_BM check by default. 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 TEST=On APL, use flashrom -VV to see not break anything Change-Id: I1e06e7b3d470423a6014e623826d9234fdebfbf9 Signed-off-by: Hsuan Ting Chen <roccochen@chromium.org> Reviewed-on: https://review.coreboot.org/c/flashrom/+/81357 Reviewed-by: Jamie Ryu <jamie.m.ryu@intel.com> Reviewed-by: Nikolai Artemiev <nartemiev@google.com> Reviewed-by: Anastasia Klimchuk <aklm@chromium.org> Tested-by: build bot (Jenkins) <no-reply@coreboot.org>
This commit is contained in:
parent
3b3e25f1ca
commit
85b977151b
84
ichspi.c
84
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,52 @@ static const char *const access_names[] = {
|
||||
"read-write", "write-only", "read-only", "locked"
|
||||
};
|
||||
|
||||
static enum ich_access_protection ich9_handle_frap(struct fd_region *fd_regions,
|
||||
uint32_t frap, unsigned int i)
|
||||
static void ich_get_bios_region_access(uint16_t *region_read_access,
|
||||
uint16_t *region_write_access)
|
||||
{
|
||||
uint32_t tmp;
|
||||
*region_read_access = 0;
|
||||
*region_write_access = 0;
|
||||
|
||||
if (ich_generation >= 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);
|
||||
msg_pdbg("0x118: 0x%04"PRIx16" (BIOS_BM_RAP)\n", *region_read_access);
|
||||
msg_pdbg("0x11a: 0x%04"PRIx16" (BIOS_BM_WAP)\n", *region_write_access);
|
||||
} else {
|
||||
/*
|
||||
* 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 = (uint16_t)ICH_BRRA(tmp);
|
||||
*region_write_access = (uint16_t)ICH_BRWA(tmp);
|
||||
}
|
||||
}
|
||||
|
||||
static unsigned int ich_get_defined_region_count(void) {
|
||||
return (ich_generation >= CHIPSET_METEOR_LAKE) ? 16 : 8;
|
||||
}
|
||||
|
||||
static enum ich_access_protection ich9_handle_region_access(struct fd_region *fd_regions,
|
||||
uint16_t region_read_access,
|
||||
uint16_t region_write_access,
|
||||
unsigned int i)
|
||||
{
|
||||
static const char *const region_names[] = {
|
||||
"Flash Descriptor", "BIOS", "Management Engine",
|
||||
@ -1863,12 +1910,12 @@ static enum ich_access_protection ich9_handle_frap(struct fd_region *fd_regions,
|
||||
}
|
||||
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*). */
|
||||
@ -2059,11 +2106,11 @@ static void init_chipset_properties(struct swseq_data *swseq, struct hwseq_data
|
||||
case CHIPSET_400_SERIES_COMET_POINT:
|
||||
case CHIPSET_500_SERIES_TIGER_POINT:
|
||||
case CHIPSET_600_SERIES_ALDER_POINT:
|
||||
case CHIPSET_METEOR_LAKE:
|
||||
case CHIPSET_APOLLO_LAKE:
|
||||
case CHIPSET_GEMINI_LAKE:
|
||||
case CHIPSET_JASPER_LAKE:
|
||||
case CHIPSET_ELKHART_LAKE:
|
||||
case CHIPSET_METEOR_LAKE:
|
||||
*num_pr = 6; /* Includes GPR0 */
|
||||
*reg_pr0 = PCH100_REG_FPR0;
|
||||
swseq->reg_ssfsc = PCH100_REG_SSFSC;
|
||||
@ -2099,11 +2146,11 @@ static void init_chipset_properties(struct swseq_data *swseq, struct hwseq_data
|
||||
case CHIPSET_400_SERIES_COMET_POINT:
|
||||
case CHIPSET_500_SERIES_TIGER_POINT:
|
||||
case CHIPSET_600_SERIES_ALDER_POINT:
|
||||
case CHIPSET_METEOR_LAKE:
|
||||
case CHIPSET_APOLLO_LAKE:
|
||||
case CHIPSET_GEMINI_LAKE:
|
||||
case CHIPSET_JASPER_LAKE:
|
||||
case CHIPSET_ELKHART_LAKE:
|
||||
case CHIPSET_METEOR_LAKE:
|
||||
*num_freg = 16;
|
||||
break;
|
||||
default:
|
||||
@ -2161,11 +2208,11 @@ static int init_ich_default(const struct programmer_cfg *cfg, void *spibar, enum
|
||||
case CHIPSET_400_SERIES_COMET_POINT:
|
||||
case CHIPSET_500_SERIES_TIGER_POINT:
|
||||
case CHIPSET_600_SERIES_ALDER_POINT:
|
||||
case CHIPSET_METEOR_LAKE:
|
||||
case CHIPSET_APOLLO_LAKE:
|
||||
case CHIPSET_GEMINI_LAKE:
|
||||
case CHIPSET_JASPER_LAKE:
|
||||
case CHIPSET_ELKHART_LAKE:
|
||||
case CHIPSET_METEOR_LAKE:
|
||||
tmp = mmio_readl(spibar + PCH100_REG_DLOCK);
|
||||
msg_pdbg("0x0c: 0x%08"PRIx32" (DLOCK)\n", tmp);
|
||||
prettyprint_pch100_reg_dlock(tmp);
|
||||
@ -2175,16 +2222,15 @@ static int init_ich_default(const struct programmer_cfg *cfg, void *spibar, enum
|
||||
}
|
||||
|
||||
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));
|
||||
/* Get the region access data from FRAP/BIOS_BM */
|
||||
uint16_t region_read_access, region_write_access;
|
||||
ich_get_bios_region_access(®ion_read_access, ®ion_write_access);
|
||||
|
||||
/* Handle FREGx and FRAP registers */
|
||||
/* Handle FREGx and region access 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_region_access(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 "
|
||||
@ -2242,12 +2288,12 @@ static int init_ich_default(const struct programmer_cfg *cfg, void *spibar, enum
|
||||
case CHIPSET_400_SERIES_COMET_POINT:
|
||||
case CHIPSET_500_SERIES_TIGER_POINT:
|
||||
case CHIPSET_600_SERIES_ALDER_POINT:
|
||||
case CHIPSET_METEOR_LAKE:
|
||||
case CHIPSET_APOLLO_LAKE:
|
||||
case CHIPSET_GEMINI_LAKE:
|
||||
case CHIPSET_JASPER_LAKE:
|
||||
case CHIPSET_BAYTRAIL:
|
||||
case CHIPSET_ELKHART_LAKE:
|
||||
case CHIPSET_METEOR_LAKE:
|
||||
break;
|
||||
default:
|
||||
ichspi_bbar = mmio_readl(spibar + ICH9_REG_BBAR);
|
||||
@ -2282,11 +2328,11 @@ static int init_ich_default(const struct programmer_cfg *cfg, void *spibar, enum
|
||||
case CHIPSET_400_SERIES_COMET_POINT:
|
||||
case CHIPSET_500_SERIES_TIGER_POINT:
|
||||
case CHIPSET_600_SERIES_ALDER_POINT:
|
||||
case CHIPSET_METEOR_LAKE:
|
||||
case CHIPSET_APOLLO_LAKE:
|
||||
case CHIPSET_GEMINI_LAKE:
|
||||
case CHIPSET_JASPER_LAKE:
|
||||
case CHIPSET_ELKHART_LAKE:
|
||||
case CHIPSET_METEOR_LAKE:
|
||||
break;
|
||||
default:
|
||||
tmp = mmio_readl(spibar + ICH9_REG_FPB);
|
||||
|
@ -357,11 +357,12 @@ enum ich_chipset {
|
||||
CHIPSET_400_SERIES_COMET_POINT,
|
||||
CHIPSET_500_SERIES_TIGER_POINT,
|
||||
CHIPSET_600_SERIES_ALDER_POINT,
|
||||
CHIPSET_METEOR_LAKE,
|
||||
CHIPSET_APOLLO_LAKE,
|
||||
CHIPSET_GEMINI_LAKE,
|
||||
CHIPSET_JASPER_LAKE,
|
||||
CHIPSET_ELKHART_LAKE,
|
||||
/* All chipsets after METEOR_LAKE should support checking BIOS_BM to get read/write access to of FREG0~15 */
|
||||
CHIPSET_METEOR_LAKE,
|
||||
};
|
||||
|
||||
/* ichspi.c */
|
||||
|
Loading…
x
Reference in New Issue
Block a user