#!/bin/sh

#
# This script triggers the ASIC register dump to a buffer. Then the kernel
# buffer is copied to a file.
#
# To-Do:
# * Walk through all blades/minis
# * Look for supporting ASIC

dump_file="/var/regdump.dmp"

if [ $# -lt 1 ]; then
	echo "Syntax: regdump <slot#/mini#/chip#>"
	exit -1
fi

# Does the chip exist?
chip=$1
if [ ! -e /proc/fabos/blade/$chip ]; then
	echo "Chip $chip not in /proc"
	exit -1
fi

# Trigger ASIC register dump
#cmd="db -f $chip dbg dump chip"
cmd="db $chip dbg dump chip"
str=`$cmd`

if [ -z "$str" ]; then
	echo "db command fails: $cmd"
	exit -1
fi

# Extract buffer address and size from string:
#   "kernel addr: 0x68d01000 size: 0x300000"
addr=`echo $str | grep kernel | cut -f3 -d" "`
size=`echo $str | grep kernel | cut -f5 -d" "`

if [ $((addr)) -eq 0 ]; then
	echo "Invalid addr: $addr"
	exit -1
fi

if [ $((size)) -eq 0 ]; then
	echo "Invalid size: $size"
	exit -1
fi

#
# Copy kernel buffer to file
#
page_size_bit=12
page_size=$((1 << page_size_bit))
blocks=$(((size + page_size - 1) / page_size))
offset=$((addr >> page_size_bit))

# Bash 2.4.0 does not support unsigned integer. Need to mask off "sign
# extended" bits for the offset.
mask=$((0x7fffffff >> (page_size_bit - 1)))
offset=$((offset & mask))

dd if=/dev/kmem of=$dump_file count=$blocks bs=$page_size skip=$offset &> /dev/nul

if [ $? -eq 0 ]; then
	echo "ASIC registers dumped to $dump_file for $chip"
else
	echo "Fails to dump ASIC registers"
fi
