[U-Boot] [PATCH 1/8] x86: Add a script to process Intel microcode files
Simon Glass
sjg at chromium.org
Mon Dec 15 01:15:34 CET 2014
Intel delivers microcode updates in a microcode.dat file which must be
split up into individual files for each CPU. Add a tool which performs
this task. It can list available microcode updates for each model and
produce a new microcode update in U-Boot's .dtsi format.
Signed-off-by: Simon Glass <sjg at chromium.org>
---
tools/microcode-tool | 1 +
tools/microcode-tool.py | 165 ++++++++++++++++++++++++++++++++++++++++++++++++
2 files changed, 166 insertions(+)
create mode 120000 tools/microcode-tool
create mode 100755 tools/microcode-tool.py
diff --git a/tools/microcode-tool b/tools/microcode-tool
new file mode 120000
index 0000000..8be8507
--- /dev/null
+++ b/tools/microcode-tool
@@ -0,0 +1 @@
+microcode-tool.py
\ No newline at end of file
diff --git a/tools/microcode-tool.py b/tools/microcode-tool.py
new file mode 100755
index 0000000..2f6a5f4
--- /dev/null
+++ b/tools/microcode-tool.py
@@ -0,0 +1,165 @@
+#!/usr/bin/env python
+#
+# Copyright (c) 2014 Google, Inc
+#
+# SPDX-License-Identifier: GPL-2.0+
+#
+#
+# Intel microcode update tool
+
+from optparse import OptionParser
+import os
+import re
+
+MICROCODE_DIR = 'arch/x86/dts/microcode'
+
+class Microcode:
+ def __init__(self, name, data):
+ self.name = name
+ # Convert data into a list of hex words
+ self.words = []
+ for value in ''.join(data).split(','):
+ hexval = value.strip()
+ if hexval:
+ self.words.append(int(hexval, 0))
+
+ # The model is in the 4rd hex word
+ self.model = '%x' % self.words[3]
+
+def ParseFile(fname):
+ re_date = re.compile('/\* *(.* [0-9]{4}) *\*/$')
+ re_license = re.compile('/[^-*+] *(.*)$')
+ re_name = re.compile('/\* *(.*)\.inc *\*/', re.IGNORECASE)
+ microcodes = {}
+ license = []
+ date = ''
+ data = []
+ name = None
+ with open(fname) as fd:
+ for line in fd:
+ line = line.rstrip()
+ m_date = re_date.match(line)
+ m_license = re_license.match(line)
+ m_name = re_name.match(line)
+ if m_name:
+ if name:
+ microcodes[name] = Microcode(name, data)
+ name = m_name.group(1).lower()
+ data = []
+ elif m_license:
+ license.append(m_license.group(1))
+ elif m_date:
+ date = m_date.group(1)
+ else:
+ data.append(line)
+ if name:
+ microcodes[name] = Microcode(name, data)
+ return date, license, microcodes
+
+def List(date, microcodes):
+ print 'Date: %s' % date
+ for name in sorted(microcodes.keys()):
+ print '%-20s: model %s' % (name, microcodes[name].model)
+
+def FindMicrocode(microcodes, model):
+ # Allow a full name to be used
+ mcode = microcodes.get(model)
+ if mcode:
+ return mcode
+
+ tried = []
+ for i in range(3):
+ abbrev = model[:-i] if i else model
+ tried.append(abbrev)
+ for mcode in microcodes.values():
+ if mcode.model.startswith(abbrev):
+ return mcode, tried
+ return None, tried
+
+def CreateFile(date, license, mcode, outfile):
+ out = '''/*%s
+ * ---
+ * This is a device tree fragment. Use #include to add these properties to a
+ * node.
+ */
+
+compatible = "intel,microcode";
+intel,header-version = <%d>;
+intel,update-revision = <%#x>;
+intel,date-code = <%#x>;
+intel,processor-signature = <%#x>;
+intel,checksum = <%#x>;
+intel,loader-revision = <%d>;
+intel,processor-flags = <%#x>;
+
+/* The first 48-bytes are the public header which repeats the above data */
+data = <%s
+\t>;'''
+ words = ''
+ for i in range(len(mcode.words)):
+ if not (i & 3):
+ words += '\n'
+ words += '\t%#010x' % mcode.words[i]
+
+ # Take care to avoid adding a space before a tab
+ text = ''
+ for line in license:
+ if line[0] == '\t':
+ text += '\n *' + line
+ else:
+ text += '\n * ' + line
+ args = [text]
+ args += [mcode.words[i] for i in range(7)]
+ args.append(words)
+ if outfile == '-':
+ print out % tuple(args)
+ else:
+ if not outfile:
+ outfile = os.path.join(MICROCODE_DIR, mcode.name + '.dtsi')
+ with open(outfile, 'w') as fd:
+ print >>fd, out % tuple(args)
+
+commands = 'create,license,list'.split(',')
+parser = OptionParser()
+parser.add_option('-d', '--mcfile', type='string', action='store',
+ help='Name of microcode.dat file')
+parser.add_option('-m', '--model', type='string', action='store',
+ help='Model name to extract')
+parser.add_option('-o', '--outfile', type='string', action='store',
+ help='Filename to use for output (- for stdout), default is'
+ ' %s/<name>.dtsi' % MICROCODE_DIR)
+parser.usage += """ command
+
+Process an Intel microcode file, Commands:
+
+ create Create microcode .dtsi file for a model
+ list List available models in microcode file
+ license Print the license
+ make Make a U-Boot .dtsi file"""
+
+(options, args) = parser.parse_args()
+if not args:
+ parser.error('Please specify a command')
+cmd = args[0]
+if cmd not in commands:
+ parser.error("Unknown command '%s'" % cmd)
+
+if not options.mcfile:
+ parser.error('You must specify a microcode file')
+date, license, microcodes = ParseFile(options.mcfile)
+
+if cmd == 'list':
+ List(date, microcodes)
+elif cmd == 'license':
+ print '\n'.join(license)
+elif cmd == 'create':
+ if not options.model:
+ parser.error('You must specify a model to create')
+ model = options.model.lower()
+ mcode, tried = FindMicrocode(microcodes, model)
+ if not mcode:
+ parser.error("Unknown model '%s' (%s) - try 'list' to list" %
+ (model, ', '.join(tried)))
+ CreateFile(date, license, mcode, options.outfile)
+else:
+ parser.error("Unknown command '%s'" % cmd)
--
2.2.0.rc0.207.ga3a616c
More information about the U-Boot
mailing list