# Test Framework Driver for GDB driving an external simulator
#   Copyright 1999-2021 Free Software Foundation, Inc.
#
# 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 <http://www.gnu.org/licenses/>.

proc sid_start {} {
    set port [lindex [split [target_info netport] ":"] 1]

    # Set a default endianness
    case [target_info multilib_flags] in {
	{ *big-endian* *-EB* *-meb* } { set sidendian "-EB" }
	{ *little-endian* *-EL* *-mel* } { set sidendian "-EL" }
	default { 
	    if {[target_info exists sim,defaultendian]} then {
		set sidendian [target_info sim,defaultendian] 
	    } else { 
                # rely on endianness settings in sid configuration defaults
                set sidendian ""
	    }
	}
    }
    case $sidendian in {
	{ -EB } { set sidendian2 {-e "set cpu endian big"} }
	{ -EL } { set sidendian2 {-e "set cpu endian little"} }
	default { set sidendian2 {} }
    }

    # test to see whether to use use sid in build or install tree
    set use_build_tree [file exists ../../sid]

    if {$use_build_tree} then {
	set pre_spawn {
	    global env
	    set env(SID_LIBRARY_PATH) [join [glob "../../sid/component/*"] ":"]
	    set env(SID) "../../sid/main/dynamic/sid"
	    if {! [file exists $env(SID)]} then { error "Cannot find sid in build tree" }
	}
	if { [board_info target sim,protocol] == "sid" } {
	    set spawncmd "[target_info sim] [target_info sim,options] $sidendian2 -e \"set cpu-gdb-socket sockaddr-local 0.0.0.0:$port\""
	} elseif { [board_info target sim,protocol] == "rawsid" } {
	    set spawncmd "[target_info sim] [target_info sim,options] -$sidendian --gdb=$port"
	} else {
	    set spawncmd "../../sid/bsp/[target_info sim] $sidendian --gdb=$port [target_info sim,options]"
	}
	set post_spawn {
	    global env
	    unset env(SID_LIBRARY_PATH)
	    unset env(SID)
	}
    } else {
	set pre_spawn {}
	if { [board_info target sim,protocol] == "sid" } {
	    # FIXME: sim,options may be from the build tree, should find
	    # it in the install tree.
	    set spawncmd "sid [target_info sim,options] $sidendian2 -e \"set cpu-gdb-socket sockaddr-local 0.0.0.0:$port\""
	} elseif { [board_info target sim,protocol] == "rawsid" } {
	    set spawncmd "[target_info sim] [target_info sim,options] -$sidendian --gdb=$port"
	} else {
	    set spawncmd "[target_info sim] $sidendian --gdb=$port [target_info sim,options]"
	}
	set post_spawn {}
    }

    eval $pre_spawn
    if {[catch [list remote_spawn host $spawncmd] msg]} {
	perror $msg
	exit 1
    }
    eval $post_spawn

    # Don't do the following any more; it breaks with "runtest ... < /dev/null"
#    expect_background {
#	-re \[^\n\]*\n { 
#	    regsub "\n" $expect_out(buffer) {} msg
#	    verbose "SID: $msg" 2
#	}
#    }

    # There should be no need to sleep to give SID time to start;
    # GDB would wait for a fair while for the stub to respond.
    sleep 4

    if ![target_info exists gdb,no_push_conn] {
        remote_push_conn host
    }
}

#
# Handle GDB talking to SID
#

proc gdb_start {} {
    sid_start
    return [default_gdb_start]
}

proc sid_exit {} {
    if ![target_info exists gdb,no_push_conn] {
	remote_close host
	remote_pop_conn host
    }
}

proc gdb_exit {} {
    set result [default_gdb_exit]
    sid_exit
    return $result
}

#
# gdb_target_sid
# Set gdb to target the simulator
#
proc send_target_sid { } {
    # wait a little while, giving sid time to shut down & restart its
    # gdb socket
    sleep 4
    send_gdb "target [target_info gdb_protocol] [target_info netport]\n"
}

proc gdb_target_sid { } {
    global gdb_prompt
    global exit_status

    send_target_sid

    global timeout
    set prev_timeout $timeout
    set timeout 60
    verbose "Timeout is now $timeout seconds" 2
    gdb_expect {
	-re ".*\[Ee\]rror.*$gdb_prompt $" {
	    perror "Couldn't set target for remote simulator."
	    gdb_exit
	}
	-re "Remote debugging using.*$gdb_prompt"	{
	    verbose "Set target to sid"
	}
	timeout { 
	    perror "Couldn't set target for remote simulator."
	    gdb_exit
	}
    }
    set timeout $prev_timeout
    verbose "Timeout is now $timeout seconds" 2
}

#
# gdb_load -- load a file into the debugger.
#             return a -1 if anything goes wrong.
#
proc gdb_load { arg } {
    global verbose
    global loadpath
    global loadfile
    global GDB
    global gdb_prompt
    global retval

    if { $arg != "" } {
	if [gdb_file_cmd $arg] then { return -1 }
    }

    gdb_target_sid

    send_gdb "load\n"
    global timeout
    set prev_timeout $timeout
    set timeout 2400
    verbose "Timeout is now $timeout seconds" 2
    gdb_expect {
	-re ".*\[Ee\]rror.*$gdb_prompt $" {
	    if $verbose>1 then {
		perror "Error during download."
	    }
	    set retval -1
	}
	-re ".*$gdb_prompt $" {
	    if $verbose>1 then {
		send_user "Loaded $arg into $GDB\n"
	    }
	    set retval 0
	}
	-re "$gdb_prompt $"     {
	    if $verbose>1 then {
		perror "GDB couldn't load."
	    }
	    set retval -1
	}
	timeout {
	    if $verbose>1 then {
		perror "Timed out trying to load $arg."
	    }
	    set retval -1
	}
    }
    set timeout $prev_timeout
    verbose "Timeout is now $timeout seconds" 2
    return $retval
}
