diff options
author | Edward O'Callaghan <quasisec@google.com> | 2023-01-30 11:58:20 +1100 |
---|---|---|
committer | Edward O'Callaghan <quasisec@chromium.org> | 2023-02-21 12:56:22 +0000 |
commit | 86babd06276196facd3c0948b466ccb665e846a7 (patch) | |
tree | 2c4f23c8a38c2f548b1c72ddc0003b66026e1ac6 /jedec.c | |
parent | ae07072e0aacc475aade990c77c193826433f07d (diff) | |
download | flashrom-86babd06276196facd3c0948b466ccb665e846a7.tar.gz flashrom-86babd06276196facd3c0948b466ccb665e846a7.tar.bz2 flashrom-86babd06276196facd3c0948b466ccb665e846a7.zip |
jedec.c: Move printlock stuff into printlock.c
Change-Id: Iacaa16c81e141aac30feb6871700c4fdc9eec8e9
Signed-off-by: Edward O'Callaghan <quasisec@google.com>
Reviewed-on: https://review.coreboot.org/c/flashrom/+/72607
Reviewed-by: Stefan Reinauer <stefan.reinauer@coreboot.org>
Reviewed-by: Thomas Heijligen <src@posteo.de>
Tested-by: build bot (Jenkins) <no-reply@coreboot.org>
Diffstat (limited to 'jedec.c')
-rw-r--r-- | jedec.c | 189 |
1 files changed, 0 insertions, 189 deletions
@@ -478,192 +478,3 @@ int write_jedec(struct flashctx *flash, const uint8_t *buf, unsigned int start, return 0; } - -struct unlockblock { - unsigned int size; - unsigned int count; -}; - -typedef int (*unlockblock_func)(const struct flashctx *flash, chipaddr offset); -static int regspace2_walk_unlockblocks(const struct flashctx *flash, const struct unlockblock *block, unlockblock_func func) -{ - chipaddr off = flash->virtual_registers + 2; - while (block->count != 0) { - unsigned int j; - for (j = 0; j < block->count; j++) { - if (func(flash, off)) - return -1; - off += block->size; - } - block++; - } - return 0; -} - -#define REG2_RWLOCK ((1 << 2) | (1 << 0)) -#define REG2_LOCKDOWN (1 << 1) -#define REG2_MASK (REG2_RWLOCK | REG2_LOCKDOWN) - -static int printlock_regspace2_block(const struct flashctx *flash, chipaddr lockreg) -{ - uint8_t state = chip_readb(flash, lockreg); - msg_cdbg("Lock status of block at 0x%0*" PRIxPTR " is ", PRIxPTR_WIDTH, lockreg); - switch (state & REG2_MASK) { - case 0: - msg_cdbg("Full Access.\n"); - break; - case 1: - msg_cdbg("Write Lock (Default State).\n"); - break; - case 2: - msg_cdbg("Locked Open (Full Access, Locked Down).\n"); - break; - case 3: - msg_cdbg("Write Lock, Locked Down.\n"); - break; - case 4: - msg_cdbg("Read Lock.\n"); - break; - case 5: - msg_cdbg("Read/Write Lock.\n"); - break; - case 6: - msg_cdbg("Read Lock, Locked Down.\n"); - break; - case 7: - msg_cdbg("Read/Write Lock, Locked Down.\n"); - break; - } - return 0; -} - -static int printlock_regspace2_uniform(struct flashctx *flash, unsigned long block_size) -{ - const unsigned int elems = flash->chip->total_size * 1024 / block_size; - struct unlockblock blocks[2] = {{.size = block_size, .count = elems}}; - return regspace2_walk_unlockblocks(flash, blocks, &printlock_regspace2_block); -} - -int printlock_regspace2_uniform_64k(struct flashctx *flash) -{ - return printlock_regspace2_uniform(flash, 64 * 1024); -} - -int printlock_regspace2_block_eraser_0(struct flashctx *flash) -{ - // FIXME: this depends on the eraseblocks not to be filled up completely (i.e. to be null-terminated). - const struct unlockblock *unlockblocks = - (const struct unlockblock *)flash->chip->block_erasers[0].eraseblocks; - return regspace2_walk_unlockblocks(flash, unlockblocks, &printlock_regspace2_block); -} - -int printlock_regspace2_block_eraser_1(struct flashctx *flash) -{ - // FIXME: this depends on the eraseblocks not to be filled up completely (i.e. to be null-terminated). - const struct unlockblock *unlockblocks = - (const struct unlockblock *)flash->chip->block_erasers[1].eraseblocks; - return regspace2_walk_unlockblocks(flash, unlockblocks, &printlock_regspace2_block); -} - -/* Try to change the lock register at address lockreg from cur to new. - * - * - Try to unlock the lock bit if requested and it is currently set (although this is probably futile). - * - Try to change the read/write bits if requested. - * - Try to set the lockdown bit if requested. - * Return an error immediately if any of this fails. */ -static int changelock_regspace2_block(const struct flashctx *flash, chipaddr lockreg, uint8_t cur, uint8_t new) -{ - /* Only allow changes to known read/write/lockdown bits */ - if (((cur ^ new) & ~REG2_MASK) != 0) { - msg_cerr("Invalid lock change from 0x%02x to 0x%02x requested at 0x%0*" PRIxPTR "!\n" - "Please report a bug at flashrom@flashrom.org\n", - cur, new, PRIxPTR_WIDTH, lockreg); - return -1; - } - - /* Exit early if no change (of read/write/lockdown bits) was requested. */ - if (((cur ^ new) & REG2_MASK) == 0) { - msg_cdbg2("Lock bits at 0x%0*" PRIxPTR " not changed.\n", PRIxPTR_WIDTH, lockreg); - return 0; - } - - /* Normally the lockdown bit can not be cleared. Try nevertheless if requested. */ - if ((cur & REG2_LOCKDOWN) && !(new & REG2_LOCKDOWN)) { - chip_writeb(flash, cur & ~REG2_LOCKDOWN, lockreg); - cur = chip_readb(flash, lockreg); - if ((cur & REG2_LOCKDOWN) == REG2_LOCKDOWN) { - msg_cwarn("Lockdown can't be removed at 0x%0*" PRIxPTR "! New value: 0x%02x.\n", - PRIxPTR_WIDTH, lockreg, cur); - return -1; - } - } - - /* Change read and/or write bit */ - if ((cur ^ new) & REG2_RWLOCK) { - /* Do not lockdown yet. */ - uint8_t wanted = (cur & ~REG2_RWLOCK) | (new & REG2_RWLOCK); - chip_writeb(flash, wanted, lockreg); - cur = chip_readb(flash, lockreg); - if (cur != wanted) { - msg_cerr("Changing lock bits failed at 0x%0*" PRIxPTR "! New value: 0x%02x.\n", - PRIxPTR_WIDTH, lockreg, cur); - return -1; - } - msg_cdbg("Changed lock bits at 0x%0*" PRIxPTR " to 0x%02x.\n", - PRIxPTR_WIDTH, lockreg, cur); - } - - /* Eventually, enable lockdown if requested. */ - if (!(cur & REG2_LOCKDOWN) && (new & REG2_LOCKDOWN)) { - chip_writeb(flash, new, lockreg); - cur = chip_readb(flash, lockreg); - if (cur != new) { - msg_cerr("Enabling lockdown FAILED at 0x%0*" PRIxPTR "! New value: 0x%02x.\n", - PRIxPTR_WIDTH, lockreg, cur); - return -1; - } - msg_cdbg("Enabled lockdown at 0x%0*" PRIxPTR ".\n", PRIxPTR_WIDTH, lockreg); - } - - return 0; -} - -static int unlock_regspace2_block_generic(const struct flashctx *flash, chipaddr lockreg) -{ - uint8_t old = chip_readb(flash, lockreg); - /* We don't care for the lockdown bit as long as the RW locks are 0 after we're done */ - return changelock_regspace2_block(flash, lockreg, old, old & ~REG2_RWLOCK); -} - -static int unlock_regspace2_uniform(struct flashctx *flash, unsigned long block_size) -{ - const unsigned int elems = flash->chip->total_size * 1024 / block_size; - struct unlockblock blocks[2] = {{.size = block_size, .count = elems}}; - return regspace2_walk_unlockblocks(flash, blocks, &unlock_regspace2_block_generic); -} - -int unlock_regspace2_uniform_64k(struct flashctx *flash) -{ - return unlock_regspace2_uniform(flash, 64 * 1024); -} - -int unlock_regspace2_uniform_32k(struct flashctx *flash) -{ - return unlock_regspace2_uniform(flash, 32 * 1024); -} - -int unlock_regspace2_block_eraser_0(struct flashctx *flash) -{ - // FIXME: this depends on the eraseblocks not to be filled up completely (i.e. to be null-terminated). - const struct unlockblock *unlockblocks = - (const struct unlockblock *)flash->chip->block_erasers[0].eraseblocks; - return regspace2_walk_unlockblocks(flash, unlockblocks, &unlock_regspace2_block_generic); -} - -int unlock_regspace2_block_eraser_1(struct flashctx *flash) -{ - // FIXME: this depends on the eraseblocks not to be filled up completely (i.e. to be null-terminated). - const struct unlockblock *unlockblocks = - (const struct unlockblock *)flash->chip->block_erasers[1].eraseblocks; - return regspace2_walk_unlockblocks(flash, unlockblocks, &unlock_regspace2_block_generic); -} |