aboutsummaryrefslogtreecommitdiff
path: root/config/vxworks.exp
blob: b49a3f6c80b9468e8536a0d41555d72f48f6a610 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
# Copyright (C) 1992-2016 Free Software Foundation, Inc.
#
# This file is part of DejaGnu.
#
# DejaGnu 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.
#
# DejaGnu 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 DejaGnu; if not, write to the Free Software Foundation,
# Inc., 51 Franklin Street - Fifth Floor, Boston, MA 02110-1301, USA.

# This file was originally written by Rob Savoye <rob@welcomehome.org>
# and modified by Bob Manson <manson@cygnus.com>.

#
# Try to boot the machine into the requested OS.
#
proc ${board}_init { dest } {
    # This is not the right way to determine the required OS...
    global target_os
    set shell_prompt [board_info $dest shell_prompt]
    set do_reboot 0

    set desired_kernel [board_info $dest "kernel,$target_os"]

    if { $desired_kernel eq "" } {
	vxworks_final_init $dest
	# Nothing to see here, nothing to do. Move along.
	return
    }

    remote_raw_open $dest raw
    remote_send $dest "\n"
    remote_expect $dest 5 {
	-re $shell_prompt {
	    set do_reboot 1
	}
	-re "Press any key to stop auto-boot" {
	    remote_send $dest "\n"
	    exp_continue
	}
	-re "VxWorks Boot" {
	    set boot_mon 0
	    set boot_mon_prompt "VxWorks Boot"
	}
	-re {[0-9][\r\n]+ *[0-9][\r\n]} {
	    remote_send $dest "\n"
	    exp_continue
	}
	timeout {
	    set do_reboot 1
	}
    }

    if { $do_reboot } {
	remote_close $dest
	remote_reboot $dest
	return
    }
    remote_binary $dest
    remote_send $dest "\n\n"
    remote_expect $dest 3 {
	timeout {}
	-re ".+" { exp_continue }
    }
    remote_send $dest "p\n"
    remote_expect $dest 20 {
	-re {file name[ \t]+: ([^ \r\n]+)[ \r\n]+} {
	    set curr_file $expect_out(1,string)
	    exp_continue
	}
	-re $boot_mon_prompt { }
    }
    if {![info exists curr_file]} {
	remote_close $dest
	remote_reboot $dest
	return
    }
    if { $curr_file ne $desired_kernel } {
	verbose "$curr_file != '$desired_kernel'"
	# Oh boy.
	remote_send $dest "c\n"
	remote_expect $dest 20 {
	    -re {file name[ \t]+:.*$} {
		remote_send $dest "$desired_kernel\n"
		exp_continue
	    }
	    -re {[a-z() \t]+:.*$} {
		remote_send $dest "\n"
		exp_continue
	    }
	    -re $boot_mon_prompt {}
	}
    }
    remote_send $dest "@\n"
    remote_expect $dest 30 {
	-re "(^|\[\r\n\])$shell_prompt" {}
	-re ".+" {
	    exp_continue
	}
    }
    vxworks_final_init $dest
    remote_close $dest
}

proc vxworks_final_init { dest } {
    if {[board_info $dest exists preload_obj]} {
	if { [target_compile [board_info $dest preload_obj] foo.out object [board_info $dest preload_obj_flags]] eq "" } {
	    vxworks_ld $dest foo.out
	}
	remote_file build delete foo.out
    }
}
#
# Execute the command PROGRAM on VxWorks.
#

proc vxworks_exec { dest program pargs inp outp } {
    global decimal hex

    set shell_id [vxworks_open $dest]
    if { $shell_id < 0 } {
	return [list -1 "open failure"]
    }

    if { $inp ne "" } {
	set inp [remote_download $dest $inp]
	set suffix " < $inp"
    } else {
	set suffix ""
    }

    set shell_prompt [board_info $dest shell_prompt]
    remote_send $dest "$program $pargs$suffix\n"
    # FIXME: The value 300 below should probably be a parameter passed in.
    remote_expect $dest 300 {
	-re {\[VxWorks Boot\]:} {
	    remote_send $dest "@\n"
	    sleep 20
	    exp_continue
	}
	-re "(.*)value = (-*$decimal) = $hex\[^\r\n\]*\[\r\n\]+$shell_prompt" {
	    set result [list $expect_out(2,string) $expect_out(1,string)]
	}
	-re "undefined symbol: .*$shell_prompt" {
	    set result [list 1 "unknown command"]
	}
	-re "syntax error.*$shell_prompt" {
	    set result [list -1 "syntax error in command"]
	}
	default {
	    set result [list -1 "unable to execute command"]
	}
    }
    if { $suffix ne "" } {
	remote_file $dest delete $inp
    }
    return $result
}

