Add FIH testing tool
Signed-off-by: Raef Coles <raef.coles@arm.com>
Change-Id: Ia05829e1b413206d83794209642080d1a937d092
diff --git a/fih_test_tool/gdb-tool/backend/qemu.py b/fih_test_tool/gdb-tool/backend/qemu.py
new file mode 100644
index 0000000..2d2e1f0
--- /dev/null
+++ b/fih_test_tool/gdb-tool/backend/qemu.py
@@ -0,0 +1,73 @@
+# Copyright (c) 2021, Arm Limited. All rights reserved.
+#
+# SPDX-License-Identifier: BSD-3-Clause
+
+import subprocess
+import os
+import gdb
+
+backend_has_saveload = True
+
+qemu_mon_in_file = None
+qemu_mon_out_file = None
+
+qemu_pid = None
+
+def backend_start_and_reset_and_connect():
+ global qemu_mon_in_file
+ global qemu_mon_out_file
+ global qemu_pid
+
+ print("(Re)Starting QEMU")
+ p = subprocess.run(os.path.dirname(os.path.realpath(__file__)) + "/../../fih_test_exec_qemu.sh")
+ p = subprocess.run(["pgrep", "qemu-system-arm"], capture_output=True)
+ qemu_pid = p.stdout.decode('utf-8').rstrip()
+
+ try:
+ gdb.execute('detach')
+ except gdb.error:
+ # We were probably not attached in the first place - this was post-crash
+ # or first run.
+ pass
+ gdb.execute('target extended-remote localhost:1234')
+
+ if qemu_mon_in_file is not None:
+ qemu_mon_in_file.close()
+ if qemu_mon_out_file is not None:
+ qemu_mon_out_file.close()
+
+ qemu_mon_in_file = open("qemu_mon.in", 'w')
+ qemu_mon_out_file = open("qemu_mon.out", 'r')
+
+def backend_reset():
+ gdb.execute('detach')
+ _kill_qemu()
+ backend_start_and_reset_and_connect()
+ print("Reset QEMU")
+
+####################### Save / Loading #########################################
+
+def backend_save_state(id):
+ print("Saving state: {} at PC {}".format(str(id),
+ hex(gdb.selected_frame().pc())))
+ _write_fifo(qemu_mon_in_file, 'savevm {}'.format(str(id)))
+
+def backend_load_state(id):
+ _write_fifo(qemu_mon_in_file, 'loadvm {}'.format(str(id)))
+ # Disconnect and reconnect to reset gdb's internal state
+ gdb.execute('detach')
+ gdb.execute('target extended-remote localhost:1234')
+ print("Loaded state: " + str(id))
+
+######################## Internal ##############################################
+
+def _write_fifo(fifo, msg):
+ fifo.write(msg + '\n')
+ fifo.flush()
+
+def _kill_qemu():
+ global qemu_pid
+ if qemu_pid is None:
+ return
+ p = subprocess.run(["kill", qemu_pid, "-9"])
+ qemu_pid = None