xref: /illumos-gate/usr/src/data/ucode/update.intel (revision a4955f4fa65e38d70c07d38e657a9aff43fa155f)
1#!/bin/ksh
2
3# This file and its contents are supplied under the terms of the
4# Common Development and Distribution License ("CDDL"), version 1.0.
5# You may only use this file in accordance with the terms of version
6# 1.0 of the CDDL.
7#
8# A full copy of the text of the CDDL should have accompanied this
9# source. A copy of the CDDL is also available via the Internet at
10# http://www.illumos.org/license/CDDL.
11
12# Copyright 2022 OmniOS Community Edition (OmniOSce) Association.
13# Copyright 2019 Joyent, Inc.
14
15# A simple update script that extracts an Intel microcode download file
16# into the intel/ directory, and updates the hardlinks in the
17# system/kernel/platform manifest.
18
19function errexit {
20	echo "$@" >&2
21	exit 1
22}
23
24[[ -n "$1" && -f "$1" ]] || errexit "Syntax: $0 <path to microcode tar>"
25
26ucodetar="$1"
27
28FW=platform/i86pc/ucode/GenuineIntel
29LINKSF=intel/Makefile.links
30
31export LC_ALL=C.UTF-8
32
33set -e
34set -o pipefail
35
36mf=../../pkg/manifests/system-microcode-intel.p5m
37[[ -f $mf ]] || errexit "Run from usr/src/data/ucode"
38
39function find_cmd {
40	typeset cmd="$1"
41	typeset var=$(echo $cmd | tr '[:lower:]' '[:upper:]')
42	typeset -n path="$var"
43	path=$(whence -fp "$cmd")
44	if (($? != 0)) || [ ! -x "$path" ]; then
45		errexit "Cannot find executable '$cmd' in PATH"
46	fi
47}
48
49# This script uses a few commands which are not part of illumos and are
50# expected to be available in the path.
51find_cmd gtar
52find_cmd pkgfmt
53# Search for 'ucodeadm'. If you need to use an updated ucodeadm to handle this
54# firmware update, as is occasionally necessary, ensure it occurs earlier in
55# the path than /usr/sbin.
56find_cmd ucodeadm
57
58tmp=$(mktemp -d)
59[[ -n "$tmp" && -d "$tmp" ]]
60mkdir $tmp/out || errexit "Failed to create temporary directory"
61trap 'rm -rf $tmp' EXIT
62
63# The distributed microcode archive uses GNU extensions
64$GTAR -C $tmp -xvf "$ucodetar"
65
66path=$({ cd $tmp; echo Intel-Linux-Processor-Microcode-Data*; })
67ver=${path##*-}
68echo "** Updating to microcode version $ver"
69
70find $tmp/$path/intel-ucode*/ -type f | while read f; do
71	echo "Converting $(basename $f)"
72	cp $f $tmp/intel-fw
73	$UCODEADM -i -R $tmp/out $tmp/intel-fw
74	rm -f $tmp/intel-fw
75done
76
77$PKGFMT -u $mf
78mv $mf $mf.tmp
79egrep -v "(file|hardlink) path=$FW" $mf.tmp > $mf
80rm -f $mf.tmp
81
82rm -f intel/*-*
83
84cp $tmp/$path/license intel/THIRDPARTYLICENSE
85echo Intel Processor Microcode Data Files > intel/THIRDPARTYLICENSE.descrip
86
87rm -f $LINKSF
88
89typeset -A seen
90typeset -A inodes
91typeset -A links
92
93for f in $tmp/out/*; do
94	bf=$(basename $f)
95	[[ -n "${seen[$bf]}" ]] && continue
96	inode=$(stat -c %i $f)
97	if [[ -n "${inodes[$inode]}" ]]; then
98		links[$bf]=${inodes[$inode]}
99	else
100		inodes[$inode]=$bf
101		cp $f intel/$bf
102	fi
103	seen[$bf]=1
104done
105
106for f in intel/*; do
107	bf=$(basename $f)
108	[[ $bf = THIRDPARTYLICENSE* ]] && continue
109	[[ $bf = Makefile* ]] && continue
110	echo "file path=$FW/$bf group=sys mode=0444 reboot-needed=true" >> $mf
111done
112
113(
114	sed '/^$/q' < ../../prototypes/prototype.Makefile
115	echo 'INTEL_LINKS = \'
116	for i in "${!links[@]}"; do
117		echo "\t$i \\"
118	done | sed '$s/ .*//'
119	echo
120) > $LINKSF
121
122for i in "${!links[@]}"; do
123	echo "hardlink path=$FW/$i target=${links[$i]}" >> $mf
124	cat << EOM >> $LINKSF
125\$(ROOTINTELDIR)/$i: \$(ROOTINTELDIR)/${links[$i]}
126	\$(RM) \$@; \$(LN) \$^ \$@
127
128EOM
129done
130
131sed -i "/pkg.fmri.*microcode\/intel@/s/@[0-9]*/@$ver/" $mf
132
133$PKGFMT -fv2 $mf
134
135