From 8dd6ad9871e35d0f3383e973207b8538d30a03a7 Mon Sep 17 00:00:00 2001 From: Evan Lojewski Date: Wed, 28 Oct 2020 22:07:05 -0600 Subject: ape: Remove a couple of posisble infinte loops that can happen with misbehaving hardware. (#154) - Stop waiting for the RX CPUs to reset after 1 second of waiting. - Stop waiting for the RMU to reset a bad packet after 100ms. Closes GH-96. --- ape/include/ape_main.h | 4 +++- ape/main.c | 27 ++++++++++++++++----------- ape/rmu.c | 21 ++++++++++++++++++++- 3 files changed, 39 insertions(+), 13 deletions(-) diff --git a/ape/include/ape_main.h b/ape/include/ape_main.h index 6c2fec0..d0ef27e 100644 --- a/ape/include/ape_main.h +++ b/ape/include/ape_main.h @@ -45,6 +45,8 @@ #ifndef APE_H #define APE_H -void initRMU(void); +void RMU_init(void); + +void RMU_resetBadPacket(void); #endif /* APE_H */ diff --git a/ape/main.c b/ape/main.c index 740e689..16cca64 100644 --- a/ape/main.c +++ b/ape/main.c @@ -64,6 +64,7 @@ #endif #define RMU_WATCHDOG_TIMEOUT_MS (10) +#define RX_CPU_RESET_TIMEOUT_MS (1000) /* Wait up to 1 second for each RX CPU to start */ static NetworkPort_t *gPort; @@ -112,6 +113,8 @@ void handleCommand(void) void wait_for_rx(const volatile DEVICE_t *device, const volatile SHM_t *shm) { + uint32_t startTime = Timer_getCurrentTime1KHz(); + bool waiting = true; do { @@ -126,6 +129,12 @@ void wait_for_rx(const volatile DEVICE_t *device, const volatile SHM_t *shm) // Firmware has finished initialization. waiting = false; } + + if (Timer_didTimeElapsed1KHz(startTime, RX_CPU_RESET_TIMEOUT_MS)) + { + printf("RX CPU reset timeout.\n"); + waiting = false; + } } while (waiting); } @@ -152,11 +161,7 @@ void handleBMCPacket(void) if (stat.bits.Bad) { // ACK bad packet. - APE_PERI.BmcToNcRxControl.bits.ResetBad = 1; - while (APE_PERI.BmcToNcRxControl.bits.ResetBad) - { - // Wait - } + RMU_resetBadPacket(); } else { @@ -202,7 +207,7 @@ void handleBMCPacket(void) printf("Resetting TX...\n"); // Reset, as it's likely locked up now. wait_for_all_rx(); - initRMU(); + RMU_init(); NCSI_reload(AS_NEEDED); } } @@ -231,7 +236,7 @@ void handleBMCPacket(void) if (Timer_didTimeElapsed1KHz(inProgressStartTime, RMU_WATCHDOG_TIMEOUT_MS)) { printf("RMU Hang detected, resetting.\n"); - initRMU(); + RMU_init(); packetInProgress = false; } } @@ -254,7 +259,7 @@ void checkSupply(bool alwaysReport) { printf("Powered off, resetting\n"); wait_for_all_rx(); - initRMU(); + RMU_init(); NCSI_reload(ALWAYS_RESET); } @@ -303,13 +308,13 @@ void __attribute__((noreturn)) loaderLoop(void) { printf("host started\n"); wait_for_all_rx(); - initRMU(); + RMU_init(); NCSI_reload(NEVER_RESET); } else { wait_for_all_rx(); - initRMU(); + RMU_init(); if (SHM_HOST_DRIVER_STATE_STATE_UNLOAD == host_state) { printf("host unloaded.\n"); @@ -396,7 +401,7 @@ void __attribute__((noreturn)) __start() checkSupply(true); - initRMU(); + RMU_init(); if (full_init) { diff --git a/ape/rmu.c b/ape/rmu.c index afc8fb4..fac1e75 100644 --- a/ape/rmu.c +++ b/ape/rmu.c @@ -45,9 +45,17 @@ #include #include #include +#include #include -void initRMU(void) +#ifndef CXX_SIMULATOR +#include +#include +#endif + +#define RMU_RESET_TIMEOUT_MS (2000) /* Allow up to two seconds for a bad packet to be reset. */ + +void RMU_init(void) { RegAPEMode_t mode; mode.r32 = APE.Mode.r32; @@ -102,9 +110,20 @@ void initRMU(void) arbControl.bits.TKNREL = 0x14; APE_PERI.ArbControl = arbControl; + RMU_resetBadPacket(); +} + +void RMU_resetBadPacket(void) +{ + uint32_t startTime = Timer_getCurrentTime1KHz(); + APE_PERI.BmcToNcRxControl.bits.ResetBad = 1; while (APE_PERI.BmcToNcRxControl.bits.ResetBad) { // Wait + if (Timer_didTimeElapsed1KHz(startTime, RMU_RESET_TIMEOUT_MS)) + { + printf("RMU packet reset failed.\n"); + } } } -- cgit v1.2.1