#   Copyright 1993, 1997-1998, 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/>.

# This file was written by Ian Lance Taylor <ian@cygnus.com>.

# GDB support routines for a board using the MIPS remote debugging
# protocol.  These are actually pretty generic.

# DejaGnu currently assumes that debugging is being done over the main
# console port.  It would probably be more convenient for people using
# IDT boards to permit the debugging port and the connected port to be
# different, since an IDT board has two ports.  This would require
# extending some of the tests in a fashion similar to that done for
# VxWorks, because the test output would appear on the other port,
# rather than being displayed by gdb.

load_lib remote.exp
load_lib gdb.exp
set gdb_prompt "\\(gdb\\)"

#
# gdb_load -- load a file into the GDB. 
#             Returns a 0 if there was an error,
#                       1 if it load successfully.
#
proc gdb_load { arg } {
    global verbose
    global loadpath
    global loadfile
    global gdb_prompt
    global GDB
    global expect_out

    set loadfile [file tail $arg]
    set loadpath [file dirname $arg]

    gdb_file_cmd $arg

    if [target_info exists gdb_protocol] {
	set protocol [target_info gdb_protocol];
    } else {
	set protocol "sparclite"
    }

    if [target_info exists serial] {
	set targetname [target_info serial];
	set command "target $protocol [target_info serial]\n";
    } else {
	if ![target_info exists netport] {
	    perror "Need either netport or gdb_serial entry for [target_info name].";
	    return -1;
	}
	set targetname [target_info netport];
	set command "target $protocol udp [target_info netport]\n";
    }
    set timeout 60
    verbose "Timeout is now $timeout seconds" 2
    set try_count 0;
    send_gdb $command;
    gdb_expect {
	 -re "Unknown response.*resetting the board.|remote timeout" {
	    incr try_count;
	    if { $try_count > 3 } {
		set try_count 0;
		reboot_target;
		sleep 5;
	    }
	    sleep 1;
	    send_gdb $command;
	    exp_continue;
	}
	 -re "Remote target.*$gdb_prompt $" { }
	 -re ".*SPARClite appears to be alive.*$gdb_prompt $"	{
	    if $verbose>1 then {
		send_user "Set target to $targetname\n"
	    }
	}
	 timeout { 
	    perror "Couldn't set SLITE target."
	    set timeout 10
	    verbose "Timeout is now $timeout seconds" 2
	    return -1
	}
    }
    
    if [target_info exists gdb_load_offset] {
	set offset "[target_info gdb_load_offset]";
    } else {
	set offset "";
    }
    if { 1 } {
	if [is_remote host] {
	    set arg [remote_download host $arg];
	    if { $arg == "" } {
		error "download failed"
		return -1;
	    }
	}
	send_gdb "load $arg $offset\n"
	verbose "Loading $arg into $GDB" 2
	set timeout 2400
	verbose "Timeout is now $timeout seconds" 2
	gdb_expect {
	     -re "Loading.*$gdb_prompt $" {
		verbose "Loaded $arg into $GDB" 1
		set timeout 30
		verbose "Timeout is now $timeout seconds" 2
	    }
	     -re "$gdb_prompt $"     {
		if $verbose>1 then {
		    perror "GDB couldn't load."
		}
	    }
	     timeout {
		if $verbose>1 then {
		    perror "Timed out trying to load $arg."
		}
	    }
	}
    }
    # Some SPARClite boards automagically do a run after the program is
    # loaded.
    if [target_info exists need_monitor_run] {
	set timeout 10
	verbose "Timeout is now $timeout seconds, doing monitor run" 2
	send_gdb "monitor run\n";
	sleep 2;
	send_gdb "";
	gdb_expect {
	     -re ".*$gdb_prompt $" { verbose "Run command succeded" }
	     default {
		perror "error sending monitor run command";
	    }
	}
    } else {
	sleep 2;
    }

    if [target_info exists gdb_serial] {
	set serial [target_info gdb_serial];
    } else {
	set serial [target_info serial];
    }
    send_gdb "target remote $serial\n"
    set timeout 60
    verbose "Timeout is now $timeout seconds" 2
    gdb_expect {
	 -re ".*Kill it?.*y or n.*" {
	    send_gdb "y\n";
	    exp_continue
	}
	 -re ".*$gdb_prompt $"	{
	    verbose "Set remote target to [target_info serial]" 2
	}
	 timeout {
	    perror "Couldn't set remote target."
	    set timeout 10
	    verbose "Timeout is now $timeout seconds" 2
	    return -1
	}
    }

    if [info exists expect_out(buffer)] then {
	send_log $expect_out(buffer)
    }
    return 0
}
