1# Test Framework Driver for GDB driving an external simulator
2#   Copyright 1999, 2001 Free Software Foundation, Inc.
3#
4# This program is free software; you can redistribute it and/or modify
5# it under the terms of the GNU General Public License as published by
6# the Free Software Foundation; either version 2 of the License, or
7# (at your option) any later version.
8#
9# This program is distributed in the hope that it will be useful,
10# but WITHOUT ANY WARRANTY; without even the implied warranty of
11# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12# GNU General Public License for more details.
13#
14# You should have received a copy of the GNU General Public License
15# along with this program; if not, write to the Free Software
16# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
17
18load_lib gdb.exp
19
20proc sid_start {} {
21    global verbose
22
23    set port [lindex [split [target_info netport] ":"] 1]
24
25    # Set a default endianness
26    case [target_info multilib_flags] in {
27	{ *big-endian* *-EB* *-meb* } { set sidendian "-EB" }
28	{ *little-endian* *-EL* *-mel* } { set sidendian "-EL" }
29	default {
30	    if {[target_info exists sim,defaultendian]} then {
31		set sidendian [target_info sim,defaultendian]
32	    } else {
33                # rely on endianness settings in sid configuration defaults
34                set sidendian ""
35	    }
36	}
37    }
38    case $sidendian in {
39	{ -EB } { set sidendian2 {-e "set cpu endian big"} }
40	{ -EL } { set sidendian2 {-e "set cpu endian little"} }
41	default { set sidendian2 {} }
42    }
43
44    # test to see whether to use use sid in build or install tree
45    set use_build_tree [file exists ../../sid]
46
47    if {$use_build_tree} then {
48	set pre_spawn {
49	    global env
50	    set env(SID_LIBRARY_PATH) [join [glob "../../sid/component/*"] ":"]
51	    set env(SID) "../../sid/main/dynamic/sid"
52	    if {! [file exists $env(SID)]} then { error "Cannot find sid in build tree" }
53	}
54	if { [board_info target sim,protocol] == "sid" } {
55	    set spawncmd "[target_info sim] [target_info sim,options] $sidendian2 -e \"set cpu-gdb-socket sockaddr-local 0.0.0.0:$port\""
56	} elseif { [board_info target sim,protocol] == "rawsid" } {
57	    set spawncmd "[target_info sim] [target_info sim,options] -$sidendian --gdb=$port"
58	} else {
59	    set spawncmd "../../sid/bsp/[target_info sim] $sidendian --gdb=$port [target_info sim,options]"
60	}
61	set post_spawn {
62	    global env
63	    unset env(SID_LIBRARY_PATH)
64	    unset env(SID)
65	}
66    } else {
67	set pre_spawn {}
68	if { [board_info target sim,protocol] == "sid" } {
69	    # FIXME: sim,options may be from the build tree, should find
70	    # it in the install tree.
71	    set spawncmd "sid [target_info sim,options] $sidendian2 -e \"set cpu-gdb-socket sockaddr-local 0.0.0.0:$port\""
72	} elseif { [board_info target sim,protocol] == "rawsid" } {
73	    set spawncmd "[target_info sim] [target_info sim,options] -$sidendian --gdb=$port"
74	} else {
75	    set spawncmd "[target_info sim] $sidendian --gdb=$port [target_info sim,options]"
76	}
77	set post_spawn {}
78    }
79
80    eval $pre_spawn
81    if {[catch [list remote_spawn host $spawncmd] msg]} {
82	perror $msg
83	exit 1
84    }
85    eval $post_spawn
86
87    # Don't do the following any more; it breaks with "runtest ... < /dev/null"
88#    expect_background {
89#	-re \[^\n\]*\n {
90#	    regsub "\n" $expect_out(buffer) {} msg
91#	    verbose "SID: $msg" 2
92#	}
93#    }
94
95    # There should be no need to sleep to give SID time to start;
96    # GDB would wait for a fair while for the stub to respond.
97    sleep 4
98
99    if ![target_info exists gdb,no_push_conn] {
100        remote_push_conn host;
101    }
102}
103
104#
105# Handle GDB talking to SID
106#
107
108proc gdb_start {} {
109    sid_start
110    return [default_gdb_start]
111}
112
113proc sid_exit {} {
114    if ![target_info exists gdb,no_push_conn] {
115	remote_close host;
116	remote_pop_conn host;
117    }
118}
119
120proc gdb_exit {} {
121    set result [default_gdb_exit]
122    sid_exit
123    return $result
124}
125
126#
127# gdb_target_sid
128# Set gdb to target the simulator
129#
130proc send_target_sid { } {
131    # wait a little while, giving sid time to shut down & restart its
132    # gdb socket
133    sleep 4
134    send_gdb "target [target_info gdb_protocol] [target_info netport]\n"
135}
136
137proc gdb_target_sid { } {
138    global gdb_prompt
139    global exit_status
140
141    send_target_sid
142
143    global timeout
144    set prev_timeout $timeout
145    set timeout 60
146    verbose "Timeout is now $timeout seconds" 2
147    gdb_expect {
148	-re ".*\[Ee\]rror.*$gdb_prompt $" {
149	    perror "Couldn't set target for remote simulator."
150	    cleanup
151	    gdb_exit
152	}
153	-re "Remote debugging using.*$gdb_prompt"	{
154	    verbose "Set target to sid"
155	}
156	timeout {
157	    perror "Couldn't set target for remote simulator."
158	    cleanup
159	    gdb_exit
160	}
161    }
162    set timeout $prev_timeout
163    verbose "Timeout is now $timeout seconds" 2
164}
165
166#
167# gdb_load -- load a file into the debugger.
168#             return a -1 if anything goes wrong.
169#
170proc gdb_load { arg } {
171    global verbose
172    global loadpath
173    global loadfile
174    global GDB
175    global gdb_prompt
176    global retval
177
178    gdb_unload
179    if [gdb_file_cmd $arg] then { return -1 }
180    gdb_target_sid
181
182    send_gdb "load\n"
183    global timeout
184    set prev_timeout $timeout
185    set timeout 2400
186    verbose "Timeout is now $timeout seconds" 2
187    gdb_expect {
188	-re ".*\[Ee\]rror.*$gdb_prompt $" {
189	    if $verbose>1 then {
190		perror "Error during download."
191	    }
192	    set retval -1;
193	}
194	-re ".*$gdb_prompt $" {
195	    if $verbose>1 then {
196		send_user "Loaded $arg into $GDB\n"
197	    }
198	    set retval 1;
199	}
200	-re "$gdb_prompt $"     {
201	    if $verbose>1 then {
202		perror "GDB couldn't load."
203	    }
204	    set retval -1;
205	}
206	timeout {
207	    if $verbose>1 then {
208		perror "Timed out trying to load $arg."
209	    }
210	    set retval -1;
211	}
212    }
213    set timeout $prev_timeout
214    verbose "Timeout is now $timeout seconds" 2
215    return $retval;
216}
217