mirror of
https://github.com/RIOT-OS/RIOT.git
synced 2024-12-29 04:50:03 +01:00
Merge pull request #18226 from benpicco/cpu_get_last_instruction
cpu: cpu_print_last_instruction() -> cpu_get_caller_pc()
This commit is contained in:
commit
6790167a18
@ -16,6 +16,7 @@
|
||||
#include <stdio.h>
|
||||
|
||||
#include "assert.h"
|
||||
#include "architecture.h"
|
||||
#include "cpu.h"
|
||||
#include "panic.h"
|
||||
|
||||
@ -27,7 +28,7 @@ __NORETURN void _assert_failure(const char *file, unsigned line)
|
||||
|
||||
__NORETURN void _assert_panic(void)
|
||||
{
|
||||
cpu_print_last_instruction();
|
||||
printf("%" PRIxTXTPTR "\n", cpu_get_caller_pc());
|
||||
core_panic(PANIC_ASSERT_FAIL, "FAILED ASSERTION.");
|
||||
}
|
||||
|
||||
|
@ -29,6 +29,10 @@ extern "C" {
|
||||
/* Doc is provided centrally in platform.h, hide this from Doxygen */
|
||||
#ifndef DOXYGEN
|
||||
#define ARCHITECTURE_WORD_BITS (8U)
|
||||
|
||||
#define ARCHITECTURE_LARGE_TXT_PTR 1
|
||||
typedef uint32_t uinttxtptr_t;
|
||||
#define PRIxTXTPTR PRIx32
|
||||
#endif /* DOXYGEN */
|
||||
|
||||
#ifdef __cplusplus
|
||||
|
@ -36,6 +36,7 @@
|
||||
#include <stdint.h>
|
||||
|
||||
#include <avr/interrupt.h>
|
||||
#include "architecture.h"
|
||||
#include "cpu_conf.h"
|
||||
#include "cpu_clock.h"
|
||||
#include "sched.h"
|
||||
@ -167,14 +168,14 @@ void avr8_exit_isr(void);
|
||||
void avr8_clk_init(void);
|
||||
|
||||
/**
|
||||
* @brief Print the last instruction's address
|
||||
* @brief Get 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)
|
||||
static inline uinttxtptr_t __attribute__((always_inline)) cpu_get_caller_pc(void)
|
||||
{
|
||||
uint32_t addr;
|
||||
uinttxtptr_t addr;
|
||||
__asm__ volatile(
|
||||
"ldi %D[dest], 0" "\n\t"
|
||||
#if __AVR_3_BYTE_PC__
|
||||
@ -198,7 +199,7 @@ static inline void __attribute__((always_inline)) cpu_print_last_instruction(voi
|
||||
* 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);
|
||||
return addr;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -127,13 +127,15 @@ void cortexm_init_misc(void);
|
||||
#endif /* defined(CPU_CORTEXM_INIT_SUBFUNCTIONS) || defined(DOXYGEN) */
|
||||
|
||||
/**
|
||||
* @brief Prints the current content of the link register (lr)
|
||||
* @brief Returns the current content of the link register (lr)
|
||||
*
|
||||
* @return content of the link register (lr)
|
||||
*/
|
||||
static inline void cpu_print_last_instruction(void)
|
||||
static inline uintptr_t cpu_get_caller_pc(void)
|
||||
{
|
||||
uint32_t *lr_ptr;
|
||||
uintptr_t lr_ptr;
|
||||
__asm__ __volatile__("mov %0, lr" : "=r"(lr_ptr));
|
||||
printf("%p\n", (void*) lr_ptr);
|
||||
return lr_ptr;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -30,13 +30,14 @@ extern "C" {
|
||||
#define PROVIDES_PM_SET_LOWEST
|
||||
|
||||
/**
|
||||
* @brief Print the last instruction's address
|
||||
* @brief Gets the last instruction's address
|
||||
*
|
||||
* @todo: Not supported
|
||||
*/
|
||||
static inline void cpu_print_last_instruction(void)
|
||||
static inline uintptr_t cpu_get_caller_pc(void)
|
||||
{
|
||||
/* This function must exist else RIOT won't compile */
|
||||
return 0;
|
||||
}
|
||||
|
||||
#ifdef __cplusplus
|
||||
|
@ -58,13 +58,13 @@ void gpio_init_ports(void);
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @brief Prints the current content of the link register (lr)
|
||||
* @brief Returns the current content of the link register (lr)
|
||||
*/
|
||||
static inline void cpu_print_last_instruction(void)
|
||||
static inline uintptr_t cpu_get_caller_pc(void)
|
||||
{
|
||||
register uint32_t *lr_ptr;
|
||||
register uintptr_t lr_ptr;
|
||||
__asm__ __volatile__("mov %0, lr" : "=r"(lr_ptr));
|
||||
printf("%p\n", (void*) lr_ptr);
|
||||
return lr_ptr;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -41,13 +41,14 @@ extern "C" {
|
||||
/** @} */
|
||||
|
||||
/**
|
||||
* @brief Print the last instruction's address
|
||||
* @brief Gets the last instruction's address
|
||||
*
|
||||
* @todo: Not supported
|
||||
*/
|
||||
static inline void cpu_print_last_instruction(void)
|
||||
static inline uintptr_t cpu_get_caller_pc(void)
|
||||
{
|
||||
/* This function must exist else RIOT won't compile */
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -118,13 +118,13 @@ static inline void __attribute__((always_inline)) __exit_isr(void)
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Print the last instruction's address
|
||||
* @brief Returns the last instruction's address
|
||||
*
|
||||
* @todo: Not supported
|
||||
*/
|
||||
static inline void cpu_print_last_instruction(void)
|
||||
static inline uintptr_t cpu_get_caller_pc(void)
|
||||
{
|
||||
puts("n/a");
|
||||
return 0;
|
||||
}
|
||||
|
||||
#ifdef __cplusplus
|
||||
|
@ -20,6 +20,7 @@
|
||||
#ifndef CPU_H
|
||||
#define CPU_H
|
||||
|
||||
#include <stdint.h>
|
||||
#include <stdio.h>
|
||||
#include "cpu_conf.h"
|
||||
|
||||
@ -34,14 +35,14 @@ extern "C" {
|
||||
#define CPU_HAS_UNALIGNED_ACCESS
|
||||
|
||||
/**
|
||||
* @brief Prints the address the callee will return to
|
||||
* @brief Gets the address the callee will return to
|
||||
*/
|
||||
__attribute__((always_inline)) static inline void cpu_print_last_instruction(void)
|
||||
__attribute__((always_inline)) static inline uintptr_t cpu_get_caller_pc(void)
|
||||
{
|
||||
/* __builtin_return_address will return the address the calling function
|
||||
* will return to - since cpu_print_last_instruction is forced inline,
|
||||
* will return to - since cpu_get_caller_pc is forced inline,
|
||||
* it is the return address of the user of this function */
|
||||
printf("%p\n", __builtin_return_address(0));
|
||||
return (uintptr_t)__builtin_return_address(0);
|
||||
}
|
||||
|
||||
#ifdef __cplusplus
|
||||
|
@ -47,13 +47,14 @@ void riscv_fpu_init(void);
|
||||
void riscv_irq_init(void);
|
||||
|
||||
/**
|
||||
* @brief Print the last instruction's address
|
||||
* @brief Gets the last instruction's address
|
||||
*
|
||||
* @todo: Not supported
|
||||
*/
|
||||
static inline void cpu_print_last_instruction(void)
|
||||
static inline uintptr_t cpu_get_caller_pc(void)
|
||||
{
|
||||
/* This function must exist else RIOT won't compile */
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -25,6 +25,7 @@
|
||||
#define ARCHITECTURE_H
|
||||
|
||||
#include <stdint.h>
|
||||
#include <inttypes.h>
|
||||
|
||||
#include "architecture_arch.h"
|
||||
|
||||
@ -79,6 +80,18 @@ typedef int32_t sword_t;
|
||||
#error "Unsupported word size (check ARCHITECTURE_WORD_BITS in architecture_arch.h)"
|
||||
#endif
|
||||
|
||||
#if !defined(ARCHITECTURE_LARGE_TXT_PTR) || DOXYGEN
|
||||
/**
|
||||
* @brief Pointer type to point anywhere in the .text section
|
||||
*/
|
||||
typedef uintptr_t uinttxtptr_t;
|
||||
|
||||
/**
|
||||
* @brief Format string macro for text section pointer
|
||||
*/
|
||||
#define PRIxTXTPTR PRIxPTR
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @brief Type qualifier to use to align data on word boundaries
|
||||
*
|
||||
|
Loading…
Reference in New Issue
Block a user