From 60ee8cd513b86cee1ad521905b39a7cab0601d66 Mon Sep 17 00:00:00 2001 From: Marian Buschsieweke Date: Sun, 9 Feb 2020 09:40:26 +0100 Subject: [PATCH] cpu/atmega_common: Fix pm_reboot with LTO The reboot process for ATmegas is to enable the watchdog timer and loop until the wdt reboots this MCU. However, this reboot will keep the wdt configuration, so that the wdt needs to be disabled during boot. This is done in get_mcusr, but without the attribute "used" it will be optimized out in LTO builds. This commits adds the attribute "used" to get_mcusr. Also simplified the backward compatibility with older ATmegas (currently not supported by RIOT) on outdated versions of avrlibc. --- cpu/atmega_common/cpu.c | 18 ++++++++++-------- 1 file changed, 10 insertions(+), 8 deletions(-) diff --git a/cpu/atmega_common/cpu.c b/cpu/atmega_common/cpu.c index d83a627fa9..423d2efc82 100644 --- a/cpu/atmega_common/cpu.c +++ b/cpu/atmega_common/cpu.c @@ -36,6 +36,13 @@ #define ENABLE_DEBUG (0) #include "debug.h" +#ifndef MCUSR +/* In older ATmegas the MCUSR register was still named MCUCSR. Current avrlibc + * versions provide the MCUSR macro for those as well, but adding a fallback + * here doesn't hurt*/ +#define MCUSR MCUCSR +#endif /* !MCUSR */ + /* * Since atmega MCUs do not feature a software reset, the watchdog timer * is being used. It will be set to the shortest time and then force a @@ -51,7 +58,7 @@ */ uint8_t mcusr_mirror __attribute__((section(".noinit"))); uint8_t soft_rst __attribute__((section(".noinit"))); -void get_mcusr(void) __attribute__((naked)) __attribute__((section(".init0"))); +void get_mcusr(void) __attribute__((naked, section(".init0"), used)); void get_mcusr(void) { @@ -62,13 +69,8 @@ void get_mcusr(void) __asm__ __volatile__("mov %0, r2\n" : "=r" (mcusr_mirror) :); #else /* save the reset flags */ -#ifdef MCUCSR - mcusr_mirror = MCUCSR; - MCUSR = 0; -#else - mcusr_mirror = MCUSR; - MCUSR = 0; -#endif + mcusr_mirror = MCUSR; + MCUSR = 0; wdt_disable(); #endif }