summaryrefslogtreecommitdiffstats
path: root/ichspi.c
diff options
context:
space:
mode:
authorNico Huber <nico.huber@secunet.com>2016-05-03 13:38:28 +0200
committerNico Huber <nico.h@gmx.de>2018-05-29 14:56:51 +0000
commit7590d1a9375e94d01cef08a2bde10a05177d5829 (patch)
treea69d185d67f2b7d846d5f92b358b917b82696b0a /ichspi.c
parentf9a30554803a670f9b95a7794be00f03929d6ecd (diff)
downloadflashrom-7590d1a9375e94d01cef08a2bde10a05177d5829.tar.gz
flashrom-7590d1a9375e94d01cef08a2bde10a05177d5829.tar.bz2
flashrom-7590d1a9375e94d01cef08a2bde10a05177d5829.zip
Enable writes with active ME
Replace the `ich_spi_force` logic with more helpful warnings. These can be hidden later, in case the necessary switches are detected. Also, demote some warnings about settings that are the default nowadays (e.g. SPI configuration lock, inaccessible ME region). Change-Id: I94a5e7074b845c227e43d76d04dd1a71082a1cef Signed-off-by: Nico Huber <nico.huber@secunet.com> Reviewed-on: https://review.coreboot.org/26261 Tested-by: build bot (Jenkins) <no-reply@coreboot.org> Reviewed-by: Arthur Heymans <arthur@aheymans.xyz>
Diffstat (limited to 'ichspi.c')
-rw-r--r--ichspi.c84
1 files changed, 38 insertions, 46 deletions
diff --git a/ichspi.c b/ichspi.c
index 1989a877e..9eb24a99d 100644
--- a/ichspi.c
+++ b/ichspi.c
@@ -221,6 +221,13 @@
#define ICH7_REG_OPTYPE 0x56 /* 16 Bits */
#define ICH7_REG_OPMENU 0x58 /* 64 Bits */
+enum ich_access_protection {
+ NO_PROT = 0,
+ READ_PROT = 1,
+ WRITE_PROT = 2,
+ LOCKED = 3,
+};
+
/* ICH SPI configuration lock-down. May be set during chipset enabling. */
static int ichspi_lock = 0;
@@ -1547,12 +1554,15 @@ static int ich_spi_send_multicommand(struct flashctx *flash,
#define ICH_BRWA(x) ((x >> 8) & 0xff)
#define ICH_BRRA(x) ((x >> 0) & 0xff)
-/* returns 0 if region is unused or r/w */
-static int ich9_handle_frap(uint32_t frap, int i)
+static const enum ich_access_protection access_perms_to_protection[] = {
+ LOCKED, WRITE_PROT, READ_PROT, NO_PROT
+};
+static const char *const access_names[] = {
+ "locked", "read-only", "write-only", "read-write"
+};
+
+static enum ich_access_protection ich9_handle_frap(uint32_t frap, int i)
{
- static const char *const access_names[4] = {
- "locked", "read-only", "write-only", "read-write"
- };
const int rwperms_unknown = ARRAY_SIZE(access_names);
static const char *const region_names[5] = {
"Flash Descriptor", "BIOS", "Management Engine",
@@ -1582,23 +1592,23 @@ static int ich9_handle_frap(uint32_t frap, int i)
/* this FREG is disabled */
msg_pdbg2("0x%02X: 0x%08x FREG%i: %s region is unused.\n",
offset, freg, i, region_name);
- return 0;
+ return NO_PROT;
}
msg_pdbg("0x%02X: 0x%08x ", offset, freg);
if (rwperms == 0x3) {
msg_pdbg("FREG%i: %s region (0x%08x-0x%08x) is %s.\n", i,
region_name, base, limit, access_names[rwperms]);
- return 0;
+ return NO_PROT;
}
if (rwperms == rwperms_unknown) {
msg_pdbg("FREG%i: %s region (0x%08x-0x%08x) has unknown permissions.\n",
i, region_name, base, limit);
- return 0;
+ return NO_PROT;
}
- msg_pwarn("FREG%i: Warning: %s region (0x%08x-0x%08x) is %s.\n", i,
+ msg_pinfo("FREG%i: %s region (0x%08x-0x%08x) is %s.\n", i,
region_name, base, limit, access_names[rwperms]);
- return 1;
+ return access_perms_to_protection[rwperms];
}
/* In contrast to FRAP and the master section of the descriptor the bits
@@ -1610,12 +1620,8 @@ static int ich9_handle_frap(uint32_t frap, int i)
#define ICH_PR_PERMS(pr) (((~((pr) >> PR_RP_OFF) & 1) << 0) | \
((~((pr) >> PR_WP_OFF) & 1) << 1))
-/* returns 0 if range is unused (i.e. r/w) */
-static int ich9_handle_pr(const size_t reg_pr0, int i)
+static enum ich_access_protection ich9_handle_pr(const size_t reg_pr0, int i)
{
- static const char *const access_names[3] = {
- "locked", "read-only", "write-only"
- };
uint8_t off = reg_pr0 + (i * 4);
uint32_t pr = mmio_readl(ich_spibar + off);
unsigned int rwperms = ICH_PR_PERMS(pr);
@@ -1627,13 +1633,13 @@ static int ich9_handle_pr(const size_t reg_pr0, int i)
if (rwperms == 0x3) {
msg_pdbg2("0x%02X: 0x%08x (%sPR%u is unused)\n", off, pr, prefix, i);
- return 0;
+ return NO_PROT;
}
msg_pdbg("0x%02X: 0x%08x ", off, pr);
msg_pwarn("%sPR%u: Warning: 0x%08x-0x%08x is %s.\n", prefix, i, ICH_FREG_BASE(pr),
ICH_FREG_LIMIT(pr), access_names[rwperms]);
- return 1;
+ return access_perms_to_protection[rwperms];
}
/* Set/Clear the read and write protection enable bits of PR register @i
@@ -1696,7 +1702,6 @@ int ich_init_spi(void *spibar, enum ich_chipset ich_gen)
uint16_t tmp2;
uint32_t tmp;
char *arg;
- int ich_spi_force = 0;
int ich_spi_rw_restricted = 0;
int desc_valid = 0;
struct ich_descriptors desc = {{ 0 }};
@@ -1805,27 +1810,11 @@ int ich_init_spi(void *spibar, enum ich_chipset ich_gen)
}
free(arg);
- arg = extract_programmer_param("ich_spi_force");
- if (arg && !strcmp(arg, "yes")) {
- ich_spi_force = 1;
- msg_pspew("ich_spi_force enabled.\n");
- } else if (arg && !strlen(arg)) {
- msg_perr("Missing argument for ich_spi_force.\n");
- free(arg);
- return ERROR_FATAL;
- } else if (arg) {
- msg_perr("Unknown argument for ich_spi_force: \"%s\" "
- "(not \"yes\").\n", arg);
- free(arg);
- return ERROR_FATAL;
- }
- free(arg);
-
tmp2 = mmio_readw(ich_spibar + ICH9_REG_HSFS);
msg_pdbg("0x04: 0x%04x (HSFS)\n", tmp2);
prettyprint_ich9_reg_hsfs(tmp2);
if (tmp2 & HSFS_FLOCKDN) {
- msg_pwarn("Warning: SPI Configuration Lockdown activated.\n");
+ msg_pinfo("SPI Configuration is locked down.\n");
ichspi_lock = 1;
}
if (tmp2 & HSFS_FDV)
@@ -1863,7 +1852,7 @@ int ich_init_spi(void *spibar, enum ich_chipset ich_gen)
for (i = 0; i < num_freg; i++)
ich_spi_rw_restricted |= ich9_handle_frap(tmp, i);
if (ich_spi_rw_restricted)
- msg_pwarn("Not all flash regions are freely accessible by flashrom. This is "
+ msg_pinfo("Not all flash regions are freely accessible by flashrom. This is "
"most likely\ndue to an active ME. Please see "
"https://flashrom.org/ME for details.\n");
}
@@ -1876,16 +1865,19 @@ int ich_init_spi(void *spibar, enum ich_chipset ich_gen)
ich_spi_rw_restricted |= ich9_handle_pr(reg_pr0, i);
}
- if (ich_spi_rw_restricted) {
- if (!ich_spi_force)
- programmer_may_write = 0;
- msg_pinfo("Writes have been disabled for safety reasons. You can enforce write\n"
- "support with the ich_spi_force programmer option, but you will most likely\n"
- "harm your hardware! If you force flashrom you will get no support if\n"
- "something breaks. On a few mainboards it is possible to enable write\n"
- "access by setting a jumper (see its documentation or the board itself).\n");
- if (ich_spi_force)
- msg_pinfo("Continuing with write support because the user forced us to!\n");
+ switch (ich_spi_rw_restricted) {
+ case WRITE_PROT:
+ msg_pwarn("At least some flash regions are write protected. For write operations,\n"
+ "you should use a flash layout and include only writable regions. See\n"
+ "manpage for more details.\n");
+ break;
+ case READ_PROT:
+ case LOCKED:
+ msg_pwarn("At least some flash regions are read protected. You have to use a flash\n"
+ "layout and include only accessible regions. For write operations, you'll\n"
+ "additionally need the --noverify-all switch. See manpage for more details.\n"
+ );
+ break;
}
tmp = mmio_readl(ich_spibar + swseq_data.reg_ssfsc);