#!/bin/sh
# /usr/sbin/dphys-kernel-cputype - determine what cpu type this host is
# author Neil Franklin, last modification 2006.10.20
# update Gurkan Sengun, dual core cpu detection (SMP) 2007.03.07
# copyright ETH Zuerich Physics Departement,
#   use under either modified/non-advertising BSD or GPL license

set -e

# get ready to work
PATH=/sbin:/bin:/usr/sbin:/usr/bin
export PATH


# --- processor type

MODEL_NAME="`cat /proc/cpuinfo | grep '^model name' | \
    cut -f 2 -d ':' | cut -f 2- -d ' '`"

if   ( echo "${MODEL_NAME}" | grep "Opteron" > /dev/null ) ; then
  # we can not generate kernels for k8 yet, as no config analysis
  CPU_TYPE=k8
elif ( echo "${MODEL_NAME}" | grep "Athlon.*64" > /dev/null ) ; then
  # we can not generate kernels for k8 yet, as no config analysis
  CPU_TYPE=k8
elif ( echo "${MODEL_NAME}" | grep "Duron" > /dev/null ) ; then
  CPU_TYPE=k7
elif ( echo "${MODEL_NAME}" | grep "Sempron" > /dev/null ) ; then
  CPU_TYPE=k7
elif ( echo "${MODEL_NAME}" | grep "Athlon" > /dev/null ) ; then
  CPU_TYPE=k7
elif ( echo "${MODEL_NAME}" | grep "Xeon" > /dev/null) ; then
  # this test will also trigger on PIII Xeon, we have none to test difference
  CPU_TYPE=p4
elif ( echo "${MODEL_NAME}" | grep "Celeron" > /dev/null) ; then
  # this test will also trigger on PIII Celeron, we have none to test diff
  CPU_TYPE=p4
elif ( echo "${MODEL_NAME}" | grep "Pentium.* 4 " > /dev/null) ; then
  CPU_TYPE=p4
elif ( echo "${MODEL_NAME}" | grep "Pentium.* III " > /dev/null) ; then
  CPU_TYPE=p3
elif ( echo "${MODEL_NAME}" | grep "Pentium.* II " > /dev/null) ; then
  # not tested as we have none, fallback to PI, as no config analysis for PII
  CPU_TYPE=p1
elif ( echo "${MODEL_NAME}" | grep "Pentium" > /dev/null) ; then
  CPU_TYPE=p1
else
  echo "$0: ERROR: unknown CPU model name: ${MODEL_NAME}" >&2
  # error output for script using this to screw up on
  echo "unknown_cpu_model_report_this"
  exit 1
fi


# --- SMP option

# this fails, if only non-smp kernel running, such as universal install kernel
#   then even smp machines appear as non-smp, as rest not used and not listed
#LAST_CPU="`cat /proc/cpuinfo | grep ^processor | tail -1 | \
#    cut -f 2 -d ':' | cut -f 2 -d ' '`"

#if [ "${LAST_CPU}" = "0" ] ; then
#  SMP_OPT=""
#else
#  SMP_OPT="-smp"
#fi


# so use external lshw to detect this
if ! which lshw > /dev/null ; then
  echo "$0: FATAL: failed to find lshw, can not work, aborting ..." >&2
fi

# get rid of unnecessary tests as lshw is called twice for each of 7 packages
SPEEDUP="-disable spd -disable cpuid -disable pci -disable isapnp \
    -disable pcmcia -disable ide -disable usb -disable scsi -disable network"

# simply count *-cpu[:n] lines
#   no "" around ${SPEEDUP}, lshw can not handle the result
CPUS="`lshw ${SPEEDUP} -class processor 2>/dev/null | \
    grep '^ *\*-cpu' | wc -l | tr -d ' '`"

if [ "${CPUS}" = "1" ] ; then
  SMP_OPT=""
else
  SMP_OPT="-smp"
fi

cat /proc/cpuinfo | grep ^"model name" | grep -i dual > /dev/null &&
  SMP_OPT="-smp"


# --- memory size

# this also fails when small memory install kernel is running
#MEMORY_MB="`free -m | grep '^Mem:' | awk '{print $2}'`"

# so also use external lshw to detect this
# find  size:  line of first (and hopefully main) *-memory section
#   'head' because some machines have an 2nd memory section for flash
MEMORY="`lshw ${SPEEDUP} -class memory 2>/dev/null | \
    sed -ne '/ *\*-memory/,/ *\*-/{ /.*size: /s/.*size: //p }' | head -n 1`"

if [ "${MEMORY}" = "" ] ; then
  # on some machines  *-memory  section delivers no  size:  line
  #   fall back to  capacity:  but standard use  size:  is more reliable value
  #     actually  capacity:  seems to be maximal memory that can be plugged in
  #   better would be to sum up  size:  from all banks, but that is difficult
  MEMORY="`lshw ${SPEEDUP} -class memory 2>/dev/null | \
      sed -ne '/ *\*-memory/,/ *\*-/{ /.*capacity: /s/.*capacity: //p }'| \
      head -n 1`"
fi

# standardise on MB, convert GB to MB
if [ "`echo "${MEMORY}" | tr -d '[0-9]'`" = GB ] ; then
  MEMORY_GB="`echo "${MEMORY}" | tr -d '[A-Z]'`"
  MEMORY_MB="`expr "${MEMORY_GB}" '*' 1024`"
else
  MEMORY_MB="`echo "${MEMORY}" | tr -d '[A-Z]'`"
fi

if   [ "${MEMORY_MB}" -gt 3500 ] ; then
  MEM_TYPE="-64gb"
elif [ "${MEMORY_MB}" -gt 880 ] ; then
  MEM_TYPE="-4gb"
else
  MEM_TYPE="-1gb"
fi


# --- output

# this should be the only output generated
echo "${CPU_TYPE}${SMP_OPT}${MEM_TYPE}"

exit 0
