From 6576a92ba57266dcf551854ef665c8250e6d1a07 Mon Sep 17 00:00:00 2001 From: Rodrigo Arias Mallo Date: Fri, 12 Jul 2024 13:47:01 +0200 Subject: [PATCH] Debug timer_mtimer_cold_init() in OpenSBI --- JOURNAL.md | 51 +++++++++++++++++++++++++++++++++++ opensbi-timer-debug.patch | 57 +++++++++++++++++++++++++++++++++++++++ 2 files changed, 108 insertions(+) diff --git a/JOURNAL.md b/JOURNAL.md index a8c1ddd..0c888da 100644 --- a/JOURNAL.md +++ b/JOURNAL.md @@ -1623,3 +1623,54 @@ These G's must be coming from the bootrom. So let's go back to the generic platform and place some `printf()` calls to determine where it is failing. + + OpenSBI v1.5 + ____ _____ ____ _____ + / __ \ / ____| _ \_ _| + | | | |_ __ ___ _ __ | (___ | |_) || | + | | | | '_ \ / _ \ '_ \ \___ \| _ < | | + | |__| | |_) | __/ | | |____) | |_) || |_ + \____/| .__/ \___|_| |_|_____/|____/_____| + | | + |_| + + sbi_timer_init: begins + sbi_timer_init: got Zicntr extension + fdt_timer_cold_init: pos = 0 + fdt_timer_cold_init: got match, name = riscv,clint0 + fdt_timer_cold_init: enabled + fdt_timer_cold_init: drc->cold_init = -3 + fdt_timer_init: fdt_timer_cold_init failed (-3) + sbi_platform_timer: sbi_platform_timer_init failed (-3) + init_coldboot: timer init failed (error -3) + +Okay, now we can see where it failed. I wonder why aren't these messages enabled +by default. I'll guess this is the `timer_mtimer_cold_init()` function, so let's +add some more instrumentation there. + +It seems that SiFive timer has a very long weird offset: + + if (is_clint) { /* SiFive CLINT */ + /* Set CLINT addresses */ + mt->mtimecmp_addr = addr[0] + ACLINT_DEFAULT_MTIMECMP_OFFSET; + mt->mtimecmp_size = ACLINT_DEFAULT_MTIMECMP_SIZE; + if (!quirks->clint_without_mtime) { + mt->mtime_addr = addr[0] + ACLINT_DEFAULT_MTIME_OFFSET; + mt->mtime_size = size[0] - mt->mtimecmp_size; + /* Adjust MTIMER address and size for CLINT device */ + mt->mtime_addr += quirks->clint_mtime_offset; + mt->mtime_size -= quirks->clint_mtime_offset; + } else { + mt->mtime_addr = mt->mtime_size = 0; + } + mt->mtimecmp_addr += quirks->clint_mtime_offset; + } else { /* RISC-V ACLINT MTIMER */ + /* Set ACLINT MTIMER addresses */ + mt->mtime_addr = addr[0]; + mt->mtime_size = size[0]; + mt->mtimecmp_addr = addr[1]; + mt->mtimecmp_size = size[1]; + } + +We may want to use the ACLINT timer instead. Let's first see where the addresses +lay in memory, and then use that to verify we change it to 0x0 and 0x8. diff --git a/opensbi-timer-debug.patch b/opensbi-timer-debug.patch index 93e2df1..f2155f2 100644 --- a/opensbi-timer-debug.patch +++ b/opensbi-timer-debug.patch @@ -98,3 +98,60 @@ index f468730..db20526 100644 + + return rc; } +diff --git a/lib/utils/timer/fdt_timer_mtimer.c b/lib/utils/timer/fdt_timer_mtimer.c +index 9e27e3a..fba48ca 100644 +--- a/lib/utils/timer/fdt_timer_mtimer.c ++++ b/lib/utils/timer/fdt_timer_mtimer.c +@@ -8,6 +8,7 @@ + */ + + #include ++#include + #include + #include + #include +@@ -33,6 +34,7 @@ static struct aclint_mtimer_data *mt_reference = NULL; + static int timer_mtimer_cold_init(void *fdt, int nodeoff, + const struct fdt_match *match) + { ++ + int rc; + unsigned long addr[2], size[2]; + struct timer_mtimer_node *mtn, *n; +@@ -40,6 +42,8 @@ static int timer_mtimer_cold_init(void *fdt, int nodeoff, + const struct timer_mtimer_quirks *quirks = match->data; + bool is_clint = quirks && quirks->is_clint; + ++ sbi_printf("timer_mtimer_cold_init: begins, is_clint = %d\n", (int) is_clint); ++ + mtn = sbi_zalloc(sizeof(*mtn)); + if (!mtn) + return SBI_ENOMEM; +@@ -49,6 +53,7 @@ static int timer_mtimer_cold_init(void *fdt, int nodeoff, + &addr[0], &size[0], &addr[1], &size[1], + &mt->first_hartid, &mt->hart_count); + if (rc) { ++ sbi_printf("timer_mtimer_cold_init: fdt_parse_aclint_node failed (%d)\n", rc); + sbi_free(mtn); + return rc; + } +@@ -57,6 +62,7 @@ static int timer_mtimer_cold_init(void *fdt, int nodeoff, + + rc = fdt_parse_timebase_frequency(fdt, &mt->mtime_freq); + if (rc) { ++ sbi_printf("timer_mtimer_cold_init: fdt_parse_timebase_frequency failed (%d)\n", rc); + sbi_free(mtn); + return rc; + } +@@ -83,6 +89,11 @@ static int timer_mtimer_cold_init(void *fdt, int nodeoff, + mt->mtimecmp_size = size[1]; + } + ++ sbi_printf("timer_mtimer_cold_init: mtime_addr = 0x%08lx\n", mt->mtime_addr); ++ sbi_printf("timer_mtimer_cold_init: mtime_size = 0x%08lx\n", mt->mtime_size); ++ sbi_printf("timer_mtimer_cold_init: mtime_addr = 0x%08lx\n", mt->mtimecmp_addr); ++ sbi_printf("timer_mtimer_cold_init: mtime_addr = 0x%08lx\n", mt->mtimecmp_size); ++ + /* Apply additional quirks */ + if (quirks) { + mt->has_64bit_mmio = quirks->has_64bit_mmio;