diff options
author | Vadim Bendebury <vbendeb@chromium.org> | 2019-05-08 09:02:29 -0700 |
---|---|---|
committer | chrome-bot <chrome-bot@chromium.org> | 2019-05-24 15:11:38 -0700 |
commit | 7a2778ea9c85a385193b46c4258996d53e5ea960 (patch) | |
tree | 1cde9fcda2a9412b75c37e3e9a5ffcc4a05ce9f5 | |
parent | cb9f4e1337c36d9e00869568610d5774a0bbf7bc (diff) | |
download | chrome-ec-7a2778ea9c85a385193b46c4258996d53e5ea960.tar.gz |
g: improve trng error handling
We want to be able to track TRNG stalls happening in the field. This
patch adds a log message to report detected TRNG stalls. The code
detecting the stall is being modified to monitor a different status
bit as per chip designer recommendation.
A console command allowing to test TRNG is being added, compiled in
only if TEST_TRNG is defined.
BRANCH=cr50, cr50-mp
BUG=b:27646393
TEST=compiled the test command in, ran the command
rand 10000000
several times, observed reasonable stats and no stall reports.
Change-Id: Idcf83ff2c41e23f601b8da8c46fa4d4d1cde0270
Signed-off-by: Vadim Bendebury <vbendeb@chromium.org>
Reviewed-on: https://chromium-review.googlesource.com/1601470
Legacy-Commit-Queue: Commit Bot <commit-bot@chromium.org>
Reviewed-by: Andrey Pronin <apronin@chromium.org>
-rw-r--r-- | chip/g/trng.c | 70 | ||||
-rw-r--r-- | include/flash_log.h | 1 |
2 files changed, 70 insertions, 1 deletions
diff --git a/chip/g/trng.c b/chip/g/trng.c index f715a1f833..69e4ce1d87 100644 --- a/chip/g/trng.c +++ b/chip/g/trng.c @@ -3,6 +3,8 @@ * found in the LICENSE file. */ +#include "common.h" +#include "flash_log.h" #include "init_chip.h" #include "registers.h" #include "trng.h" @@ -34,9 +36,12 @@ void init_trng(void) uint32_t rand(void) { while (GREAD(TRNG, EMPTY)) { - if (GREAD_FIELD(TRNG, FSM_STATE, FSM_TIMEOUT)) { + if (GREAD_FIELD(TRNG, FSM_STATE, FSM_IDLE)) { /* TRNG timed out, restart */ GWRITE(TRNG, STOP_WORK, 1); +#if !defined(SECTION_IS_RO) && defined(CONFIG_FLASH_LOG) + flash_log_add_event(FE_LOG_TRNG_STALL, 0, NULL); +#endif GWRITE(TRNG, GO_EVENT, 1); } } @@ -64,3 +69,66 @@ void rand_bytes(void *buffer, size_t len) ((random_togo-- - 1) * 8); } } + +#if !defined(SECTION_IS_RO) && defined(TEST_TRNG) +#include "console.h" +#include "watchdog.h" + +static uint32_t histogram[256]; +static int command_rand(int argc, char **argv) +{ + int count = 1000; /* Default number of cycles. */ + struct pair { + uint32_t value; + uint32_t count; + }; + struct pair min; + struct pair max; + + if (argc == 2) + count = strtoi(argv[1], NULL, 10); + + memset(histogram, 0, sizeof(histogram)); + ccprintf("Retrieving %d random words.\n", count); + while (count-- > 0) { + uint32_t rvalue; + int size; + + rvalue = rand(); + for (size = 0; size < sizeof(rvalue); size++) + histogram[((uint8_t *)&rvalue)[size]]++; + + if (!(count % 10000)) + watchdog_reload(); + } + + min.count = ~0; + max.count = 0; + for (count = 0; count < ARRAY_SIZE(histogram); count++) { + if (histogram[count] > max.count) { + max.count = histogram[count]; + max.value = count; + continue; + } + if (histogram[count] >= min.count) + continue; + + min.count = histogram[count]; + min.value = count; + } + + ccprintf("min %d(%d), max %d(%d)", min.count, min.value, + max.count, max.value); + + for (count = 0; count < ARRAY_SIZE(histogram); count++) { + if (!(count % 8)) { + ccprintf("\n"); + cflush(); + } + ccprintf(" %6d", histogram[count]); + } + ccprintf("\n"); + return EC_SUCCESS; +} +DECLARE_CONSOLE_COMMAND(rand, command_rand, NULL, NULL); +#endif /* !defined(SECTION_IS_RO) && defined(TEST_TRNG) */ diff --git a/include/flash_log.h b/include/flash_log.h index ee56226be6..3e2dca8c2c 100644 --- a/include/flash_log.h +++ b/include/flash_log.h @@ -19,6 +19,7 @@ enum flash_event_type { FE_LOG_LOCKS = 4, /* A single byte, lock failures counter. */ FE_LOG_NVMEM = 5, /* NVMEM failure, variable structure. */ FE_LOG_TPM_WIPE_ERROR = 6, /* Failed to wipe the TPM */ + FE_LOG_TRNG_STALL = 7, /* Stall while retrieving a random number. */ /* * Fixed padding value makes it easier to parse log space |