[U-Boot] [PATCH 1/8] x86: Add a script to process Intel microcode files
Simon Glass
sjg at chromium.org
Mon Dec 15 06:28:16 CET 2014
Hi Bin,
On Dec 14, 2014 10:24 PM, "Bin Meng" <bmeng.cn at gmail.com> wrote:
>
> Hi Simon,
>
> On Mon, Dec 15, 2014 at 8:15 AM, Simon Glass <sjg at chromium.org> wrote:
> > 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
> >
>
> Is there specific microcode file format this tool expects? I always
> get 'error: You must specify a microcode file' message.
>
> $ ./tools/microcode-tool.py create M0220661105.h
> Usage: microcode-tool.py [options] 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
>
>
> And what is the [options] parameters for?
Use -h to see that. It needs the microcode.dat file. I need to update the
help. The output file goes in the right place automatically. Use the model
number of your chip as the model.
Regards,
Simon
More information about the U-Boot
mailing list