#!/bin/bash

LANG=C
LC_ALL=
DATAMB=${1:-512}
FILENM=~/test.dat
[ -f /flash/config.txt ] && CONFIG=/flash/config.txt || CONFIG=/boot/config.txt

trap "rm -f ${FILENM}" EXIT

[ "$(whoami)" == "root" ] || { echo "Must be run as root!"; exit 1; }

HDCMD="hdparm -t --direct /dev/mmcblk0 | grep Timing"
WRCMD="rm -f ${FILENM} && sync && dd if=/dev/zero of=${FILENM} bs=1M count=${DATAMB} conv=fsync 2>&1 | grep -v records"
RDCMD="echo 3 > /proc/sys/vm/drop_caches && sync && dd if=${FILENM} of=/dev/null bs=1M 2>&1 | grep -v records"
#grep OpenELEC /etc/os-release >/dev/null && DDTIME=5 || DDTIME=6
DDTIME=8

getperfmbs()
{
  local cmd="${1}" fcount="${2}" ftime="${3}" bormb="${4}"
  local result count _time perf

  result="$(eval "${cmd}")"
  count="$(echo "${result}" | awk "{print \$${fcount}}")"
  _time="$(echo "${result}" | awk "{print \$${ftime}}")"
  if [ "${bormb}" == "MB" ]; then
    perf="$(echo "${count}" "${_time}" | awk '{printf("%0.2f", $1/$2)}')"
  else
    perf="$(echo "${count}" "${_time}" | awk '{printf("%0.2f", $1/$2/1024/1024)}')"
  fi
  echo "${perf}"
  echo "${result}" >&2
}

getavgmbs()
{
  echo "${1} ${2} ${3}" | awk '{r=($1 + $2 + $3)/3.0; printf("%0.2f MB/s",r)}'
}

systemctl stop kodi 2>/dev/null
#clear
sync

[ -f /sys/kernel/debug/mmc0/ios ] || mount -t debugfs none /sys/kernel/debug

gethwinfo()
{
  conf_core_freq="$(grep -E "^core_freq" ${CONFIG})"
  conf_sd_overclock="$(grep -E "^dtoverlay|^dtparam" ${CONFIG} | grep -E "mmc|sdhost|sd_overclock")"
  conf=("${conf_core_freq}" "${conf_sd_overclock}")
  for idx in "${!conf[@]}"; do [ -z "${conf[$idx]}" ] && unset -v 'conf[$idx]'; done
  [ -z "${conf[*]}" ] && conf=("default")

  clock_sdbus="$(grep "actual clock" /sys/kernel/debug/mmc0/ios 2>/dev/null | awk '{printf("%0.3f MHz", $3/1000000)}')"
  clock_arm="$(vcgencmd measure_clock arm | awk -F= '{printf("%0.3f MHz", $2/1000000)}')"
  clock_sdram="$(vcgencmd get_config int | grep sdram_freq | awk -F= '{print $2}')"
  soc_temp="$(cat /sys/class/thermal/thermal_zone0/temp | awk '{printf("%0.3f ℃", $1/1000)}')"
  volt_core="$(vcgencmd measure_volts core | awk -F= '{print $2}')"
  volt_sdram_c="$(vcgencmd measure_volts sdram_c | awk -F= '{print $2}')"
  volt_sdram_i="$(vcgencmd measure_volts sdram_i | awk -F= '{print $2}')"
  volt_sdram_p="$(vcgencmd measure_volts sdram_p | awk -F= '{print $2}')"
  core_now="$(vcgencmd measure_clock core | awk -F= '{print $2/1000000}')"
  core_max="$(vcgencmd get_config int | grep core_freq | awk -F= '{print $2}')"
  turbo="$(vcgencmd get_config int | grep force_turbo | awk -F= '{print $2}')"
  [ -n "${turbo}"    ] || turbo=0
  [ ${turbo} -eq 0 ]   && turbo="$(cat /sys/devices/system/cpu/cpufreq/ondemand/io_is_busy)"
  [ -n "${core_max}" ] || core_max="${core_now}"
}

gethwinfo
echo
echo "CONFIG: $(IFS=","; echo "${conf[*]}")"
echo "CLOCK : SD Bus: ${clock_sdbus}, CPU: ${clock_arm}, CPU Temp: ${soc_temp}, SDRAM: ${clock_sdram} MHz"
echo "VOLTS : core: ${volt_core}, sdram(controller, I/O, physical): ${volt_sdram_c}, ${volt_sdram_i}, ${volt_sdram_p}"
echo "CORE  : ${core_max} MHz(${core_now} MHz), turbo=${turbo}"
echo "DATA  : ${DATAMB} MB, ${FILENM}"
echo

echo "HDPARM:"
echo "======"
HD1="$(getperfmbs "${HDCMD}" 5 8 MB)"
HD2="$(getperfmbs "${HDCMD}" 5 8 MB)"
HD3="$(getperfmbs "${HDCMD}" 5 8 MB)"
HDA="$(getavgmbs "${HD1}" "${HD2}" "${HD3}")"

echo
echo "WRITE:"
echo "====="
WR1="$(getperfmbs "${WRCMD}" 1 ${DDTIME} B)"
WR2="$(getperfmbs "${WRCMD}" 1 ${DDTIME} B)"
WR3="$(getperfmbs "${WRCMD}" 1 ${DDTIME} B)"
WRA="$(getavgmbs "${WR1}" "${WR2}" "${WR3}")"

echo
echo "READ:"
echo "===="
RD1="$(getperfmbs "${RDCMD}" 1 ${DDTIME} B)"
RD2="$(getperfmbs "${RDCMD}" 1 ${DDTIME} B)"
RD3="$(getperfmbs "${RDCMD}" 1 ${DDTIME} B)"
RDA="$(getavgmbs "${RD1}" "${RD2}" "${RD3}")"

gethwinfo
echo
echo "RESULT (AVG):"
echo "============"
printf "%9s %7s %12s %11s %11s %13s\n" "core_freq" "turbo" "sd clock" "WRITE" "READ" "HDPARM"
printf "   %d        %d     %11s   %10s   %10s   %10s\n" "${core_max}" "${turbo}" "${clock_sdbus}" "${WRA}" "${RDA}" "${HDA}"

echo
echo "microSD card benchmark complete!"
echo "CPU Temp: ${soc_temp}"
echo
