diff options
author | Vadim Bendebury <vbendeb@chromium.org> | 2016-02-11 15:00:55 -0800 |
---|---|---|
committer | chrome-bot <chrome-bot@chromium.org> | 2016-02-17 12:01:31 -0800 |
commit | b37a7b7166e2408f3a4e25abadea00e3dff4a864 (patch) | |
tree | 3cae3eff29e55486df52a624d6f642a93527954a /chip/g/flash.c | |
parent | 38c64408f77a9efbf39091cf7d34e185272673c3 (diff) | |
download | chrome-ec-b37a7b7166e2408f3a4e25abadea00e3dff4a864.tar.gz |
cr50: improve flash driver error reporting
It is difficult to tell what went wrong if a flash operation failed.
This patch adds printouts in cases of failure. The extension command
console channel is used.
BRANCH=none
BUG=chrome-os-partner:37754
TEST=observed error messages reported while debugging firmware update
code.
Change-Id: I73d509ac5088249e8d34e32e760f3d2f063c91cd
Signed-off-by: Vadim Bendebury <vbendeb@chromium.org>
Reviewed-on: https://chromium-review.googlesource.com/327411
Reviewed-by: Bill Richardson <wfrichar@chromium.org>
Diffstat (limited to 'chip/g/flash.c')
-rw-r--r-- | chip/g/flash.c | 30 |
1 files changed, 23 insertions, 7 deletions
diff --git a/chip/g/flash.c b/chip/g/flash.c index f27ebb20d8..06cd2304ed 100644 --- a/chip/g/flash.c +++ b/chip/g/flash.c @@ -39,11 +39,14 @@ */ #include "common.h" +#include "console.h" #include "flash.h" #include "registers.h" #include "timer.h" #include "watchdog.h" +#define CPRINTF(format, args...) cprintf(CC_EXTENSION, format, ## args) + int flash_pre_init(void) { /* Enable access to the upper half of the flash */ @@ -104,10 +107,12 @@ static int do_flash_op(enum flash_op op, int byte_offset, int words) uint32_t opcode, tmp, errors; int retry_count, max_attempts, extra_prog_pulse, i; int timedelay_us = 100; + uint32_t prev_error = 0; /* Make sure the smart program/erase algorithms are enabled. */ if (!GREAD(FLASH, FSH_TIMING_PROG_SMART_ALGO_ON) || !GREAD(FLASH, FSH_TIMING_ERASE_SMART_ALGO_ON)) { + CPRINTF("%s:%d\n", __func__, __LINE__); return EC_ERROR_UNIMPLEMENTED; } @@ -120,8 +125,10 @@ static int do_flash_op(enum flash_op op, int byte_offset, int words) } /* If we can't clear the error status register then something is wrong. */ - if (tmp) + if (tmp) { + CPRINTF("%s:%d\n", __func__, __LINE__); return EC_ERROR_UNKNOWN; + } /* We have two flash banks. Adjust offset and registers accordingly. */ if (byte_offset >= CONFIG_FLASH_SIZE / 2) { @@ -176,12 +183,18 @@ static int do_flash_op(enum flash_op op, int byte_offset, int words) } /* Timed out waiting for control register to clear */ - if (tmp) + if (tmp) { + CPRINTF("%s:%d\n", __func__, __LINE__); return EC_ERROR_UNKNOWN; - + } /* Check error status */ errors = GREAD(FLASH, FSH_ERROR); + if (errors && (errors != prev_error)) { + prev_error = errors; + CPRINTF("%s:%d errors %x fsh_pe_control %p\n", + __func__, __LINE__, errors, fsh_pe_control); + } /* Error status is self-clearing. Read it until it does * (we hope). */ @@ -194,9 +207,10 @@ static int do_flash_op(enum flash_op op, int byte_offset, int words) /* If we can't clear the error status register then something * is wrong. */ - if (tmp) + if (tmp) { + CPRINTF("%s:%d\n", __func__, __LINE__); return EC_ERROR_UNKNOWN; - + } /* The operation was successful. */ if (!errors) { /* From the spec: @@ -213,7 +227,7 @@ static int do_flash_op(enum flash_op op, int byte_offset, int words) /* If there were errors after completion retry. */ watchdog_reload(); } - + CPRINTF("%s:%d, retry count %d\n", __func__, __LINE__, retry_count); return EC_ERROR_UNKNOWN; } @@ -282,8 +296,10 @@ int flash_physical_erase(int byte_offset, int num_bytes) ret = do_flash_op(OP_ERASE_BLOCK, byte_offset, num_bytes / 4); /* word count */ - if (ret) + if (ret) { + CPRINTF("Failed to erase block at %x\n", byte_offset); return ret; + } num_bytes -= CONFIG_FLASH_ERASE_SIZE; byte_offset += CONFIG_FLASH_ERASE_SIZE; |