From b9558dcb65612b60a20719ea489dadda4776e1e4 Mon Sep 17 00:00:00 2001 From: Andrew Geissler Date: Thu, 7 Jul 2011 17:11:24 -0500 Subject: HW Procedure Compile Support - New .tcl scripts to be used to do the compiling - New hw procedure function for hw procedure writers to overload for their testing Change-Id: I90af3f4d7aea07f63ec7f52daf224070c944ccee Reviewed-on: http://gfw160.austin.ibm.com:8080/gerrit/190 Tested-by: Jenkins Server Reviewed-by: Douglas R. Gilbert Reviewed-by: MIKE J. JONES --- src/build/hwpf/prcd_compile.tcl | 467 +++++++++++++++++++++ src/build/hwpf/prcd_compile_test | 99 +++++ src/build/hwpf/prcd_server.tcl | 543 +++++++++++++++++++++++++ src/include/usr/hwpf/hwp/fapiTestHwp.H | 12 + src/include/usr/hwpf/plat/fapiPlatHwpInvoker.H | 8 + src/usr/hwpf/hwp/fapiTestHwp.C | 29 ++ src/usr/hwpf/plat/fapiPlatHwpInvoker.C | 38 ++ src/usr/hwpf/test/hwpftest.H | 15 +- 8 files changed, 1210 insertions(+), 1 deletion(-) create mode 100755 src/build/hwpf/prcd_compile.tcl create mode 100755 src/build/hwpf/prcd_compile_test create mode 100755 src/build/hwpf/prcd_server.tcl (limited to 'src') diff --git a/src/build/hwpf/prcd_compile.tcl b/src/build/hwpf/prcd_compile.tcl new file mode 100755 index 000000000..1e8d7a3bd --- /dev/null +++ b/src/build/hwpf/prcd_compile.tcl @@ -0,0 +1,467 @@ +#!/bin/sh +# The next line is executed by /bin/sh, but not tcl \ +exec tclsh "$0" "$@" + +# Name: prcd_compile.tcl - Compile a hardware procedure remotely +# +# Based on if_make.tcl by Doug Gilbert + + +#--------------------------------------------------------- +# TBD - No Support Yet +#--------------------------------------------------------- +proc getPassword { prompt } { + exec stty -echo echonl <@stdin + + # Print the prompt + puts -nonewline stdout $prompt + flush stdout + + # Read that password! :^) + gets stdin password + + # Reset the terminal + exec stty echo -echonl <@stdin + + return $password +} + +#--------------------------------------------------------- +# TBD - No Support Yet +#--------------------------------------------------------- +proc mysend { chan val } { + #puts "Sending>>>$val<<<<" + puts $chan $val +} + +#--------------------------------------------------------- +# TBD - No Support Yet +#--------------------------------------------------------- +proc telnetResult { telnet } { + global telnet_out + #puts "Reading $telnet" + + if { [eof $telnet] || [catch { set dat [read $telnet]}] } { + #puts "GOT>>>AT END<<<" + set telnet_out {AT END} + if { [catch {close $telnet} res] } { + puts "Error: $res" + } + } else { + #puts "GOT>>>$dat<<<<" + append telnet_out $dat + } +} + + +# Wait for p to showup in telnet_out +# return 1 if timout else returns 0 +proc wait_for { p } { + global telnet_out + while { 1 } { + vwait telnet_out + if { [string last $p $telnet_out] > -1 } { return 0 } + if { [string compare {timeout} $telnet_out] == 0 } { return 1 } + } +} + + +#--------------------------------------------------------- +# TBD - No Support Yet +#--------------------------------------------------------- +proc get_fsp_info { fspip fsppassword} { + global telnet_out + set telnet_out {} + + # Open telnet session + if {[catch {set telnet [open "|telnet $fspip" r+]} res]} { + puts "Could not telnet to $fspip" + return {} + } + fconfigure $telnet -buffering none -blocking 0 + + # all output from telnet session captured by telnetResult procedure + # put into telnet_out variable + fileevent $telnet readable [list telnetResult $telnet] + + # Set a timeout of 20 seconds + set timeoutid [after 20000 { + set telnet_out {timeout} + close $telnet + } ] + + if {[wait_for {login:}]} { return {} } + + mysend $telnet {root} + if { [wait_for {Password:}]} { return {} } + + mysend $telnet "$fsppassword" + while { 1 } { + vwait telnet_out + if { [string last {$} $telnet_out] > 0 } { break } + if { [string last {Login incorrect} $telnet_out] > 0 } { + puts {Login incorrect} + close $telnet + return {} + } + if { [string compare $telnet_out {timeout}] == 0 } { return {} } + } + set telnet_out {} + + mysend $telnet {registry -r fstp/DriverName} + if { [wait_for {$}]} { return {} } + + regexp {registry -r fstp/DriverName.+fips[0-9]+/(.+)\n.+} $telnet_out a driver + set telnet_out {} + + mysend $telnet {cat /proc/mounts | grep /nfs} + if { [wait_for {$}]} { return {} } + + regexp {.+\n(.+?):(.+?) +/nfs nfs .+} $telnet_out a companion_ip nfs_dir + + mysend $telnet {exit} + if { [wait_for {AT END}]} { return {} } + + # Cancel the timout + after cancel $timeoutid + + return "$driver:$companion_ip:$nfs_dir" +} + +#--------------------------------------------------------- +# TBD - No Support Yet +#--------------------------------------------------------- +proc start_patch_server_on_fsp { fspip fsppassword } { + global telnet_out + global telnet + global fsp_server_port + set telnet_out {} + # Open telnet session + if {[catch {set telnet [open "|telnet $fspip" r+]} res]} { + puts "Could not telnet to $fspip" + return 0 + } + fconfigure $telnet -buffering none -blocking 0 + + # all output from telnet session captured by telnetResult procedure + # put into telnet_out variable + fileevent $telnet readable [list telnetResult $telnet] + + # Set a timeout of 20 seconds + set timeoutid [after 20000 { + set telnet_out {timeout} + close $telnet + } ] + + if { [wait_for {login:}]} { return 0 } + + mysend $telnet {root} + if { [wait_for {Password:}]} { return 0 } + + mysend $telnet "$fsppassword" + while { 1 } { + vwait telnet_out + if { [string last {$} $telnet_out] > 0 } { break } + if { [string last {Login incorrect} $telnet_out] > 0 } { + puts {Login incorrect} + close $telnet + return 0 + } + if { [string compare $telnet_out {timeout}] == 0 } { return 0 } + } + set telnet_out {} + + mysend $telnet {mkdir -p /nfs/data/engd} + if { [wait_for {$}]} { return 0 } + + set telnet_out {} + mysend $telnet {mkdir -p /nfs/data/rtbl} + if { [wait_for {$}]} { return 0 } + + set telnet_out {} + mysend $telnet {killall cini_patcher} + if { [wait_for {$}]} { return 0 } + + set telnet_out {} + mysend $telnet "cini_patcher &" + if { [wait_for {Server ready}]} { return 0 } + + puts $telnet_out + set telnet_out {} + mysend $telnet {} + if { [wait_for {$}]} { return 0 } + set telnet_out {} + + mysend $telnet {exit} + if { [wait_for {AT END}]} { return 0 } + + # Cancel the timout + after cancel $timeoutid + return 1 +} + +# ------------------------ +# MAIN +# ------------------------ +set userid $::env(USER) +set home $::env(HOME) +set domain [exec hostname -d] +set version "1.0" + +set files [list] +set cmds [list] +set servers [list gfw160.austin.ibm.com] + +#----------------------------------------------------------------------------------------- +# Parse ARGs +#----------------------------------------------------------------------------------------- + +set state flag +foreach arg $argv { + switch -- $state { + flag { + switch -glob -- $arg { + -quit { set cmds [list quit] } + -d { set state driverflag } +# NOT SUPPORTED -s { set state fspflag } +# NOT SUPPORTED -p { set state portflag } + -v { set verbose 1 } + -o { set state outputflag } + -*h* { puts {prcd_compile.tcl [--help] [-d ] [-o ] fapiTestHwp.C fapiTestHwp.H } + puts {} + puts {Note that currently this tool only supports the 2 files listed above as input } + puts {} + puts {example: > prcd_compile.tcl -d b0621a_2001_Sprint2 -o ./output/ fapiTestHwp.C fapiTestHwp.C } + puts {} + puts {On success, 5 files (hbicore.bin and hbicore_test.bin, hbicore.syms } + puts { hbicore_test.syms and hbotStringFile) will be placed in the output dir. } + puts {} + puts {The -d and -o parameters are optional. Default for -d is the master level of code } + puts { and default for -o is the current working directory } + puts {} + puts "Version: $version" + puts {} + exit + } + *fapiTestHwp\.* { lappend files $arg } + default { puts "Unsupported File or Argument: $arg " + exit + } + } + } + driverflag { + #lappend cmds ":DRIVER $arg" + set driver $arg + set state flag + } + fspflag { + foreach {fspip fsp_port} [split $arg :] break + set state flag + } + portflag { + # Set the port the fsp patch server is listening on. + # This is not the telnet port used in simics. + # defaults to 7779 + set fsp_server_port $arg + set state flag + } + outputflag { + set output_dir $arg + set state flag + } + } +} + +if {![info exists fsp_server_port]} { set fsp_server_port 7779 } + +#----------------------------------------------------------------------------------------- +# Get fspip if not specified +#----------------------------------------------------------------------------------------- +# TBD - NOT SUPPORTED +if { ![info exists fspip] && ![info exists driver] } { +# puts -nonewline {Enter telnet address of fsp: } +# flush stdout +# fconfigure stdin -blocking 1 +# foreach {fspip fsp_port} [split [gets stdin] { :}] break +# fconfigure stdin -blockin 0 +# puts { No driver name input! } +# exit +} + +if { [info exists fspip] } { + set fsppassword [getPassword "root password for fsp $fspip:"] + set res [get_fsp_info "$fspip $fsp_port" $fsppassword] + if { $res != "" } { foreach {driver companion_ip nfs_dir} [split $res {:}] break } + + if { [info exists driver]} { + puts "FSP Driver: $driver" + } else { + puts {FSP login failed!} + exit -1 + } + + if { $companion_ip != {} } { + puts "Companion: $companion_ip" + } else { unset companion_ip } + + + if { $nfs_dir != {} } { + puts "nfs_dir: $nfs_dir" + } +} + + +if { ![info exists driver] } { + # default to the master for the driver + set driver "master" +} + +if { ![info exists output_dir] } { + # default to PWD for output + set output_dir "./" +} + +# Make the output directory +eval {exec} "mkdir -p $output_dir" + +lappend cmds ":INFO userid $userid version $version" +lappend cmds ":DRIVER $driver" + + +########################################################## +# Generate command to send each input file +########################################################## +foreach filen $files { + + set file_size [file size $filen] + set filesource($filen) $filen + lappend cmds ":HWP_FILE $filen $file_size" +} + +########################################################## +# Generate compile, retrieve, and complete directives +########################################################## +lappend cmds ":HWP_COMPILE" +lappend cmds ":HWP_RETRIEVE" +lappend cmds ":HWP_DONE" + + +set xfer_file_list {} + +if {[llength $cmds] > 0 } { + set result "" + ########################################################## + # Find a server to run on + ########################################################## + foreach server $servers { + set result "" + puts "Trying $server ..." + if {[catch {set sockid [socket $server 7779] } res ] } { + set result " $res" + puts $result + continue + } else { break } + } + ########################################################## + # Now send all of the commands we generated sequentially + # to the server, waiting for a :DONE between each one. + ########################################################## + # Note that currently we only support fapiTestHwp.C and .H as input + if {$result == ""} { + puts "Connected to $server - Starting Compile" + foreach cmd $cmds { + if {[info exists verbose]} {puts "Send to hw procedure compiler: $cmd"} + if {[string compare $cmd {quit}] == 0 } { + puts $sockid {quit} + break + } elseif {[regexp {^:HWP_FILE +(.+) +(.+)} $cmd a hwpfilename filesize]} { + puts $sockid $cmd + set hwpfile [open $filesource($hwpfilename) r] + fconfigure $sockid -translation binary + fconfigure $hwpfile -translation binary + fcopy $hwpfile $sockid -size $filesize + close $hwpfile + fconfigure $sockid -translation auto + } else { + puts $sockid $cmd + } + flush $sockid + set line "" + while {[string compare $line {:DONE}] != 0} { + if {[eof $sockid]} { break } + gets $sockid line + if {[info exists verbose]} {puts "Received from hw procedure compiler: $line"} + if {[regexp {^:OBJ_FILE +(.+) +(.+)\n*} $line a b c] } { + fconfigure $sockid -translation binary + lappend xfer_file_list $b + set fp [open "$output_dir/$b" w] + fconfigure $fp -translation binary + fcopy $sockid $fp -size $c + close $fp + fconfigure $sockid -translation auto + } elseif {[regexp {.*error:.*} $line ->] } { + puts stderr "Error in compile - $line" + set error 1 + } + } + if {[eof $sockid]} { break } + } + close $sockid + if {[info exists error]} { + puts "Compile Failed! See above errors" + exit -1 + } else { + puts "Compile Complete" + } + } else { + # The server must be down + puts stderr "All The servers seems to be down" + exit -1 + } +} + + +# telnet back to fsp and start patch server +# TBD - Not implemented in this sprint +if {[info exists companion_ip]} { + if {$companion_ip != {}} { + set res [start_patch_server_on_fsp "$fspip $fsp_port" $fsppassword] + if { $res } { + #puts "fspip $fspip" + if {[catch { set sockid [socket $fspip $fsp_server_port] } res ] } { + puts $res + exit -1 + } + # call fspipResult when sockid becomes readable + fileevent $sockid readable [list fspipResult $sockid] + #fconfigure $sockid -buffering line + + # send files + foreach f $xfer_file_list { + #puts "file: $f" + if {[string match {*.if} $f] || [string match {*.dat} $f] } { + set dest_dir {/nfs/data/engd} + } else { + set dest_dir {/nfs/data/rtbl} + } + set filesize [file size $f] + puts $sockid ":PUT $dest_dir/[file tail $f] $filesize" + puts ":FSPPUT $fspip:$dest_dir/[file tail $f] $filesize" + set hwpfile [open $f r] + fconfigure $sockid -translation binary + fconfigure $hwpfile -translation binary + #puts "fcopy $hwpfile $sockid -size $filesize" + fcopy $hwpfile $sockid -size $filesize + close $hwpfile + fconfigure $sockid -translation auto + } + close $sockid + } + } +} + +# should only see data comming back if there were errors. +proc fspipResult { sockid } { + gets $sockid line + puts $line +} diff --git a/src/build/hwpf/prcd_compile_test b/src/build/hwpf/prcd_compile_test new file mode 100755 index 000000000..a1f4abed5 --- /dev/null +++ b/src/build/hwpf/prcd_compile_test @@ -0,0 +1,99 @@ +#!/bin/bash + +#Note that this test case assumes 2 files present in the PWD (along with prcd_compile.tcl) +# - fapiTestHwp.C and fapiTestHwp.H + +#BUILD="b0621a_2001_Sprint2" +BUILD="master" + +############################################################### +# Validate return code, exit on failure +############################################################### +function check_good_rc { + + if [ $1 -eq 0 ]; then + echo SUCCESS + rm -f hbicore* + rm -f hbotStringFile + echo + else + echo FAIL; exit -1 + fi +} + +############################################################### +# Validate return code is non-zero, exit on failure +############################################################### +function check_bad_rc { + + if [ $1 -ne 0 ]; then + echo SUCCESS + echo + else + echo FAIL; exit -1 + fi +} + +############################################################### +# Main +############################################################### + +# Check if the needed files exist, if not try and copy them in +if [ ! -f "./fapiTestHwp.H" ]; then + cp ../../include/usr/hwpf/hwp/fapiTestHwp.H ./ + check_good_rc $? +fi + +if [ ! -f "./fapiTestHwp.C" ]; then + cp ../../usr/hwpf/hwp/fapiTestHwp.C ./ + check_good_rc $? +fi + +echo + +echo "TEST - Good Path - Multi Process" +./prcd_compile.tcl -d $BUILD ./fapiTestHwp.H ./fapiTestHwp.C & +sleep 2 +./prcd_compile.tcl -d $BUILD ./fapiTestHwp.H ./fapiTestHwp.C & +sleep 2 +./prcd_compile.tcl -d $BUILD ./fapiTestHwp.H ./fapiTestHwp.C & +sleep 20 + +echo +echo "TEST - Good Path - 1 C File" +./prcd_compile.tcl -d $BUILD ./fapiTestHwp.C +check_good_rc $? + +echo +echo "TEST - Good Path - 1 H File with -o Param" +./prcd_compile.tcl -d $BUILD -o ./ ./fapiTestHwp.H +check_good_rc $? + +echo +echo "TEST - Good Path - 2 Files" +./prcd_compile.tcl -d $BUILD ./fapiTestHwp.H ./fapiTestHwp.C +check_good_rc $? + +echo +echo "TEST - Good Path - Directory Path and Output Directory" +cp fapiTestHwp.H /tmp/ +mkdir output +./prcd_compile.tcl -d $BUILD -o ./output/ /tmp/fapiTestHwp.H fapiTestHwp.C +check_good_rc $? +rm -rf output +rm /tmp/fapiTestHwp.H + +echo +echo "TEST - Good Path - No Files" +./prcd_compile.tcl -d $BUILD +check_good_rc $? + +echo +echo "TEST - Bad Path - Compile Failure" +rm -f hbicore*; +cp fapiTestHwp.H /tmp/ +echo COMPILE_FAIL >> /tmp/fapiTestHwp.H +./prcd_compile.tcl -d $BUILD /tmp/fapiTestHwp.H fapiTestHwp.C +check_bad_rc $? +rm /tmp/fapiTestHwp.H + diff --git a/src/build/hwpf/prcd_server.tcl b/src/build/hwpf/prcd_server.tcl new file mode 100755 index 000000000..2382872a1 --- /dev/null +++ b/src/build/hwpf/prcd_server.tcl @@ -0,0 +1,543 @@ +# the next line restarts using tclsh\ +exec tclsh "$0" "$@" + + +# Name: prcd_server.tcl - Compile a hardware procedure provided by a client. +# +# Based on if_server.tcl by Doug Gilbert + + +set version "1.0" + +############################################################################ +# Accept is called when a new client request comes in +# An event is forked that calls AquireData whenever the socket becomes +# readable the main thread continues to run looking for more client requests +############################################################################ + +proc Accept { sock addr port} { + + global socklist + global log + puts "[clock format [clock seconds]]: Accept $sock from $addr port $port" + puts $log "$port: [clock format [clock seconds]]: Accept $sock from $addr port $port" + set socklist(addr,$sock) [list $addr $port] + fconfigure $sock -buffering line + fileevent $sock readable [list AquireData $sock] + +} + + +############################################################################ +# AquireData is called whenever there is data avaiable from a client. +# with line buffering on sock, this means when a line is +# Processes commands and collect data from client +############################################################################ + +proc AquireData { sock } { + + global socklist + global sandbox + global forever + global sb_dir + global sbname + global hwpfile + global git_sh + global backing + global log + global running + global driver + + + if { [eof $sock] || [catch {gets $sock line}] } { + puts "Client closed unexpectedly" + puts $log "$sock: Client closed unexpectedly" + CloseOut $sock + } else { + if { [string compare $line "quit"] == 0 } { + close $socklist(main) + puts $sock "hw procedure compiler server is terminating" + puts $log "$sock: hw procedure compiler server is terminating" + CloseOut $sock + set forever 0 + } elseif {[regexp {:DRIVER +(.+)} $line a b] } { + + ################################################################ + # Make a unique sandbox backed to the driver specified + # Do a workon to the sandbox. + ################################################################ + + set driver $b + set release "" + puts $log "$sock: Input driver $driver" + flush $log + + ################################################################ + # create git repository + ################################################################ + + set sbname($sock) "sb[string range [clock seconds] 4 end]" + puts $sock "$sbname($sock)" + puts $log "$sock: $sbname($sock)" + + # Make sure sandbox dir exists + if {[file exists $sb_dir]} { + file mkdir "$sb_dir/$sbname($sock)" + + set git_sh($sock) [open "|bash" r+] + fconfigure $git_sh($sock) -buffering none + fileevent $git_sh($sock) readable [list IfResult $git_sh($sock) $sock $sbname($sock)] + + ExtractSandbox $sock $git_sh($sock) + + } else { + puts $sock "Could not extract code\n" + puts $log "$sock: Could not extract code\n)" + CloseOut $sock + } + } elseif {[regexp {:HWP_FILE +(.+) +(.+)} $line a b c] } { + + ################################################################ + # Open the hw procedure file in the hw procedure directory + ################################################################ + + puts $log "$sock: Input File $b $c" + flush $log + + if { ![info exists sbname($sock)] } { + puts $sock "No sandbox found" + puts $log "$sock: No sandbox found" + CloseOut $sock + return + + } + ################################################################ + # Create the path to the file in the git sandbox + # If it's a .C file it goes to src/usr/hwpf/hwp/ otherwise + # it's a .H and needs to go to src/include/usr/hwpf/hwp/ + # Note that I can't get /* to work correctly in the regexp so I had to + # hard code in the fapi which should be ok, but annoying. + ################################################################ + + if {[regexp {.*/*(fapi.+\.C)} $b -> file] } { + set filen "$sb_dir/$sbname($sock)/src/usr/hwpf/hwp/$file" + } elseif {[regexp {.*/*(fapi.+\.H)} $b -> file] } { + set filen "$sb_dir/$sbname($sock)/src/include/usr/hwpf/hwp/$file" + } else { + puts $sock "Invalid Input File - $b" + puts $log "$sock: Invalid Input File - $b" + CloseOut $sock + return + } + + # Open with create/overwrite option + if {[catch {set hwpfile($sock) [open "$filen" w+] } res ] } { + puts $sock "Server can't open $filen" + puts $log "$sock: Server can't open $filen" + CloseOut $sock + } else { + fconfigure $hwpfile($sock) -translation binary + fconfigure $sock -translation binary + fcopy $sock $hwpfile($sock) -size $c + close $hwpfile($sock) + fconfigure $sock -translation auto + puts $sock ":DONE" + puts $log "$sock: DONE" + flush $sock + } + } elseif {[string compare $line ":HWP_COMPILE"] == 0} { + set git_sh($sock) [open "|bash" r+] + fconfigure $git_sh($sock) -buffering none + fileevent $git_sh($sock) readable [list IfResult $git_sh($sock) $sock $sbname($sock)] + puts $git_sh($sock) "cd $sb_dir/$sbname($sock)" + SendSandbox $sock $git_sh($sock) + puts $sock ":DONE" + puts $log "$sock: DONE" + flush $sock + flush $log + } elseif {[string compare $line ":HWP_RETRIEVE"] == 0} { + SendObjFiles $sock "$sb_dir/$sbname($sock)/img" + puts $sock ":DONE" + puts $log "$sock: DONE" + flush $sock + } elseif {[string compare $line ":HWP_DONE"] == 0} { + puts $sock ":DONE" + puts $log "$sock: DONE" + CloseOut $sock + set line "" + } elseif {[regexp {:INFO +(.+)} $line a b] } { + puts $sock ":DONE" + puts $log "$sock: $b" + flush $sock + flush $log + } else { + # Unrecognized command + # if it's just blank line then skipt it - else report it + if {[string length $line] > 0 } { + puts "Unknown command:$line" + puts $sock "Unknown command: $line" + puts $log "$sock: Unknown command: $line" + } + puts $sock ":DONE" + puts $log "$sock: DONE" + flush $sock + } + + } + +} + +################################################################## +# Clean up and close the socket +################################################################## +proc CloseOut { sock } { + global socklist + global sandbox + global sbname + global sb_dir + global git_sh + global backing + global log + + if {![eof $sock]} { flush $sock } + + puts $log "$sock [clock format [clock seconds]]: Close $socklist(addr,$sock)- " + flush $log + close $sock + puts "[clock format [clock seconds]]: Close $socklist(addr,$sock)- " + unset socklist(addr,$sock) + if {[info exists git_sh($sock)] } { + # Comment out next line to avoid deleting the /tmp/hwp/ sandbox + # eval {exec} "rm -rf $sb_dir/$sbname($sock)" + unset git_sh($sock) + #unset sandbox($sbname($sock)) + } + + if {[info exists sbname($sock)]} { unset sbname($sock) } + if {[info exists backint($sock)]} { unset backing($sock) } + +} + +################################################################## +# Sets up the sandbox with the required code from git +################################################################## +proc ExtractSandbox { sock git_sh} { + global sandbox + global running + global sbname + global sb_dir + global driver + global log + + ############################################################ + # Create GIT repository and extract input driver + # Open a separate pipe which does the extraction and + # compiling + ############################################################ + puts $git_sh "cd $sb_dir/$sbname($sock)" + puts $git_sh {git init} + puts $git_sh {git remote add gerrit ssh://gfw160.austin.ibm.com:29418/hostboot} + puts $git_sh {unlog} + puts $git_sh {git fetch gerrit} + + if {[string compare $driver "master"] == 0} { + puts $log "$sock: Using master branch" + puts $git_sh "git checkout -b master gerrit/master" + } else { + puts $log "$sock: Using $driver branch" + puts $git_sh "git checkout -b $sbname($sock) $driver" + } + + ################################################## + # tell the workon shell to terminate + ################################################## + puts $git_sh {echo :DONE} + flush $git_sh + + ############################################################ + ## if the git_sh is not done by 180 sec, it probably crashed + ## keep a list of running sandboxes + ## hopefully processes timeout in the same order they were started + ## Kick off an event that waits 10 sec then executes + ############################################################ + + lappend running $sbname($sock) + set timoutid [after 10000 { + set sandbox([lindex $running 0]) crashed + lreplace $running 0 0 + } ] + + + ############################################################ + ## This thread now waits until an event changes sandbox($sbname) + ## either the simulator exits or times out + ############################################################ + + vwait sandbox($sbname($sock)) + + ############################################################ + # If the git_sh workon crashed then close the workon shell + # else cancel the timout event + ############################################################ + if { [string compare $sandbox($sbname($sock)) "crashed"] == 0 } { + if { [catch {close $git_sh} res]} { + puts $sock "Failed: $res\n" + puts $log "$sock: Failed: $res\n" + } + set sandbox($sbname($sock)) idle + } else { + after cancel $timoutid + } + flush $sock + flush $log + + ## just a flag to indicate sandbox is being used + set sandbox($sbname($sock)) running + puts $sock ":DONE" + puts $log "$sock: DONE" + flush $sock +} + + +################################################################## +# Sets up the sandbox for the ifcompiler & sends commands +# sets up an event to collect the simulation results +# closes and deletes the sandbox +################################################################## +proc SendSandbox { sock git_sh} { + global sandbox + global running + global sbname + global missing_spies + global log + + # set missing_spies($sock) {} + +################################################################## +# Start Compile +################################################################## + + puts $git_sh "source env.bash; make -j4" + +################################################################## +# tell the workon shell to terminate +################################################################## + + puts $git_sh {echo :DONE} + flush $git_sh + +################################################################## +## if the git_sh is not done by 180 sec, it probably crashed +## keep a list of running sandboxes +## hopefully processes timeout in the same order they were started +## Kick off an event that waits 180 sec then executes +################################################################## + + lappend running $sbname($sock) + set timoutid [after 180000 { + set sandbox([lindex $running 0]) crashed + lreplace $running 0 0 + + } ] + + +################################################################## +## This thread now waits until an event changes sandbox($sbname) +## either the simulator exits or timesout +################################################################## + + vwait sandbox($sbname($sock)) + +################################################################## +# If the git_sh workon crashed then close the workon shell else cancel the +# timout event +################################################################## + + if { [string compare $sandbox($sbname($sock)) "crashed"] == 0 } { + if { [catch {close $git_sh} res]} { + puts $sock "Fail: $res\n" + puts $log "$sock: Fail: $res\n" + } + set sandbox($sbname($sock)) idle + } else { + after cancel $timoutid + } + + flush $sock + flush $log +} + + +################################################################## +# This is a list of regular expressions. Any line sent to stdout during +# mk processing that matches one of these expressions will be sent to the +# client. Note: Everything from stderr gets returned +################################################################## + +set explist [list {ERROR:.*} {^IfScrub..E>.*} {^Parse Error.*} ] + +################################################################## +## This event catches the output of the sandbox when the pipe become readable +## and sends it back to the client. +## The git_sh pipe is closed when the full result has been processed +################################################################## + +proc IfResult { git_sh sock sbname_sock } { + global sandbox + global explist + global log + + if { [eof $git_sh] || [catch {gets $git_sh line}] } { + puts $sock "compile unexpectedly terminated. sandbox $sbname_sock" + puts $log "$sock: compile unexpectedly terminated. sandbox $sbname_sock" + + if { [catch {close $git_sh} res] } { + puts $sock "Error is $res\n" + puts $log "$sock: Error is $res\n" + } + set sandbox($sbname_sock) "idle" + } else { + + # Uncomment to send back all compile output + #puts $sock "$sock $line" + #puts $log "$sock: $line" + + if { [string compare $line ":DONE"] == 0 } { + if { [catch {close $git_sh} res]} { + #res has the stderr + # Need to weed out the junk + set rlines [split $res "\n"] + foreach rline $rlines { + # weed out the errors from mk + if {[regexp {.*error.*} $rline ->] } { + puts $sock "$rline - ERROR" + puts $log "$sock: $rline" + } + } + } + + puts $sock "Exit Sandbox" + puts $log "$sock: Exit Sandbox" + set sandbox($sbname_sock) "idle" + + } else { + foreach exp $explist { + if {[regexp $exp $line a]} { + puts $sock $line + puts $log "$sock: $line" + } + } + } + } +} + + +################################################################## +# send the *.if and *.dat files from the compile back to the client +################################################################## +proc SendObjFiles { sock obj_dir } { + + global log + + set hbi_files {} + + # Send the .bin files + if {[catch {set hbi_files [glob -dir $obj_dir *.bin]} res]} { + puts $sock "ERROR: No *.bin files found in $obj_dir" + puts $log "$sock: ERROR: No *.bin files found in $obj_dir" + } else { + SendFiles $sock $hbi_files + } + + # Now send the .syms files + if {[catch {set hbi_files [glob -dir $obj_dir *.syms]} res]} { + puts $sock "ERROR: No *.syms files found in $obj_dir" + puts $log "$sock: ERROR: No *.syms files found in $obj_dir" + } else { + SendFiles $sock $hbi_files + } + + # Now send the hbotStringFile + if {[catch {set hbi_files [glob -dir $obj_dir hbotStringFile]} res]} { + puts $sock "ERROR: No hbotStringFile files found in $obj_dir" + puts $log "$sock: ERROR: No hbotStringFile files found in $obj_dir" + } else { + SendFiles $sock $hbi_files + } + + flush $sock + flush $log + +} + + +################################################################## +# Send a file to the client +################################################################## +proc SendFiles { sock files } { + global log + + foreach f $files { + set size [file size $f] + puts $sock ":OBJ_FILE [file tail $f] $size" + puts $log "$sock: :OBJ_FILE [file tail $f] $size" + fconfigure $sock -translation binary + set fp [open $f r] + fconfigure $fp -translation binary + fcopy $fp $sock -size $size + close $fp + fconfigure $sock -translation auto + } + flush $log +} + + + +################################################################## +# main +################################################################## +set forever 1 +set logfile {/tmp/prcd_server.log} +set log {} + + +# Where are we running? +foreach {host site c d} [split [exec hostname] .] break +if {[string compare $host {gfw160}] == 0} { + set sb_dir {/tmp/hwp/} + eval {exec} "mkdir -p $sb_dir" +} else { + puts "Invalid Location to run server!" + exit -1 +} + +# array to keep track of ode sandboxes and thier state +array set sandbox { + + sb00000000 idle + +} + +array set backing {} + +puts "Logfile: $logfile" + + +if { [file exists $logfile] } { + set log [open "$logfile" a] +} else { + set log [open "$logfile" w 0666] +} + + +puts "Logfile: $logfile $log" +exec chmod 666 $logfile + +puts "[clock format [clock seconds]]: HWP compiler Server is starting" +puts $log "[clock format [clock seconds]]: HWP compiler Server is starting" +flush $log + +set socklist(main) [socket -server Accept 7779] + +# By catching errors from vwait- we can ignore them +catch {vwait forever} diff --git a/src/include/usr/hwpf/hwp/fapiTestHwp.H b/src/include/usr/hwpf/hwp/fapiTestHwp.H index 5deb60246..4dc5a4dab 100644 --- a/src/include/usr/hwpf/hwp/fapiTestHwp.H +++ b/src/include/usr/hwpf/hwp/fapiTestHwp.H @@ -34,6 +34,18 @@ extern "C" fapi::ReturnCode hwpIsP7EM0ChipletClockOn(const fapi::Target & i_chip, bool & o_clocksOn); +/** + * @brief Run a sample test function that can be overloaded by the hw dev + * team. + * + * @param[in] i_chip Target chip + * + * @return ReturnCode + */ +fapi::ReturnCode hwpInitialTest(const fapi::Target & i_chip); + + + } // extern "C" #endif // FAPITESTHWPROC_H_ diff --git a/src/include/usr/hwpf/plat/fapiPlatHwpInvoker.H b/src/include/usr/hwpf/plat/fapiPlatHwpInvoker.H index 232cb981c..287f97c11 100644 --- a/src/include/usr/hwpf/plat/fapiPlatHwpInvoker.H +++ b/src/include/usr/hwpf/plat/fapiPlatHwpInvoker.H @@ -27,6 +27,14 @@ namespace fapi errlHndl_t invokeHwpIsP7EM0ChipletClockOn(TARGETING::Target* i_target, bool & o_clocksOn); +/** + * @brief Invokes hwpInitialTest procedure + * + * @param[in] i_target Pointer to Chip + */ +errlHndl_t invokeHwpInitialTest(TARGETING::Target* i_target); + + } #endif // FAPIPLATHWPINVOKER_H_ diff --git a/src/usr/hwpf/hwp/fapiTestHwp.C b/src/usr/hwpf/hwp/fapiTestHwp.C index 14292864f..2a7e2fae7 100644 --- a/src/usr/hwpf/hwp/fapiTestHwp.C +++ b/src/usr/hwpf/hwp/fapiTestHwp.C @@ -11,6 +11,7 @@ * mjjones 04/21/2011 Created. * mjjones 06/02/2011 Use ecmdDataBufferBase * mjjones 06/28/2011 Removed attribute tests + * andrewg 07/07/2011 Added test for hw team to fill in * */ @@ -67,4 +68,32 @@ fapi::ReturnCode hwpIsP7EM0ChipletClockOn(const fapi::Target & i_chip, return l_rc; } +//****************************************************************************** +// hwpInitialTest function - Override with whatever you want here +//****************************************************************************** +fapi::ReturnCode hwpInitialTest(const fapi::Target & i_chip) +{ + fapi::ReturnCode l_rc; + + // Figure out the scom address and create a 64 bit data buffer + ecmdDataBufferBase l_data(64); + + const uint64_t l_addr = 0x0201240B; + + // Perform a GetScom operation on the chip + l_rc = GetScom(i_chip, l_addr, l_data); + + if (l_rc != fapi::FAPI_RC_SUCCESS) + { + FAPI_ERR("hwpInitialTest: Error from GetScomChip"); + } + else + { + FAPI_INF("hwpInitialTest: Data from SCOM:0x%X 0x%16X",l_data.getDoubleWord(0)); + + } + + return l_rc; +} + } // extern "C" diff --git a/src/usr/hwpf/plat/fapiPlatHwpInvoker.C b/src/usr/hwpf/plat/fapiPlatHwpInvoker.C index d6d8cbaad..44455a130 100644 --- a/src/usr/hwpf/plat/fapiPlatHwpInvoker.C +++ b/src/usr/hwpf/plat/fapiPlatHwpInvoker.C @@ -81,4 +81,42 @@ errlHndl_t invokeHwpIsP7EM0ChipletClockOn(TARGETING::Target* i_target, return l_err; } +//****************************************************************************** +// invokeHwpInitial function +//****************************************************************************** +errlHndl_t invokeHwpInitialTest(TARGETING::Target* i_target) +{ + + FAPI_DBG(ENTER_MRK "invokeHwpInitialTest"); + + errlHndl_t l_err = NULL; + + // Create a generic Target object + Target l_target(TARGET_TYPE_PROC_CHIP, reinterpret_cast (i_target)); + + //@todo + // Double check to see if any locking is needed here. + // Lower XSCOM already has a mutex lock. + + // Call the HWP executor macro + ReturnCode l_rc; + FAPI_EXEC_HWP(l_rc, hwpInitialTest, l_target); + + if (l_rc != FAPI_RC_SUCCESS) + { + FAPI_ERR("invokeHwpInitialTest: Error (0x%x) from " + "exechwpInitialTest", + static_cast (l_rc)); + l_err = rcToErrl(l_rc); + } + else + { + FAPI_INF("Success in call to exechwpInitialTest"); + } + + FAPI_DBG(EXIT_MRK "invokeHwpInitialTest"); + + return l_err; +} + } // End namespace diff --git a/src/usr/hwpf/test/hwpftest.H b/src/usr/hwpf/test/hwpftest.H index fa9a1c555..2bfd6734d 100644 --- a/src/usr/hwpf/test/hwpftest.H +++ b/src/usr/hwpf/test/hwpftest.H @@ -70,7 +70,7 @@ public: l_err = invokeHwpIsP7EM0ChipletClockOn(l_testTarget, l_clocksOn); if (l_err) { - TS_FAIL("testHwpf2: Unit Test failed. HWP failed. Error logged"); + TS_FAIL("testHwpf2: Unit Test failed. invokeHwpIsP7EM0ChipletClockOn failed. Error logged"); // Commit/delete error errlCommit(l_err); } @@ -86,6 +86,19 @@ public: } } + // Call test procedure too + l_err = invokeHwpInitialTest(l_testTarget); + if (l_err) + { + TS_FAIL("testHwpf2: Unit Test failed. invokeHwpInitialTest failed. Error logged"); + // Commit/delete error + errlCommit(l_err); + } + else + { + TS_TRACE("testHwpf2: Unit test passed! invokeHwpInitialTest"); + } + return; } -- cgit v1.2.1