#!/bin/sh

# PROVIDE: cpupdate
# REQUIRE: FILESYSTEMS kldxref
# BEFORE:  netif
# KEYWORD: nojail resume

# Add these lines to /etc/rc.conf.local or /etc/rc.conf
# to enable this service:
#
# cpupdate_enable (bool):		Set to NO by default.
#					Set it to YES to enable cpupdate.
# cpupdate_ibrs_enable (bool):		Enable Indirect Branch Restricted
#					Speculation after start of cpupdate.
#					Default is YES.
# cpupdate_flags (string):		Command line flags for cpupdate.
#					Default is "-w -u".

. /etc/rc.subr

name=cpupdate
rcvar=cpupdate_enable
start_postcmd="cpupdate_poststart"

load_rc_config $name

: ${cpupdate_enable:="NO"}
: ${cpupdate_flags:="-w -u"}
: ${cpupdate_ibrs_enable:="YES"}
: ${cpupdate_fetch:=/usr/bin/fetch -Fpr}
: ${cpupdate_sites:=https://codeload.github.com/intel/Intel-Linux-Processor-Microcode-Data-Files/tar.gz/:intel  https://codeload.github.com/platomav/CPUMicrocodes/tar.gz/7d439dd?dummy=/:cpm}
: ${cpupdate_distfiles:=microcode-20241112:intel platomav-CPUMicrocodes-7d439dd_GH0.tar.gz:cpm}

command=/usr/local/sbin/${name}
download_cmd="cpupdate_download"
resume_cmd="cpupdate_resume"
extra_commands="download resume"

cpupdate_distfile() {
  local _distfile

  setvar $1 ''
  for _distfile in $cpupdate_distfiles
  do
    case $_distfile in
    *:$2) setvar $1 ${_distfile%:*}; return;;
    esac
  done
}

cpupdate_download() {
  local _d _dst _file _tmpdir _url
  local -

  set -e
  : ${TMPDIR:=/var/tmp}
  export TMPDIR
  trap 'rm -rf $_tmpdir' EXIT
  _tmpdir=$(mktemp -d -t ${name})

  for _url in $cpupdate_sites
  do
    case "$_url" in
    *:cpm|*:intel)
      cpupdate_distfile _file ${_url##*:}
      _url=${_url%:*}${_file}
      echo Downloading "$_url"
      $cpupdate_fetch -o - "$_url" | tar -C $_tmpdir -xf - || exit
      ;;
    esac
  done

  echo -n Installing microcodes to /usr/local/share/cpupdate ...
  umask 022
  _dst=/usr/local/share/cpupdate/CPUMicrocodes/primary/Intel
  _d=/construction/sysutils/cpupdate/Intel-Linux-Processor-Microcode-Data-Files-microcode-20241112/intel-ucode
  _d=$_tmpdir/Intel${_d##*/Intel}
  if [ -d $_d ]; then
    rm -rf $_dst || true
    mkdir -p $_dst
    cp -Rp $_d/ $_dst
    [ -d $_d-with-caveats ] && cp -Rp $_d-with-caveats/ $_dst
    chmod -R 644 $_dst
    chown -R root:wheel $_dst
    chmod 755 $_dst
  fi

  _dst=/usr/local/share/cpupdate/CPUMicrocodes/secondary/Intel
  _d=/construction/sysutils/cpupdate/CPUMicrocodes-7d439dd
  _d=$_tmpdir/${_d##*/}/Intel
  if [ -d $_d ]; then
    rm -rf $_d/LICENSE $_dst || true
    mkdir -p $_dst
    /usr/local/sbin/${name} -q -IC -S $_d -T $_dst >/dev/null
  fi
  echo ' done.'
  echo '!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!'
  echo NOTE: you have to manually remove the directory
  echo /usr/local/share/cpupdate
  echo after deinstallation of ${name}.
  echo '!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!'
}

cpupdate_poststart() {
  checkyesno cpupdate_ibrs_enable && sysctl -i hw.ibrs_disable=0
  return 0
}

cpupdate_resume() {
  run_rc_command start
  _postcmd=''
}

run_rc_command "$1"
