/* * Copyright (c) 2021 Intel Corporation. * * SPDX-License-Identifier: Apache-2.0 */ #include #ifndef ZEPHYR_INCLUDE_ARCH_XTENSA_GDBSTUB_SYS_H_ #define ZEPHYR_INCLUDE_ARCH_XTENSA_GDBSTUB_SYS_H_ #ifdef CONFIG_GDBSTUB #define XTREG_GRP_MASK 0x0F00 #define XTREG_GRP_GENERAL 0x0000 #define XTREG_GRP_ADDR 0x0100 #define XTREG_GRP_SPECIAL 0x0200 #define XTREG_GRP_USER 0x0300 /** * @brief Register description for GDB stub. * * Values are based on gdb/gdb/xtensa-config.c in the Xtensa overlay, * where registers are defined using XTREG() macro: * XTREG(index,ofs,bsz,sz,al,tnum,flg,cp,ty,gr,name,fet,sto,mas,ct,x,y) * * Translation: * idx : index * regno : tnum * 0x00xx : General Registers (A0 - A15, PC) * 0x01xx : Address Registers (AR0 - AR31/AR63) * 0x02xx : Special Registers (access via RSR/WSR) * 0x03xx : User Registers (access via RUR/WUR) * byte_size : sz * gpkt_offset : ofs */ struct xtensa_register { /** Register value */ uint32_t val; /** GDB register index (for p/P packets) */ uint8_t idx; /** Size of register */ uint8_t byte_size; /** Xtensa register number */ uint16_t regno; /** * Offset of this register in GDB G-packet. * -1 if register is not in G-packet. */ int16_t gpkt_offset; /** * Offset of saved register in stack frame. * 0 if not saved in stack frame. */ int8_t stack_offset; /** Sequence number */ uint8_t seqno; /** * Set to 1 if register should not be written * to during debugging. */ uint8_t is_read_only:1; }; /* Due to Xtensa SoCs being highly configurable, * the register files between SoCs are not identical. * * This means generic registers can, sometimes, have * different offsets from start of register files * needed to communicate with GDB. * * Therefore, it is better to defer to the SoC layer * for proper support for GDB. */ #include /** * @brief Architecture specific GDB context. */ struct gdb_ctx { /** Exception reason */ unsigned int exception; /** Register descriptions */ struct xtensa_register *regs; /** Number of registers */ uint8_t num_regs; /** Sequence number */ uint8_t seqno; /** Index in register descriptions of A0 register */ uint8_t a0_idx; /** Index in register descriptions of AR0 register */ uint8_t ar_idx; /** Index in register descriptions of WINDOWBASE register */ uint8_t wb_idx; }; /** * Test if the register is a logical address register (A0 - A15). * * @retval true if register is A0 - A15 * @retval false if register is not A0 - A15 */ static inline bool gdb_xtensa_is_logical_addr_reg(struct xtensa_register *reg) { if (reg->regno < 16) { return true; } else { return false; } } /** * Test if the register is a address register (AR0 - AR31/AR63). * * @retval true if register is AR0 - AR31/AR63 * @retval false if not */ static inline bool gdb_xtensa_is_address_reg(struct xtensa_register *reg) { if ((reg->regno & XTREG_GRP_MASK) == XTREG_GRP_ADDR) { return true; } else { return false; } } /** * Test if the register is a special register that needs to be * accessed via RSR/WSR. * * @retval true if special register * @retval false if not */ static inline bool gdb_xtensa_is_special_reg(struct xtensa_register *reg) { if ((reg->regno & XTREG_GRP_MASK) == XTREG_GRP_SPECIAL) { return true; } else { return false; } } /** * Test if the register is a user register that needs to be * accessed via RUR/WUR. * * @retval true if user register * @retval false if not */ static inline bool gdb_xtensa_is_user_reg(struct xtensa_register *reg) { if ((reg->regno & XTREG_GRP_MASK) == XTREG_GRP_USER) { return true; } else { return false; } } #endif /* CONFIG_GDBSTUB */ #endif /* ZEPHYR_INCLUDE_ARCH_XTENSA_GDBSTUB_SYS_H_ */