aboutsummaryrefslogtreecommitdiff
path: root/target/arm/internals.h
diff options
context:
space:
mode:
authorFrancesco Cagnin <fcagnin@quarkslab.com>2023-06-06 10:19:29 +0100
committerPeter Maydell <peter.maydell@linaro.org>2023-06-06 10:19:29 +0100
commit0ca52a5fedeae3987ab2a84077d8ecb7d913aa37 (patch)
treef028c00a149c8bfb61d0fcb402de343912e37230 /target/arm/internals.h
parent369081c4558e7e940fa36ce59bf17b2e390f55d3 (diff)
arm: move KVM breakpoints helpers
These helpers will be also used for HVF. Aside from reformatting a couple of comments for 'checkpatch.pl' and updating meson to compile 'hyp_gdbstub.c', this is just code motion. Signed-off-by: Francesco Cagnin <fcagnin@quarkslab.com> Reviewed-by: Alex Bennée <alex.bennee@linaro.org> Reviewed-by: Peter Maydell <peter.maydell@linaro.org> Message-id: 20230601153107.81955-2-fcagnin@quarkslab.com Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
Diffstat (limited to 'target/arm/internals.h')
-rw-r--r--target/arm/internals.h50
1 files changed, 50 insertions, 0 deletions
diff --git a/target/arm/internals.h b/target/arm/internals.h
index c869d18c38..ce26299f7f 100644
--- a/target/arm/internals.h
+++ b/target/arm/internals.h
@@ -1447,4 +1447,54 @@ static inline bool arm_fgt_active(CPUARMState *env, int el)
}
void assert_hflags_rebuild_correctly(CPUARMState *env);
+
+/*
+ * Although the ARM implementation of hardware assisted debugging
+ * allows for different breakpoints per-core, the current GDB
+ * interface treats them as a global pool of registers (which seems to
+ * be the case for x86, ppc and s390). As a result we store one copy
+ * of registers which is used for all active cores.
+ *
+ * Write access is serialised by virtue of the GDB protocol which
+ * updates things. Read access (i.e. when the values are copied to the
+ * vCPU) is also gated by GDB's run control.
+ *
+ * This is not unreasonable as most of the time debugging kernels you
+ * never know which core will eventually execute your function.
+ */
+
+typedef struct {
+ uint64_t bcr;
+ uint64_t bvr;
+} HWBreakpoint;
+
+/*
+ * The watchpoint registers can cover more area than the requested
+ * watchpoint so we need to store the additional information
+ * somewhere. We also need to supply a CPUWatchpoint to the GDB stub
+ * when the watchpoint is hit.
+ */
+typedef struct {
+ uint64_t wcr;
+ uint64_t wvr;
+ CPUWatchpoint details;
+} HWWatchpoint;
+
+/* Maximum and current break/watch point counts */
+extern int max_hw_bps, max_hw_wps;
+extern GArray *hw_breakpoints, *hw_watchpoints;
+
+#define cur_hw_wps (hw_watchpoints->len)
+#define cur_hw_bps (hw_breakpoints->len)
+#define get_hw_bp(i) (&g_array_index(hw_breakpoints, HWBreakpoint, i))
+#define get_hw_wp(i) (&g_array_index(hw_watchpoints, HWWatchpoint, i))
+
+bool find_hw_breakpoint(CPUState *cpu, target_ulong pc);
+int insert_hw_breakpoint(target_ulong pc);
+int delete_hw_breakpoint(target_ulong pc);
+
+bool check_watchpoint_in_range(int i, target_ulong addr);
+CPUWatchpoint *find_hw_watchpoint(CPUState *cpu, target_ulong addr);
+int insert_hw_watchpoint(target_ulong addr, target_ulong len, int type);
+int delete_hw_watchpoint(target_ulong addr, target_ulong len, int type);
#endif