aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRob Savoye <rob@senecass.com>2020-07-06 13:52:34 -0600
committerRob Savoye <rob@senecass.com>2020-07-06 13:52:34 -0600
commit60e555675a9990270be8c4d63d3b4b8f484f3f51 (patch)
tree4e98eff0088454f9b67a8a77201de86d753cc924
parent155ad7ac7f606f43613bb457ea36cc466d113613 (diff)
Add board support file for QEMU for bare metal testing.
-rw-r--r--baseboards/qemu.exp274
1 files changed, 274 insertions, 0 deletions
diff --git a/baseboards/qemu.exp b/baseboards/qemu.exp
new file mode 100644
index 0000000..b699805
--- /dev/null
+++ b/baseboards/qemu.exp
@@ -0,0 +1,274 @@
+#
+# Copyright (C) 2020 Free Software Foundation, Inc.
+#
+# This program is free software; you can redistribute it and/or modify
+# 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.
+#
+# DejaGnu 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 DejaGnu; if not, write to the Free Software Foundation,
+# Inc., 51 Franklin Street - Fifth Floor, Boston, MA 02110-1301, USA.
+
+# Load the generic configuration for this board. This will define a basic
+# set of routines used to communicate with the board.
+# load_generic_config "sim"
+load_generic_config "gdbserver"
+#load_lib gdbserver-support.exp
+
+
+set qemu ""
+set spec ""
+
+proc gdb_start {} {
+ puts "TRACE: gdb_start"
+ default_gdb_start
+
+ return 0
+}
+
+# No multilib flags needed by default.
+process_multilib_options ""
+
+set_board_info compiler [find_gcc]
+
+# When testing GCC in tree, the libgloss linker scripts files aren't
+# usually in a known location, so we have to find them in the sysroot.
+# FIXME: this may change in the near future, but for now it works.
+set compiler "[find_gcc]"
+set ret [local_exec "$compiler --print-sysroot" "" "" $timeout]
+if { [lindex $ret 0] == 0 } {
+ set sysroot "[lindex $ret 1]"
+ # Strip the CR or LF off the end of the line as returned by GCC
+ regsub -all "\[\n\r\]+" $sysroot "" sysroot
+}
+# set library path environment variable for qemu
+set env(QEMU_LD_PREFIX) $sysroot
+
+# In the beginning, only linker scripts were used to produce a fully
+# linked executable. Then a better solution of having GCC spec file
+# "patches" worked much better. None of the ARM/AARCH64 target
+# use linker scripts, some targets support both, some just the
+# linker script.
+set ldscripts [ glob -nocomplain $sysroot/usr/lib/*.ld ]
+if { [string length $ldscripts] == 0 } {
+ warning "No linker scripts found."
+}
+set specfiles [ glob -nocomplain $sysroot/usr/lib/*.specs ]
+if { [string length $specfiles] == 0 } {
+ warning "No spec files found."
+} else {
+ # FIXME: For now, both ldscripts and specfiles are ignored, and a
+ # single value is used tor testing.
+ foreach spec $specfiles {
+ verbose "Found spec file $spec"
+ }
+}
+
+# The basic set of flags needed to build "hello world" for this
+# board. This board uses libgloss and newlib.
+case "$target_triplet" in {
+ { "armeb-*-eabi*" } {
+ set qemu "qemu-armeb"
+ set spec "elf-rdimon.specs"
+ }
+ { "arm-pi3-*" } {
+ set qemu "qemu-arm"
+ set spec="-static"
+ set target_list pi
+ }
+ { "arm*-*-eabi*" } {
+ set qemu "qemu-arm"
+ set spec "elf-rdimon.specs"
+ }
+ { "aarch64be-*-elf" } {
+ set qemu "qemu-aarch64_be"
+ set spec "rdimon.specs"
+ }
+ { "aarch64*-*elf*" } {
+ # There's multiple spec files, but rdimon is the
+ # one usually used for testing.
+ set qemu "qemu-aarch64"
+ set spec "rdimon.specs"
+ set target_list qemu
+ }
+ # FIXME: These following qemu variants are just what QEMU
+ # support, the pattern to match for the target needs to be
+ # researched.
+ { "cris*" } {
+ set qemu "qemu-cris"
+ }
+ { "microblaze-*" } {
+ set qemu "qemu-microblaze"
+ set spec "elf-gloss-linux.specs"
+ }
+ { "microblazeel-*" } {
+ set qemu "qemu-microblazeel"
+ set spec "elf-gloss-linux.specs"
+ }
+ { "mips" } {
+ set qemu "qemu-mips"
+ }
+ { "mips64-*" } {
+ set qemu "qemu-mips64"
+ }
+ { "mips64el-*" } {
+ set qemu "qemu-mips64el"
+ }
+ { "mipsel-*" } {
+ set qemu "qemu-mipsel"
+ }
+ { "mipsn32-*" } {
+ set qemu "qemu-mipsn32"
+ }
+ { "mipsn32el-*" } {
+ set qemu "qemu-mipsn32el"
+ }
+ { "ppc-*" } {
+ set qemu "qemu-ppc"
+ }
+ { "ppc64-*" } {
+ set qemu "qemu-ppc64"
+ }
+ { "ppc64abi32-*" } {
+ set qemu "qemu-ppc64abi32"
+ }
+ { "ppc64le-*" } {
+ set qemu "qemu-ppc64le"
+ }
+ { "riscv32-elf" } {
+ set qemu "qemu-riscv32"
+ }
+ { "riscv64-elf" } {
+ set qemu "qemu-riscv64"
+ set spec "nano.spec"
+ }
+ { "sh4-*" } {
+ set qemu "qemu-sh4"
+ }
+ { "sh4eb-*" } {
+ set qemu "qemu-sh4eb"
+ }
+ { "sparc=*" } {
+ set qemu "qemu-sparc"
+ }
+ { "sparc32plus-*" } {
+ set qemu "qemu-sparc32plus"
+ }
+ { "sparc64-*" } {
+ set qemu "qemu-sparc64"
+ }
+ default {
+ puts "No target hardware for $target_triplet"
+ }
+}
+
+set port "2345"
+# QEMU uses the standard renmote debugging protocol as used by gdbserver.
+set_board_info gdb_protocol "remote"
+# localhost is the default host used for the remote debugging protocol
+set_board_info gdb,sockethost "localhost"
+# 2345 is the default port used for the remote debugging protocol
+set_board_info gdb,socketport $port
+set_board_info target_sim_options "-g $port"
+set_board_info gdb_server_prog $qemu
+set_board_info specfile $spec
+set_board_info needs_status_wrapper 1
+set_board_info protocol standard
+push_config target qemu
+
+# This gdbserver can only run a process once per session.
+set_board_info gdb,do_reload_on_run 1
+set_board_info exit_is_reliable 1
+
+# Set this if the board does not support passing arguments to the
+# inferior process.
+set_board_info noargs 0
+
+set_board_info cflags "[libgloss_include_flags]"
+set_board_info ldflags "[libgloss_link_flags] [newlib_link_flags] -specs=$spec -static"
+
+proc qemu_load { dest prog args } {
+ global qemu
+ global timeout
+ set ret [local_exec "$qemu $prog" "" "" $timeout]
+
+ if { [array size ret] == 0 } {
+ return "pass"
+ } else {
+ return "fail"
+ }
+}
+
+#
+# Start QEMU with the executable
+#
+proc qemu_download { dest prog args } {
+ global qemu
+ global timeout
+ puts "TRACE: qemu_download $dest $prog $args"
+ # qemu is already running with our executable.
+}
+
+proc qemu_exec { dest prog args } {
+ global qemu
+ global timeout
+ puts "TRACE: qemu_exec $dest $prog $args"
+
+ # gdb_target_cmd "remote" ""
+
+}
+
+#
+# Load executable into GDB
+#
+proc gdb_load { args } {
+ global gdb_prompt
+ global verbose
+ global GDB
+ global user_spawn_id
+ global qemu
+ puts "TRACE: gdb_load $args"
+
+ # qemu implements the gdbserver protocol.
+ spawn -nottyinit -noecho $qemu -g 2345 $args
+ # disconnect
+
+ if { $args != "" } {
+ if [gdb_file_cmd $args] then { return -1 }
+ }
+
+ # Only the remote protocol is used with the QEMU's gdbserver support
+ set ret [gdb_target_cmd "remote" ":2345"]
+ # set ret [gdb_target_cmd $protocol ""]
+ puts $ret
+
+ send_gdb "load\n"
+ gdb_expect 2400 {
+ -re ".*$gdb_prompt $" {
+ if $verbose>1 then {
+ send_user "Loaded $args into $GDB\n"
+ }
+ close $spawn_id
+ return 0
+ }
+ -re "$gdb_prompt $" {
+ if $verbose>1 then {
+ perror "GDB couldn't load."
+ }
+ }
+ timeout {
+ if $verbose>1 then {
+ perror "Timed out trying to load $args."
+ }
+ }
+ }
+
+ close $spawn_id
+ return -1
+}