From 21daf782a75d8b05940e7242c17b2df50cd8bdce Mon Sep 17 00:00:00 2001 From: Marian Buschsieweke Date: Mon, 20 Jun 2022 19:41:32 +0200 Subject: [PATCH 1/2] cpu/avr8_common: clean up thread_arch.c Use __AVR_HAVE_RAMP__ and __AVR_HAVE_3_BYTE_PC__ provided by the compiler instead of custom macros. --- cpu/avr8_common/thread_arch.c | 48 ++++++++++++++++++----------------- 1 file changed, 25 insertions(+), 23 deletions(-) diff --git a/cpu/avr8_common/thread_arch.c b/cpu/avr8_common/thread_arch.c index d07d6448b1..768583a93f 100644 --- a/cpu/avr8_common/thread_arch.c +++ b/cpu/avr8_common/thread_arch.c @@ -34,21 +34,9 @@ #include "board.h" #include "macros/xtstr.h" -#define CHECK_EIND_REG FLASHEND > 0x1ffff - -#if defined(DATAMEM_SIZE) -#define CHECK_RAMPZ_REG DATAMEM_SIZE > 0xffff || FLASHEND > 0xffff -#define CHECK_RAMPDXY_REG DATAMEM_SIZE > 0xffff -#else -#define CHECK_RAMPZ_REG FLASHEND > 0xffff -#define CHECK_RAMPDXY_REG 0 -#endif - -#if (CHECK_EIND_REG) #ifndef __EIND__ #define __EIND__ 0x3C #endif -#endif static void avr8_context_save(void); static void avr8_context_restore(void); @@ -109,7 +97,7 @@ char *thread_stack_init(thread_task_func_t task_func, void *arg, tmp_adress >>= 8; *stk = (uint8_t)(tmp_adress & (uint16_t)0x00ff); -#if (CHECK_EIND_REG) +#if __AVR_3_BYTE_PC__ /* Devices with more than 128kb FLASH use a PC with more than 16bits, we * set whole the top byte forcibly to 0 */ stk--; @@ -124,7 +112,7 @@ char *thread_stack_init(thread_task_func_t task_func, void *arg, tmp_adress >>= 8; *stk = (uint8_t)(tmp_adress & (uint16_t)0x00ff); -#if (CHECK_EIND_REG) +#if __AVR_3_BYTE_PC__ /* Devices with more than 128kb FLASH use a PC with more than 16bits, we * set whole the top byte forcibly to 0 */ stk--; @@ -139,21 +127,25 @@ char *thread_stack_init(thread_task_func_t task_func, void *arg, stk--; *stk = (uint8_t)0x80; -#if (CHECK_RAMPZ_REG) +#if __AVR_HAVE_RAMPZ__ stk--; *stk = (uint8_t)0x00; /* RAMPZ */ #endif -#if (CHECK_RAMPDXY_REG) +#if __AVR_HAVE_RAMPY__ stk--; *stk = (uint8_t)0x00; /* RAMPY */ +#endif +#if __AVR_HAVE_RAMPX__ stk--; *stk = (uint8_t)0x00; /* RAMPX */ +#endif +#if __AVR_HAVE_RAMPD__ stk--; *stk = (uint8_t)0x00; /* RAMPD */ #endif -#if (CHECK_EIND_REG) +#if __AVR_3_BYTE_PC__ stk--; *stk = (uint8_t)0x00; /* EIND */ #endif @@ -302,21 +294,27 @@ __attribute__((always_inline)) static inline void avr8_context_save(void) "cli \n\t" "push __tmp_reg__ \n\t" -#if (CHECK_RAMPZ_REG) +#if __AVR_HAVE_RAMPZ__ "in __tmp_reg__, __RAMPZ__ \n\t" "push __tmp_reg__ \n\t" #endif -#if (CHECK_RAMPDXY_REG) +#if __AVR_HAVE_RAMPY__ "in __tmp_reg__, __RAMPY__ \n\t" "push __tmp_reg__ \n\t" +#endif + +#if __AVR_HAVE_RAMPX__ "in __tmp_reg__, __RAMPX__ \n\t" "push __tmp_reg__ \n\t" +#endif + +#if __AVR_HAVE_RAMPD__ "in __tmp_reg__, __RAMPD__ \n\t" "push __tmp_reg__ \n\t" #endif -#if (CHECK_EIND_REG) +#if __AVR_3_BYTE_PC__ "in __tmp_reg__, " XTSTR(__EIND__) " \n\t" "push __tmp_reg__ \n\t" #endif @@ -402,21 +400,25 @@ __attribute__((always_inline)) static inline void avr8_context_restore(void) "pop r2 \n\t" "pop r1 \n\t" -#if (CHECK_EIND_REG) +#if __AVR_3_BYTE_PC__ "pop __tmp_reg__ \n\t" "out " XTSTR(__EIND__) ", __tmp_reg__ \n\t" #endif -#if (CHECK_RAMPDXY_REG) +#if __AVR_HAVE_RAMPD__ "pop __tmp_reg__ \n\t" "out __RAMPD__, __tmp_reg__ \n\t" +#endif +#if __AVR_HAVE_RAMPX__ "pop __tmp_reg__ \n\t" "out __RAMPX__, __tmp_reg__ \n\t" +#endif +#if __AVR_HAVE_RAMPY__ "pop __tmp_reg__ \n\t" "out __RAMPY__, __tmp_reg__ \n\t" #endif -#if (CHECK_RAMPZ_REG) +#if __AVR_HAVE_RAMPZ__ "pop __tmp_reg__ \n\t" "out __RAMPZ__, __tmp_reg__ \n\t" #endif From 740c2faaa882ad08ca2bf7c86018b6e30a188d10 Mon Sep 17 00:00:00 2001 From: Marian Buschsieweke Date: Mon, 20 Jun 2022 19:56:00 +0200 Subject: [PATCH 2/2] cpu/avr8_common: fix cpu_print_last_instruction --- cpu/avr8_common/include/cpu.h | 38 ++++++++++++++++++++++++----------- 1 file changed, 26 insertions(+), 12 deletions(-) diff --git a/cpu/avr8_common/include/cpu.h b/cpu/avr8_common/include/cpu.h index a02786dedb..0c28ad2f6c 100644 --- a/cpu/avr8_common/include/cpu.h +++ b/cpu/avr8_common/include/cpu.h @@ -168,23 +168,37 @@ void avr8_clk_init(void); /** * @brief Print the last instruction's address + * + * @details This works only if called in a function as first statement, as + * it relies on the return address to be the topmost item on the stack. */ static inline void __attribute__((always_inline)) cpu_print_last_instruction(void) { - uint8_t hi; - uint8_t lo; - uint16_t ptr; - - __asm__ volatile ( - "in %[hi], __SP_H__ \n\t" - "in %[lo], __SP_L__ \n\t" - : [hi] "=r"(hi), - [lo] "=r"(lo) + uint32_t addr; + __asm__ volatile( + "ldi %D[dest], 0" "\n\t" +#if __AVR_3_BYTE_PC__ + "pop %C[dest] " "\n\t" +#else + "ldi %C[dest], 0" "\n\t" +#endif + "pop %B[dest]" "\n\t" + "pop %A[dest]" "\n\t" + "push %A[dest]" "\n\t" + "push %B[dest]" "\n\t" +#if __AVR_3_BYTE_PC__ + "push %C[dest] " "\n\t" +#endif + : [dest] "=r"(addr) : /* no inputs */ - : /* no clobbers */ + : "memory" ); - ptr = hi << 8 | lo; - printf("Stack Pointer: 0x%04x\n", ptr); + + /* addr now contains instruction to return to, subtract one to get + * the instruction that called this function. Also multiply by two to get + * the byte position, rather than the (16 bit) instruction position */ + addr = (addr - 1 ) * 2; + printf("0x%" PRIx32 "\n", addr); } /**