OpenCores
URL https://opencores.org/ocsvn/or1k/or1k/trunk

Subversion Repositories or1k

[/] [or1k/] [trunk/] [insight/] [dejagnu/] [config/] [vxworks.exp] - Rev 1771

Go to most recent revision | Compare with Previous | Blame | View Log

# Copyright (C) 92, 93, 94, 95, 1996, 1997 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 2 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, write to the Free Software
# Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.  

# Please email any bugs, comments, and/or additions to this file to:
# DejaGnu@cygnus.com

# This file was originally written by Rob Savoye. (rob@cygnus.com)
# 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 == "" } {
        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 != $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]] == "" } {
            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 != "" } {
        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 != "" } {
        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] } {
                        exec rm -f $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 == "" || $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 {
                # ??? This is really an error.  It's not clear whether `perror'
                # or `warning' should be used here.  There are *lots* of other
                # cases like this.
                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 != "" } {
        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 == "" } {
        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] != "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 != "" } {
            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;

Go to most recent revision | Compare with Previous | Blame | View Log

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.