File microcode.init of Package microcode_ctl

#! /bin/sh
# Copyright (c) 2001-2002 SuSE Linux AG Nuernberg.  All rights reserved.
#
# Author: Björn Jacke <feedback@suse.de>
#
# /etc/init.d/microcode
#
# description: init script for Intel amd AMD CPU microcode update
### BEGIN INIT INFO
# Provides:          microcode
# Required-Start:
# Required-Stop:
# Default-Start:     1 2 3 5
# Default-Stop:
# X-UnitedLinux-Default-Enabled: yes
# Short-Description: CPU microcode updater
# Description:       update the Intel or AMD CPU microcode (both 32 and 64 bit)
### END INIT INFO

. /etc/rc.status

rc_reset

function do_microcode_update()
{
    /sbin/modinfo microcode >& /dev/null
    if [ $? != 0 ];then
	echo -n ".. No microcode module info found"
	# microcode kernel driver not found, did the kernel get upgraded
	# without reboot?
	rc_failed
    elif grep -q -i intel /proc/cpuinfo; then
	# TBD: Shall we keep this check whether
	# /lib/firmware/intel-ucode/$family-$model-$stepping exists to avoid
	# per cpu file not found messages? Otherwise udev firmware loader rule
	# complaints about not found firmware files in /var/log/messages
	#
	TMP=$(grep -m1 "^cpu family" /proc/cpuinfo)
	# Convert cpu family from /proc/cpuinfo from decimal to a 2 digit hex
	cpu_family=$(printf "%02x" ${TMP#cpu family*: })
	TMP=$(grep -m1 "^model" /proc/cpuinfo)
	model=$(printf "%02x" ${TMP#model*: })
	TMP=$(grep -m1 "^stepping" /proc/cpuinfo)
	stepping=$(printf "%02x" ${TMP#stepping*: })
	if [ -e /lib/firmware/intel-ucode/${cpu_family}-${model}-${stepping} ];then
	    rmmod microcode >& /dev/null
	    echo -n ".. upload Intel microcode"
            /sbin/modprobe -q microcode
	else
	    echo -n ".. no microcode available for CPU model"
	fi
    elif grep -q -i AuthenticAMD /proc/cpuinfo; then
	fam=`head /proc/cpuinfo |sed -n -e 's/cpu family.*: \([0-9]\+\)/\1/p'`
	# Only try to update when family >= 16 (0x10, fam 10h)
	if [ $fam -ge 16 >& /dev/null ];then
	    # Loading the driver automatically requests the firmware
	    rmmod microcode >& /dev/null
	    echo -n ".. upload AMD microcode"
	    /sbin/modprobe -q microcode
	else
	    printf ".. unsupported AMD CPU family: 0x%x" $fam
	    # skipped
	    rc_failed 5
	fi
    else
	echo -n ".. unkown CPU"
	# skipped
	rc_failed 5
    fi
    rc_status -v
    rc_exit
}

do_start()
{
    echo -n "Checking CPU"
    HYPER="`lscpu |sed -ne 's/^Hypervisor vendor:     \([:alpha:]*\)/\1/p'`"
    if [ "${HYPER}" = "Xen" ] && [ -r /proc/xen/capabilities ];then
	read -t1 caps < /proc/xen/capabilities
	if [ "$caps" = "${caps%control_d*}" ];then
	    # Xen DomU
	    echo -n ".. ${HYPER} guest detected"
	    rc_failed 6
	else
	    # Xen Dom0
	    echo -n ".. Xen Dom0"
	    do_microcode_update
	fi
    elif [ "${HYPER}" = "KVM" ];then
	echo -n ".. ${HYPER} guest detected"
	rc_failed 6
    else
	do_microcode_update
    fi
    rc_status -v
    rc_exit
}

# See how we were called.
case "$1" in
    start)
        do_start
        ;;
    status)
        echo "$0: reading the microcode status is not yet suported"
        rc_failed 4
        rc_status -v
        ;;
    stop)
        ;;
    reload)
        do_start
        ;;
    *)
        echo "Usage: $0 start"
        exit 1
        ;;
esac
rc_exit


# vim: set sw=4 ts=4 et ft=sh: