/* Native-dependent code for GNU/Linux on LoongArch processors. Copyright (C) 2024 Free Software Foundation, Inc. Contributed by Loongson Ltd. This file is part of GDB. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . */ #ifndef NAT_LOONGARCH_HW_POINT_H #define NAT_LOONGARCH_HW_POINT_H /* Macro definitions, data structures, and code for the hardware breakpoint and hardware watchpoint support follow. We use the following abbreviations throughout the code: hw - hardware bp - breakpoint wp - watchpoint */ /* Maximum number of hardware breakpoint and watchpoint registers. Neither of these values may exceed the width of dr_changed_t measured in bits. */ #define LOONGARCH_HBP_MAX_NUM 8 #define LOONGARCH_HWP_MAX_NUM 8 /* The maximum length of a memory region that can be watched by one hardware watchpoint register. */ #define LOONGARCH_HWP_MAX_LEN_PER_REG 8 #define CTRL_PLV3_ENABLE 0x10 #define DR_CONTROL_ENABLED(ctrl) ((ctrl & CTRL_PLV3_ENABLE) == CTRL_PLV3_ENABLE) /* Structure for managing the hardware breakpoint/watchpoint resources. DR_ADDR_* stores the address, DR_CTRL_* stores the control register content, and DR_REF_COUNT_* counts the numbers of references to the corresponding bp/wp, by which way the limited hardware resources are not wasted on duplicated bp/wp settings (though so far gdb has done a good job by not sending duplicated bp/wp requests). */ struct loongarch_debug_reg_state { /* hardware breakpoint */ CORE_ADDR dr_addr_bp[LOONGARCH_HBP_MAX_NUM]; unsigned int dr_ctrl_bp[LOONGARCH_HBP_MAX_NUM]; unsigned int dr_ref_count_bp[LOONGARCH_HBP_MAX_NUM]; /* hardware watchpoint */ CORE_ADDR dr_addr_wp[LOONGARCH_HWP_MAX_NUM]; unsigned int dr_ctrl_wp[LOONGARCH_HWP_MAX_NUM]; unsigned int dr_ref_count_wp[LOONGARCH_HWP_MAX_NUM]; }; extern int loongarch_num_bp_regs; extern int loongarch_num_wp_regs; /* Invoked when IDXth breakpoint/watchpoint register pair needs to be updated. */ void loongarch_notify_debug_reg_change (ptid_t ptid, int is_watchpoint, unsigned int idx); int loongarch_handle_breakpoint (enum target_hw_bp_type type, CORE_ADDR addr, int len, int is_insert, ptid_t ptid, struct loongarch_debug_reg_state *state); int loongarch_handle_watchpoint (enum target_hw_bp_type type, CORE_ADDR addr, int len, int is_insert, ptid_t ptid, struct loongarch_debug_reg_state *state); /* Return TRUE if there are any hardware breakpoints. If WATCHPOINT is TRUE, check hardware watchpoints instead. */ bool loongarch_any_set_debug_regs_state (loongarch_debug_reg_state *state, bool watchpoint); /* Print the values of the cached breakpoint/watchpoint registers. */ void loongarch_show_debug_reg_state (struct loongarch_debug_reg_state *state, const char *func, CORE_ADDR addr, int len, enum target_hw_bp_type type); /* Return true if we can watch a memory region that starts address ADDR and whose length is LEN in bytes. */ int loongarch_region_ok_for_watchpoint (CORE_ADDR addr, int len); #endif /* NAT_LOONGARCH_HW_POINT_H */