summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorVadim Bendebury <vbendeb@chromium.org>2019-05-08 09:02:29 -0700
committerchrome-bot <chrome-bot@chromium.org>2019-05-24 15:11:38 -0700
commit7a2778ea9c85a385193b46c4258996d53e5ea960 (patch)
tree1cde9fcda2a9412b75c37e3e9a5ffcc4a05ce9f5
parentcb9f4e1337c36d9e00869568610d5774a0bbf7bc (diff)
downloadchrome-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.c70
-rw-r--r--include/flash_log.h1
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