[U-Boot] [PATCH v2 1/3] board_r: move initr_watchdog to be called after initr_serial

The initr_watchdog is currently placed before initr_serial. The initr_watchdog calls printf and printf finally calls ops->putc of a serial driver.
However, gd->cur_serial_dev points to a udevice allocated in board_f. The gd->cur_serial_dev->driver->ops->putc points the the code region before relocation.
Some serial drivers call WATCHDOG_RESET() in ops->putc. When DM is enabled for watchdog, watchdog_reset() is called. watchdog_reset() calls get_timer to get current timer.
On some platforms the timer driver is also a DM driver. initr_watchdog is placed right after initr_dm, which means the timer driver hasn't been initialized. So dm_timer_init() is called. To create a new udevice, calloc is called.
However start from ops->putc, u-boot execution flow is redirected into the memory region before relocation (board_f). In board_f, dlmalloc hasn't been initialized. The call to calloc will fail, and this will cause DM to print out an error message, and it will call printf again, causing recursive error outputs.
This patch places initr_watchdog after initr_serial to solve this issue.
Cc: Stefan Roese sr@denx.de Reviewed-by: Ryder Lee ryder.lee@mediatek.com Signed-off-by: Weijie Gao weijie.gao@mediatek.com --- Changes since v1: move initr_watchdog instead of initr_serial --- common/board_r.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-)
diff --git a/common/board_r.c b/common/board_r.c index 150e8cd424..df24021f2c 100644 --- a/common/board_r.c +++ b/common/board_r.c @@ -678,9 +678,6 @@ static init_fnc_t init_sequence_r[] = { #ifdef CONFIG_DM initr_dm, #endif -#if defined(CONFIG_WDT) - initr_watchdog, -#endif #if defined(CONFIG_ARM) || defined(CONFIG_NDS32) || defined(CONFIG_RISCV) || \ defined(CONFIG_SANDBOX) board_init, /* Setup chipselects */ @@ -700,6 +697,9 @@ static init_fnc_t init_sequence_r[] = { stdio_init_tables, initr_serial, initr_announce, +#if defined(CONFIG_WDT) + initr_watchdog, +#endif INIT_FUNC_WATCHDOG_RESET #ifdef CONFIG_NEEDS_MANUAL_RELOC initr_manual_reloc_cmdtable,

Hi,
May I know if this patch is still under review ?
I have converted OMAP3 watchdog driver into driver model for TI AM33XX based SOC and tested corresponding patches on BeagleBone Black board.
Build was successful but board goes into a loop when turned on/runtime, problem identified and is in sync with Weijie Gao's explanation and his patch for such behaviour (please follow this thread for explanation).
When initr_watchdog is moved/placed just after initr_serial, board is behaving normal. Tested on BeagleBone Black.
Please suggest if there are any workarounds for this problem.
Regards

Cc'ing a few people
On 16.05.19 11:19, Weijie Gao wrote:
The initr_watchdog is currently placed before initr_serial. The initr_watchdog calls printf and printf finally calls ops->putc of a serial driver.
However, gd->cur_serial_dev points to a udevice allocated in board_f. The gd->cur_serial_dev->driver->ops->putc points the the code region before relocation.
Some serial drivers call WATCHDOG_RESET() in ops->putc. When DM is enabled for watchdog, watchdog_reset() is called. watchdog_reset() calls get_timer to get current timer.
On some platforms the timer driver is also a DM driver. initr_watchdog is placed right after initr_dm, which means the timer driver hasn't been initialized. So dm_timer_init() is called. To create a new udevice, calloc is called.
However start from ops->putc, u-boot execution flow is redirected into the memory region before relocation (board_f). In board_f, dlmalloc hasn't been initialized. The call to calloc will fail, and this will cause DM to print out an error message, and it will call printf again, causing recursive error outputs.
This patch places initr_watchdog after initr_serial to solve this issue.
Cc: Stefan Roese sr@denx.de Reviewed-by: Ryder Lee ryder.lee@mediatek.com Signed-off-by: Weijie Gao weijie.gao@mediatek.com
Changes since v1: move initr_watchdog instead of initr_serial
common/board_r.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-)
diff --git a/common/board_r.c b/common/board_r.c index 150e8cd424..df24021f2c 100644 --- a/common/board_r.c +++ b/common/board_r.c @@ -678,9 +678,6 @@ static init_fnc_t init_sequence_r[] = { #ifdef CONFIG_DM initr_dm, #endif -#if defined(CONFIG_WDT)
- initr_watchdog,
-#endif #if defined(CONFIG_ARM) || defined(CONFIG_NDS32) || defined(CONFIG_RISCV) || \ defined(CONFIG_SANDBOX) board_init, /* Setup chipselects */ @@ -700,6 +697,9 @@ static init_fnc_t init_sequence_r[] = { stdio_init_tables, initr_serial, initr_announce, +#if defined(CONFIG_WDT)
- initr_watchdog,
+#endif INIT_FUNC_WATCHDOG_RESET #ifdef CONFIG_NEEDS_MANUAL_RELOC initr_manual_reloc_cmdtable,
Reviewed-by: Stefan Roese sr@denx.de
Frank, does this patch fix the watchdog issue on your board as well?
Tom, could you please apply this patch to the upcoming release?
Thanks, Stefan

Hi Stefan/Tom
this Patch in combination with https://patchwork.ozlabs.org/patch/1113120/ seem to fix issues on bananapi-r2 /mt7623 (bootloop/hang on WDT servicing) if CONFIG_WATCHDOG is not set to "n" (else it will be set to y because of new "imply WATCHDOG" inside of "config WDT").
@tom can you please include this 2 Patches in master?
regards Frank

Hi Frank,
On 29.06.19 10:44, Frank Wunderlich wrote:
Hi Stefan/Tom
this Patch in combination with https://patchwork.ozlabs.org/patch/1113120/
This one already is applied in mainline:
https://gitlab.denx.de/u-boot/u-boot/commit/2bc1821e8662f9ed67cc6eeb680148bb...
Even though the coding style is pretty messed up. We should clean this file up a bit.
Thanks, Stefan

Hi
It looks this fix is not yet merged. Tom can you add it before release? Without it bpi-r2 and maybe other boards are broken.
Regards Frank

Tested-by: Frank Wunderlich frank-w@public-files.de

Agreed with frank. My patches for watchdog DM conversion depends on this change set.
tested on AM335x based Beaglebone Black
Tested-by: Suniel Mahesh sunil.m@techveda.org
Regards

On Thu, May 16, 2019 at 05:19:13PM +0800, Weijie Gao wrote:
The initr_watchdog is currently placed before initr_serial. The initr_watchdog calls printf and printf finally calls ops->putc of a serial driver.
However, gd->cur_serial_dev points to a udevice allocated in board_f. The gd->cur_serial_dev->driver->ops->putc points the the code region before relocation.
Some serial drivers call WATCHDOG_RESET() in ops->putc. When DM is enabled for watchdog, watchdog_reset() is called. watchdog_reset() calls get_timer to get current timer.
On some platforms the timer driver is also a DM driver. initr_watchdog is placed right after initr_dm, which means the timer driver hasn't been initialized. So dm_timer_init() is called. To create a new udevice, calloc is called.
However start from ops->putc, u-boot execution flow is redirected into the memory region before relocation (board_f). In board_f, dlmalloc hasn't been initialized. The call to calloc will fail, and this will cause DM to print out an error message, and it will call printf again, causing recursive error outputs.
This patch places initr_watchdog after initr_serial to solve this issue.
Cc: Stefan Roese sr@denx.de Reviewed-by: Ryder Lee ryder.lee@mediatek.com Signed-off-by: Weijie Gao weijie.gao@mediatek.com Reviewed-by: Stefan Roese sr@denx.de Tested-by: Frank Wunderlich frank-w@public-files.de Tested-by: Suniel Mahesh sunil.m@techveda.org
Applied to u-boot/master, thanks!
participants (5)
-
Frank Wunderlich
-
Stefan Roese
-
Suniel Mahesh
-
Tom Rini
-
Weijie Gao