# Test Framework Driver for GDB driving a ROM monitor (via monitor.c).
#   Copyright 1995-2000, 2007-2012 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
# puts "***** DID USE MONITOR ******"

#
# gdb_target_cmd
# Send gdb the "target" command
#
proc gdb_target_cmd { targetname serialport } {
    global gdb_prompt

    for {set i 1} {$i <= 3} {incr i} {
	send_gdb "target $targetname $serialport\n"
	gdb_expect 60 {
	    -re "A program is being debugged already.*ill it.*y or n. $" {
		send_gdb "y\n";
		exp_continue;
	    }
	    -re "Couldn't establish connection to remote.*$gdb_prompt" {
		verbose "Connection failed";
	    }
	    -re "Remote MIPS debugging.*$gdb_prompt" {
		verbose "Set target to $targetname";
		return 0;
	    }
	    -re "Remote debugging using .*$serialport.*$gdb_prompt" {
		verbose "Set target to $targetname";
		return 0;
	    }
	    -re "Remote target $targetname connected to.*$gdb_prompt" {
		verbose "Set target to $targetname";
		return 0;
	    }
	    -re "Connected to.*$gdb_prompt" { 
		verbose "Set target to $targetname";
		return 0;
	    }
	    -re "Ending remote.*$gdb_prompt" { }
	    -re "Connection refused.*$gdb_prompt" {
		verbose "Connection refused by remote target.  Pausing, and trying again."
		sleep 30
		continue
	    }
	    -re "Timeout reading from remote system.*$gdb_prompt" {
		verbose "Got timeout error from gdb.";
	    }
	    timeout {
		send_gdb "";
		break
	    }
	}
    }
    return 1
}



#
# gdb_target_monitor
# Set gdb to target the monitor
#
proc gdb_target_monitor { exec_file } {
    global gdb_prompt
    global exit_status
    global timeout

    if [target_info exists gdb_protocol] {
	set targetname "[target_info gdb_protocol]"
    } else {
	perror "No protocol specified for [target_info name].";
	return -1;
    }
    if [target_info exists baud] {
	gdb_test "set remotebaud [target_info baud]" "" ""
    }
    if [target_info exists binarydownload] {
	gdb_test "set remotebinarydownload [target_info binarydownload]" "" ""
    }
    if { [ target_info exists disable_x_packet ] } {
	gdb_test "set remote X-packet disable" ""
    }
    if { [ target_info exists disable_z_packet ] } {
	gdb_test "set remote Z-packet disable" ""
    }
    if [target_info exists gdb_serial] {
       set serialport "[target_info gdb_serial]";
    } elseif [target_info exists netport] {
	set serialport "[target_info netport]"
    } else {
	set serialport "[target_info serial]"
    }

    for {set j 1} {$j <= 2} {incr j} {
	if [gdb_file_cmd $exec_file] { return -1; }

	if ![gdb_target_cmd $targetname $serialport] { return 0; }

	gdb_target_exec;

	if { $j == 1 && ![reboot_target] } {
	    break;
	}
    }

    perror "Couldn't set target for $targetname, port is $serialport.";
    return -1;
}

proc gdb_target_exec { } {
    gdb_test "target exec" "No executable file now." "" ".*Kill it.*y or n.*" "y"
    
}
#
# 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 timeout
    global last_gdb_file;

    if { $arg == "" } {
	if [info exists last_gdb_file] {
	    set arg $last_gdb_file;
	} else {
	    send_gdb "info files\n";
	    gdb_expect 30 {
		-re "Symbols from \"(\[^\"\]+)\"" {
		    set arg $expect_out(1,string);
		    exp_continue;
		}
		-re "Local exec file:\[\r\n\]+\[ \t\]*`(\[^'\]+)'," {
		    set arg $expect_out(1,string);
		    exp_continue;
		}
		-re "$gdb_prompt $" { }
	    }
	}
    }

    set last_gdb_file $arg;

    for { set j 1; } { $j <= 2 } {incr j; } {
	if [target_info exists gdb,use_standard_load] {
	    gdb_target_exec;
	    if ![target_info exists gdb,no_push_conn] {
		remote_push_conn host;
	    }
	    set state [remote_ld target $arg];
	    if ![target_info exists gdb,no_push_conn] {
		remote_close target;
		remote_pop_conn host;
	    }
	    if { $state == "pass" } {
		if [gdb_target_monitor $arg] { return -1; }
		gdb_test "list main" ".*" ""
		verbose "Loaded $arg into $GDB\n";
		return 0;
	    }
	} else {

	    if [gdb_target_monitor $arg] { return -1 }

	    if [is_remote host] {
		# FIXME: Multiple downloads. bleah.
		set farg [remote_download host $arg];
	    } else {
		set farg $arg;
	    }

	    if { $arg != "" && [target_info exists gdb_sect_offset] } {
		set textoff [target_info gdb_sect_offset];
		send_gdb "sect .text $textoff\n";
		gdb_expect 30 {
		    -re "(0x\[0-9a-z]+) - 0x\[0-9a-z\]+ is \\.data" {
			set dataoff $expect_out(1,string);
			exp_continue;
		    }
		    -re "(0x\[0-9a-z\]+) - 0x\[0-9a-z\]+ is \\.bss" {
			set bssoff $expect_out(1,string);
			exp_continue;
		    }
		    -re "$gdb_prompt" { }
		}
		set dataoff [format 0x%x [expr $dataoff + $textoff]];
		set bssoff [format 0x%x [expr $bssoff + $textoff]];
		send_gdb "sect .data $dataoff\n";
		gdb_expect 30 {
		    -re "$gdb_prompt" { }
		}
		send_gdb "sect .bss $bssoff\n";
		gdb_expect 30 {
		    -re "$gdb_prompt" { }
		}
	    }

	    verbose "Loading $farg"
	    if [target_info exists gdb_load_offset] {
		set command "load $farg [target_info gdb_load_offset]\n";
	    } else {
		set command "load $farg\n";
	    }
	    if [target_info exists gdb_load_timeout] {
		set loadtimeout [target_info gdb_load_timeout]
	    } else {
		set loadtimeout 1600
	    }

	    if [is_remote target] {
		set oldremotetimeout [get_remotetimeout]
		set_remotetimeout $loadtimeout
	    }

	    set load_ok 0
	    send_gdb $command;
	    gdb_expect $loadtimeout {
		-re "\[Ff\]ailed.*$gdb_prompt $" {
		    verbose "load failed";
		}
		-re "Timeout reading from remote.*$gdb_prompt" {
		}
		-re "$gdb_prompt $" {
		    verbose "Loaded $farg into $GDB\n"
		    set load_ok 1
		}
		timeout {
		    if { $verbose > 1 } {
			perror "Timed out trying to load $farg."
		    }
		}
	    }

	    if [is_remote target] {
		set_remotetimeout $oldremotetimeout
	    }

	    if { $load_ok == 1 } {
		return 0;
	    }
	}

	# Make sure we don't have an open connection to the target.
	gdb_target_exec;

	if { $j == 1 } {
	    if { ![reboot_target] } {
		break;
	    }
	}
    }
    perror "Couldn't load file into GDB.";
    return -1;
}
