Fix shellcheck warnings
[dejagnu.git] / config / vxworks.exp
blobbb9fd16504417c21805632c35a35b39c24ac4317
1 # Copyright (C) 1992-2016 Free Software Foundation, Inc.
3 # This file is part of DejaGnu.
5 # DejaGnu is free software: you can redistribute it and/or modify it
6 # under the terms of the GNU General Public License as published by
7 # the Free Software Foundation, either version 3 of the License, or
8 # (at your option) any later version.
10 # DejaGnu is distributed in the hope that it will be useful, but
11 # WITHOUT ANY WARRANTY; without even the implied warranty of
12 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
13 # General Public License for more details.
15 # You should have received a copy of the GNU General Public License
16 # along with DejaGnu.  If not, see <http://www.gnu.org/licenses/>.
18 # This file was originally written by Rob Savoye <rob@welcomehome.org>
19 # and modified by Bob Manson <manson@cygnus.com>.
22 # Try to boot the machine into the requested OS.
24 proc ${board}_init { dest } {
25     # This is not the right way to determine the required OS...
26     global target_os
27     set shell_prompt [board_info $dest shell_prompt]
28     set do_reboot 0
30     set desired_kernel [board_info $dest "kernel,$target_os"]
32     if { $desired_kernel eq "" } {
33         vxworks_final_init $dest
34         # Nothing to see here, nothing to do. Move along.
35         return
36     }
38     remote_raw_open $dest raw
39     remote_send $dest "\n"
40     remote_expect $dest 5 {
41         -re $shell_prompt {
42             set do_reboot 1
43         }
44         -re "Press any key to stop auto-boot" {
45             remote_send $dest "\n"
46             exp_continue
47         }
48         -re "VxWorks Boot" {
49             set boot_mon 0
50             set boot_mon_prompt "VxWorks Boot"
51         }
52         -re {[0-9][\r\n]+ *[0-9][\r\n]} {
53             remote_send $dest "\n"
54             exp_continue
55         }
56         timeout {
57             set do_reboot 1
58         }
59     }
61     if { $do_reboot } {
62         remote_close $dest
63         remote_reboot $dest
64         return
65     }
66     remote_binary $dest
67     remote_send $dest "\n\n"
68     remote_expect $dest 3 {
69         timeout {}
70         -re ".+" { exp_continue }
71     }
72     remote_send $dest "p\n"
73     remote_expect $dest 20 {
74         -re {file name[ \t]+: ([^ \r\n]+)[ \r\n]+} {
75             set curr_file $expect_out(1,string)
76             exp_continue
77         }
78         -re $boot_mon_prompt { }
79     }
80     if {![info exists curr_file]} {
81         remote_close $dest
82         remote_reboot $dest
83         return
84     }
85     if { $curr_file ne $desired_kernel } {
86         verbose "$curr_file != '$desired_kernel'"
87         # Oh boy.
88         remote_send $dest "c\n"
89         remote_expect $dest 20 {
90             -re {file name[ \t]+:.*$} {
91                 remote_send $dest "$desired_kernel\n"
92                 exp_continue
93             }
94             -re {[a-z() \t]+:.*$} {
95                 remote_send $dest "\n"
96                 exp_continue
97             }
98             -re $boot_mon_prompt {}
99         }
100     }
101     remote_send $dest "@\n"
102     remote_expect $dest 30 {
103         -re "(^|\[\r\n\])$shell_prompt" {}
104         -re ".+" {
105             exp_continue
106         }
107     }
108     vxworks_final_init $dest
109     remote_close $dest
112 proc vxworks_final_init { dest } {
113     if {[board_info $dest exists preload_obj]} {
114         if { [target_compile [board_info $dest preload_obj] foo.out object [board_info $dest preload_obj_flags]] eq "" } {
115             vxworks_ld $dest foo.out
116         }
117         remote_file build delete foo.out
118     }
121 # Execute the command PROGRAM on VxWorks.
124 proc vxworks_exec { dest program pargs inp outp } {
125     global decimal hex
127     set shell_id [vxworks_open $dest]
128     if { $shell_id < 0 } {
129         return [list -1 "open failure"]
130     }
132     if { $inp ne "" } {
133         set inp [remote_download $dest $inp]
134         set suffix " < $inp"
135     } else {
136         set suffix ""
137     }
139     set shell_prompt [board_info $dest shell_prompt]
140     remote_send $dest "$program $pargs$suffix\n"
141     # FIXME: The value 300 below should probably be a parameter passed in.
142     remote_expect $dest 300 {
143         -re {\[VxWorks Boot\]:} {
144             remote_send $dest "@\n"
145             sleep 20
146             exp_continue
147         }
148         -re "(.*)value = (-*$decimal) = $hex\[^\r\n\]*\[\r\n\]+$shell_prompt" {
149             set result [list $expect_out(2,string) $expect_out(1,string)]
150         }
151         -re "undefined symbol: .*$shell_prompt" {
152             set result [list 1 "unknown command"]
153         }
154         -re "syntax error.*$shell_prompt" {
155             set result [list -1 "syntax error in command"]
156         }
157         default {
158             set result [list -1 "unable to execute command"]
159         }
160     }
161     if { $suffix ne "" } {
162         remote_file $dest delete $inp
163     }
164     return $result
167 proc vxworks_download { dest localfile remotefile } {
168     if {[board_info $dest exists vxworks_homedir]} {
169         set rfile "[board_info $dest vxworks_homedir]/$remotefile"
170         remote_download build $localfile $rfile
171         return $rfile
172     }
173     return [remote_raw_download $dest $localfile $remotefile]
176 proc vxworks_file { dest op args } {
177     set file [lindex $args 0]
178     if {[board_info $dest exists vxworks_homedir]} {
179         set dir "[board_info $dest vxworks_homedir]"
180         switch -- $op {
181             exists {
182                 set file "$dir/[file tail $file]"
183                 return [file exists $file]
184             }
185             delete {
186                 foreach x $args {
187                     set x "$dir/[file tail $x]"
188                     if { [file exists $x] && [file isfile $x] } {
189                         file delete -force -- $x
190                     }
191                 }
192                 return {}
193             }
194         }
195     }
196     return [eval remote_raw_file \"$dest\" \"$op\" $args]
199 proc vxworks_send { dest string } {
200     # Convert LFs to CRs, 'cause that is what VxWorks wants to see.
201     regsub -all "\n" $string "\r" string
202     verbose "Sending '$string' to $dest" 2
203     return [remote_raw_send $dest $string]
206 proc vxworks_open { dest args } {
207     if {[board_info $dest exists fileid]} {
208         return [board_info $dest fileid]
209     }
211     set shell_prompt [board_info $dest shell_prompt]
213     set shell_id [remote_raw_open $dest]
215     if { $shell_id eq "" || $shell_id < 0 } {
216         return -1
217     }
219     if {[board_info $dest exists logname]} {
220         set logname [board_info $dest logname]
221         if {[board_info $dest exists password]} {
222             remote_send $dest "iam \"$logname\",\"[board_info $dest passwd]\"\r"
223         } else {
224             remote_send $dest "iam \"$logname\"\r"
225         }
227         remote_expect $dest 30 {
228             "iam*value = 0 = 0x0*$shell_prompt" {
229                 verbose "Set default user." 2
230             }
231             timeout {
232                 perror "Couldn't set default user."
233                 return -1
234             }
235         }
236     }
238     set dir ""
239     if {[board_info $dest exists ftp_directory]} {
240         set dir [board_info $dest ftp_directory]
241     }
242     if {[board_info $dest exists vxworks_homedir]} {
243         set dir [board_info $dest vxworks_homedir]
244     }
245     if { $dir ne "" } {
246         set status [remote_exec $dest "cd" "\"$dir\""]
247         if {[lindex $status 0]} {
248             perror "Error in cd to $dir--[lindex $status 1]"
249             return 1
250         }
251     }
252     return $shell_id
255 # Load a file into vxworks
257 # The result is:
258 #  0 - success
259 #  1 - failed (eg: link failed so testcase should fail)
260 # -1 - unresolved (eg: timeout), may be fixed by rebooting
262 proc vxworks_ld { dest prog } {
263     global decimal hex
264     global board_info
266     if { $prog eq "" } {
267         return 1
268     }
270     set shell_id [remote_open $dest]
272     if { $shell_id < 0 } {
273         return -1
274     }
276     set prog [remote_download $dest $prog]
278     set shell_prompt [board_info $dest shell_prompt]
280     # We always want to exit the program via the code at the end.
281     # If the load fails we want `expect_out' stored in the log and this
282     # saves duplicating that code.
284     for { set x 0 } { $x < 3 } { incr x } {
285         remote_send $dest "\n"
286         remote_expect $dest 30 {
287             -re ".*$shell_prompt $" { set x 20 }
288             -re {\[VxWorks Boot\]:} {
289                 remote_send $dest "@\n"
290                 sleep 20
291                 exp_continue
292             }
293             timeout { return -1 }
294         }
295     }
297     set tries 0
298     set maxtries 3
299     set result -7       ;# -7 is a local value meaning "not done"
301     while { $result == -7 && $tries < $maxtries } {
302         verbose "Loading $prog into vxworks."
303         remote_send $dest "ld < $prog\n"
304         incr tries
305         remote_expect $dest 300 {
306             -re "USER.*command not understood" {
307                 perror "Need to set the user and password."
308                 set result 1
309             }
310             -re "Stale NFS file handle.*$shell_prompt $" {
311                 # Need to retry.
312             }
313             -re "undefined symbol:.*$shell_prompt $" {
314                 # This is an error in the testcase, don't call perror.
315                 warning "Undefined symbol, $prog not loaded."
316                 set result 1
317             }
318             -re "memPartAlloc: block too.*$shell_prompt $" {
319                 perror "Not enough memory to load $prog."
320                 set result -1
321             }
322             -re "can't open input.*$shell_prompt $" {
323                 perror "Can't access $prog."
324                 set result 1
325             }
326             -re "value = (-*$decimal) = $hex.*$shell_prompt $" {
327                 verbose "Loaded $prog into vxworks."
328                 set board_info([board_info $dest name],vx_module) $expect_out(1,string)
329                 set result 0
330             }
331             -re "(.*)$shell_prompt $" {
332                 warning "Load failed: $expect_out(1,string)"
333             }
334             timeout {
335                 warning "Timed out trying load $prog."
336                 set result -1
337             }
338         }
339     }
341     if { $result && [info exists expect_out(buffer)] } {
342         send_log $expect_out(buffer)
343     }
345     remote_file $dest delete $prog
346     return $result
350 # Start a thread (process) executing
352 # The result is:
353 #  0 - success
354 #  1 - failed (eg: testcase aborted)
355 # -1 - unresolved, may be fixed by rebooting
357 proc vxworks_run { dest function pargs inp outp } {
358     global hex decimal
360     set shell_prompt [board_info $dest shell_prompt]
361     set output ""
363     # There isn't a command to wait for a thread to finish, so we have to keep
364     # polling. Instead, we expect the status wrapper to return an exit
365     # status.
367     set status [remote_exec $dest "sp" "$function $pargs" $inp $outp]
369     set tid [lindex $status 0]
371     # Bad task id, reboot and try again.
372     if { $tid == -1 || $tid == 0 } {
373         return -1
374     }
376     set result 1
377     # FIXME: The value 300 below should be a parameter.
378     remote_expect $dest 300 {
379         -re "task $hex - aborted.*$shell_prompt $" {
380             # FIXME: It's not clear we'll ever get here.
381             verbose "$function aborted"
382             set result 1
383         }
384         -re {[\r\n]syntax error[\r\n]} {
385             verbose "weirdness after task started"
386             set result -1
387         }
388         -re "(.*)\\*\\*\\* EXIT code ($decimal)\[\r\n\]" {
389             set output $expect_out(1,string)
390             set exit_code $expect_out(2,string)
391             if { ($exit_code + 0) != 0 } {
392                 set result 1
393             } else {
394                 set result 0
395             }
396         }
397         -re "Operation Fault.*fault type:" {
398             set result 1
399         }
400         -re "Bus Error" {
401             # This is here to try to cope with apparently flaky h/w.
402             # This is potentially an error in the testcase, but we don't
403             # really know, do we?
404             warning "Bus Error."
405             set result 1
406             set output "Bus Error"
407             remote_reboot $dest
408         }
409         timeout {
410             # Infinite loop? probably.
411             remote_exec $dest "td" $tid
412             set result 1
413         }
414     }
416     return [list $result $output]
420 # Unload the last executable that we loaded, so we can free up its memory.
422 proc vxworks_unld { dest } {
423     global board_info
425     if {[board_info $dest exists vx_module]} {
426         # Vxworks5.0 does not have the unld command.
427         if { [board_info $dest os] ne "vxworks5.0" } {
428             remote_exec $dest "unld" "[board_info $dest vx_module]"
429         }
430         unset board_info([board_info $dest name],vx_module)
431     }
435 # We loop around rebooting the box until either the load and run
436 # "work" or we give up.
438 proc vxworks_load {dest prog args} {
439     set result ""
440     set output ""
442     if { [llength $args] > 0 } {
443         set pargs "[lindex $args 0]"
444     } else {
445         set pargs ""
446     }
448     if { [llength $args] > 1 } {
449         set inp "[lindex $args 1]"
450     } else {
451         set inp ""
452     }
454     if { [llength $args] > 2 } {
455         set outp "[lindex $args 2]"
456     } else {
457         set outp ""
458     }
460     for { set x 0 } { $x < 3 } { incr x } {
461         set status [vxworks_ld $dest $prog]
462         if { $status >= 0 } {
463             if { $status > 0 } {
464                 set result "fail"
465             } else {
466                 set out [vxworks_run $dest __wrap_main $pargs $inp $outp]
467                 set status [lindex $out 0]
468                 set output [lindex $out 1]
469                 # Get rid of the carriage returns, because they confuse
470                 # callers that try to parse the result.
471                 regsub -all "\r" $output "" output
472                 if { $status != 0 } {
473                     if { $status > 0 } {
474                         set result "fail"
475                     }
476                 } else {
477                     set result "pass"
478                 }
479             }
480         }
481         if { $result ne "" } {
482             vxworks_unld $dest
483             return [list $result $output]
484         }
485         remote_reboot $dest
486     }
487     return [list "fail" ""]
490 set_board_info protocol "vxworks"
491 # -lm under vxworks isn't needed.
492 set_board_info mathlib ""
493 set_board_info shell_prompt "->"
494 set_board_info needs_status_wrapper 1
495 # FTP doesn't work in passive mode to this board.
496 set_board_info ftp_no_passive 1
497 # Wait 15 seconds after powercycling.
498 set_board_info reboot_delay 15
500 # We don't have sys/unistd.h.
501 set_board_info wrap_compile_flags "-DNO_UNISTD_H"
503 set_board_info gdb_prompt "\[(\]vxgdb\[)\]"
505 set_board_info is_vxworks 1
506 set_board_info gdb,nosignals 1