summaryrefslogtreecommitdiff
path: root/usr/src/data/ucode/update.intel
blob: 65898e419042ba8f5626c7861f73307c69138315 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
#!/bin/ksh

# This file and its contents are supplied under the terms of the
# Common Development and Distribution License ("CDDL"), version 1.0.
# You may only use this file in accordance with the terms of version
# 1.0 of the CDDL.
#
# A full copy of the text of the CDDL should have accompanied this
# source. A copy of the CDDL is also available via the Internet at
# http://www.illumos.org/license/CDDL.

# Copyright 2022 OmniOS Community Edition (OmniOSce) Association.
# Copyright 2019 Joyent, Inc.

# A simple update script that extracts an Intel microcode download file
# into the intel/ directory, and updates the hardlinks in the
# system/kernel/platform manifest.

function errexit {
	echo "$@" >&2
	exit 1
}

[[ -n "$1" && -f "$1" ]] || errexit "Syntax: $0 <path to microcode tar>"

ucodetar="$1"

FW=platform/i86pc/ucode/GenuineIntel
LINKSF=intel/Makefile.links

export LC_ALL=C.UTF-8

set -e
set -o pipefail

mf=../../pkg/manifests/system-microcode-intel.p5m
[[ -f $mf ]] || errexit "Run from usr/src/data/ucode"

function find_cmd {
	typeset cmd="$1"
	typeset var=$(echo $cmd | tr '[:lower:]' '[:upper:]')
	typeset -n path="$var"
	path=$(whence -fp "$cmd")
	if (($? != 0)) || [ ! -x "$path" ]; then
		errexit "Cannot find executable '$cmd' in PATH"
	fi
}

# This script uses a few commands which are not part of illumos and are
# expected to be available in the path.
find_cmd gtar
find_cmd pkgfmt
# Search for 'ucodeadm'. If you need to use an updated ucodeadm to handle this
# firmware update, as is occasionally necessary, ensure it occurs earlier in
# the path than /usr/sbin.
find_cmd ucodeadm

tmp=$(mktemp -d)
[[ -n "$tmp" && -d "$tmp" ]]
mkdir $tmp/out || errexit "Failed to create temporary directory"
trap 'rm -rf $tmp' EXIT

# The distributed microcode archive uses GNU extensions
$GTAR -C $tmp -xvf "$ucodetar"

path=$({ cd $tmp; echo Intel-Linux-Processor-Microcode-Data*; })
ver=${path##*-}
echo "** Updating to microcode version $ver"

find $tmp/$path/intel-ucode*/ -type f | while read f; do
	echo "Converting $(basename $f)"
	cp $f $tmp/intel-fw
	$UCODEADM -i -R $tmp/out $tmp/intel-fw
	rm -f $tmp/intel-fw
done

$PKGFMT -u $mf
mv $mf $mf.tmp
egrep -v "(file|hardlink) path=$FW" $mf.tmp > $mf
rm -f $mf.tmp

rm -f intel/*-*

cp $tmp/$path/license intel/THIRDPARTYLICENSE
echo Intel Processor Microcode Data Files > intel/THIRDPARTYLICENSE.descrip

rm -f $LINKSF

typeset -A seen
typeset -A inodes
typeset -A links

for f in $tmp/out/*; do
	bf=$(basename $f)
	[[ -n "${seen[$bf]}" ]] && continue
	inode=$(stat -c %i $f)
	if [[ -n "${inodes[$inode]}" ]]; then
		links[$bf]=${inodes[$inode]}
	else
		inodes[$inode]=$bf
		cp $f intel/$bf
	fi
	seen[$bf]=1
done

for f in intel/*; do
	bf=$(basename $f)
	[[ $bf = THIRDPARTYLICENSE* ]] && continue
	[[ $bf = Makefile* ]] && continue
	echo "file path=$FW/$bf group=sys mode=0444 reboot-needed=true" >> $mf
done

(
	sed '/^$/q' < ../../prototypes/prototype.Makefile
	echo 'INTEL_LINKS = \'
	for i in "${!links[@]}"; do
		echo "\t$i \\"
	done | sed '$s/ .*//'
	echo
) > $LINKSF

for i in "${!links[@]}"; do
	echo "hardlink path=$FW/$i target=${links[$i]}" >> $mf
	cat << EOM >> $LINKSF
\$(ROOTINTELDIR)/$i: \$(ROOTINTELDIR)/${links[$i]}
	\$(RM) \$@; \$(LN) \$^ \$@

EOM
done

sed -i "/pkg.fmri.*microcode\/intel@/s/@[0-9]*/@$ver/" $mf

$PKGFMT -fv2 $mf