xref: /illumos-gate/usr/src/data/ucode/update.intel (revision f739c8b7)
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
29
30export LC_ALL=C.UTF-8
31
32set -e
33set -o pipefail
34
35mf=../../pkg/manifests/system-microcode-intel.p5m
36[[ -f $mf ]] || errexit "Run from usr/src/data/ucode"
37
38function find_cmd {
39	typeset cmd="$1"
40	typeset var=$(echo $cmd | tr '[:lower:]' '[:upper:]')
41	typeset -n path="$var"
42	path=$(whence -fp "$cmd")
43	if (($? != 0)) || [ ! -x "$path" ]; then
44		errexit "Cannot find executable '$cmd' in PATH"
45	fi
46}
47
48# This script uses a few commands which are not part of illumos and are
49# expected to be available in the path.
50find_cmd gtar
51find_cmd pkgfmt
52# Search for 'ucodeadm'. If you need to use an updated ucodeadm to handle this
53# firmware update, as is occasionally necessary, ensure it occurs earlier in
54# the path than /usr/sbin.
55find_cmd ucodeadm
56
57tmp=$(mktemp -d)
58[[ -n "$tmp" && -d "$tmp" ]]
59mkdir $tmp/out || errexit "Failed to create temporary directory"
60trap 'rm -rf $tmp' EXIT
61
62# The distributed microcode archive uses GNU extensions
63$GTAR -C $tmp -xvf "$ucodetar"
64
65path=$({ cd $tmp; echo Intel-Linux-Processor-Microcode-Data*; })
66ver=${path##*-}
67echo "** Updating to microcode version $ver"
68
69find $tmp/$path/intel-ucode*/ -type f | while read f; do
70	echo "Converting $(basename $f)"
71	cp $f $tmp/intel-fw
72	$UCODEADM -i -R $tmp/out $tmp/intel-fw
73	rm -f $tmp/intel-fw
74done
75
76$PKGFMT -u $mf
77mv $mf $mf.tmp
78egrep -v "(file|hardlink) path=$FW" $mf.tmp > $mf
79rm -f $mf.tmp
80
81rm -f intel/*
82
83cp $tmp/$path/license intel/THIRDPARTYLICENSE
84echo Intel Processor Microcode Data Files > intel/THIRDPARTYLICENSE.descrip
85
86rm -f Makefile.links
87
88typeset -A seen
89typeset -A inodes
90typeset -A links
91
92for f in $tmp/out/*; do
93	bf=$(basename $f)
94	[[ -n "${seen[$bf]}" ]] && continue
95	inode=$(stat -c %i $f)
96	if [[ -n "${inodes[$inode]}" ]]; then
97		links[$bf]=${inodes[$inode]}
98	else
99		inodes[$inode]=$bf
100		cp $f intel/$bf
101	fi
102	seen[$bf]=1
103done
104
105for f in intel/*; do
106	bf=$(basename $f)
107	[[ $bf = THIRDPARTYLICENSE* ]] && continue
108	echo "file path=$FW/$bf group=sys mode=0444 reboot-needed=true" >> $mf
109done
110
111(
112	sed '/^$/q' < ../../prototypes/prototype.Makefile
113	echo 'INTEL_LINKS = \'
114	for i in "${!links[@]}"; do
115		echo "\t$i \\"
116	done | sed '$s/ .*//'
117	echo
118) > Makefile.links
119
120for i in "${!links[@]}"; do
121	echo "hardlink path=$FW/$i target=${links[$i]}" >> $mf
122	cat << EOM >> Makefile.links
123\$(ROOTINTELDIR)/$i: \$(ROOTINTELDIR)/${links[$i]}
124	\$(RM) \$@; \$(LN) \$^ \$@
125
126EOM
127done
128
129sed -i "/pkg.fmri.*microcode\/intel@/s/@[0-9]*/@$ver/" $mf
130
131$PKGFMT -fv2 $mf
132
133