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

# 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

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
}
