#!/bin/ksh # Each time the API changes we bump version by one simulate_version="1" command_line="$0 $@" tool=$0 usage() { echo "" echo "usage: `/bin/basename $tool` [-p ] [-c ] [-w ] [-s|-r|-d|-R ] [-f ...] [-a][-v] [-C ] [-L ] ..." echo " " echo " -p : Create sam.rc file and run sam on processor " echo " -c : Configuration: config is say 1up, 1g2p, 1g4p, 1g8p, 1g16p, or 1g32p, etc" echo " -w : Number of worker threads, default is 1" echo " -s : Boot Solaris" echo " -d : Run diag" echo " -R : Restore from checkpoint " echo " -f : Pass -f to sam" echo " -a : Auto boot OBP (Solaris boot only): expects nvram1-auto file" echo " -v : Boot solaris in verbose mode (more printfs to console): expects disk1.verbose" echo " -I : Include rc file in the setup." echo " -C : Provide user version of system part of rc file (for advanced users)" echo " -L : Load into memory. Image can be file,addr for binary or file for image format" echo " -D : Add m4 style define to control the rc file" echo " -l : Turn on sam output logging to file " echo "" } err_usage () { echo "Error: $1" usage exit 2 } err () { echo "Error: $1" exit 2 } len () { echo $# } head () { echo $1 } tail () { shift echo $* } # reserse returns the reverse of the argument list reverse () { xs=$* rs="" while [ "$xs" != "" ]; do hd=$(head $xs) xs=$(tail $xs) rs="$hd $rs" done echo "$rs" } # nibble2list(base,nibble) takes a hex nibble and returns # a list of set bits. The bit numbers reported start from base. nibble2list() { base=$1 bit0=$(($base + 0)) bit1=$(($base + 1)) bit2=$(($base + 2)) bit3=$(($base + 3)) case $2 in 0) list="" ;; 1) list="$bit0" ;; 2) list="$bit1" ;; 3) list="$bit0 $bit1" ;; 4) list="$bit2" ;; 5) list="$bit0 $bit2" ;; 6) list="$bit1 $bit2" ;; 7) list="$bit0 $bit1 $bit2" ;; 8) list="$bit3" ;; 9) list="$bit0 $bit3" ;; a|A) list="$bit1 $bit3" ;; b|B) list="$bit0 $bit1 $bit3" ;; c|C) list="$bit2 $bit3" ;; d|D) list="$bit0 $bit2 $bit3" ;; e|E) list="$bit1 $bit2 $bit3" ;; f|F) list="$bit0 $bit1 $bit2 $bit3" ;; default) list="" ;; esac echo "$list" } # bitset(mask) takes a hex value mask (no 0x prefix) and converts # it into a list of set bits. # First it turns mask into a list of nibbles: 12af => "1 2 a f ". # Then it reverses the list of nibbles so nibble 0 (bit 0) is first. # Next it turns the nibbles into bit lists and joins them. bitset () { xs=$(echo "$1" | /bin/sed -e 's/_//g' | /bin/sed -e 's/\(.\)/\1 /g') xs=$(reverse $xs) bs="" bv=0 while [ "$xs" != "" ]; do hd=$(head $xs) xs=$(tail $xs) bs="$bs $(nibble2list $bv $hd)" bv=$(($bv + 4)) done echo "$bs" } # Check we are on a USIII or above machine isa=$(/bin/isalist | /usr/xpg4/bin/grep -e 'sparcv9+vis2' -e 'amd64') if [ "$isa" = "" ]; then err "need isa sparcv9+vis2 or above or amd64" fi # In case of softlink follow the softlink back to the real binary. # If people copy the binary out of the release then tough, don't do that. sam=$0 sambin=$(/bin/dirname $sam) samexe=$(/bin/ls -l $sam | /bin/awk '{print $11}') while [ "$samexe" != "" ]; do sam=$samexe sambin=$(/bin/dirname $sam) samexe=$(/bin/ls -l $sam | /bin/awk '{print $11}') done # Do a quick sanity check on the sambin location if [ ! -x $sambin/sam ]; then err "$0 is not a link to proper release of SAM" fi # Look for .simulate.sh script to feed info to wizard . # .simulate.sh is part of the set of binaries that is # obtained with getsolaris. [ -r .simulate.sh ] && . ./.simulate.sh default_processor=${processor:-} default_boot=${boot:-} processor="" boot="" defines=${defines:-} loadextra=${loadextra:-} includes=${includes:-} require=${require:-20070101} rcfile="" workers="1" restore="" auto=/bin/false verbose=/bin/false virtual=${virtual:-/bin/true} # false when scsi boot disk ... disk1="" config="" python=/bin/false log_file="" # The simulate wizard protects itself from having to be # compatible with future releases of solaris. # This next line should compare $require against D A T E (w/o spaces) # and not a actual timestamp. The timestamp will be inserted during # the build/installation process. if (($require > 20080105)); then err "Use simulate that has been build or released after $require" fi # Parse the commandline options while getopts p:c:w:srdf:avR:C:L:I:D:Yl: OPT; do case $OPT in p) if [ "$processor" != "" ]; then err "I'm confused, you already specified -p$processor" fi processor="$OPTARG" ;; c) config="$config $OPTARG" ;; w) workers="$OPTARG" validint=$(echo $workers | /bin/tr -d '[0-9]*') if [ ! -z $validint ]; then err "$workers is not an integer: -w requires an integer argument" fi ;; f) cmd_files="$cmd_files -f $OPTARG" ;; a) auto=/bin/true ;; v) verbose=/bin/true ;; s) if [ "$boot" != "" ]; then err "I'm confused, you already specified $boot" fi boot="solaris" ;; d) if [ "$boot" != "" ]; then err "I'm confused, you already specified $boot" fi boot="diag" ;; L) loadextra="$loadextra $OPTARG" ;; C) rcfile="$rcfile $OPTARG" ;; R) if [ "$boot" != "" ]; then err "I'm confused, you already specified $boot" fi boot="restore" restore="$OPTARG" ;; D) defines="$defines -D$OPTARG" ;; I) includes="$includes $OPTARG" ;; Y) python=/bin/true ;; l) if [ "$log_file" != "" ]; then echo "Error: I'm confused, you already specified $log_file" exit 2 fi log_file="-l $OPTARG" ;; h) usage exit 0 ;; *) usage exit 2 ;; esac done shift $(($OPTIND - 1)) # Policy for solaris is that we need .simulate.sh # For restore and diag modes we don't require it. if [ ! -r .simulate.sh ]; then case $boot in solaris) err "Cannot find .simulate.sh. Refresh your workarea with getsolaris." ;; esac fi # Check .simulate.sh again and exits if not there # and we're not doing diag work case $boot in solaris) if [ ! -f .simulate.sh ]; then echo "Error: the file .simulate.sh is missing" echo "" echo "Please refresh your workarea with getsolaris" exit 2 fi ;; esac # Make sure we have a processor to work with. Take into # account the default we get from the .simulate.sh if [ "$processor" = "" ]; then processor=$default_processor fi if [ "$processor" = "" ]; then err_usage "I need exactly one -p argument." fi if [ "$processor" != "$default_processor" -a "$default_processor" != "" ]; then err_usage "Default processor $default_processor and user specified processor $processor are conflicting." fi # Now check that the selected processor is actually # supported and part of the package used if [ ! -r $sambin/../lib/libriesling_${processor}_vcpu.so ]; then err "Processor '$processor' is not supported in the SAM package you use" fi # Check for existing system part rc file if [ "$rcfile" = "" ]; then rcfile=$sambin/../etc/${processor}.rc fi if [ ! -r $rcfile ]; then err "Can not find user defined system rc file: '$rcfile'" fi # When not restoring if [ "$restore" = "" ]; then # Check boot option if [ "$boot" = "" ]; then boot=$default_boot fi if [ "$boot" = "" ]; then err_usage "Expect -s, -r, -d, or -R option." fi if [ "$boot" != "$default_boot" -a "$default_boot" != "" ]; then err_usage "Default boot $default_boot and user specified boot $boot are conflicting." fi # Check config option if [ "$(len $config)" != "1" ]; then err_usage "I need exactly one -c argument." fi config=$(echo $config) fi # Any remaining arguments are passed to the python interpreter arg=$* if [ "$arg" != "" ]; then arg="-- $arg" fi # Check that the configurarion is valid for the processor # Each processor has it's own set of recognized configs and # they are kept in $SAM/etc/${processor}/cfg . strand_mask=$(/bin/grep "^$config" $sambin/../etc/${processor}.cfg | /bin/awk '{print $2}') if [ "$strand_mask" = "" ]; then if [ "$restore" = "" ]; then err_usage "Configuration -c $config unknown" fi fi /bin/rm -f sam.rc generate_strands () { bs=$(bitset $1) while [ "$bs" != "" ]; do nr=$(head $bs) bs=$(tail $bs) echo "sysconf cpu name=s$nr id=$nr cpu-type=riesling_${processor}_vcpu clock-frequency=ifdef(\`STICK_FREQ',STICK_FREQ,0x400000)" done } # node_defs(strands_per_node,strand_mask) creates a list of # defines -DNODE1 -DNODE2 ... one for each node that is required. node_defs () { max_strands=$1 bs=$(bitset $2) node=1 defs="-DNODE1" while [ "$bs" != "" ]; do nr=$(head $bs) bs=$(tail $bs) if [ $nr -ge $max_strands ] ; then max_strands=$(($max_strands + $1)) node=$(($node + 1)) defs="$defs -DNODE$node" fi done echo $defs } if [ "$restore" = "" ]; then # For solaris we have nvram that handles autoboot # Alse select the main image to boot: solaris. case $boot in solaris) defines="-DSOLARIS $defines" md_bin=${config}-md.bin hv_bin=${config}-hv.bin if $auto ; then nvram1="nvram1-auto" else nvram1="nvram1" fi if $virtual ; then if $verbose ; then disk1="disk1.verbose" else disk1="disk1.img" fi fi if [ "$processor" = "xx" ]; then sram="sram" else sram="" fi files="reset.bin q.bin openboot.bin $sram $hv_bin $md_bin $nvram1 $image" ;; diag) defines="-DDIAG $defines" ;; esac # Do some legwork to make sure we have no missing files for f in $files ; do if [ ! -r $f ]; then err "Error: missing file: $f" fi done for f in $includes ; do if [ ! -r $f ]; then err "Error: missing include file: $f" fi done if [ "$loadextra" != "" ]; then for f in $loadextra ; do name=${f%,*} if [ ! -r $name ]; then err "Error: missing file: $name" fi done fi # Generate the defines to enable multi node parts in rc files case $processor in n2) strands_per_node=64 ;; esac defines="$defines $(node_defs $strands_per_node $strand_mask)" case $processor in n2) stickfreq=1417000000 ;; *) stickfreq=12500000 ;; esac # Generate the sam.rc file ( echo "# sam.rc generated by: $command_line" echo "" echo "conf ramsize 1M" # Need this ?!? echo "conf stickfreq ifdef(\`STICK_FREQ',STICK_FREQ,$stickfreq)" echo "conf mips 1000" echo "conf numthreads $workers" echo "" generate_strands $strand_mask echo "" cat $rcfile echo "" case $boot in solaris) echo "load bin reset.bin BASE_RESET_BIN" echo "load bin q.bin BASE_Q_BIN" echo "load bin openboot.bin BASE_OPENBOOT_BIN" echo "load bin $nvram1 BASE_NVRAM1" echo "load bin $md_bin BASE_MD_BIN" echo "load bin $hv_bin BASE_HV_BIN" if $virtual ; then echo "load bin $disk1 BASE_DISK1" fi ;; esac # Generate the extra files to load: we accept name,addr # as binary. If addr is blank: name, or if the comma is # not present then load name as an image. if [ "$loadextra" != "" ]; then for f in $loadextra ; do name=${f%,*} addr=${f##*,} if [ "$f" = "$addr" -o "$addr" = "" ]; then echo "load image $name" else echo "load bin $name $addr" fi done fi # Now include all the user defined rc files extensions # in the order given on the command line for f in $includes ; do cat $f done # Generate the rc-file entries for our frontend # If a file ${config}.py exists then we will assume that that # file contains tweaks to make the particulare config work proper. ) \ | /usr/ccs/bin/m4 $defines > sam.rc else ( # Grab the dumped rc file cat $restore/rc.dmp # Now include all the user defined rc files extensions # in the order given on the command line for f in $includes ; do cat $f done ) \ | /usr/ccs/bin/m4 $defines > sam.rc restore="-R $restore" fi $PFEPRE $sambin/sam $restore -c sam.rc $cmd_files $log_file -py $arg exit $?