# Test Framework Driver for GDB driving a ROM monitor (via monitor.c).
#   Copyright 1995-2013 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;
}
