[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