aboutsummaryrefslogtreecommitdiff
path: root/hw
diff options
context:
space:
mode:
authorRyan Grimm <grimm@linux.ibm.com>2021-08-04 12:51:36 +0530
committerVasant Hegde <hegdevasant@linux.vnet.ibm.com>2021-08-06 12:34:05 +0530
commita649c51cc134b2770e6ec166a778b6aa824e9810 (patch)
tree3a38c7f9e36851e61c5ce30855f92ca9cec96bc0 /hw
parent4ed9a073fd3c3af776af643fa021e145e08ef55e (diff)
downloadskiboot-a649c51cc134b2770e6ec166a778b6aa824e9810.zip
skiboot-a649c51cc134b2770e6ec166a778b6aa824e9810.tar.gz
skiboot-a649c51cc134b2770e6ec166a778b6aa824e9810.tar.bz2
hw/chiptod: Retry the sync procedure on failure
The chiptod sync will sometimes fail and then sync successfully after a retry. So, try an arbitrary 10 numbers of times before we either abort() on main procedure fail or disable threads on secondary procedure fail. Also, put a message on the log if secondaries fail so we have evidence in the log when they aren't enabled. Signed-off-by: Ryan Grimm <grimm@linux.ibm.com> Signed-off-by: Vasant Hegde <hegdevasant@linux.vnet.ibm.com>
Diffstat (limited to 'hw')
-rw-r--r--hw/chiptod.c33
1 files changed, 23 insertions, 10 deletions
diff --git a/hw/chiptod.c b/hw/chiptod.c
index 3b57f5f..fd94149 100644
--- a/hw/chiptod.c
+++ b/hw/chiptod.c
@@ -221,6 +221,8 @@ static uint64_t base_tfmr;
static struct lock chiptod_lock = LOCK_UNLOCKED;
static bool chiptod_unrecoverable;
+#define NUM_SYNC_RETRIES 10
+
static void _chiptod_cache_tod_regs(int32_t chip_id)
{
int i;
@@ -892,7 +894,7 @@ static void chiptod_sync_master(void *data)
*result = true;
return;
error:
- prerror("Master sync failed! TFMR=0x%016lx\n", mfspr(SPR_TFMR));
+ prerror("Master sync failed! TFMR=0x%016lx, retrying...\n", mfspr(SPR_TFMR));
*result = false;
}
@@ -962,7 +964,7 @@ static void chiptod_sync_slave(void *data)
*result = true;
return;
error:
- prerror("Slave sync failed ! TFMR=0x%016lx\n", mfspr(SPR_TFMR));
+ prerror("Slave sync failed ! TFMR=0x%016lx, retrying...\n", mfspr(SPR_TFMR));
*result = false;
}
@@ -1818,6 +1820,7 @@ void chiptod_init(void)
{
struct cpu_thread *cpu0, *cpu;
bool sres;
+ int i;
/* Mambo and qemu doesn't simulate the chiptod */
if (chip_quirk(QUIRK_NO_CHIPTOD))
@@ -1841,10 +1844,14 @@ void chiptod_init(void)
prlog(PR_DEBUG, "Base TFMR=0x%016llx\n", base_tfmr);
- /* Schedule master sync */
- sres = false;
- cpu_wait_job(cpu_queue_job(cpu0, "chiptod_sync_master",
+ i = NUM_SYNC_RETRIES;
+ do {
+ /* Schedule master sync */
+ sres = false;
+ cpu_wait_job(cpu_queue_job(cpu0, "chiptod_sync_master",
chiptod_sync_master, &sres), true);
+ } while (!sres && i--);
+
if (!sres) {
op_display(OP_FATAL, OP_MOD_CHIPTOD, 2);
abort();
@@ -1858,13 +1865,19 @@ void chiptod_init(void)
if (cpu == cpu0)
continue;
- /* Queue job */
- sres = false;
- cpu_wait_job(cpu_queue_job(cpu, "chiptod_sync_slave",
- chiptod_sync_slave, &sres),
- true);
+ i = NUM_SYNC_RETRIES;
+ do {
+ /* Queue job */
+ sres = false;
+ cpu_wait_job(cpu_queue_job(cpu, "chiptod_sync_slave",
+ chiptod_sync_slave, &sres),
+ true);
+ } while (!sres && i--);
+
if (!sres) {
op_display(OP_WARN, OP_MOD_CHIPTOD, 3|(cpu->pir << 8));
+ prerror("CHIPTOD: Failed to sync PIR 0x%04x\n",
+ this_cpu()->pir);
/* Disable threads */
cpu_disable_all_threads(cpu);