proc vxworks_download { dest localfile remotefile } {
    if {[board_info $dest exists vxworks_homedir]} {
	set rfile "[board_info $dest vxworks_homedir]/$remotefile"
	remote_download build $localfile $rfile
	return $rfile
    }
    return [remote_raw_download $dest $localfile $remotefile]
}

proc vxworks_file { dest op args } {
    set file [lindex $args 0]
    if {[board_info $dest exists vxworks_homedir]} {
	set dir "[board_info $dest vxworks_homedir]"
	switch -- $op {
	    exists {
		set file "$dir/[file tail $file]"
		return [file exists $file]
	    }
	    delete {
		foreach x $args {
		    set x "$dir/[file tail $x]"
		    if { [file exists $x] && [file isfile $x] } {
			file delete -force -- $x
		    }
		}
		return {}
	    }
	}
    }
    return [eval remote_raw_file \"$dest\" \"$op\" $args]
}

proc vxworks_send { dest string } {
    # Convert LFs to CRs, 'cause that is what VxWorks wants to see.
    regsub -all "\n" $string "\r" string
    verbose "Sending '$string' to $dest" 2
    return [remote_raw_send $dest $string]
}

proc vxworks_open { dest args } {
    if {[board_info $dest exists fileid]} {
	return [board_info $dest fileid]
    }

    set shell_prompt [board_info $dest shell_prompt]

    set shell_id [remote_raw_open $dest]

    if { $shell_id eq "" || $shell_id < 0 } {
	return -1
    }

    if {[board_info $dest exists logname]} {
	set logname [board_info $dest logname]
	if {[board_info $dest exists password]} {
	    remote_send $dest "iam \"$logname\",\"[board_info $dest passwd]\"\r"
	} else {
	    remote_send $dest "iam \"$logname\"\r"
	}

	remote_expect $dest 30 {
	    "iam*value = 0 = 0x0*$shell_prompt" {
		verbose "Set default user." 2
	    }
	    timeout {
		perror "Couldn't set default user."
		return -1
	    }
	}
    }

    set dir ""
    if {[board_info $dest exists ftp_directory]} {
	set dir [board_info $dest ftp_directory]
    }
    if {[board_info $dest exists vxworks_homedir]} {
	set dir [board_info $dest vxworks_homedir]
    }
    if { $dir ne "" } {
	set status [remote_exec $dest "cd" "\"$dir\""]
	if {[lindex $status 0]} {
	    perror "Error in cd to $dir--[lindex $status 1]"
	    return 1
	}
    }
    return $shell_id
}
#
# Load a file into vxworks
#
# The result is:
#  0 - success
#  1 - failed (eg: link failed so testcase should fail)
# -1 - unresolved (eg: timeout), may be fixed by rebooting
#
proc vxworks_ld { dest prog } {
    global decimal hex
    global board_info

    if { $prog eq "" } {
	return 1
    }

    set shell_id [remote_open $dest]

    if { $shell_id < 0 } {
	return -1
    }

    set prog [remote_download $dest $prog]

    set shell_prompt [board_info $dest shell_prompt]

    # We always want to exit the program via the code at the end.
    # If the load fails we want `expect_out' stored in the log and this
    # saves duplicating that code.

    for { set x 0 } { $x < 3 } { incr x } {
	remote_send $dest "\n"
	remote_expect $dest 30 {
	    -re ".*$shell_prompt $" { set x 20 }
	    -re {\[VxWorks Boot\]:} {
		remote_send $dest "@\n"
		sleep 20
		exp_continue
	    }
	    timeout { return -1 }
	}
    }

    set tries 0
    set maxtries 3
    set result -7	;# -7 is a local value meaning "not done"

    while { $result == -7 && $tries < $maxtries } {
	verbose "Loading $prog into vxworks."
	remote_send $dest "ld < $prog\n"
	incr tries
	remote_expect $dest 300 {
	    -re "USER.*command not understood" {
		perror "Need to set the user and password."
		set result 1
	    }
	    -re "Stale NFS file handle.*$shell_prompt $" {
		# Need to retry.
	    }
	    -re "undefined symbol:.*$shell_prompt $" {
		# This is an error in the testcase, don't call perror.
		warning "Undefined symbol, $prog not loaded."
		set result 1
	    }
	    -re "memPartAlloc: block too.*$shell_prompt $" {
		perror "Not enough memory to load $prog."
		set result -1
	    }
	    -re "can't open input.*$shell_prompt $" {
		perror "Can't access $prog."
		set result 1
	    }
	    -re "value = (-*$decimal) = $hex.*$shell_prompt $" {
		verbose "Loaded $prog into vxworks."
		set board_info([board_info $dest name],vx_module) $expect_out(1,string)
		set result 0
	    }
	    -re "(.*)$shell_prompt $" {
		warning "Load failed: $expect_out(1,string)"
	    }
	    timeout {
		warning "Timed out trying load $prog."
		set result -1
	    }
	}
    }

    if { $result && [info exists expect_out(buffer)] } {
	send_log $expect_out(buffer)
    }

    remote_file $dest delete $prog
    return $result
}

#
# Start a thread (process) executing
#
# The result is:
#  0 - success
#  1 - failed (eg: testcase aborted)
# -1 - unresolved, may be fixed by rebooting
#
proc vxworks_run { dest function pargs inp outp } {
    global hex decimal

    set shell_prompt [board_info $dest shell_prompt]
    set output ""

    # There isn't a command to wait for a thread to finish, so we have to keep
    # polling. Instead, we expect the status wrapper to return an exit
    # status.

    set status [remote_exec $dest "sp" "$function $pargs" $inp $outp]

    set tid [lindex $status 0]

    # Bad task id, reboot and try again.
    if { $tid == -1 || $tid == 0 } {
	return -1
    }

    set result 1
    # FIXME: The value 300 below should be a parameter.
    remote_expect $dest 300 {
	-re "task $hex - aborted.*$shell_prompt $" {
	    # FIXME: It's not clear we'll ever get here.
	    verbose "$function aborted"
	    set result 1
	}
	-re {[\r\n]syntax error[\r\n]} {
	    verbose "weirdness after task started"
	    set result -1
	}
	-re "(.*)\\*\\*\\* EXIT code ($decimal)\[\r\n\]" {
	    set output $expect_out(1,string)
	    set exit_code $expect_out(2,string)
	    if { ($exit_code + 0) != 0 } {
		set result 1
	    } else {
		set result 0
	    }
	}
	-re "Operation Fault.*fault type:" {
	    set result 1
	}
	-re "Bus Error" {
	    # This is here to try to cope with apparently flaky h/w.
	    # This is potentially an error in the testcase, but we don't
	    # really know, do we?
	    warning "Bus Error."
	    set result 1
	    set output "Bus Error"
	    remote_reboot $dest
	}
	timeout {
	    # Infinite loop? probably.
	    remote_exec $dest "td" $tid
	    set result 1
	}
    }

    return [list $result $output]
}

#
# Unload the last executable that we loaded, so we can free up its memory.
#
proc vxworks_unld { dest } {
    global board_info

    if {[board_info $dest exists vx_module]} {
	# Vxworks5.0 does not have the unld command.
	if { [board_info $dest os] ne "vxworks5.0" } {
	    remote_exec $dest "unld" "[board_info $dest vx_module]"
	}
	unset board_info([board_info $dest name],vx_module)
    }
}

#
# We loop around rebooting the box until either the load and run
# "work" or we give up.
#
proc vxworks_load {dest prog args} {
    set result ""
    set output ""

    if { [llength $args] > 0 } {
	set pargs "[lindex $args 0]"
    } else {
	set pargs ""
    }

    if { [llength $args] > 1 } {
	set inp "[lindex $args 1]"
    } else {
	set inp ""
    }

    if { [llength $args] > 2 } {
	set outp "[lindex $args 2]"
    } else {
	set outp ""
    }

    for { set x 0 } { $x < 3 } { incr x } {
	set status [vxworks_ld $dest $prog]
	if { $status >= 0 } {
	    if { $status > 0 } {
		set result "fail"
	    } else {
		set out [vxworks_run $dest __wrap_main $pargs $inp $outp]
		set status [lindex $out 0]
		set output [lindex $out 1]
		# Get rid of the carriage returns, because they confuse
		# callers that try to parse the result.
		regsub -all "\r" $output "" output
		if { $status != 0 } {
		    if { $status > 0 } {
			set result "fail"
		    }
		} else {
		    set result "pass"
		}
	    }
	}
	if { $result ne "" } {
	    vxworks_unld $dest
	    return [list $result $output]
	}
	remote_reboot $dest
    }
    return [list "fail" ""]
}

set_board_info protocol "vxworks"
# -lm under vxworks isn't needed.
set_board_info mathlib ""
set_board_info shell_prompt "->"
set_board_info needs_status_wrapper 1
# FTP doesn't work in passive mode to this board.
set_board_info ftp_no_passive 1
# Wait 15 seconds after powercycling.
set_board_info reboot_delay 15

# We don't have sys/unistd.h.
set_board_info wrap_compile_flags "-DNO_UNISTD_H"

set_board_info gdb_prompt "\[(\]vxgdb\[)\]"

set_board_info is_vxworks 1
set_board_info gdb,nosignals 1