Initial commit of OpenSPARC T2 architecture model.
[OpenSPARC-T2-SAM] / sam-t2 / sam / cpus / vonk / ss / api / sam / src / simulate
#!/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 <processor>] [-c <config>] [-w <workers>] [-s|-r|-d|-R <chkpnt>] [-f <cmd_file> ...] [-a][-v] [-C <system>] [-L <image>] ..."
echo " "
echo " -p <processor> : Create sam.rc file and run sam on processor <processor>"
echo " -c <config> : Configuration: config is say 1up, 1g2p, 1g4p, 1g8p, 1g16p, or 1g32p, etc"
echo " -w <workers> : Number of worker threads, default is 1"
echo " -s : Boot Solaris"
echo " -d : Run diag"
echo " -R <chkpnt> : Restore from checkpoint <chkpnt>"
echo " -f <cmd_file> : Pass -f <cmd_file> 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 <system> : Include rc file <system> in the setup."
echo " -C <system> : Provide user version of system part of rc file (for advanced users)"
echo " -L <image> : Load <image> into memory. Image can be file,addr for binary or file for image format"
echo " -D <define> : Add m4 style define to control the rc file"
echo " -l <log_file> : Turn on sam output logging to file <log_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 $?