Continue simplifying flash write protect

Now that read-only code is protected iff the persistent state is
locked, we don't need to track per-block in the persistent state.

BUG=chrome-os-partner:11150
TEST=if it builds and boots, it's fine

Change-Id: I80e6a85c0c72136b7ed8964ce02c8abdbaafe637
Signed-off-by: Randall Spangler <rspangler@chromium.org>
Reviewed-on: https://gerrit.chromium.org/gerrit/27719
This commit is contained in:
Randall Spangler
2012-07-17 15:24:26 -07:00
parent aabe50f0d5
commit 3f492b471b
3 changed files with 39 additions and 101 deletions

View File

@@ -45,7 +45,7 @@
* register with persistent state. Put that up at the top.
*/
#define CONFIG_SECTION_FLASH_PSTATE_SIZE (1 * CONFIG_FLASH_BANK_SIZE)
#define CONFIG_SECTION_FLASH_PSTATE_OFF (CONFIG_FLASH_SIZE \
#define CONFIG_SECTION_FLASH_PSTATE_OFF (CONFIG_FLASH_PHYSICAL_SIZE \
- CONFIG_SECTION_FLASH_PSTATE_SIZE)
/* Then there are the two major sections. */

View File

@@ -15,8 +15,9 @@
#include "system.h"
#include "util.h"
#define PERSIST_STATE_VERSION 1
#define PERSIST_STATE_VERSION 2
#define MAX_BANKS (CONFIG_FLASH_SIZE / CONFIG_FLASH_BANK_SIZE)
#define PHYSICAL_BANKS (CONFIG_FLASH_PHYSICAL_SIZE / CONFIG_FLASH_BANK_SIZE)
/* Persistent protection state flash offset / size / bank */
#define PSTATE_OFFSET (CONFIG_SECTION_FLASH_PSTATE_OFF - CONFIG_FLASH_BASE)
@@ -33,9 +34,10 @@ struct persist_state {
uint8_t version; /* Version of this struct */
uint8_t lock; /* Lock flags */
uint8_t reserved[2]; /* Reserved; set 0 */
uint8_t blocks[MAX_BANKS]; /* Per-block flags */
};
int stuck_locked; /* Is physical flash stuck protected? */
static struct persist_state pstate; /* RAM copy of pstate data */
@@ -61,7 +63,6 @@ static int read_pstate(void)
memset(&pstate, 0, sizeof(pstate));
pstate.version = PERSIST_STATE_VERSION;
#else
int i;
int rv = flash_physical_read(PSTATE_OFFSET, sizeof(pstate),
(char *)&pstate);
if (rv)
@@ -75,8 +76,7 @@ static int read_pstate(void)
/* Mask off currently-valid flags */
pstate.lock &= FLASH_PROTECT_LOCK_SET;
for (i = 0; i < MAX_BANKS; i++)
pstate.blocks[i] = 0;
#endif /* CHIP_stm32 */
return EC_SUCCESS;
}
@@ -84,6 +84,9 @@ static int read_pstate(void)
/* Write persistent state from pstate, erasing if necessary. */
static int write_pstate(void)
{
#ifdef CHIP_stm32
return EC_SUCCESS;
#else
int rv;
/* Erase pstate */
@@ -104,6 +107,7 @@ static int write_pstate(void)
/* Rewrite the data */
return flash_physical_write(PSTATE_OFFSET, sizeof(pstate),
(const char *)&pstate);
#endif
}
/* Apply write protect based on persistent state. */
@@ -140,11 +144,6 @@ static int is_pstate_lock_applied(void)
return flash_physical_get_protect(PSTATE_BANK);
}
int flash_get_size(void)
{
return CONFIG_FLASH_SIZE;
}
int flash_dataptr(int offset, int size_req, int align, char **ptrp)
{
if (offset < 0 || size_req < 0 ||
@@ -221,55 +220,6 @@ int flash_lock_protect(int lock)
return apply_pstate();
}
const uint8_t *flash_get_protect_array(void)
{
/*
* Return a copy of the current write protect state. This is an array
* of per-protect-block flags. (This is NOT the actual array, so
* attempting to change it will have no effect.)
*/
int i;
/* Read the current persist state from flash */
read_pstate();
/* Combine with current block protection state */
for (i = 0; i < MAX_BANKS; i++) {
if (flash_physical_get_protect(i))
pstate.blocks[i] |= FLASH_PROTECT_UNTIL_REBOOT;
}
/* Return the block array */
return pstate.blocks;
}
int flash_get_protect(int offset, int size)
{
int pbsize = flash_get_protect_block_size();
uint8_t minflags = 0xff;
int i;
if (flash_dataptr(offset, size, pbsize, NULL) < 0)
return 0; /* Invalid range; assume nothing protected */
/* Convert offset and size to blocks */
offset /= pbsize;
size /= pbsize;
/* Read the current persist state from flash */
read_pstate();
/* Combine with current block protection state */
for (i = 0; i < size; i++) {
int f = pstate.blocks[offset + i];
if (flash_physical_get_protect(offset + i))
f |= FLASH_PROTECT_UNTIL_REBOOT;
minflags &= f;
}
return minflags;
}
int flash_get_protect_lock(void)
{
int flags;
@@ -295,13 +245,10 @@ int flash_get_protect_lock(void)
int flash_pre_init(void)
{
/* Initialize the physical flash interface */
/*
* TODO: track pre-init error so we can report it later. Do at the
* same time as new flash commands to get/set write protect status.
*/
flash_physical_pre_init();
if (flash_physical_pre_init() == EC_ERROR_ACCESS_DENIED)
stuck_locked = 1;
/* Read pstate and apply write protect to blocks if needed */
/* Apply write protect to blocks if needed */
return apply_pstate();
}
@@ -342,30 +289,35 @@ static int parse_offset_size(int argc, char **argv, int shift,
static int command_flash_info(int argc, char **argv)
{
const uint8_t *wp;
int banks = flash_get_size() / flash_get_protect_block_size();
int i;
ccprintf("Physical:%4d KB\n", flash_physical_size() / 1024);
ccprintf("Usable: %4d KB\n", flash_get_size() / 1024);
ccprintf("Physical:%4d KB\n", CONFIG_FLASH_PHYSICAL_SIZE / 1024);
if (flash_physical_size() != CONFIG_FLASH_PHYSICAL_SIZE)
ccprintf("But chip claims %d KB!\n",
flash_physical_size() / 1024);
ccprintf("Usable: %4d KB\n", CONFIG_FLASH_SIZE / 1024);
ccprintf("Write: %4d B\n", flash_get_write_block_size());
ccprintf("Erase: %4d B\n", flash_get_erase_block_size());
ccprintf("Protect: %4d B\n", flash_get_protect_block_size());
i = flash_get_protect_lock();
ccprintf("Lock: %s%s\n",
(i & FLASH_PROTECT_LOCK_SET) ? "LOCKED" : "unlocked",
(i & FLASH_PROTECT_LOCK_APPLIED) ? ",APPLIED" : "");
ccprintf("Lock: %s",
(i & FLASH_PROTECT_LOCK_SET) ? "LOCKED" : "unlocked");
if (i & FLASH_PROTECT_LOCK_APPLIED)
ccputs(",APPLIED");
if (stuck_locked)
ccputs(",STUCK");
ccputs("\n");
ccprintf("WP pin: %sasserted\n",
(i & FLASH_PROTECT_PIN_ASSERTED) ? "" : "de");
wp = flash_get_protect_array();
ccputs("Protected now:");
for (i = 0; i < banks; i++) {
for (i = 0; i < PHYSICAL_BANKS; i++) {
if (!(i & 7))
ccputs(" ");
ccputs(wp[i] & FLASH_PROTECT_UNTIL_REBOOT ? "Y" : ".");
ccputs(flash_physical_get_protect(i) ? "Y" : ".");
}
ccputs("\n");
@@ -376,7 +328,6 @@ DECLARE_CONSOLE_COMMAND(flashinfo, command_flash_info,
"Print flash info",
NULL);
static int command_flash_erase(int argc, char **argv)
{
int offset = -1;
@@ -411,7 +362,7 @@ static int command_flash_write(int argc, char **argv)
if (size > shared_mem_size())
size = shared_mem_size();
/* Acquire the shared memory buffer */
/* Acquire the shared memory buffer */
rv = shared_mem_acquire(size, 0, &data);
if (rv) {
ccputs("Can't get shared mem\n");
@@ -463,7 +414,7 @@ static int flash_command_get_info(struct host_cmd_handler_args *args)
struct ec_response_flash_info *r =
(struct ec_response_flash_info *)args->response;
r->flash_size = flash_get_size();
r->flash_size = CONFIG_FLASH_SIZE;
r->write_block_size = flash_get_write_block_size();
r->erase_block_size = flash_get_erase_block_size();
r->protect_block_size = flash_get_protect_block_size();

View File

@@ -151,30 +151,17 @@ int flash_protect_until_reboot(void);
* persistently-protected blocks. */
int flash_lock_protect(int lock);
/* Flags for flash_get_protect() and flash_get_protect_array(). */
/* Protected until reboot. This will be set for persistently-protected blocks
* as soon as the flash module protects them, and for non-persistent protection
* after flash_protect_until_reboot() is called on a block. */
#define FLASH_PROTECT_UNTIL_REBOOT 0x01
/* Return a copy of the current write protect state. This is an array of
* per-protect-block flags. The data is valid until the next call to a flash
* function. */
const uint8_t *flash_get_protect_array(void);
/* Return the lowest amount of protection for any flash block in the specified
* range. That is, if any byte in the range is not protected until reboot,
* FLASH_PROTECT_UNTIL_REBOOT will not be set. */
int flash_get_protect(int offset, int size);
/* Flags for flash_get_protect_lock() */
/* Flash protection lock has been set. Note that if the write protect pin was
/*
* Flash protection lock has been set. Note that if the write protect pin was
* deasserted at boot time, this simply indicates the state of the lock
* setting, and not whether blocks are actually protected. */
* setting, and not whether blocks are actually protected.
*/
#define FLASH_PROTECT_LOCK_SET 0x01
/* Flash protection lock has actually been applied. All blocks with
FLASH_PROTECT_PERSISTENT have been protected, and flash protection cannot be
unlocked. */
/*
* Flash protection lock has actually been applied. Read-only firmware is
* protected, and flash protection cannot be unlocked.
*/
#define FLASH_PROTECT_LOCK_APPLIED 0x02
/* Write protect pin is currently asserted */
#define FLASH_PROTECT_PIN_ASSERTED 0x04