#! /bin/bash

#--------------------------------------------------------------------
# File      : gen_arch_info_large.sh
#--------------------------------------------------------------------

NB_TTY=4
TTY_CHANNEL_SIZE=0x10
TTY_SIZE=0x1000

DMA_SIZE=0x1000
XICU_SIZE=0x1000
BDEV_SIZE=0x1000
# FrameBuffer size
#FB_SIZE=0x80000
FB_SIZE=0x200000

MEMC_TGTID=0
XICU_TGTID=1
MDMA_TGTID=2
MTTY_TGTID=3
BDEV_TGTID=4
MNIC_TGTID=5
BROM_TGTID=6
CDMA_TGTID=7
SIMH_TGTID=8
FBUF_TGTID=9


# Physical address width
ADDR_WIDTH=32

# Default values
DEFAULT_X_MAX=8
DEFAULT_Y_MAX=8
DEFAULT_CPU_PER_CLUSTER=4

function mymin()
{
   if test $1 -lt $2 ; then
      echo "$1"
   else
      echo "$2"
   fi
}

#------------------------

X_MAX=${1-$DEFAULT_X_MAX}
Y_MAX=${2-$DEFAULT_Y_MAX}
NPROCS=$DEFAULT_CPU_PER_CLUSTER

#------------------------
CLUSTER_INC=$((0x80000000 / (X_MAX * Y_MAX) * 2))
MAX_MEMC_SIZE=$((0x40000000 / (X_MAX * Y_MAX)))
size=$(mymin $MAX_MEMC_SIZE $((0x04000000)))
MEMC_SIZE=$(printf "0x%X" $size)


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=$BSTTY"
    echo "        BSDMA=$BSDMA"
    echo " "
    echo " "
}

print_cluster()
{
    offset=$1
    cid=$2
    memc_base=$(printf "0x%X" $offset)
    memc_size=$(printf "0x%X" $MEMC_SIZE)
    xicu_base=$(printf "0x%X" $((offset + (CLUSTER_INC / 2) + (XICU_TGTID << 19))))
    dma_base=$(printf "0x%X" $((offset  + (CLUSTER_INC / 2) + (MDMA_TGTID << 19))))
    
    echo "[CLUSTER]"
    echo "         CID="$cid
    echo "         CPU_NR="$NPROCS
    echo "         DEV_NR=3"
    echo "         DEVID=RAM       BASE=$memc_base         SIZE=$memc_size     IRQ=-1"
    echo "         DEVID=XICU      BASE=$xicu_base         SIZE=$DMA_SIZE         IRQ=-1"
    echo "         DEVID=DMA       BASE=$dma_base         SIZE=$XICU_SIZE         IRQ=8"
    echo " "
    echo " "
}

print_io_cluster()
{
    offset=$1
    cid=$2
    memc_base=$(printf "0x%X" $offset)
    memc_size=$(printf "0x%X" $MEMC_SIZE)
    xicu_base=$(printf "0x%X" $((offset + (CLUSTER_INC / 2) + (XICU_TGTID << 19))))
    dma_base=$(printf "0x%X" $((offset  + (CLUSTER_INC / 2) + (MDMA_TGTID << 19))))
    bdev_base=$(printf "0x%X" $((offset + (CLUSTER_INC / 2) + (BDEV_TGTID << 19))))
    tty_base=$(printf "0x%X" $((offset  + (CLUSTER_INC / 2) + (MTTY_TGTID << 19))))
    fbf_base=$(printf "0x%X" $((offset  + (CLUSTER_INC / 2) + (FBUF_TGTID << 19))))

    echo "[CLUSTER]"
    echo "         CID="$cid
    echo "         CPU_NR="$NPROCS
    echo "         DEV_NR=9"
    echo "         DEVID=RAM       BASE=$memc_base         SIZE=$memc_size     IRQ=-1"
    echo "         DEVID=XICU      BASE=$xicu_base         SIZE=$XICU_SIZE         IRQ=-1"
    echo "         DEVID=DMA       BASE=$dma_base         SIZE=$DMA_SIZE         IRQ=8"
    echo "         DEVID=BLKDEV    BASE=$bdev_base         SIZE=$BDEV_SIZE         IRQ=31"
    ntty=0
    irq=16
    while test $ntty -lt $NB_TTY
    do
       tty_base_i=$(printf "0x%X" $((tty_base + ntty * TTY_CHANNEL_SIZE)))
       echo "         DEVID=TTY       BASE=$tty_base_i         SIZE=$TTY_CHANNEL_SIZE           IRQ=$irq"
       irq=$((irq + 1))
       ntty=$((ntty + 1))
    done
    echo "         DEVID=FB        BASE=$fbf_base         SIZE=$FB_SIZE        IRQ=-1"
    echo " "
    echo " "
}

# Derive X_WIDTH form X_MAX
case $X_MAX in
    1)      X_WIDTH=0
   ;;

    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
    1)      Y_WIDTH=0
   ;;


    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=$(($io_cid * $NPROCS))

break_loop=0
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
         BSDMA=$(printf "0x%X" $((offset  + (CLUSTER_INC / 2) + (MDMA_TGTID << 19))))
         BSTTY=$(printf "0x%X" $((offset  + (CLUSTER_INC / 2) + (MTTY_TGTID << 19))))
         break_loop=1
         break
      else
         BSDMA="error"
      fi

      y=$((y + 1))
   done
   if test $break_loop -eq 1 ; then
      break
   fi
   y=0
   x=$((x + 1))
done

# Generate the description
print_comments "$0"
print_header

x=0; y=0
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                            #
#-------------------------------------------------------------------------#
