# Test Framework Driver for GDB driving an external simulator
#   Copyright 1999, 2001, 2007, 2008, 2009, 2010
#   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/>.

load_lib gdb.exp

proc sid_start {} {
    global verbose

    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."
	    cleanup
	    gdb_exit
	}
	-re "Remote debugging using.*$gdb_prompt"	{
	    verbose "Set target to sid"
	}
	timeout { 
	    perror "Couldn't set target for remote simulator."
	    cleanup
	    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;
}
