#! /bin/bash

#--------------------------------------------------------------------
# File      : arch_info_gen.sh
# Author    : Ghassan Almaless
# Contact   : ghassan.almaless@lip6.fr
# Copyright : UPMC/LIP6
# Version   : 1.2
# Date      : 2010/11/06  (YYYY/MM/DD)
#--------------------------------------------------------------------
# This script is released under the GNU public license version 2
#--------------------------------------------------------------------
# Description : 
# - This script will generate TSAR hardware description 
#   in the Boot Information Block (BIB) format defined by 
#   the Advanced Locality Management Operating System (ALMOS).
#
# - The output of this script is ready to be transformed to BIB 
#   binary layout with info2bib utility.
#
# - 5 arguments can be passed to this script (order is relevant)
#     MEMSZ: per cluster memory size (given in decimal bytes)
#     XMAX: number of clusters in a row
#     YMAX: number of clusters in a column
#     NPROCS: number of CPUs per Cluster
#     BSCPU: bootstrap cpu id (global one) declared as operationnal
#   Default values are (in order) 0xC00000 2 2 4 (io-cid)
#--------------------------------------------------------------------

# XICU Segment Base
XICU_BASE=0xF00000

# MEMC Segment Base
MEMC_BASE=0xF40000

# FrameBuffer size
FB_SIZE=0x200000

# Physical address width
ADDR_WIDTH=32

# Default values
DEFAULT_X_MAX=2
DEFAULT_Y_MAX=2
DEFAULT_CPU_PER_CLUSTER=4
DEFAULT_MEMSZ=0xC00000
#------------------------
MEMSZ=${1-$DEFAULT_MEMSZ}
X_MAX=${2-$DEFAULT_X_MAX}
Y_MAX=${3-$DEFAULT_Y_MAX}
NPROCS=${4-$DEFAULT_CPU_PER_CLUSTER}
#------------------------

print_comments()
{
    date=$(date "+%c")
    echo "# TSAR hardware description in BIB (Boot Information Block) format"
    echo "# This file is autogenerated by the command: $0 $X_MAX $Y_MAX $NPROCS $BSCPU"
    echo "# It is ready to be passed to info2bib utility so the binary format can be generated"
    echo " "
    echo "# $USER on $HOSTNAME $date" 
    echo " "
    echo " "
}

print_header()
{
    echo "[HEADER]"
    echo "        REVISION=1"
    echo "        ARCH=SOCLIB-TSAR"
    echo "        XMAX="$X_MAX
    echo "        YMAX="$Y_MAX
    echo "        CPU_NR="$NPROCS
    echo "        BSCPU="$BSCPU
    echo "        BSTTY=0xBFF20000"
    echo "        BSDMA=0xBFF30000"
    echo " "
    echo " "
}

print_cluster()
{
    offset=$1
    cid=$2
    ram_base=$(printf "0x%x" $offset)
    ram_size=$(printf "0x%x" $MEMSZ)
    xicu_base=$(printf "0x%x" $((offset + $XICU_BASE)))
    memc_base=$(printf "0x%x" $((offset + $MEMC_BASE)))
    
    echo "[CLUSTER]"
    echo "         CID="$cid
    echo "         CPU_NR="$NPROCS
    echo "         DEV_NR=3"
    echo "         DEVID=RAM      BASE=$ram_base     SIZE=$ram_size    IRQ=-1"
    echo "         DEVID=XICU     BASE=$xicu_base     SIZE=0x1000      IRQ=-1"
    echo "         DEVID=MEMC     BASE=$memc_base     SIZE=0x1000      IRQ=-1"
    echo " "
    echo " "

}

print_io_cluster()
{
    offset=$1
    cid=$2
    ram_base=$(printf "0x%x" $offset)
    ram_size=$(printf "0x%x" $MEMSZ)
    xicu_base=$(printf "0x%x" $((offset + $XICU_BASE)))
    memc_base=$(printf "0x%x" $((offset + $MEMC_BASE)))

    echo "[CLUSTER]"
    echo "         CID="$cid
    echo "         CPU_NR="$NPROCS
    echo "         DEV_NR=10"
    echo "         DEVID=RAM      BASE=$ram_base     SIZE=$ram_size  IRQ=-1"
    echo "         DEVID=XICU     BASE=$xicu_base     SIZE=0x1000    IRQ=-1"
    echo "         DEVID=FB       BASE=0xBFD00000     SIZE=$FB_SIZE  IRQ=-1"
    echo "         DEVID=MEMC     BASE=$memc_base     SIZE=0x1000    IRQ=-1"
    echo "         DEVID=BLKDEV   BASE=0xBFF10000     SIZE=0x20      IRQ=0"
    echo "         DEVID=TTY      BASE=0xBFF20000     SIZE=0x10      IRQ=2"
    echo "         DEVID=TTY      BASE=0xBFF20010     SIZE=0x10      IRQ=3"
    echo "         DEVID=TTY      BASE=0xBFF20020     SIZE=0x10      IRQ=4"
    echo "         DEVID=TTY      BASE=0xBFF20030     SIZE=0x10      IRQ=5"
    echo "         DEVID=DMA      BASE=0xBFF30000     SIZE=0x14      IRQ=1"
    echo " "
    echo " "
}

# Derive X_WIDTH form X_MAX
case $X_MAX in
    2)      X_WIDTH=1
	;;
    
    [3-4])  X_WIDTH=2
	;;

    [5-8])  X_WIDTH=3
	;;

    *)      X_WIDTH=4
	;;
esac

# Derive Y_WIDTH form Y_MAX
case $Y_MAX in
    2)      Y_WIDTH=1
	;;
    
    [3-4])  Y_WIDTH=2
	;;

    [5-8])  Y_WIDTH=3
	;;

    *)      Y_WIDTH=4
	;;
esac

x=0; y=0
io_cid=$((0xbf >> (8 - X_WIDTH - Y_WIDTH)))
BSCPU=${5-$(($io_cid * $NPROCS))}

# Generate the description
print_comments "$0"
print_header

while test $x -lt $X_MAX
do
    while test $y -lt $Y_MAX
    do
	cid=$((x * Y_MAX + y))  
	offset=$(( cid  << (ADDR_WIDTH - X_WIDTH - Y_WIDTH)))
		
	if [ $cid -eq $io_cid ]
	then
	    print_io_cluster $offset $cid
	else
	    print_cluster $offset $cid
	fi

	y=$((y + 1))
    done
    
    y=0; x=$((x + 1))
done 

#-------------------------------------------------------------------------#
#                                End of script                            #
#-------------------------------------------------------------------------#