Skip to contentSkip to conversation

x86: Add bare support for Intel Minnowboard Max

PATCH Superseded Simon Glass 4 participants 64 messages Jan 27, 2015 – Jan 28, 2015

Subsystems (8)
x86 USB Kbuild PCI +4 more subsystems

v1 of 2 Superseded Latest is v2 →

lore
Share & tools
lore
#0 lore raw

cover x86: Add bare support for Intel Minnowboard Max

This series adds support for the Intel Minnowboard Max (called Minnowmax for short). Along the way a few refactors and additions are made:

- The Intel Firmware Support Package support is moved from queensbay to a common location
- PCI support for XHCI is added
- A few tweaks are made to the PCI support
- Support for the debug UART (early debug output) is provided
- The microcode tool now also supports reading in header files

This board has been lightly tested. The following seem to work:

- USB2 on the blue port (not USB3), e.g. for keyboard
- Ethernet
- HDMI out and console
- UART
- uSD card
- SPI

SATA is detected but I have not attached a drive to try it. USB3 shows signs of life but does not detect a USB stick, and crashes when trying to use a USB Ethernet adaptor.

For SPI some parts cannot be read and others cannot be written. This seems to be a feature of the Intel hardware configuration. It may be possible to fix this using the SPI registers but I cannot work out how / lost interest trying. So far, addresses from 500000 to 700000 can be used.

I have not tried the ICH GPIO driver but it likely needs work before it will function. I2C is not supported as there is currently no U-Boot driver for this.

The zboot command can be used to start a bzImage kernel. Verified boot is supported - use mkimage to sign images as described in this walk-through:
doc/uImage.FIT/beaglebone_vboot.txt

Boot time is grim:
- 1423ms to set up display (Intel FSP)
- 454ms to scan AHCI (when no devices are connected)
- ~1000ms to power up and start cache-as-RAM init (Intel FSP) (this is not benchmarked, may be inaccurate)
- ~950ms to set up memory and initial machine configuration (Intel FSP) (this is not benchmarked, may be inaccurate)

So it takes over 4 seconds to get to booting a kernel.

Implementing the Memory Reference Code (MRC) cache should improve this slightly (perhaps a reduction of 500-1000ms). This cache is implemented for ivybridge so that code needs to be moved into a generic x86 directory and plumbed into the FSP code. This has not been done in this series. Also the video and SATA/AHCI can be disabled if preferred.

It is also possible to run as a coreboot payload. See the instructions in README.x86 for this. In this case video does not work since coreboot does not pass through the VESA display information.

To support the single-core 1GB variant, changes would need to be made to arch/x86/cpu/baytrail/fsp_configs.c to select different values for the memory. The microcode update may need to change also.

This series is available at u-boot-x86 branch minnow-working.

Simon Glass (23):
x86: Enhance the microcode tool to support header files as input
pci: Add a function to find a device by class
x86: pci: Add PCI IDs for Minnowboard Max
x86: video: Enable video for Minnowboard Max
usb: pci: Use pci_find_class() to find the device
usb: pci: Add XHCI driver for PCI
x86: Add an option to enabling building a ROM file
x86: Make MMCONF_BASE_ADDRESS common across x86
x86: video: Allow video ROM execution to fall back to the other method
x86: bootstage: Add time measurement for vesa start-up
x86: Move common FSP code into a common location
x86: Adjust the FSP types slightly
x86: Make CAR and DRAM FSP code common
x86: Move common FSP functions into a common file
x86: Remove unnecessary casts and fix comment typos
x86: Allow FSP Kconfig settings for all x86
x86: Define cache line size
x86: Allow a UART to be set up before the FSP is ready
x86: spi: Support ValleyView in ICH SPI driver
scsi: bootstage: Measure time taken to scan the bus
x86: Enable bootstage features
x86: Add some documentation on how to port U-Boot on x86
x86: Add support for Intel Minnowboard Max

 Makefile                                           |    5 +-
 arch/x86/Kconfig                                   |   62 +
 arch/x86/cpu/Makefile                              |    1 +
 arch/x86/cpu/baytrail/Kconfig                      |    9 +
 arch/x86/cpu/baytrail/Makefile                     |   10 +
 arch/x86/cpu/baytrail/early_uart.c                 |   82 +
 arch/x86/cpu/baytrail/fsp_configs.c                |  156 +
 arch/x86/cpu/baytrail/pci.c                        |   47 +
 arch/x86/cpu/baytrail/valleyview.c                 |   37 +
 arch/x86/cpu/ivybridge/gma.c                       |    3 +-
 arch/x86/cpu/queensbay/Kconfig                     |   38 -
 arch/x86/cpu/queensbay/Makefile                    |    4 +-
 arch/x86/cpu/queensbay/fsp_configs.c               |    2 +-
 arch/x86/cpu/queensbay/tnc.c                       |   29 +-
 arch/x86/cpu/queensbay/tnc_pci.c                   |   17 +-
 arch/x86/cpu/queensbay/topcliff.c                  |   32 +-
 arch/x86/dts/Makefile                              |    3 +-
 arch/x86/dts/microcode/m0130673322.dtsi            | 3284 ++++++++++++++++++++
 arch/x86/dts/minnowmax.dts                         |   45 +
 arch/x86/dts/serial.dtsi                           |    2 +-
 arch/x86/include/asm/arch-baytrail/fsp/azalia.h    |   39 +
 arch/x86/include/asm/arch-baytrail/fsp/fsp_vpd.h   |   95 +
 arch/x86/include/asm/arch-baytrail/gpio.h          |   13 +
 arch/x86/include/asm/arch-queensbay/fsp/fsp_vpd.h  |    2 -
 arch/x86/include/asm/cache.h                       |    2 +
 .../include/asm/{arch-queensbay => }/fsp/fsp_api.h |    6 +-
 .../asm/{arch-queensbay => }/fsp/fsp_bootmode.h    |    0
 .../include/asm/{arch-queensbay => }/fsp/fsp_ffs.h |    0
 .../include/asm/{arch-queensbay => }/fsp/fsp_fv.h  |    0
 .../include/asm/{arch-queensbay => }/fsp/fsp_hob.h |    0
 .../asm/{arch-queensbay => }/fsp/fsp_infoheader.h  |    0
 .../asm/{arch-queensbay => }/fsp/fsp_platform.h    |    0
 .../asm/{arch-queensbay => }/fsp/fsp_support.h     |    6 +-
 .../asm/{arch-queensbay => }/fsp/fsp_types.h       |    0
 arch/x86/include/asm/u-boot-x86.h                  |   20 +
 arch/x86/lib/Makefile                              |    1 +
 arch/x86/lib/cmd_hob.c                             |    2 +-
 arch/x86/lib/fsp/Makefile                          |   10 +
 .../{cpu/queensbay/tnc_car.S => lib/fsp/fsp_car.S} |    0
 arch/x86/lib/fsp/fsp_common.c                      |   88 +
 .../queensbay/tnc_dram.c => lib/fsp/fsp_dram.c}    |    2 +-
 arch/x86/{cpu/queensbay => lib/fsp}/fsp_support.c  |   20 +-
 board/google/chromebook_link/Kconfig               |    1 -
 board/intel/minnowmax/Kconfig                      |   31 +
 board/intel/minnowmax/MAINTAINERS                  |    6 +
 board/intel/minnowmax/Makefile                     |    7 +
 board/intel/minnowmax/minnowmax.c                  |   32 +
 board/intel/minnowmax/start.S                      |    9 +
 common/cmd_scsi.c                                  |    2 +
 configs/minnowmax_defconfig                        |   13 +
 doc/README.x86                                     |  120 +-
 drivers/pci/pci.c                                  |   38 +
 drivers/pci/pci_rom.c                              |   32 +-
 drivers/spi/ich.c                                  |   56 +-
 drivers/spi/ich.h                                  |   11 +-
 drivers/usb/host/Makefile                          |    1 +
 drivers/usb/host/ehci-pci.c                        |   53 +-
 drivers/usb/host/xhci-pci.c                        |   60 +
 drivers/video/vesa_fb.c                            |    9 +-
 include/bootstage.h                                |    1 +
 include/configs/minnowmax.h                        |   69 +
 include/configs/x86-common.h                       |    3 +
 include/pci.h                                      |    3 +-
 include/pci_ids.h                                  |    5 +
 include/pci_rom.h                                  |   15 +-
 tools/microcode-tool.py                            |   90 +-
 66 files changed, 4589 insertions(+), 252 deletions(-)
 create mode 100644 arch/x86/cpu/baytrail/Kconfig
 create mode 100644 arch/x86/cpu/baytrail/Makefile
 create mode 100644 arch/x86/cpu/baytrail/early_uart.c
 create mode 100644 arch/x86/cpu/baytrail/fsp_configs.c
 create mode 100644 arch/x86/cpu/baytrail/pci.c
 create mode 100644 arch/x86/cpu/baytrail/valleyview.c
 create mode 100644 arch/x86/dts/microcode/m0130673322.dtsi
 create mode 100644 arch/x86/dts/minnowmax.dts
 create mode 100644 arch/x86/include/asm/arch-baytrail/fsp/azalia.h
 create mode 100644 arch/x86/include/asm/arch-baytrail/fsp/fsp_vpd.h
 create mode 100644 arch/x86/include/asm/arch-baytrail/gpio.h
 rename arch/x86/include/asm/{arch-queensbay => }/fsp/fsp_api.h (88%)
 rename arch/x86/include/asm/{arch-queensbay => }/fsp/fsp_bootmode.h (100%)
 rename arch/x86/include/asm/{arch-queensbay => }/fsp/fsp_ffs.h (100%)
 rename arch/x86/include/asm/{arch-queensbay => }/fsp/fsp_fv.h (100%)
 rename arch/x86/include/asm/{arch-queensbay => }/fsp/fsp_hob.h (100%)
 rename arch/x86/include/asm/{arch-queensbay => }/fsp/fsp_infoheader.h (100%)
 rename arch/x86/include/asm/{arch-queensbay => }/fsp/fsp_platform.h (100%)
 rename arch/x86/include/asm/{arch-queensbay => }/fsp/fsp_support.h (98%)
 rename arch/x86/include/asm/{arch-queensbay => }/fsp/fsp_types.h (100%)
 create mode 100644 arch/x86/lib/fsp/Makefile
 rename arch/x86/{cpu/queensbay/tnc_car.S => lib/fsp/fsp_car.S} (100%)
 create mode 100644 arch/x86/lib/fsp/fsp_common.c
 rename arch/x86/{cpu/queensbay/tnc_dram.c => lib/fsp/fsp_dram.c} (98%)
 rename arch/x86/{cpu/queensbay => lib/fsp}/fsp_support.c (96%)
 create mode 100644 board/intel/minnowmax/Kconfig
 create mode 100644 board/intel/minnowmax/MAINTAINERS
 create mode 100644 board/intel/minnowmax/Makefile
 create mode 100644 board/intel/minnowmax/minnowmax.c
 create mode 100644 board/intel/minnowmax/start.S
 create mode 100644 configs/minnowmax_defconfig
 create mode 100644 drivers/usb/host/xhci-pci.c
 create mode 100644 include/configs/minnowmax.h
Signature · 1 line
2.2.0.rc0.207.ga3a616c
#1 lore raw

PATCH 1/23 x86: Enhance the microcode tool to support header files as input

Sometimes microcode is delivered as a header file. Allow the tool to support this as well as collecting multiple microcode blocks into a single update.

---

 tools/microcode-tool.py | 90 ++++++++++++++++++++++++++++++++++++++-----------
 1 file changed, 70 insertions(+), 20 deletions(-)
tools/microcode-tool.py +70 -20
index 003716d..71c2e91 100755
@@ -76,6 +76,35 @@ def ParseFile(fname):
         microcodes[name] = Microcode(name, data)
     return date, license_text, microcodes
 
+def ParseHeaderFiles(fname_list):
+    """Parse a list of header files and return the component parts
+
+    Args:
+        fname_list: List of files to parse
+    Returns:
+            date:         String containing date from the file's header
+            license_text: List of text lines for the license file
+            microcodes:   List of Microcode objects from the file
+    """
+    microcodes = {}
+    license_text = []
+    date = ''
+    name = None
+    for fname in fname_list:
+        name = os.path.basename(fname).lower()
+        name = os.path.splitext(name)[0]
+        data = []
+        with open(fname) as fd:
+            for line in fd:
+                line = line.rstrip()
+
+                # Omit anything after the last comma
+                words = line.split(',')[:-1]
+                data += [word + ',' for word in words]
+        microcodes[name] = Microcode(name, data)
+    return date, license_text, microcodes
+
+
 def List(date, microcodes, model):
     """List the available microcode chunks
 
@@ -129,13 +158,13 @@ def FindMicrocode(microcodes, model):
             break
     return found, tried
 
-def CreateFile(date, license_text, mcode, outfile):
+def CreateFile(date, license_text, mcodes, outfile):
     """Create a microcode file in U-Boot's .dtsi format
 
     Args:
         date:       String containing date of original microcode file
         license:    List of text lines for the license file
-        mcode:      Microcode object to write
+        mcodes:      Microcode objects to write (normally only 1)
         outfile:    Filename to write to ('-' for stdout)
     """
     out = '''/*%s
@@ -159,15 +188,22 @@ intel,processor-flags = <%#x>;
 data = <%s
 \t>;'''
     words = ''
-    for i in range(len(mcode.words)):
-        if not (i & 3):
-            words += '\n'
-        val = mcode.words[i]
-        # Change each word so it will be little-endian in the FDT
-        # This data is needed before RAM is available on some platforms so we
-        # cannot do an endianness swap on boot.
-        val = struct.unpack("<I", struct.pack(">I", val))[0]
-        words += '\t%#010x' % val
+    add_comments = len(mcodes) > 1
+    for mcode in mcodes:
+        if add_comments:
+            words += '\n/* %s */' % mcode.name
+        for i in range(len(mcode.words)):
+            if not (i & 3):
+                words += '\n'
+            val = mcode.words[i]
+            # Change each word so it will be little-endian in the FDT
+            # This data is needed before RAM is available on some platforms so
+            # we cannot do an endianness swap on boot.
+            val = struct.unpack("<I", struct.pack(">I", val))[0]
+            words += '\t%#010x' % val
+
+    # Use the first microcode for the headers
+    mcode = mcodes[0]
 
     # Take care to avoid adding a space before a tab
     text = ''
@@ -187,8 +223,8 @@ data = <%s
                 print >> sys.stderr, "Creating directory '%s'" % MICROCODE_DIR
                 os.makedirs(MICROCODE_DIR)
             outfile = os.path.join(MICROCODE_DIR, mcode.name + '.dtsi')
-            print >> sys.stderr, "Writing microcode for '%s' to '%s'" % (
-                     mcode.name, outfile)
+        print >> sys.stderr, "Writing microcode for '%s' to '%s'" % (
+                ', '.join([mcode.name for mcode in mcodes]), outfile)
         with open(outfile, 'w') as fd:
             print >> fd, out % tuple(args)
 
@@ -198,8 +234,12 @@ def MicrocodeTool():
     parser = OptionParser()
     parser.add_option('-d', '--mcfile', type='string', action='store',
                     help='Name of microcode.dat file')
+    parser.add_option('-H', '--headerfile', type='string', action='append',
+                    help='Name of .h file containing microcode')
     parser.add_option('-m', '--model', type='string', action='store',
-                    help='Model name to extract')
+                    help="Model name to extract ('all' for all)")
+    parser.add_option('-M', '--multiple', type='string', action='store',
+                    help="Allow output of multiple models")
     parser.add_option('-o', '--outfile', type='string', action='store',
                     help='Filename to use for output (- for stdout), default is'
                     ' %s/<name>.dtsi' % MICROCODE_DIR)
@@ -224,9 +264,14 @@ def MicrocodeTool():
     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_text, microcodes = ParseFile(options.mcfile)
+    if (not not options.mcfile) != (not not options.mcfile):
+        parser.error("You must specify either header files or a microcode file, not both")
+    if options.headerfile:
+        date, license_text, microcodes = ParseHeaderFiles(options.headerfile)
+    elif options.mcfile:
+        date, license_text, microcodes = ParseFile(options.mcfile)
+    else:
+        parser.error('You must specify a microcode file (or header files)')
 
     if cmd == 'list':
         List(date, microcodes, options.model)
@@ -236,16 +281,21 @@ def MicrocodeTool():
         if not options.model:
             parser.error('You must specify a model to create')
         model = options.model.lower()
-        mcode_list, tried = FindMicrocode(microcodes, model)
+        if options.model == 'all':
+            options.multiple = True
+            mcode_list = microcodes.values()
+            tried = []
+        else:
+            mcode_list, tried = FindMicrocode(microcodes, model)
         if not mcode_list:
             parser.error("Unknown model '%s' (%s) - try 'list' to list" %
                         (model, ', '.join(tried)))
-        if len(mcode_list) > 1:
+        if not options.multiple and len(mcode_list) > 1:
             parser.error("Ambiguous model '%s' (%s) matched %s - try 'list' "
                         "to list or specify a particular file" %
                         (model, ', '.join(tried),
                         ', '.join([m.name for m in mcode_list])))
-        CreateFile(date, license_text, mcode_list[0], options.outfile)
+        CreateFile(date, license_text, mcode_list, options.outfile)
     else:
         parser.error("Unknown command '%s'" % cmd)
 
Signature · 1 line
2.2.0.rc0.207.ga3a616c
#2 lore raw

PATCH 1/23 x86: Enhance the microcode tool to support header files as input

Hi Simon,

Quoted 6 lines · Simon Glass

Sometimes microcode is delivered as a header file. Allow the tool to support this as well as collecting multiple microcode blocks into a single update.

---

But please see my comments below.

Quoted 150 lines
 tools/microcode-tool.py | 90 ++++++++++++++++++++++++++++++++++++++-----------
 1 file changed, 70 insertions(+), 20 deletions(-)
tools/microcode-tool.py +69 -19
index 003716d..71c2e91 100755
@@ -76,6 +76,35 @@ def ParseFile(fname):
         microcodes[name] = Microcode(name, data)
     return date, license_text, microcodes
 
+def ParseHeaderFiles(fname_list):
+    """Parse a list of header files and return the component parts
+
+    Args:
+        fname_list: List of files to parse
+    Returns:
+            date:         String containing date from the file's header
+            license_text: List of text lines for the license file
+            microcodes:   List of Microcode objects from the file
+    """
+    microcodes = {}
+    license_text = []
+    date = ''
+    name = None
+    for fname in fname_list:
+        name = os.path.basename(fname).lower()
+        name = os.path.splitext(name)[0]
+        data = []
+        with open(fname) as fd:
+            for line in fd:
+                line = line.rstrip()
+
+                # Omit anything after the last comma
+                words = line.split(',')[:-1]
+                data += [word + ',' for word in words]
+        microcodes[name] = Microcode(name, data)
+    return date, license_text, microcodes
+
+
 def List(date, microcodes, model):
     """List the available microcode chunks
 
@@ -129,13 +158,13 @@ def FindMicrocode(microcodes, model):
             break
     return found, tried
 
-def CreateFile(date, license_text, mcode, outfile):
+def CreateFile(date, license_text, mcodes, outfile):
     """Create a microcode file in U-Boot's .dtsi format
 
     Args:
         date:       String containing date of original microcode file
         license:    List of text lines for the license file
-        mcode:      Microcode object to write
+        mcodes:      Microcode objects to write (normally only 1)
         outfile:    Filename to write to ('-' for stdout)
     """
     out = '''/*%s
@@ -159,15 +188,22 @@ intel,processor-flags = <%#x>;
 data = <%s
 \t>;'''
     words = ''
-    for i in range(len(mcode.words)):
-        if not (i & 3):
-            words += '\n'
-        val = mcode.words[i]
-        # Change each word so it will be little-endian in the FDT
-        # This data is needed before RAM is available on some platforms so we
-        # cannot do an endianness swap on boot.
-        val = struct.unpack("<I", struct.pack(">I", val))[0]
-        words += '\t%#010x' % val
+    add_comments = len(mcodes) > 1
+    for mcode in mcodes:
+        if add_comments:
+            words += '\n/* %s */' % mcode.name
+        for i in range(len(mcode.words)):
+            if not (i & 3):
+                words += '\n'
+            val = mcode.words[i]
+            # Change each word so it will be little-endian in the FDT
+            # This data is needed before RAM is available on some platforms so
+            # we cannot do an endianness swap on boot.
+            val = struct.unpack("<I", struct.pack(">I", val))[0]
+            words += '\t%#010x' % val
+
+    # Use the first microcode for the headers
+    mcode = mcodes[0]
 
     # Take care to avoid adding a space before a tab
     text = ''
@@ -187,8 +223,8 @@ data = <%s
                 print >> sys.stderr, "Creating directory '%s'" % MICROCODE_DIR
                 os.makedirs(MICROCODE_DIR)
             outfile = os.path.join(MICROCODE_DIR, mcode.name + '.dtsi')
-            print >> sys.stderr, "Writing microcode for '%s' to '%s'" % (
-                     mcode.name, outfile)
+        print >> sys.stderr, "Writing microcode for '%s' to '%s'" % (
+                ', '.join([mcode.name for mcode in mcodes]), outfile)
         with open(outfile, 'w') as fd:
             print >> fd, out % tuple(args)
 
@@ -198,8 +234,12 @@ def MicrocodeTool():
     parser = OptionParser()
     parser.add_option('-d', '--mcfile', type='string', action='store',
                     help='Name of microcode.dat file')
+    parser.add_option('-H', '--headerfile', type='string', action='append',
+                    help='Name of .h file containing microcode')
     parser.add_option('-m', '--model', type='string', action='store',
-                    help='Model name to extract')
+                    help="Model name to extract ('all' for all)")
+    parser.add_option('-M', '--multiple', type='string', action='store',
+                    help="Allow output of multiple models")
     parser.add_option('-o', '--outfile', type='string', action='store',
                     help='Filename to use for output (- for stdout), default is'
                     ' %s/<name>.dtsi' % MICROCODE_DIR)
@@ -224,9 +264,14 @@ def MicrocodeTool():
     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_text, microcodes = ParseFile(options.mcfile)
+    if (not not options.mcfile) != (not not options.mcfile):
+        parser.error("You must specify either header files or a microcode file, not both")
+    if options.headerfile:
+        date, license_text, microcodes = ParseHeaderFiles(options.headerfile)
+    elif options.mcfile:
+        date, license_text, microcodes = ParseFile(options.mcfile)
+    else:
+        parser.error('You must specify a microcode file (or header files)')
 
     if cmd == 'list':
         List(date, microcodes, options.model)
@@ -236,16 +281,21 @@ def MicrocodeTool():
         if not options.model:
             parser.error('You must specify a model to create')
         model = options.model.lower()
-        mcode_list, tried = FindMicrocode(microcodes, model)
+        if options.model == 'all':
+            options.multiple = True
+            mcode_list = microcodes.values()
+            tried = []
+        else:
+            mcode_list, tried = FindMicrocode(microcodes, model)
         if not mcode_list:
             parser.error("Unknown model '%s' (%s) - try 'list' to list" %
                         (model, ', '.join(tried)))
-        if len(mcode_list) > 1:
+        if not options.multiple and len(mcode_list) > 1:

tools/microcode-tool.py def MicrocodeTool():

Quoted 10 lines
tools/microcode-tool.py +1 -2
             parser.error("Ambiguous model '%s' (%s) matched %s - try 'list' "
                         "to list or specify a particular file" %
                         (model, ', '.join(tried),
                         ', '.join([m.name for m in mcode_list])))
-        CreateFile(date, license_text, mcode_list[0], options.outfile)
+        CreateFile(date, license_text, mcode_list, options.outfile)
     else:
         parser.error("Unknown command '%s'" % cmd)
 
--

My testing results show that, compared to '-d microcode.dat' approach, generated microcode.dtsi using '-H' does not have license header and date set. Is this intentional?

Regards,
Bin

#3 lore raw

PATCH 1/23 x86: Enhance the microcode tool to support header files as input

Hi Bin,

Quoted 173 lines · Bin Meng

Hi Simon,

Quoted 6 lines · Simon Glass

Sometimes microcode is delivered as a header file. Allow the tool to support this as well as collecting multiple microcode blocks into a single update.

---

But please see my comments below.

Quoted 159 lines
 tools/microcode-tool.py | 90 ++++++++++++++++++++++++++++++++++++++-----------
 1 file changed, 70 insertions(+), 20 deletions(-)
tools/microcode-tool.py +70 -20
index 003716d..71c2e91 100755
@@ -76,6 +76,35 @@ def ParseFile(fname):
         microcodes[name] = Microcode(name, data)
     return date, license_text, microcodes
 
+def ParseHeaderFiles(fname_list):
+    """Parse a list of header files and return the component parts
+
+    Args:
+        fname_list: List of files to parse
+    Returns:
+            date:         String containing date from the file's header
+            license_text: List of text lines for the license file
+            microcodes:   List of Microcode objects from the file
+    """
+    microcodes = {}
+    license_text = []
+    date = ''
+    name = None
+    for fname in fname_list:
+        name = os.path.basename(fname).lower()
+        name = os.path.splitext(name)[0]
+        data = []
+        with open(fname) as fd:
+            for line in fd:
+                line = line.rstrip()
+
+                # Omit anything after the last comma
+                words = line.split(',')[:-1]
+                data += [word + ',' for word in words]
+        microcodes[name] = Microcode(name, data)
+    return date, license_text, microcodes
+
+
 def List(date, microcodes, model):
     """List the available microcode chunks
 
@@ -129,13 +158,13 @@ def FindMicrocode(microcodes, model):
             break
     return found, tried
 
-def CreateFile(date, license_text, mcode, outfile):
+def CreateFile(date, license_text, mcodes, outfile):
     """Create a microcode file in U-Boot's .dtsi format
 
     Args:
         date:       String containing date of original microcode file
         license:    List of text lines for the license file
-        mcode:      Microcode object to write
+        mcodes:      Microcode objects to write (normally only 1)
         outfile:    Filename to write to ('-' for stdout)
     """
     out = '''/*%s
@@ -159,15 +188,22 @@ intel,processor-flags = <%#x>;
 data = <%s
 \t>;'''
     words = ''
-    for i in range(len(mcode.words)):
-        if not (i & 3):
-            words += '\n'
-        val = mcode.words[i]
-        # Change each word so it will be little-endian in the FDT
-        # This data is needed before RAM is available on some platforms so we
-        # cannot do an endianness swap on boot.
-        val = struct.unpack("<I", struct.pack(">I", val))[0]
-        words += '\t%#010x' % val
+    add_comments = len(mcodes) > 1
+    for mcode in mcodes:
+        if add_comments:
+            words += '\n/* %s */' % mcode.name
+        for i in range(len(mcode.words)):
+            if not (i & 3):
+                words += '\n'
+            val = mcode.words[i]
+            # Change each word so it will be little-endian in the FDT
+            # This data is needed before RAM is available on some platforms so
+            # we cannot do an endianness swap on boot.
+            val = struct.unpack("<I", struct.pack(">I", val))[0]
+            words += '\t%#010x' % val
+
+    # Use the first microcode for the headers
+    mcode = mcodes[0]
 
     # Take care to avoid adding a space before a tab
     text = ''
@@ -187,8 +223,8 @@ data = <%s
                 print >> sys.stderr, "Creating directory '%s'" % MICROCODE_DIR
                 os.makedirs(MICROCODE_DIR)
             outfile = os.path.join(MICROCODE_DIR, mcode.name + '.dtsi')
-            print >> sys.stderr, "Writing microcode for '%s' to '%s'" % (
-                     mcode.name, outfile)
+        print >> sys.stderr, "Writing microcode for '%s' to '%s'" % (
+                ', '.join([mcode.name for mcode in mcodes]), outfile)
         with open(outfile, 'w') as fd:
             print >> fd, out % tuple(args)
 
@@ -198,8 +234,12 @@ def MicrocodeTool():
     parser = OptionParser()
     parser.add_option('-d', '--mcfile', type='string', action='store',
                     help='Name of microcode.dat file')
+    parser.add_option('-H', '--headerfile', type='string', action='append',
+                    help='Name of .h file containing microcode')
     parser.add_option('-m', '--model', type='string', action='store',
-                    help='Model name to extract')
+                    help="Model name to extract ('all' for all)")
+    parser.add_option('-M', '--multiple', type='string', action='store',
+                    help="Allow output of multiple models")
     parser.add_option('-o', '--outfile', type='string', action='store',
                     help='Filename to use for output (- for stdout), default is'
                     ' %s/<name>.dtsi' % MICROCODE_DIR)
@@ -224,9 +264,14 @@ def MicrocodeTool():
     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_text, microcodes = ParseFile(options.mcfile)
+    if (not not options.mcfile) != (not not options.mcfile):
+        parser.error("You must specify either header files or a microcode file, not both")
+    if options.headerfile:
+        date, license_text, microcodes = ParseHeaderFiles(options.headerfile)
+    elif options.mcfile:
+        date, license_text, microcodes = ParseFile(options.mcfile)
+    else:
+        parser.error('You must specify a microcode file (or header files)')
 
     if cmd == 'list':
         List(date, microcodes, options.model)
@@ -236,16 +281,21 @@ def MicrocodeTool():
         if not options.model:
             parser.error('You must specify a model to create')
         model = options.model.lower()
-        mcode_list, tried = FindMicrocode(microcodes, model)
+        if options.model == 'all':
+            options.multiple = True
+            mcode_list = microcodes.values()
+            tried = []
+        else:
+            mcode_list, tried = FindMicrocode(microcodes, model)
         if not mcode_list:
             parser.error("Unknown model '%s' (%s) - try 'list' to list" %
                         (model, ', '.join(tried)))
-        if len(mcode_list) > 1:
+        if not options.multiple and len(mcode_list) > 1:
             parser.error("Ambiguous model '%s' (%s) matched %s - try 'list' "
                         "to list or specify a particular file" %
                         (model, ', '.join(tried),
                         ', '.join([m.name for m in mcode_list])))
-        CreateFile(date, license_text, mcode_list[0], options.outfile)
+        CreateFile(date, license_text, mcode_list, options.outfile)
     else:
         parser.error("Unknown command '%s'" % cmd)
 
Quoted 5 lines
Quoted 1 line

--

My testing results show that, compared to '-d microcode.dat' approach, generated microcode.dtsi using '-H' does not have license header and date set. Is this intentional?

Not really, but the header I tested with has no license info.

I suspect we could enable use of -d also to pick this up. But we still wouldn't get the date. I'm not sure what automation we should have for this case.

Regards,
Simon

#4 lore raw

PATCH 1/23 x86: Enhance the microcode tool to support header files as input

Hi Simon,

Quoted 176 lines · Simon Glass

Hi Bin,

Quoted 173 lines · Bin Meng

Hi Simon,

Quoted 6 lines · Simon Glass

Sometimes microcode is delivered as a header file. Allow the tool to support this as well as collecting multiple microcode blocks into a single update.

---

But please see my comments below.

Quoted 159 lines
 tools/microcode-tool.py | 90 ++++++++++++++++++++++++++++++++++++++-----------
 1 file changed, 70 insertions(+), 20 deletions(-)
tools/microcode-tool.py +70 -20
index 003716d..71c2e91 100755
@@ -76,6 +76,35 @@ def ParseFile(fname):
         microcodes[name] = Microcode(name, data)
     return date, license_text, microcodes
 
+def ParseHeaderFiles(fname_list):
+    """Parse a list of header files and return the component parts
+
+    Args:
+        fname_list: List of files to parse
+    Returns:
+            date:         String containing date from the file's header
+            license_text: List of text lines for the license file
+            microcodes:   List of Microcode objects from the file
+    """
+    microcodes = {}
+    license_text = []
+    date = ''
+    name = None
+    for fname in fname_list:
+        name = os.path.basename(fname).lower()
+        name = os.path.splitext(name)[0]
+        data = []
+        with open(fname) as fd:
+            for line in fd:
+                line = line.rstrip()
+
+                # Omit anything after the last comma
+                words = line.split(',')[:-1]
+                data += [word + ',' for word in words]
+        microcodes[name] = Microcode(name, data)
+    return date, license_text, microcodes
+
+
 def List(date, microcodes, model):
     """List the available microcode chunks
 
@@ -129,13 +158,13 @@ def FindMicrocode(microcodes, model):
             break
     return found, tried
 
-def CreateFile(date, license_text, mcode, outfile):
+def CreateFile(date, license_text, mcodes, outfile):
     """Create a microcode file in U-Boot's .dtsi format
 
     Args:
         date:       String containing date of original microcode file
         license:    List of text lines for the license file
-        mcode:      Microcode object to write
+        mcodes:      Microcode objects to write (normally only 1)
         outfile:    Filename to write to ('-' for stdout)
     """
     out = '''/*%s
@@ -159,15 +188,22 @@ intel,processor-flags = <%#x>;
 data = <%s
 \t>;'''
     words = ''
-    for i in range(len(mcode.words)):
-        if not (i & 3):
-            words += '\n'
-        val = mcode.words[i]
-        # Change each word so it will be little-endian in the FDT
-        # This data is needed before RAM is available on some platforms so we
-        # cannot do an endianness swap on boot.
-        val = struct.unpack("<I", struct.pack(">I", val))[0]
-        words += '\t%#010x' % val
+    add_comments = len(mcodes) > 1
+    for mcode in mcodes:
+        if add_comments:
+            words += '\n/* %s */' % mcode.name
+        for i in range(len(mcode.words)):
+            if not (i & 3):
+                words += '\n'
+            val = mcode.words[i]
+            # Change each word so it will be little-endian in the FDT
+            # This data is needed before RAM is available on some platforms so
+            # we cannot do an endianness swap on boot.
+            val = struct.unpack("<I", struct.pack(">I", val))[0]
+            words += '\t%#010x' % val
+
+    # Use the first microcode for the headers
+    mcode = mcodes[0]
 
     # Take care to avoid adding a space before a tab
     text = ''
@@ -187,8 +223,8 @@ data = <%s
                 print >> sys.stderr, "Creating directory '%s'" % MICROCODE_DIR
                 os.makedirs(MICROCODE_DIR)
             outfile = os.path.join(MICROCODE_DIR, mcode.name + '.dtsi')
-            print >> sys.stderr, "Writing microcode for '%s' to '%s'" % (
-                     mcode.name, outfile)
+        print >> sys.stderr, "Writing microcode for '%s' to '%s'" % (
+                ', '.join([mcode.name for mcode in mcodes]), outfile)
         with open(outfile, 'w') as fd:
             print >> fd, out % tuple(args)
 
@@ -198,8 +234,12 @@ def MicrocodeTool():
     parser = OptionParser()
     parser.add_option('-d', '--mcfile', type='string', action='store',
                     help='Name of microcode.dat file')
+    parser.add_option('-H', '--headerfile', type='string', action='append',
+                    help='Name of .h file containing microcode')
     parser.add_option('-m', '--model', type='string', action='store',
-                    help='Model name to extract')
+                    help="Model name to extract ('all' for all)")
+    parser.add_option('-M', '--multiple', type='string', action='store',
+                    help="Allow output of multiple models")
     parser.add_option('-o', '--outfile', type='string', action='store',
                     help='Filename to use for output (- for stdout), default is'
                     ' %s/<name>.dtsi' % MICROCODE_DIR)
@@ -224,9 +264,14 @@ def MicrocodeTool():
     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_text, microcodes = ParseFile(options.mcfile)
+    if (not not options.mcfile) != (not not options.mcfile):
+        parser.error("You must specify either header files or a microcode file, not both")
+    if options.headerfile:
+        date, license_text, microcodes = ParseHeaderFiles(options.headerfile)
+    elif options.mcfile:
+        date, license_text, microcodes = ParseFile(options.mcfile)
+    else:
+        parser.error('You must specify a microcode file (or header files)')
 
     if cmd == 'list':
         List(date, microcodes, options.model)
@@ -236,16 +281,21 @@ def MicrocodeTool():
         if not options.model:
             parser.error('You must specify a model to create')
         model = options.model.lower()
-        mcode_list, tried = FindMicrocode(microcodes, model)
+        if options.model == 'all':
+            options.multiple = True
+            mcode_list = microcodes.values()
+            tried = []
+        else:
+            mcode_list, tried = FindMicrocode(microcodes, model)
         if not mcode_list:
             parser.error("Unknown model '%s' (%s) - try 'list' to list" %
                         (model, ', '.join(tried)))
-        if len(mcode_list) > 1:
+        if not options.multiple and len(mcode_list) > 1:
             parser.error("Ambiguous model '%s' (%s) matched %s - try 'list' "
                         "to list or specify a particular file" %
                         (model, ', '.join(tried),
                         ', '.join([m.name for m in mcode_list])))
-        CreateFile(date, license_text, mcode_list[0], options.outfile)
+        CreateFile(date, license_text, mcode_list, options.outfile)
     else:
         parser.error("Unknown command '%s'" % cmd)
 
Quoted 8 lines
Quoted 5 lines
Quoted 1 line

--

My testing results show that, compared to '-d microcode.dat' approach, generated microcode.dtsi using '-H' does not have license header and date set. Is this intentional?

Not really, but the header I tested with has no license info.

OK.

Quoted 4 lines

I suspect we could enable use of -d also to pick this up. But we still wouldn't get the date. I'm not sure what automation we should have for this case.

Specifying '-d' might be confusing. Let's just go with current implementation without license and date.

Regards,
Bin

#5 lore raw

PATCH 2/23 pci: Add a function to find a device by class

In reply to Simon Glass

There is an existing function prototype in the header file but it is not implemented. Implement something similar.

---

 drivers/pci/pci.c | 38 ++++++++++++++++++++++++++++++++++++++
 include/pci.h     |  3 +--
 2 files changed, 39 insertions(+), 2 deletions(-)
drivers/pci/pci.c +38 -0
index 950a247..215a092 100644
@@ -15,6 +15,7 @@
 #include <common.h>
 
 #include <command.h>
+#include <errno.h>
 #include <asm/processor.h>
 #include <asm/io.h>
 #include <pci.h>
@@ -236,6 +237,43 @@ pci_dev_t pci_find_devices(struct pci_device_id *ids, int index)
 	return -1;
 }
 
+pci_dev_t pci_find_class(uint find_class, int index)
+{
+	int bus;
+	int devnum;
+	pci_dev_t bdf;
+	uint32_t class;
+
+	for (bus = 0; bus <= pci_last_busno(); bus++) {
+		for (devnum = 0; devnum < PCI_MAX_PCI_DEVICES-1; devnum++) {
+			pci_read_config_dword(PCI_BDF(bus, devnum, 0),
+					      PCI_CLASS_REVISION, &class);
+			if (class >> 16 == 0xffff)
+				continue;
+
+			for (bdf = PCI_BDF(bus, devnum, 0);
+					bdf <= PCI_BDF(bus, devnum,
+						PCI_MAX_PCI_FUNCTIONS - 1);
+					bdf += PCI_BDF(0, 0, 1)) {
+				pci_read_config_dword(bdf, PCI_CLASS_REVISION,
+						      &class);
+				class >>= 8;
+
+				if (class != find_class)
+					continue;
+				if (index) {
+					index--;
+					continue;
+				}
+				/* Return index'th controller. */
+				return bdf;
+			}
+		}
+	}
+
+	return -ENODEV;
+}
+
 pci_dev_t pci_find_device(unsigned int vendor, unsigned int device, int index)
 {
 	struct pci_device_id ids[2] = { {}, {0, 0} };
include/pci.h +1 -2
index 4fbb8f6..004a048 100644
@@ -644,8 +644,7 @@ extern int pciauto_config_device(struct pci_controller *hose, pci_dev_t dev);
 
 extern pci_dev_t pci_find_device (unsigned int vendor, unsigned int device, int index);
 extern pci_dev_t pci_find_devices (struct pci_device_id *ids, int index);
-extern pci_dev_t pci_find_class(int wanted_class, int wanted_sub_code,
-				int wanted_prog_if, int index);
+pci_dev_t pci_find_class(unsigned int find_class, int index);
 
 extern int pci_hose_config_device(struct pci_controller *hose,
 				  pci_dev_t dev,
Signature · 1 line
2.2.0.rc0.207.ga3a616c
#6 lore raw

PATCH 2/23 pci: Add a function to find a device by class

Hi Simon,

Quoted 25 lines · Simon Glass

There is an existing function prototype in the header file but it is not implemented. Implement something similar.

---

 drivers/pci/pci.c | 38 ++++++++++++++++++++++++++++++++++++++
 include/pci.h     |  3 +--
 2 files changed, 39 insertions(+), 2 deletions(-)
drivers/pci/pci.c +1 -0
index 950a247..215a092 100644
@@ -15,6 +15,7 @@
 #include <common.h>
 
 #include <command.h>
+#include <errno.h>
 #include <asm/processor.h>
 #include <asm/io.h>
 #include <pci.h>
@@ -236,6 +237,43 @@ pci_dev_t pci_find_devices(struct pci_device_id *ids, int index)
        return -1;
 }

drivers/pci/pci.c pci_dev_t pci_find_devices(struct pci_device_id *ids, int index) · line 248

Quoted 10 lines
drivers/pci/pci.c +9 -0
 
+pci_dev_t pci_find_class(uint find_class, int index)
+{
+       int bus;
+       int devnum;
+       pci_dev_t bdf;
+       uint32_t class;
+
+       for (bus = 0; bus <= pci_last_busno(); bus++) {
+               for (devnum = 0; devnum < PCI_MAX_PCI_DEVICES-1; devnum++) {

space after PCI_MAX_PCI_DEVICES and before 1?

Quoted 8 lines
drivers/pci/pci.c +8 -0
+                       pci_read_config_dword(PCI_BDF(bus, devnum, 0),
+                                             PCI_CLASS_REVISION, &class);
+                       if (class >> 16 == 0xffff)
+                               continue;
+
+                       for (bdf = PCI_BDF(bus, devnum, 0);
+                                       bdf <= PCI_BDF(bus, devnum,
+                                               PCI_MAX_PCI_FUNCTIONS - 1);

drivers/pci/pci.c pci_dev_t pci_find_devices(struct pci_device_id *ids, int index) · line 266

Quoted 10 lines
drivers/pci/pci.c +10 -0
+                                       bdf += PCI_BDF(0, 0, 1)) {
+                               pci_read_config_dword(bdf, PCI_CLASS_REVISION,
+                                                     &class);
+                               class >>= 8;
+
+                               if (class != find_class)
+                                       continue;
+                               if (index) {
+                                       index--;
+                                       continue;

It is worth to have a comment block to explain the 'index' logic here.

Quoted 18 lines
drivers/pci/pci.c +10 -0
+                               }
+                               /* Return index'th controller. */
+                               return bdf;
+                       }
+               }
+       }
+
+       return -ENODEV;
+}
+
 pci_dev_t pci_find_device(unsigned int vendor, unsigned int device, int index)
 {
        struct pci_device_id ids[2] = { {}, {0, 0} };
include/pci.h +0 -0
index 4fbb8f6..004a048 100644

include/pci.h extern int pciauto_config_device(struct pci_controller *hose, pci_dev_t dev);

Quoted 10 lines
include/pci.h +1 -3
@@ -644,8 +644,7 @@ extern int pciauto_config_device(struct pci_controller *hose, pci_dev_t dev);
 
 extern pci_dev_t pci_find_device (unsigned int vendor, unsigned int device, int index);
 extern pci_dev_t pci_find_devices (struct pci_device_id *ids, int index);
-extern pci_dev_t pci_find_class(int wanted_class, int wanted_sub_code,
-                               int wanted_prog_if, int index);
+pci_dev_t pci_find_class(unsigned int find_class, int index);
 
 extern int pci_hose_config_device(struct pci_controller *hose,
                                  pci_dev_t dev,
--

Regards,
Bin

#7 lore raw

PATCH 3/23 x86: pci: Add PCI IDs for Minnowboard Max

In reply to Simon Glass

This board includes a few IDs we have not seen before.

---

 include/pci_ids.h | 5 +++++
 1 file changed, 5 insertions(+)
include/pci_ids.h +5 -0
index 26f4748..1012abe 100644
@@ -1346,6 +1346,7 @@
 
 #define PCI_VENDOR_ID_REALTEK		0x10ec
 #define PCI_DEVICE_ID_REALTEK_8139	0x8139
+#define PCI_DEVICE_ID_REALTEK_8168	0x8168
 
 #define PCI_VENDOR_ID_XILINX		0x10ee
 #define PCI_DEVICE_ID_RME_DIGI96	0x3fc0
@@ -2594,6 +2595,10 @@
 #define PCI_DEVICE_ID_INTEL_I960	0x0960
 #define PCI_DEVICE_ID_INTEL_I960RM	0x0962
 #define PCI_DEVICE_ID_INTEL_CENTERTON_ILB	0x0c60
+#define PCI_DEVICE_ID_INTEL_VALLEYVIEW_SDIO	0x0f15
+#define PCI_DEVICE_ID_INTEL_VALLEYVIEW_SDCARD	0x0f16
+#define PCI_DEVICE_ID_INTEL_VALLEYVIEW_LPC	0x0f1c
+#define PCI_DEVICE_ID_INTEL_VALLEYVIEW_SATA	0x0f23
 #define PCI_DEVICE_ID_INTEL_82541ER	0x1078
 #define PCI_DEVICE_ID_INTEL_82541GI_LF	0x107c
 #define PCI_DEVICE_ID_INTEL_82542	0x1000
Signature · 1 line
2.2.0.rc0.207.ga3a616c
#8 lore raw

PATCH 3/23 x86: pci: Add PCI IDs for Minnowboard Max

Quoted 22 lines · Simon Glass

This board includes a few IDs we have not seen before.

---

 include/pci_ids.h | 5 +++++
 1 file changed, 5 insertions(+)
include/pci_ids.h +1 -0
index 26f4748..1012abe 100644
@@ -1346,6 +1346,7 @@
 
 #define PCI_VENDOR_ID_REALTEK          0x10ec
 #define PCI_DEVICE_ID_REALTEK_8139     0x8139
+#define PCI_DEVICE_ID_REALTEK_8168     0x8168
 
 #define PCI_VENDOR_ID_XILINX           0x10ee
 #define PCI_DEVICE_ID_RME_DIGI96       0x3fc0
@@ -2594,6 +2595,10 @@
 #define PCI_DEVICE_ID_INTEL_I960       0x0960

include/pci_ids.h

Quoted 10 lines
include/pci_ids.h +4 -1
 #define PCI_DEVICE_ID_INTEL_I960RM     0x0962
 #define PCI_DEVICE_ID_INTEL_CENTERTON_ILB      0x0c60
+#define PCI_DEVICE_ID_INTEL_VALLEYVIEW_SDIO    0x0f15
+#define PCI_DEVICE_ID_INTEL_VALLEYVIEW_SDCARD  0x0f16
+#define PCI_DEVICE_ID_INTEL_VALLEYVIEW_LPC     0x0f1c
+#define PCI_DEVICE_ID_INTEL_VALLEYVIEW_SATA    0x0f23
 #define PCI_DEVICE_ID_INTEL_82541ER    0x1078
 #define PCI_DEVICE_ID_INTEL_82541GI_LF 0x107c
 #define PCI_DEVICE_ID_INTEL_82542      0x1000
--
#9 lore raw

PATCH 4/23 x86: video: Enable video for Minnowboard Max

In reply to Simon Glass

This board uses a new PCI ID.

---

 drivers/video/vesa_fb.c | 1 +
 1 file changed, 1 insertion(+)
drivers/video/vesa_fb.c +1 -0
index 3dacafd..3a0fea2 100644
@@ -23,6 +23,7 @@ struct pci_device_id vesa_video_ids[] = {
 	{ .vendor = 0x1002, .device = 0x5159 },
 	{ .vendor = 0x1002, .device = 0x4752 },
 	{ .vendor = 0x1002, .device = 0x5452 },
+	{ .vendor = 0x8086, .device = 0x0f31 },
 	{},
 };
 
Signature · 1 line
2.2.0.rc0.207.ga3a616c
#10 lore raw

PATCH 4/23 x86: video: Enable video for Minnowboard Max

Quoted 13 lines · Simon Glass

This board uses a new PCI ID.

---

 drivers/video/vesa_fb.c | 1 +
 1 file changed, 1 insertion(+)
drivers/video/vesa_fb.c +0 -0
index 3dacafd..3a0fea2 100644

drivers/video/vesa_fb.c struct pci_device_id vesa_video_ids[] = {

Quoted 8 lines
drivers/video/vesa_fb.c +1 -1
@@ -23,6 +23,7 @@ struct pci_device_id vesa_video_ids[] = {
        { .vendor = 0x1002, .device = 0x5159 },
        { .vendor = 0x1002, .device = 0x4752 },
        { .vendor = 0x1002, .device = 0x5452 },
+       { .vendor = 0x8086, .device = 0x0f31 },
        {},
 };
 
--
#11 lore raw

PATCH 5/23 usb: pci: Use pci_find_class() to find the device

In reply to Simon Glass

Use the new utility function instead of local code.

---

 drivers/usb/host/ehci-pci.c | 53 +--------------------------------------------
 1 file changed, 1 insertion(+), 52 deletions(-)
drivers/usb/host/ehci-pci.c +1 -52
index 991b199..b9eabc5 100644
@@ -34,57 +34,6 @@ static struct pci_device_id ehci_pci_ids[] = {
 	{0, 0}
 };
 #else
-static pci_dev_t ehci_find_class(int index)
-{
-	int bus;
-	int devnum;
-	pci_dev_t bdf;
-	uint32_t class;
-
-	for (bus = 0; bus <= pci_last_busno(); bus++) {
-		for (devnum = 0; devnum < PCI_MAX_PCI_DEVICES-1; devnum++) {
-			pci_read_config_dword(PCI_BDF(bus, devnum, 0),
-					      PCI_CLASS_REVISION, &class);
-			if (class >> 16 == 0xffff)
-				continue;
-
-			for (bdf = PCI_BDF(bus, devnum, 0);
-					bdf <= PCI_BDF(bus, devnum,
-						PCI_MAX_PCI_FUNCTIONS - 1);
-					bdf += PCI_BDF(0, 0, 1)) {
-				pci_read_config_dword(bdf, PCI_CLASS_REVISION,
-						      &class);
-				class >>= 8;
-				/*
-				 * Here be dragons! In case we have multiple
-				 * PCI EHCI controllers, this function will
-				 * be called multiple times as well. This
-				 * function will scan the PCI busses, always
-				 * starting from bus 0, device 0, function 0,
-				 * until it finds an USB controller. The USB
-				 * stack gives us an 'index' of a controller
-				 * that is currently being registered, which
-				 * is a number, starting from 0 and growing
-				 * in ascending order as controllers are added.
-				 * To avoid probing the same controller in tne
-				 * subsequent runs of this function, we will
-				 * skip 'index - 1' detected controllers and
-				 * report the index'th controller.
-				 */
-				if (class != PCI_CLASS_SERIAL_USB_EHCI)
-					continue;
-				if (index) {
-					index--;
-					continue;
-				}
-				/* Return index'th controller. */
-				return bdf;
-			}
-		}
-	}
-
-	return -ENODEV;
-}
 #endif
 
 /*
@@ -102,7 +51,7 @@ int ehci_hcd_init(int index, enum usb_init_type init,
 #ifdef CONFIG_PCI_EHCI_DEVICE
 	pdev = pci_find_devices(ehci_pci_ids, CONFIG_PCI_EHCI_DEVICE);
 #else
-	pdev = ehci_find_class(index);
+	pdev = pci_find_class(PCI_CLASS_SERIAL_USB_EHCI, index);
 #endif
 	if (pdev < 0) {
 		printf("EHCI host controller not found\n");
Signature · 1 line
2.2.0.rc0.207.ga3a616c
#12 lore raw

PATCH 5/23 usb: pci: Use pci_find_class() to find the device

Quoted 71 lines · Simon Glass

Use the new utility function instead of local code.

---

 drivers/usb/host/ehci-pci.c | 53 +--------------------------------------------
 1 file changed, 1 insertion(+), 52 deletions(-)
drivers/usb/host/ehci-pci.c +0 -51
index 991b199..b9eabc5 100644
@@ -34,57 +34,6 @@ static struct pci_device_id ehci_pci_ids[] = {
        {0, 0}
 };
 #else
-static pci_dev_t ehci_find_class(int index)
-{
-       int bus;
-       int devnum;
-       pci_dev_t bdf;
-       uint32_t class;
-
-       for (bus = 0; bus <= pci_last_busno(); bus++) {
-               for (devnum = 0; devnum < PCI_MAX_PCI_DEVICES-1; devnum++) {
-                       pci_read_config_dword(PCI_BDF(bus, devnum, 0),
-                                             PCI_CLASS_REVISION, &class);
-                       if (class >> 16 == 0xffff)
-                               continue;
-
-                       for (bdf = PCI_BDF(bus, devnum, 0);
-                                       bdf <= PCI_BDF(bus, devnum,
-                                               PCI_MAX_PCI_FUNCTIONS - 1);
-                                       bdf += PCI_BDF(0, 0, 1)) {
-                               pci_read_config_dword(bdf, PCI_CLASS_REVISION,
-                                                     &class);
-                               class >>= 8;
-                               /*
-                                * Here be dragons! In case we have multiple
-                                * PCI EHCI controllers, this function will
-                                * be called multiple times as well. This
-                                * function will scan the PCI busses, always
-                                * starting from bus 0, device 0, function 0,
-                                * until it finds an USB controller. The USB
-                                * stack gives us an 'index' of a controller
-                                * that is currently being registered, which
-                                * is a number, starting from 0 and growing
-                                * in ascending order as controllers are added.
-                                * To avoid probing the same controller in tne
-                                * subsequent runs of this function, we will
-                                * skip 'index - 1' detected controllers and
-                                * report the index'th controller.
-                                */
-                               if (class != PCI_CLASS_SERIAL_USB_EHCI)
-                                       continue;
-                               if (index) {
-                                       index--;
-                                       continue;
-                               }
-                               /* Return index'th controller. */
-                               return bdf;
-                       }
-               }
-       }
-
-       return -ENODEV;
-}
 #endif
 
 /*

drivers/usb/host/ehci-pci.c int ehci_hcd_init(int index, enum usb_init_type init,

Quoted 9 lines
drivers/usb/host/ehci-pci.c +1 -2
@@ -102,7 +51,7 @@ int ehci_hcd_init(int index, enum usb_init_type init,
 #ifdef CONFIG_PCI_EHCI_DEVICE
        pdev = pci_find_devices(ehci_pci_ids, CONFIG_PCI_EHCI_DEVICE);
 #else
-       pdev = ehci_find_class(index);
+       pdev = pci_find_class(PCI_CLASS_SERIAL_USB_EHCI, index);
 #endif
        if (pdev < 0) {
                printf("EHCI host controller not found\n");
--
#13 lore raw

PATCH 5/23 usb: pci: Use pci_find_class() to find the device

In reply to Simon Glass
Quoted 8 lines · Simon Glass

Use the new utility function instead of local code.

---

 drivers/usb/host/ehci-pci.c | 53

+-------------------------------------------- 1 file changed, 1 insertion(+), 52 deletions(-)

Nice!

Do you want to pick it through the x86 tree or shall I pick it through USB ?

Best regards,
Marek Vasut

#14 lore raw

PATCH 5/23 usb: pci: Use pci_find_class() to find the device

Hi Marek,

Quoted 10 lines · Marek Vasut
Quoted 8 lines · Simon Glass

Use the new utility function instead of local code.

---

 drivers/usb/host/ehci-pci.c | 53

+-------------------------------------------- 1 file changed, 1 insertion(+), 52 deletions(-)

Quoted 6 lines

Nice!

Do you want to pick it through the x86 tree or shall I pick it through USB ?

I think x86 is better since it is part of a series.

Regards,
Simon

#15 lore raw

PATCH 5/23 usb: pci: Use pci_find_class() to find the device

Quoted 1 line · Simon Glass

Hi Marek,

Hi Simon,

Quoted 12 lines · Marek Vasut
Quoted 11 lines · Simon Glass
Quoted 9 lines

Use the new utility function instead of local code.

---

 drivers/usb/host/ehci-pci.c | 53

+-------------------------------------------- 1 file changed, 1 insertion(+), 52 deletions(-)

Quoted 8 lines
Quoted 6 lines

Nice!

Do you want to pick it through the x86 tree or shall I pick it through USB ?

I think x86 is better since it is part of a series.

I agree, thanks!

Best regards,
Marek Vasut

#16 lore raw

PATCH 6/23 usb: pci: Add XHCI driver for PCI

In reply to Simon Glass

Add a driver which locates the available XHCI controllers on the PCI bus and makes them available.

---

 drivers/usb/host/Makefile   |  1 +
 drivers/usb/host/xhci-pci.c | 60 +++++++++++++++++++++++++++++++++++++++++++++
 2 files changed, 61 insertions(+)
 create mode 100644 drivers/usb/host/xhci-pci.c
drivers/usb/host/Makefile +1 -0
index c11b551..66d6e9a 100644
@@ -47,6 +47,7 @@ obj-$(CONFIG_USB_XHCI) += xhci.o xhci-mem.o xhci-ring.o
 obj-$(CONFIG_USB_XHCI_KEYSTONE) += xhci-keystone.o
 obj-$(CONFIG_USB_XHCI_EXYNOS) += xhci-exynos5.o
 obj-$(CONFIG_USB_XHCI_OMAP) += xhci-omap.o
+obj-$(CONFIG_USB_XHCI_PCI) += xhci-pci.o
 
 # designware
 obj-$(CONFIG_USB_DWC2) += dwc2.o
drivers/usb/host/xhci-pci.c new file +60 -0

60 lines not on this page · raw message

Signature · 1 line
2.2.0.rc0.207.ga3a616c
#17 lore raw

PATCH 6/23 usb: pci: Add XHCI driver for PCI

Quoted 80 lines · Simon Glass

Add a driver which locates the available XHCI controllers on the PCI bus and makes them available.

---

 drivers/usb/host/Makefile   |  1 +
 drivers/usb/host/xhci-pci.c | 60 +++++++++++++++++++++++++++++++++++++++++++++
 2 files changed, 61 insertions(+)
 create mode 100644 drivers/usb/host/xhci-pci.c
drivers/usb/host/Makefile +1 -0
index c11b551..66d6e9a 100644
@@ -47,6 +47,7 @@ obj-$(CONFIG_USB_XHCI) += xhci.o xhci-mem.o xhci-ring.o
 obj-$(CONFIG_USB_XHCI_KEYSTONE) += xhci-keystone.o
 obj-$(CONFIG_USB_XHCI_EXYNOS) += xhci-exynos5.o
 obj-$(CONFIG_USB_XHCI_OMAP) += xhci-omap.o
+obj-$(CONFIG_USB_XHCI_PCI) += xhci-pci.o
 
 # designware
 obj-$(CONFIG_USB_DWC2) += dwc2.o
drivers/usb/host/xhci-pci.c new file +51 -0
new file mode 100644
index 0000000..361fcce
@@ -0,0 +1,60 @@
+/*
+ * Copyright (c) 2015, Google, Inc
+ * Written by Simon Glass <[email protected]>
+ * All rights reserved.
+ *
+ * SPDX-License-Identifier:    GPL-2.0
+ */
+
+#include <common.h>
+#include <errno.h>
+#include <pci.h>
+#include <usb.h>
+
+#include "xhci.h"
+
+/*
+ * Create the appropriate control structures to manage a new XHCI host
+ * controller.
+ */
+int xhci_hcd_init(int index, struct xhci_hccr **ret_hccr,
+                 struct xhci_hcor **ret_hcor)
+{
+       struct xhci_hccr *hccr;
+       struct xhci_hcor *hcor;
+       pci_dev_t pdev;
+       uint32_t cmd;
+       int len;
+
+       pdev = pci_find_class(PCI_CLASS_SERIAL_USB_XHCI, index);
+       if (pdev < 0) {
+               printf("XHCI host controller not found\n");
+               return -1;
+       }
+
+       hccr = (struct xhci_hccr *)pci_map_bar(pdev,
+                       PCI_BASE_ADDRESS_0, PCI_REGION_MEM);
+       len = HC_LENGTH(xhci_readl(&hccr->cr_capbase));
+       hcor = (struct xhci_hcor *)((uint32_t)hccr + len);
+
+       debug("XHCI-PCI init hccr 0x%x and hcor 0x%x hc_length %d\n",
+             (uint32_t)hccr, (uint32_t)hcor, len);
+
+       *ret_hccr = hccr;
+       *ret_hcor = hcor;
+
+       /* enable busmaster */
+       pci_read_config_dword(pdev, PCI_COMMAND, &cmd);
+       cmd |= PCI_COMMAND_MASTER;
+       pci_write_config_dword(pdev, PCI_COMMAND, cmd);
+
+       return 0;

drivers/usb/host/xhci-pci.c

Quoted 10 lines
drivers/usb/host/xhci-pci.c new file +9 -1
+}
+
+/*
+ * Destroy the appropriate control structures corresponding * to the XHCI host
+ * controller
+ */
+void xhci_hcd_stop(int index)
+{
+}
--
#18 lore raw

PATCH 6/23 usb: pci: Add XHCI driver for PCI

In reply to Simon Glass
Quoted 4 lines · Simon Glass

Add a driver which locates the available XHCI controllers on the PCI bus and makes them available.

Hi!

Which xhci controllers did you test with this patch and on which platform please? Is it just the minnow max + the integrated usb 3.0 controller on it? I recall I tried this, but had trouble getting the xhci-pci going on MX6 with a PCIe card with renesas controller.

Thanks for working on this !

Best regards,
Marek Vasut

#19 lore raw

PATCH 6/23 usb: pci: Add XHCI driver for PCI

Hi Marek,

Quoted 6 lines · Marek Vasut
Quoted 4 lines · Simon Glass

Add a driver which locates the available XHCI controllers on the PCI bus and makes them available.

Quoted 8 lines

Hi!

Which xhci controllers did you test with this patch and on which platform please? Is it just the minnow max + the integrated usb 3.0 controller on it? I recall I tried this, but had trouble getting the xhci-pci going on MX6 with a PCIe card with renesas controller.

Thanks for working on this !

I tested it on an Intel controller (MinnowMax board). As mentioned in the cover letter it doesn't actually work, but I suspect that could be an XHCI stack issue. Not 100% sure though. At least this is a starting point.

Regards,
Simon

#20 lore raw

PATCH 6/23 usb: pci: Add XHCI driver for PCI

Quoted 1 line · Simon Glass

Hi Marek,

Hi!

Quoted 14 lines · Marek Vasut
Quoted 13 lines · Simon Glass
Quoted 4 lines

Add a driver which locates the available XHCI controllers on the PCI bus and makes them available.

Hi!

Which xhci controllers did you test with this patch and on which platform please? Is it just the minnow max + the integrated usb 3.0 controller on it? I recall I tried this, but had trouble getting the xhci-pci going on MX6 with a PCIe card with renesas controller.

Quoted 6 lines
Quoted 1 line

Thanks for working on this !

I tested it on an Intel controller (MinnowMax board). As mentioned in the cover letter it doesn't actually work, but I suspect that could be an XHCI stack issue. Not 100% sure though. At least this is a starting point.

Ah, I must have missed that, sorry. Good luck with this USB3 stuff!

Best regards,
Marek Vasut

#21 lore raw

PATCH 7/23 x86: Add an option to enabling building a ROM file

In reply to Simon Glass

Rather than requiring the Makefile to be modified, provide a build option to enable the ROM to be built.

We cannot do this by default since it requires binary blobs. Without these the build will fail.

---

 Makefile       |  5 +++--
 doc/README.x86 | 10 ++++++----
 2 files changed, 9 insertions(+), 6 deletions(-)
Makefile +3 -2
index a876f1f..c6e4ad1 100644
@@ -729,8 +729,9 @@ ALL-$(CONFIG_SPL) += $(CONFIG_SPL_TARGET:"%"=%)
 endif
 ALL-$(CONFIG_REMAKE_ELF) += u-boot.elf
 
-# We can't do this yet due to the need for binary blobs
-# ALL-$(CONFIG_X86_RESET_VECTOR) += u-boot.rom
+ifneq ($(BUILD_ROM),)
+ALL-$(CONFIG_X86_RESET_VECTOR) += u-boot.rom
+endif
 
 # enable combined SPL/u-boot/dtb rules for tegra
 ifneq ($(CONFIG_TEGRA),)
doc/README.x86 +6 -4
index 7df8cc5..809a291 100644
@@ -51,9 +51,11 @@ Building ROM version of U-Boot (hereafter referred to as u-boot.rom) is a
 little bit tricky, as generally it requires several binary blobs which are not
 shipped in the U-Boot source tree. Due to this reason, the u-boot.rom build is
 not turned on by default in the U-Boot source tree. Firstly, you need turn it
-on by uncommenting the following line in the main U-Boot Makefile:
+on by enabling the ROM board:
 
-# ALL-$(CONFIG_X86_RESET_VECTOR) += u-boot.rom
+$ export BUILD_ROM=y
+
+This tells the Makefile to build u-boot.rom as a target.
 
 Link-specific instructions:
 
@@ -126,11 +128,11 @@ Make sure 0x1110000 matches CONFIG_SYS_TEXT_BASE and 0x1110015 matches the
 symbol address of _start (in arch/x86/cpu/start.S).
 
 If you want to use ELF as the coreboot payload, change U-Boot configuration to
-use CONFIG_OF_EMBED.
+use CONFIG_OF_EMBED instead of CONFIG_OF_SEPARATE.
 
 CPU Microcode
 -------------
-Modern CPU usually requires a special bit stream called microcode [5] to be
+Modern CPUs usually requires a special bit stream called microcode [5] to be
 loaded on the processor after power up in order to function properly. U-Boot
 has already integrated these as hex dumps in the source tree.
 
Signature · 1 line
2.2.0.rc0.207.ga3a616c
#22 lore raw

PATCH 7/23 x86: Add an option to enabling building a ROM file

Hi Simon,

Quoted 34 lines · Simon Glass

Rather than requiring the Makefile to be modified, provide a build option to enable the ROM to be built.

We cannot do this by default since it requires binary blobs. Without these the build will fail.

---

 Makefile       |  5 +++--
 doc/README.x86 | 10 ++++++----
 2 files changed, 9 insertions(+), 6 deletions(-)
Makefile +3 -2
index a876f1f..c6e4ad1 100644
@@ -729,8 +729,9 @@ ALL-$(CONFIG_SPL) += $(CONFIG_SPL_TARGET:"%"=%)
 endif
 ALL-$(CONFIG_REMAKE_ELF) += u-boot.elf
 
-# We can't do this yet due to the need for binary blobs
-# ALL-$(CONFIG_X86_RESET_VECTOR) += u-boot.rom
+ifneq ($(BUILD_ROM),)
+ALL-$(CONFIG_X86_RESET_VECTOR) += u-boot.rom
+endif
 
 # enable combined SPL/u-boot/dtb rules for tegra
 ifneq ($(CONFIG_TEGRA),)
doc/README.x86 +0 -0
index 7df8cc5..809a291 100644

doc/README.x86 Building ROM version of U-Boot (hereafter referred to as u-boot.rom) is a · line 54

Quoted 5 lines
doc/README.x86 +1 -1
@@ -51,9 +51,11 @@ Building ROM version of U-Boot (hereafter referred to as u-boot.rom) is a
 little bit tricky, as generally it requires several binary blobs which are not
 shipped in the U-Boot source tree. Due to this reason, the u-boot.rom build is
 not turned on by default in the U-Boot source tree. Firstly, you need turn it
-on by uncommenting the following line in the main U-Boot Makefile:
+on by enabling the ROM board:

the ROM 'board', or the ROM 'build'?

Quoted 9 lines
doc/README.x86 +3 -1
-# ALL-$(CONFIG_X86_RESET_VECTOR) += u-boot.rom
+$ export BUILD_ROM=y
+
+This tells the Makefile to build u-boot.rom as a target.
 
 Link-specific instructions:
 

doc/README.x86 Make sure 0x1110000 matches CONFIG_SYS_TEXT_BASE and 0x1110015 matches the · line 135

Quoted 10 lines
doc/README.x86 +2 -2
@@ -126,11 +128,11 @@ Make sure 0x1110000 matches CONFIG_SYS_TEXT_BASE and 0x1110015 matches the
 symbol address of _start (in arch/x86/cpu/start.S).
 
 If you want to use ELF as the coreboot payload, change U-Boot configuration to
-use CONFIG_OF_EMBED.
+use CONFIG_OF_EMBED instead of CONFIG_OF_SEPARATE.
 
 CPU Microcode
 -------------
-Modern CPU usually requires a special bit stream called microcode [5] to be
+Modern CPUs usually requires a special bit stream called microcode [5] to be

I don't understand the changes. 'CPUs requires'?

doc/README.x86 Make sure 0x1110000 matches CONFIG_SYS_TEXT_BASE and 0x1110015 matches the

Quoted 4 lines
doc/README.x86 +0 -1
 loaded on the processor after power up in order to function properly. U-Boot
 has already integrated these as hex dumps in the source tree.
 
--

Regards,
Bin

#23 lore raw

PATCH 8/23 x86: Make MMCONF_BASE_ADDRESS common across x86

In reply to Simon Glass

This setting will be used by more than just ivybridge so make it common.

---

 arch/x86/Kconfig                     | 12 ++++++++++++
 board/google/chromebook_link/Kconfig |  1 -
 2 files changed, 12 insertions(+), 1 deletion(-)
arch/x86/Kconfig +12 -0
index 90e828a..1523c91 100644
@@ -356,4 +356,16 @@ source "board/google/chromebook_link/Kconfig"
 
 source "board/intel/crownbay/Kconfig"
 
+config MMCONF_BASE_ADDRESS
+	hex
+        default 0xe0000000
+	help
+	  This is the address of PCI configuration space. It can be set up
+	  amost anywhere. Before it is set up, it is possible to access PCI
+	  configuration space through I/O access, but memory access is more
+	  convenient. Using this, PCI can be scanned and configured. This
+	  should be set to a region that does not conflict with memory
+	  assigned to PCI devices - i.e. the memory and prefetch regions, as
+	  passed to pci_set_region().
+
 endmenu
board/google/chromebook_link/Kconfig +0 -1
index 33a31f3..948af59 100644
@@ -23,7 +23,6 @@ config BOARD_SPECIFIC_OPTIONS # dummy
 	select BOARD_ROMSIZE_KB_8192
 
 config MMCONF_BASE_ADDRESS
-	hex
 	default 0xf0000000
 
 config EARLY_POST_CROS_EC
Signature · 1 line
2.2.0.rc0.207.ga3a616c
#24 lore raw

PATCH 8/23 x86: Make MMCONF_BASE_ADDRESS common across x86

Hi Simon,

Quoted 14 lines · Simon Glass

This setting will be used by more than just ivybridge so make it common.

---

 arch/x86/Kconfig                     | 12 ++++++++++++
 board/google/chromebook_link/Kconfig |  1 -
 2 files changed, 12 insertions(+), 1 deletion(-)
arch/x86/Kconfig +0 -0
index 90e828a..1523c91 100644

arch/x86/Kconfig source "board/google/chromebook_link/Kconfig" · line 359

Quoted 4 lines
arch/x86/Kconfig +1 -0
@@ -356,4 +356,16 @@ source "board/google/chromebook_link/Kconfig"
 
 source "board/intel/crownbay/Kconfig"
 
+config MMCONF_BASE_ADDRESS

This name is sort of generic. How about PCIE_ECAM_BASE?

arch/x86/Kconfig source "board/google/chromebook_link/Kconfig" · line 363

Quoted 4 lines
arch/x86/Kconfig +4 -0
+       hex
+        default 0xe0000000
+       help
+         This is the address of PCI configuration space. It can be set up

Would it be better to write: This is the memory-mapped address of PCI configuration space, which is only available through Enhanced Configuration Access Mechanism (ECAM) with PCI Express.

arch/x86/Kconfig source "board/google/chromebook_link/Kconfig" · line 364

Quoted 1 line
arch/x86/Kconfig +1 -0
+         amost anywhere. Before it is set up, it is possible to access PCI

Typo of 'almost'. How about it is 'only' possible?

Quoted 12 lines
arch/x86/Kconfig +6 -0
+         configuration space through I/O access, but memory access is more
+         convenient. Using this, PCI can be scanned and configured. This
+         should be set to a region that does not conflict with memory
+         assigned to PCI devices - i.e. the memory and prefetch regions, as
+         passed to pci_set_region().
+
 endmenu
board/google/chromebook_link/Kconfig +0 -0
index 33a31f3..948af59 100644

board/google/chromebook_link/Kconfig config BOARD_SPECIFIC_OPTIONS # dummy

Quoted 8 lines
board/google/chromebook_link/Kconfig +0 -2
@@ -23,7 +23,6 @@ config BOARD_SPECIFIC_OPTIONS # dummy
        select BOARD_ROMSIZE_KB_8192
 
 config MMCONF_BASE_ADDRESS
-       hex
        default 0xf0000000
 
 config EARLY_POST_CROS_EC
--

Regards,
Bin

#25 lore raw

PATCH 9/23 x86: video: Allow video ROM execution to fall back to the other method

In reply to Simon Glass

If the BIOS emulator is not available, allow use of native execution if available, and vice versa. This can be controlled by the caller.

---

 arch/x86/cpu/ivybridge/gma.c |  3 ++-
 drivers/pci/pci_rom.c        | 32 +++++++++++++++++++++++++-------
 drivers/video/vesa_fb.c      |  6 +++---
 include/pci_rom.h            | 15 +++++++++++++--
 4 files changed, 43 insertions(+), 13 deletions(-)
arch/x86/cpu/ivybridge/gma.c +2 -1
index 6cf9654..821ea25 100644
@@ -758,7 +758,8 @@ int gma_func0_init(pci_dev_t dev, struct pci_controller *hose,
 
 #ifdef CONFIG_VIDEO
 	start = get_timer(0);
-	ret = pci_run_vga_bios(dev, int15_handler, false);
+	ret = pci_run_vga_bios(dev, int15_handler, PCI_ROM_USE_NATIVE |
+			       PCI_ROM_ALLOW_FALLBACK);
 	debug("BIOS ran in %lums\n", get_timer(start));
 #endif
 	/* Post VBIOS init */
drivers/pci/pci_rom.c +25 -7
index eb76591..0796179 100644
@@ -228,11 +228,12 @@ int vbe_get_video_info(struct graphic_device *gdev)
 #endif
 }
 
-int pci_run_vga_bios(pci_dev_t dev, int (*int15_handler)(void), bool emulate)
+int pci_run_vga_bios(pci_dev_t dev, int (*int15_handler)(void), int exec_method)
 {
 	struct pci_rom_header *rom, *ram;
 	int vesa_mode = -1;
 	uint16_t class;
+	bool emulate;
 	int ret;
 
 	/* Only execute VGA ROMs */
@@ -262,6 +263,29 @@ int pci_run_vga_bios(pci_dev_t dev, int (*int15_handler)(void), bool emulate)
 	vesa_mode = CONFIG_FRAMEBUFFER_VESA_MODE;
 #endif
 	debug("Selected vesa mode %#x\n", vesa_mode);
+
+	if (exec_method & PCI_ROM_USE_NATIVE) {
+#ifdef CONFIG_X86
+		emulate = false;
+#else
+		if (!(exec_method & PCI_ROM_ALLOW_FALLBACK)) {
+			printf("BIOS native execution is only available on x86\n");
+			return -ENOSYS;
+		}
+		emulate = true;
+#endif
+	} else {
+#ifdef CONFIG_BIOSEMU
+		emulate = true;
+#else
+		if (!(exec_method & PCI_ROM_ALLOW_FALLBACK)) {
+			printf("BIOS emulation not available - see CONFIG_BIOSEMU\n");
+			return -ENOSYS;
+		}
+		emulate = false;
+#endif
+	}
+
 	if (emulate) {
 #ifdef CONFIG_BIOSEMU
 		BE_VGAInfo *info;
@@ -274,9 +298,6 @@ int pci_run_vga_bios(pci_dev_t dev, int (*int15_handler)(void), bool emulate)
 				  vesa_mode, &mode_info);
 		if (ret)
 			return ret;
-#else
-		printf("BIOS emulation not available - see CONFIG_BIOSEMU\n");
-		return -ENOSYS;
 #endif
 	} else {
 #ifdef CONFIG_X86
@@ -284,9 +305,6 @@ int pci_run_vga_bios(pci_dev_t dev, int (*int15_handler)(void), bool emulate)
 
 		bios_run_on_x86(dev, (unsigned long)ram, vesa_mode,
 				&mode_info);
-#else
-		printf("BIOS native execution is only available on x86\n");
-		return -ENOSYS;
 #endif
 	}
 	debug("Final vesa mode %#x\n", mode_info.video_mode);
drivers/video/vesa_fb.c +3 -3
index 3a0fea2..9164f8d 100644
@@ -42,8 +42,8 @@ void *video_hw_init(void)
 			printf("no card detected\n");
 			return NULL;
 		}
-		printf("bdf %x\n", dev);
-		ret = pci_run_vga_bios(dev, NULL, true);
+		ret = pci_run_vga_bios(dev, NULL, PCI_ROM_USE_NATIVE |
+				       PCI_ROM_ALLOW_FALLBACK);
 		if (ret) {
 			printf("failed to run video BIOS: %d\n", ret);
 			return NULL;
@@ -59,7 +59,7 @@ void *video_hw_init(void)
 	sprintf(gdev->modeIdent, "%dx%dx%d", gdev->winSizeX, gdev->winSizeY,
 		bits_per_pixel);
 	printf("%s\n", gdev->modeIdent);
-	debug("Framex buffer at %x\n", gdev->pciBase);
+	debug("Frame buffer at %x\n", gdev->pciBase);
 
 	return (void *)gdev;
 }
include/pci_rom.h +13 -2
index 4ba36eb..d24c52a 100644
@@ -33,14 +33,25 @@ struct pci_rom_data {
 	uint16_t reserved_2;
 };
 
+/*
+ * Determines which execution method is used and whether we allow falling back
+ * to the other if the requested method is not available.
+ */
+enum pci_rom_emul_t {
+	PCI_ROM_EMULATE		= 0 << 0,
+	PCI_ROM_USE_NATIVE	= 1 << 0,
+	PCI_ROM_ALLOW_FALLBACK	= 1 << 1,
+};
+
  /**
  * pci_run_vga_bios() - Run the VGA BIOS in an x86 PC
  *
  * @dev:	Video device containing the BIOS
  * @int15_handler:	Function to call to handle int 0x15
- * @emulate:	true to use the x86 emulator, false to run native
+ * @exec_method:	flags from enum pci_rom_emul_t
  */
-int pci_run_vga_bios(pci_dev_t dev, int (*int15_handler)(void), bool emulate);
+int pci_run_vga_bios(pci_dev_t dev, int (*int15_handler)(void),
+		     int exec_method);
 
 /**
  * board_map_oprom_vendev() - map several PCI IDs to the one the ROM expects
Signature · 1 line
2.2.0.rc0.207.ga3a616c
#26 lore raw

PATCH 9/23 x86: video: Allow video ROM execution to fall back to the other method

Hi Simon,

Quoted 6 lines · Simon Glass

If the BIOS emulator is not available, allow use of native execution if available, and vice versa. This can be controlled by the caller.

---

But please see a minor comment below.

Quoted 117 lines
 arch/x86/cpu/ivybridge/gma.c |  3 ++-
 drivers/pci/pci_rom.c        | 32 +++++++++++++++++++++++++-------
 drivers/video/vesa_fb.c      |  6 +++---
 include/pci_rom.h            | 15 +++++++++++++--
 4 files changed, 43 insertions(+), 13 deletions(-)
arch/x86/cpu/ivybridge/gma.c +2 -1
index 6cf9654..821ea25 100644
@@ -758,7 +758,8 @@ int gma_func0_init(pci_dev_t dev, struct pci_controller *hose,
 
 #ifdef CONFIG_VIDEO
        start = get_timer(0);
-       ret = pci_run_vga_bios(dev, int15_handler, false);
+       ret = pci_run_vga_bios(dev, int15_handler, PCI_ROM_USE_NATIVE |
+                              PCI_ROM_ALLOW_FALLBACK);
        debug("BIOS ran in %lums\n", get_timer(start));
 #endif
        /* Post VBIOS init */
drivers/pci/pci_rom.c +25 -7
index eb76591..0796179 100644
@@ -228,11 +228,12 @@ int vbe_get_video_info(struct graphic_device *gdev)
 #endif
 }
 
-int pci_run_vga_bios(pci_dev_t dev, int (*int15_handler)(void), bool emulate)
+int pci_run_vga_bios(pci_dev_t dev, int (*int15_handler)(void), int exec_method)
 {
        struct pci_rom_header *rom, *ram;
        int vesa_mode = -1;
        uint16_t class;
+       bool emulate;
        int ret;
 
        /* Only execute VGA ROMs */
@@ -262,6 +263,29 @@ int pci_run_vga_bios(pci_dev_t dev, int (*int15_handler)(void), bool emulate)
        vesa_mode = CONFIG_FRAMEBUFFER_VESA_MODE;
 #endif
        debug("Selected vesa mode %#x\n", vesa_mode);
+
+       if (exec_method & PCI_ROM_USE_NATIVE) {
+#ifdef CONFIG_X86
+               emulate = false;
+#else
+               if (!(exec_method & PCI_ROM_ALLOW_FALLBACK)) {
+                       printf("BIOS native execution is only available on x86\n");
+                       return -ENOSYS;
+               }
+               emulate = true;
+#endif
+       } else {
+#ifdef CONFIG_BIOSEMU
+               emulate = true;
+#else
+               if (!(exec_method & PCI_ROM_ALLOW_FALLBACK)) {
+                       printf("BIOS emulation not available - see CONFIG_BIOSEMU\n");
+                       return -ENOSYS;
+               }
+               emulate = false;
+#endif
+       }
+
        if (emulate) {
 #ifdef CONFIG_BIOSEMU
                BE_VGAInfo *info;
@@ -274,9 +298,6 @@ int pci_run_vga_bios(pci_dev_t dev, int (*int15_handler)(void), bool emulate)
                                  vesa_mode, &mode_info);
                if (ret)
                        return ret;
-#else
-               printf("BIOS emulation not available - see CONFIG_BIOSEMU\n");
-               return -ENOSYS;
 #endif
        } else {
 #ifdef CONFIG_X86
@@ -284,9 +305,6 @@ int pci_run_vga_bios(pci_dev_t dev, int (*int15_handler)(void), bool emulate)
 
                bios_run_on_x86(dev, (unsigned long)ram, vesa_mode,
                                &mode_info);
-#else
-               printf("BIOS native execution is only available on x86\n");
-               return -ENOSYS;
 #endif
        }
        debug("Final vesa mode %#x\n", mode_info.video_mode);
drivers/video/vesa_fb.c +3 -3
index 3a0fea2..9164f8d 100644
@@ -42,8 +42,8 @@ void *video_hw_init(void)
                        printf("no card detected\n");
                        return NULL;
                }
-               printf("bdf %x\n", dev);
-               ret = pci_run_vga_bios(dev, NULL, true);
+               ret = pci_run_vga_bios(dev, NULL, PCI_ROM_USE_NATIVE |
+                                      PCI_ROM_ALLOW_FALLBACK);
                if (ret) {
                        printf("failed to run video BIOS: %d\n", ret);
                        return NULL;
@@ -59,7 +59,7 @@ void *video_hw_init(void)
        sprintf(gdev->modeIdent, "%dx%dx%d", gdev->winSizeX, gdev->winSizeY,
                bits_per_pixel);
        printf("%s\n", gdev->modeIdent);
-       debug("Framex buffer at %x\n", gdev->pciBase);
+       debug("Frame buffer at %x\n", gdev->pciBase);
 
        return (void *)gdev;
 }
include/pci_rom.h +0 -0
index 4ba36eb..d24c52a 100644

include/pci_rom.h struct pci_rom_data { · line 40

Quoted 8 lines
include/pci_rom.h +5 -0
@@ -33,14 +33,25 @@ struct pci_rom_data {
        uint16_t reserved_2;
 };
 
+/*
+ * Determines which execution method is used and whether we allow falling back
+ * to the other if the requested method is not available.
+ */
+enum pci_rom_emul_t {

I think we don't need the _t suffix?

Quoted 10 lines
include/pci_rom.h +5 -0
+       PCI_ROM_EMULATE         = 0 << 0,
+       PCI_ROM_USE_NATIVE      = 1 << 0,
+       PCI_ROM_ALLOW_FALLBACK  = 1 << 1,
+};
+
  /**
  * pci_run_vga_bios() - Run the VGA BIOS in an x86 PC
  *
  * @dev:       Video device containing the BIOS
  * @int15_handler:     Function to call to handle int 0x15

include/pci_rom.h struct pci_rom_data {

Quoted 10 lines
include/pci_rom.h +3 -3
- * @emulate:   true to use the x86 emulator, false to run native
+ * @exec_method:       flags from enum pci_rom_emul_t
  */
-int pci_run_vga_bios(pci_dev_t dev, int (*int15_handler)(void), bool emulate);
+int pci_run_vga_bios(pci_dev_t dev, int (*int15_handler)(void),
+                    int exec_method);
 
 /**
  * board_map_oprom_vendev() - map several PCI IDs to the one the ROM expects
--

Regards,
Bin

#27 lore raw

PATCH 10/23 x86: bootstage: Add time measurement for vesa start-up

In reply to Simon Glass

Since we must run a PCI BIOS ROM, and this can take a calamitous amount of time, measure it using bootstage.

---

 drivers/video/vesa_fb.c | 2 ++
 1 file changed, 2 insertions(+)
drivers/video/vesa_fb.c +2 -0
index 9164f8d..47f824a 100644
@@ -42,8 +42,10 @@ void *video_hw_init(void)
 			printf("no card detected\n");
 			return NULL;
 		}
+		bootstage_start(BOOTSTAGE_ID_ACCUM_LCD, "vesa display");
 		ret = pci_run_vga_bios(dev, NULL, PCI_ROM_USE_NATIVE |
 				       PCI_ROM_ALLOW_FALLBACK);
+		bootstage_accum(BOOTSTAGE_ID_ACCUM_LCD);
 		if (ret) {
 			printf("failed to run video BIOS: %d\n", ret);
 			return NULL;
Signature · 1 line
2.2.0.rc0.207.ga3a616c
#28 lore raw

PATCH 10/23 x86: bootstage: Add time measurement for vesa start-up

Quoted 15 lines · Simon Glass

Since we must run a PCI BIOS ROM, and this can take a calamitous amount of time, measure it using bootstage.

---

 drivers/video/vesa_fb.c | 2 ++
 1 file changed, 2 insertions(+)
drivers/video/vesa_fb.c +0 -0
index 9164f8d..47f824a 100644
@@ -42,8 +42,10 @@ void *video_hw_init(void)
                        printf("no card detected\n");

drivers/video/vesa_fb.c void *video_hw_init(void)

Quoted 10 lines
drivers/video/vesa_fb.c +2 -1
                        return NULL;
                }
+               bootstage_start(BOOTSTAGE_ID_ACCUM_LCD, "vesa display");
                ret = pci_run_vga_bios(dev, NULL, PCI_ROM_USE_NATIVE |
                                       PCI_ROM_ALLOW_FALLBACK);
+               bootstage_accum(BOOTSTAGE_ID_ACCUM_LCD);
                if (ret) {
                        printf("failed to run video BIOS: %d\n", ret);
                        return NULL;
--
#29 lore raw

PATCH 11/23 x86: Move common FSP code into a common location

In reply to Simon Glass

---

 arch/x86/cpu/queensbay/Makefile                                | 2 +-
 arch/x86/cpu/queensbay/fsp_configs.c                           | 2 +-
 arch/x86/cpu/queensbay/tnc.c                                   | 2 +-
 arch/x86/cpu/queensbay/tnc_dram.c                              | 2 +-
 arch/x86/cpu/queensbay/tnc_pci.c                               | 2 +-
 arch/x86/include/asm/{arch-queensbay => }/fsp/fsp_api.h        | 0
 arch/x86/include/asm/{arch-queensbay => }/fsp/fsp_bootmode.h   | 0
 arch/x86/include/asm/{arch-queensbay => }/fsp/fsp_ffs.h        | 0
 arch/x86/include/asm/{arch-queensbay => }/fsp/fsp_fv.h         | 0
 arch/x86/include/asm/{arch-queensbay => }/fsp/fsp_hob.h        | 0
 arch/x86/include/asm/{arch-queensbay => }/fsp/fsp_infoheader.h | 0
 arch/x86/include/asm/{arch-queensbay => }/fsp/fsp_platform.h   | 0
 arch/x86/include/asm/{arch-queensbay => }/fsp/fsp_support.h    | 2 +-
 arch/x86/include/asm/{arch-queensbay => }/fsp/fsp_types.h      | 0
 arch/x86/lib/Makefile                                          | 1 +
 arch/x86/lib/cmd_hob.c                                         | 2 +-
 arch/x86/lib/fsp/Makefile                                      | 7 +++++++
 arch/x86/{cpu/queensbay => lib/fsp}/fsp_support.c              | 2 +-
 18 files changed, 16 insertions(+), 8 deletions(-)
 rename arch/x86/include/asm/{arch-queensbay => }/fsp/fsp_api.h (100%)
 rename arch/x86/include/asm/{arch-queensbay => }/fsp/fsp_bootmode.h (100%)
 rename arch/x86/include/asm/{arch-queensbay => }/fsp/fsp_ffs.h (100%)
 rename arch/x86/include/asm/{arch-queensbay => }/fsp/fsp_fv.h (100%)
 rename arch/x86/include/asm/{arch-queensbay => }/fsp/fsp_hob.h (100%)
 rename arch/x86/include/asm/{arch-queensbay => }/fsp/fsp_infoheader.h (100%)
 rename arch/x86/include/asm/{arch-queensbay => }/fsp/fsp_platform.h (100%)
 rename arch/x86/include/asm/{arch-queensbay => }/fsp/fsp_support.h (99%)
 rename arch/x86/include/asm/{arch-queensbay => }/fsp/fsp_types.h (100%)
 create mode 100644 arch/x86/lib/fsp/Makefile
 rename arch/x86/{cpu/queensbay => lib/fsp}/fsp_support.c (99%)
arch/x86/cpu/queensbay/Makefile +1 -1
index 2c2ec01..b3e7d87 100644
@@ -5,5 +5,5 @@
 #
 
 obj-y += tnc_car.o tnc_dram.o tnc.o topcliff.o
-obj-y += fsp_configs.o fsp_support.o
+obj-y += fsp_configs.o
 obj-$(CONFIG_PCI) += tnc_pci.o
arch/x86/cpu/queensbay/fsp_configs.c +1 -1
index af28e45..78bc966 100644
@@ -6,7 +6,7 @@
  */
 
 #include <common.h>
-#include <asm/arch/fsp/fsp_support.h>
+#include <asm/fsp/fsp_support.h>
 
 void update_fsp_upd(struct upd_region *fsp_upd)
 {
arch/x86/cpu/queensbay/tnc.c +1 -1
index 8637cdc..f9b3bfa 100644
@@ -9,7 +9,7 @@
 #include <asm/pci.h>
 #include <asm/post.h>
 #include <asm/arch/tnc.h>
-#include <asm/arch/fsp/fsp_support.h>
+#include <asm/fsp/fsp_support.h>
 #include <asm/processor.h>
 
 static void unprotect_spi_flash(void)
arch/x86/cpu/queensbay/tnc_dram.c +1 -1
index df79a39..4c0a7c8 100644
@@ -5,7 +5,7 @@
  */
 
 #include <common.h>
-#include <asm/arch/fsp/fsp_support.h>
+#include <asm/fsp/fsp_support.h>
 #include <asm/e820.h>
 #include <asm/post.h>
 
arch/x86/cpu/queensbay/tnc_pci.c +1 -1
index 39bff49..9b0b725 100644
@@ -7,7 +7,7 @@
 #include <common.h>
 #include <pci.h>
 #include <asm/pci.h>
-#include <asm/arch/fsp/fsp_support.h>
+#include <asm/fsp/fsp_support.h>
 
 DECLARE_GLOBAL_DATA_PTR;
 
arch/x86/include/asm/fsp/fsp_api.h renamed from arch/x86/include/asm/arch-queensbay/fsp/fsp_api.h +0 -0
similarity index 100%
rename from arch/x86/include/asm/arch-queensbay/fsp/fsp_api.h
rename to arch/x86/include/asm/fsp/fsp_api.h
arch/x86/include/asm/fsp/fsp_bootmode.h renamed from arch/x86/include/asm/arch-queensbay/fsp/fsp_bootmode.h +0 -0
similarity index 100%
rename from arch/x86/include/asm/arch-queensbay/fsp/fsp_bootmode.h
rename to arch/x86/include/asm/fsp/fsp_bootmode.h
arch/x86/include/asm/fsp/fsp_ffs.h renamed from arch/x86/include/asm/arch-queensbay/fsp/fsp_ffs.h +0 -0
similarity index 100%
rename from arch/x86/include/asm/arch-queensbay/fsp/fsp_ffs.h
rename to arch/x86/include/asm/fsp/fsp_ffs.h
arch/x86/include/asm/fsp/fsp_fv.h renamed from arch/x86/include/asm/arch-queensbay/fsp/fsp_fv.h +0 -0
similarity index 100%
rename from arch/x86/include/asm/arch-queensbay/fsp/fsp_fv.h
rename to arch/x86/include/asm/fsp/fsp_fv.h
arch/x86/include/asm/fsp/fsp_hob.h renamed from arch/x86/include/asm/arch-queensbay/fsp/fsp_hob.h +0 -0
similarity index 100%
rename from arch/x86/include/asm/arch-queensbay/fsp/fsp_hob.h
rename to arch/x86/include/asm/fsp/fsp_hob.h
arch/x86/include/asm/fsp/fsp_infoheader.h renamed from arch/x86/include/asm/arch-queensbay/fsp/fsp_infoheader.h +0 -0
similarity index 100%
rename from arch/x86/include/asm/arch-queensbay/fsp/fsp_infoheader.h
rename to arch/x86/include/asm/fsp/fsp_infoheader.h
arch/x86/include/asm/fsp/fsp_platform.h renamed from arch/x86/include/asm/arch-queensbay/fsp/fsp_platform.h +0 -0
similarity index 100%
rename from arch/x86/include/asm/arch-queensbay/fsp/fsp_platform.h
rename to arch/x86/include/asm/fsp/fsp_platform.h
arch/x86/include/asm/fsp/fsp_support.h renamed from arch/x86/include/asm/arch-queensbay/fsp/fsp_support.h +1 -1
similarity index 99%
rename from arch/x86/include/asm/arch-queensbay/fsp/fsp_support.h
rename to arch/x86/include/asm/fsp/fsp_support.h
index ebdbd03..6329cfe 100644
@@ -16,7 +16,7 @@
 #include "fsp_platform.h"
 #include "fsp_infoheader.h"
 #include "fsp_bootmode.h"
-#include "fsp_vpd.h"
+#include <asm/arch/fsp/fsp_vpd.h>
 
 struct shared_data {
 	struct fsp_header	*fsp_hdr;
arch/x86/include/asm/fsp/fsp_types.h renamed from arch/x86/include/asm/arch-queensbay/fsp/fsp_types.h +0 -0
similarity index 100%
rename from arch/x86/include/asm/arch-queensbay/fsp/fsp_types.h
rename to arch/x86/include/asm/fsp/fsp_types.h
arch/x86/lib/Makefile +1 -0
index 32d7b98..c17f7f0 100644
@@ -25,6 +25,7 @@ obj-y	+= string.o
 obj-$(CONFIG_SYS_X86_TSC_TIMER)	+= tsc_timer.o
 obj-$(CONFIG_VIDEO_VGA)	+= video.o
 obj-$(CONFIG_CMD_ZBOOT)	+= zimage.o
+obj-$(CONFIG_HAVE_FSP) += fsp/
 
 extra-$(CONFIG_USE_PRIVATE_LIBGCC) := lib.a
 
arch/x86/lib/cmd_hob.c +1 -1
index a0ef037..915746a 100644
@@ -7,7 +7,7 @@
 #include <common.h>
 #include <command.h>
 #include <linux/compiler.h>
-#include <asm/arch/fsp/fsp_support.h>
+#include <asm/fsp/fsp_support.h>
 
 DECLARE_GLOBAL_DATA_PTR;
 
arch/x86/lib/fsp/Makefile new file +7 -0
new file mode 100644
index 0000000..1b9b0e2
@@ -0,0 +1,7 @@
+#
+# Copyright (C) 2015 Google, Inc
+#
+# SPDX-License-Identifier:	GPL-2.0+
+#
+
+obj-y += fsp_support.o
arch/x86/lib/fsp/fsp_support.c renamed from arch/x86/cpu/queensbay/fsp_support.c +1 -1
similarity index 99%
rename from arch/x86/cpu/queensbay/fsp_support.c
rename to arch/x86/lib/fsp/fsp_support.c
index aed3e2b..f6ae85a 100644
@@ -6,7 +6,7 @@
  */
 
 #include <common.h>
-#include <asm/arch/fsp/fsp_support.h>
+#include <asm/fsp/fsp_support.h>
 #include <asm/post.h>
 
 /**
Signature · 1 line
2.2.0.rc0.207.ga3a616c
#30 lore raw

PATCH 11/23 x86: Move common FSP code into a common location

Hi Simon,

Quoted 3 lines · Simon Glass

---

Nice to see the existing FSP support codes are common for new platforms.

Quoted 188 lines
 arch/x86/cpu/queensbay/Makefile                                | 2 +-
 arch/x86/cpu/queensbay/fsp_configs.c                           | 2 +-
 arch/x86/cpu/queensbay/tnc.c                                   | 2 +-
 arch/x86/cpu/queensbay/tnc_dram.c                              | 2 +-
 arch/x86/cpu/queensbay/tnc_pci.c                               | 2 +-
 arch/x86/include/asm/{arch-queensbay => }/fsp/fsp_api.h        | 0
 arch/x86/include/asm/{arch-queensbay => }/fsp/fsp_bootmode.h   | 0
 arch/x86/include/asm/{arch-queensbay => }/fsp/fsp_ffs.h        | 0
 arch/x86/include/asm/{arch-queensbay => }/fsp/fsp_fv.h         | 0
 arch/x86/include/asm/{arch-queensbay => }/fsp/fsp_hob.h        | 0
 arch/x86/include/asm/{arch-queensbay => }/fsp/fsp_infoheader.h | 0
 arch/x86/include/asm/{arch-queensbay => }/fsp/fsp_platform.h   | 0
 arch/x86/include/asm/{arch-queensbay => }/fsp/fsp_support.h    | 2 +-
 arch/x86/include/asm/{arch-queensbay => }/fsp/fsp_types.h      | 0
 arch/x86/lib/Makefile                                          | 1 +
 arch/x86/lib/cmd_hob.c                                         | 2 +-
 arch/x86/lib/fsp/Makefile                                      | 7 +++++++
 arch/x86/{cpu/queensbay => lib/fsp}/fsp_support.c              | 2 +-
 18 files changed, 16 insertions(+), 8 deletions(-)
 rename arch/x86/include/asm/{arch-queensbay => }/fsp/fsp_api.h (100%)
 rename arch/x86/include/asm/{arch-queensbay => }/fsp/fsp_bootmode.h (100%)
 rename arch/x86/include/asm/{arch-queensbay => }/fsp/fsp_ffs.h (100%)
 rename arch/x86/include/asm/{arch-queensbay => }/fsp/fsp_fv.h (100%)
 rename arch/x86/include/asm/{arch-queensbay => }/fsp/fsp_hob.h (100%)
 rename arch/x86/include/asm/{arch-queensbay => }/fsp/fsp_infoheader.h (100%)
 rename arch/x86/include/asm/{arch-queensbay => }/fsp/fsp_platform.h (100%)
 rename arch/x86/include/asm/{arch-queensbay => }/fsp/fsp_support.h (99%)
 rename arch/x86/include/asm/{arch-queensbay => }/fsp/fsp_types.h (100%)
 create mode 100644 arch/x86/lib/fsp/Makefile
 rename arch/x86/{cpu/queensbay => lib/fsp}/fsp_support.c (99%)
arch/x86/cpu/queensbay/Makefile +1 -1
index 2c2ec01..b3e7d87 100644
@@ -5,5 +5,5 @@
 #
 
 obj-y += tnc_car.o tnc_dram.o tnc.o topcliff.o
-obj-y += fsp_configs.o fsp_support.o
+obj-y += fsp_configs.o
 obj-$(CONFIG_PCI) += tnc_pci.o
arch/x86/cpu/queensbay/fsp_configs.c +1 -1
index af28e45..78bc966 100644
@@ -6,7 +6,7 @@
  */
 
 #include <common.h>
-#include <asm/arch/fsp/fsp_support.h>
+#include <asm/fsp/fsp_support.h>
 
 void update_fsp_upd(struct upd_region *fsp_upd)
 {
arch/x86/cpu/queensbay/tnc.c +1 -1
index 8637cdc..f9b3bfa 100644
@@ -9,7 +9,7 @@
 #include <asm/pci.h>
 #include <asm/post.h>
 #include <asm/arch/tnc.h>
-#include <asm/arch/fsp/fsp_support.h>
+#include <asm/fsp/fsp_support.h>
 #include <asm/processor.h>
 
 static void unprotect_spi_flash(void)
arch/x86/cpu/queensbay/tnc_dram.c +1 -1
index df79a39..4c0a7c8 100644
@@ -5,7 +5,7 @@
  */
 
 #include <common.h>
-#include <asm/arch/fsp/fsp_support.h>
+#include <asm/fsp/fsp_support.h>
 #include <asm/e820.h>
 #include <asm/post.h>
 
arch/x86/cpu/queensbay/tnc_pci.c +1 -1
index 39bff49..9b0b725 100644
@@ -7,7 +7,7 @@
 #include <common.h>
 #include <pci.h>
 #include <asm/pci.h>
-#include <asm/arch/fsp/fsp_support.h>
+#include <asm/fsp/fsp_support.h>
 
 DECLARE_GLOBAL_DATA_PTR;
 
arch/x86/include/asm/fsp/fsp_api.h renamed from arch/x86/include/asm/arch-queensbay/fsp/fsp_api.h +0 -0
similarity index 100%
rename from arch/x86/include/asm/arch-queensbay/fsp/fsp_api.h
rename to arch/x86/include/asm/fsp/fsp_api.h
arch/x86/include/asm/fsp/fsp_bootmode.h renamed from arch/x86/include/asm/arch-queensbay/fsp/fsp_bootmode.h +0 -0
similarity index 100%
rename from arch/x86/include/asm/arch-queensbay/fsp/fsp_bootmode.h
rename to arch/x86/include/asm/fsp/fsp_bootmode.h
arch/x86/include/asm/fsp/fsp_ffs.h renamed from arch/x86/include/asm/arch-queensbay/fsp/fsp_ffs.h +0 -0
similarity index 100%
rename from arch/x86/include/asm/arch-queensbay/fsp/fsp_ffs.h
rename to arch/x86/include/asm/fsp/fsp_ffs.h
arch/x86/include/asm/fsp/fsp_fv.h renamed from arch/x86/include/asm/arch-queensbay/fsp/fsp_fv.h +0 -0
similarity index 100%
rename from arch/x86/include/asm/arch-queensbay/fsp/fsp_fv.h
rename to arch/x86/include/asm/fsp/fsp_fv.h
arch/x86/include/asm/fsp/fsp_hob.h renamed from arch/x86/include/asm/arch-queensbay/fsp/fsp_hob.h +0 -0
similarity index 100%
rename from arch/x86/include/asm/arch-queensbay/fsp/fsp_hob.h
rename to arch/x86/include/asm/fsp/fsp_hob.h
arch/x86/include/asm/fsp/fsp_infoheader.h renamed from arch/x86/include/asm/arch-queensbay/fsp/fsp_infoheader.h +0 -0
similarity index 100%
rename from arch/x86/include/asm/arch-queensbay/fsp/fsp_infoheader.h
rename to arch/x86/include/asm/fsp/fsp_infoheader.h
arch/x86/include/asm/fsp/fsp_platform.h renamed from arch/x86/include/asm/arch-queensbay/fsp/fsp_platform.h +0 -0
similarity index 100%
rename from arch/x86/include/asm/arch-queensbay/fsp/fsp_platform.h
rename to arch/x86/include/asm/fsp/fsp_platform.h
arch/x86/include/asm/fsp/fsp_support.h renamed from arch/x86/include/asm/arch-queensbay/fsp/fsp_support.h +1 -1
similarity index 99%
rename from arch/x86/include/asm/arch-queensbay/fsp/fsp_support.h
rename to arch/x86/include/asm/fsp/fsp_support.h
index ebdbd03..6329cfe 100644
@@ -16,7 +16,7 @@
 #include "fsp_platform.h"
 #include "fsp_infoheader.h"
 #include "fsp_bootmode.h"
-#include "fsp_vpd.h"
+#include <asm/arch/fsp/fsp_vpd.h>
 
 struct shared_data {
        struct fsp_header       *fsp_hdr;
arch/x86/include/asm/fsp/fsp_types.h renamed from arch/x86/include/asm/arch-queensbay/fsp/fsp_types.h +0 -0
similarity index 100%
rename from arch/x86/include/asm/arch-queensbay/fsp/fsp_types.h
rename to arch/x86/include/asm/fsp/fsp_types.h
arch/x86/lib/Makefile +1 -0
index 32d7b98..c17f7f0 100644
@@ -25,6 +25,7 @@ obj-y += string.o
 obj-$(CONFIG_SYS_X86_TSC_TIMER)        += tsc_timer.o
 obj-$(CONFIG_VIDEO_VGA)        += video.o
 obj-$(CONFIG_CMD_ZBOOT)        += zimage.o
+obj-$(CONFIG_HAVE_FSP) += fsp/
 
 extra-$(CONFIG_USE_PRIVATE_LIBGCC) := lib.a
 
arch/x86/lib/cmd_hob.c +1 -1
index a0ef037..915746a 100644
@@ -7,7 +7,7 @@
 #include <common.h>
 #include <command.h>
 #include <linux/compiler.h>
-#include <asm/arch/fsp/fsp_support.h>
+#include <asm/fsp/fsp_support.h>
 
 DECLARE_GLOBAL_DATA_PTR;
 
arch/x86/lib/fsp/Makefile new file +7 -0
new file mode 100644
index 0000000..1b9b0e2
@@ -0,0 +1,7 @@
+#
+# Copyright (C) 2015 Google, Inc
+#
+# SPDX-License-Identifier:     GPL-2.0+
+#
+
+obj-y += fsp_support.o
arch/x86/lib/fsp/fsp_support.c renamed from arch/x86/cpu/queensbay/fsp_support.c +0 -0
similarity index 99%
rename from arch/x86/cpu/queensbay/fsp_support.c
rename to arch/x86/lib/fsp/fsp_support.c
index aed3e2b..f6ae85a 100644

arch/x86/lib/fsp/fsp_support.c

Quoted 9 lines
arch/x86/lib/fsp/fsp_support.c renamed from arch/x86/cpu/queensbay/fsp_support.c +1 -2
@@ -6,7 +6,7 @@
  */
 
 #include <common.h>
-#include <asm/arch/fsp/fsp_support.h>
+#include <asm/fsp/fsp_support.h>
 #include <asm/post.h>
 
 /**
--

Regards,
Bin

#31 lore raw

PATCH 12/23 x86: Adjust the FSP types slightly

In reply to Simon Glass

To avoid casts, find_fsp_header() should return a pointer. Add asmlinkage to two API functions which use that convention. UPD_TERMINATOR is common so move it into a common file.

---

 arch/x86/include/asm/arch-queensbay/fsp/fsp_vpd.h | 2 --
 arch/x86/include/asm/fsp/fsp_api.h                | 6 ++++--
 arch/x86/include/asm/fsp/fsp_support.h            | 4 +++-
 arch/x86/lib/fsp/fsp_support.c                    | 4 ++--
 4 files changed, 9 insertions(+), 7 deletions(-)
arch/x86/include/asm/arch-queensbay/fsp/fsp_vpd.h +0 -2
index bce58b1..3c57558 100644
@@ -10,8 +10,6 @@
 #ifndef __VPDHEADER_H__
 #define __VPDHEADER_H__
 
-#define UPD_TERMINATOR	0x55AA
-
 struct __packed upd_region {
 	u64	sign;			/* Offset 0x0000 */
 	u64	reserved;		/* Offset 0x0008 */
arch/x86/include/asm/fsp/fsp_api.h +4 -2
index a9d7156..2d34d13 100644
@@ -8,6 +8,8 @@
 #ifndef __FSP_API_H__
 #define __FSP_API_H__
 
+#include <linux/linkage.h>
+
 /*
  * FspInit continuation function prototype.
  * Control will be returned to this callback function after FspInit API call.
@@ -47,9 +49,9 @@ struct fsp_notify_params {
 };
 
 /* FspInit API function prototype */
-typedef u32 (*fsp_init_f)(struct fsp_init_params *params);
+typedef asmlinkage u32 (*fsp_init_f)(struct fsp_init_params *params);
 
 /* FspNotify API function prototype */
-typedef u32 (*fsp_notify_f)(struct fsp_notify_params *params);
+typedef asmlinkage u32 (*fsp_notify_f)(struct fsp_notify_params *params);
 
 #endif
arch/x86/include/asm/fsp/fsp_support.h +3 -1
index 6329cfe..c6c7dc0 100644
@@ -26,6 +26,8 @@ struct shared_data {
 
 #define FSP_LOWMEM_BASE		0x100000UL
 #define FSP_HIGHMEM_BASE	0x100000000ULL
+#define UPD_TERMINATOR		0x55AA
+
 
 /**
  * FSP Continuation assembly helper routine
@@ -61,7 +63,7 @@ void fsp_continue(struct shared_data *shared_data, u32 status,
  *
  * @retval: the offset of FSP header. If signature is invalid, returns 0.
  */
-u32 find_fsp_header(void);
+struct fsp_header *find_fsp_header(void);
 
 /**
  * FSP initialization wrapper function.
arch/x86/lib/fsp/fsp_support.c +2 -2
index f6ae85a..bf37807 100644
@@ -30,7 +30,7 @@ static bool compare_guid(const struct efi_guid *guid1,
 		return false;
 }
 
-u32 __attribute__((optimize("O0"))) find_fsp_header(void)
+struct fsp_header *__attribute__((optimize("O0"))) find_fsp_header(void)
 {
 	/*
 	 * This function may be called before the a stack is established,
@@ -84,7 +84,7 @@ u32 __attribute__((optimize("O0"))) find_fsp_header(void)
 		fsp = 0;
 	}
 
-	return (u32)fsp;
+	return (struct fsp_header *)fsp;
 }
 
 void fsp_continue(struct shared_data *shared_data, u32 status, void *hob_list)
Signature · 1 line
2.2.0.rc0.207.ga3a616c
#32 lore raw

PATCH 12/23 x86: Adjust the FSP types slightly

Quoted 87 lines · Simon Glass

To avoid casts, find_fsp_header() should return a pointer. Add asmlinkage to two API functions which use that convention. UPD_TERMINATOR is common so move it into a common file.

---

 arch/x86/include/asm/arch-queensbay/fsp/fsp_vpd.h | 2 --
 arch/x86/include/asm/fsp/fsp_api.h                | 6 ++++--
 arch/x86/include/asm/fsp/fsp_support.h            | 4 +++-
 arch/x86/lib/fsp/fsp_support.c                    | 4 ++--
 4 files changed, 9 insertions(+), 7 deletions(-)
arch/x86/include/asm/arch-queensbay/fsp/fsp_vpd.h +0 -2
index bce58b1..3c57558 100644
@@ -10,8 +10,6 @@
 #ifndef __VPDHEADER_H__
 #define __VPDHEADER_H__
 
-#define UPD_TERMINATOR 0x55AA
-
 struct __packed upd_region {
        u64     sign;                   /* Offset 0x0000 */
        u64     reserved;               /* Offset 0x0008 */
arch/x86/include/asm/fsp/fsp_api.h +4 -2
index a9d7156..2d34d13 100644
@@ -8,6 +8,8 @@
 #ifndef __FSP_API_H__
 #define __FSP_API_H__
 
+#include <linux/linkage.h>
+
 /*
  * FspInit continuation function prototype.
  * Control will be returned to this callback function after FspInit API call.
@@ -47,9 +49,9 @@ struct fsp_notify_params {
 };
 
 /* FspInit API function prototype */
-typedef u32 (*fsp_init_f)(struct fsp_init_params *params);
+typedef asmlinkage u32 (*fsp_init_f)(struct fsp_init_params *params);
 
 /* FspNotify API function prototype */
-typedef u32 (*fsp_notify_f)(struct fsp_notify_params *params);
+typedef asmlinkage u32 (*fsp_notify_f)(struct fsp_notify_params *params);
 
 #endif
arch/x86/include/asm/fsp/fsp_support.h +3 -1
index 6329cfe..c6c7dc0 100644
@@ -26,6 +26,8 @@ struct shared_data {
 
 #define FSP_LOWMEM_BASE                0x100000UL
 #define FSP_HIGHMEM_BASE       0x100000000ULL
+#define UPD_TERMINATOR         0x55AA
+
 
 /**
  * FSP Continuation assembly helper routine
@@ -61,7 +63,7 @@ void fsp_continue(struct shared_data *shared_data, u32 status,
  *
  * @retval: the offset of FSP header. If signature is invalid, returns 0.
  */
-u32 find_fsp_header(void);
+struct fsp_header *find_fsp_header(void);
 
 /**
  * FSP initialization wrapper function.
arch/x86/lib/fsp/fsp_support.c +1 -1
index f6ae85a..bf37807 100644
@@ -30,7 +30,7 @@ static bool compare_guid(const struct efi_guid *guid1,
                return false;
 }
 
-u32 __attribute__((optimize("O0"))) find_fsp_header(void)
+struct fsp_header *__attribute__((optimize("O0"))) find_fsp_header(void)
 {
        /*
         * This function may be called before the a stack is established,

arch/x86/lib/fsp/fsp_support.c u32 __attribute__((optimize("O0"))) find_fsp_header(void)

Quoted 9 lines
arch/x86/lib/fsp/fsp_support.c +1 -2
@@ -84,7 +84,7 @@ u32 __attribute__((optimize("O0"))) find_fsp_header(void)
                fsp = 0;
        }
 
-       return (u32)fsp;
+       return (struct fsp_header *)fsp;
 }
 
 void fsp_continue(struct shared_data *shared_data, u32 status, void *hob_list)
--
#33 lore raw

PATCH 13/23 x86: Make CAR and DRAM FSP code common

In reply to Simon Glass

For now this code seems to be the same for all FSP platforms. Make it common until we see what differences are required.

---

 arch/x86/cpu/queensbay/Makefile                           | 2 +-
 arch/x86/lib/fsp/Makefile                                 | 2 ++
 arch/x86/{cpu/queensbay/tnc_car.S => lib/fsp/fsp_car.S}   | 0
 arch/x86/{cpu/queensbay/tnc_dram.c => lib/fsp/fsp_dram.c} | 0
 4 files changed, 3 insertions(+), 1 deletion(-)
 rename arch/x86/{cpu/queensbay/tnc_car.S => lib/fsp/fsp_car.S} (100%)
 rename arch/x86/{cpu/queensbay/tnc_dram.c => lib/fsp/fsp_dram.c} (100%)
arch/x86/cpu/queensbay/Makefile +1 -1
index b3e7d87..d8761fd 100644
@@ -4,6 +4,6 @@
 # SPDX-License-Identifier:	GPL-2.0+
 #
 
-obj-y += tnc_car.o tnc_dram.o tnc.o topcliff.o
 obj-y += fsp_configs.o
+obj-y += tnc.o topcliff.o
 obj-$(CONFIG_PCI) += tnc_pci.o
arch/x86/lib/fsp/Makefile +2 -0
index 1b9b0e2..3a2bac0 100644
@@ -4,4 +4,6 @@
 # SPDX-License-Identifier:	GPL-2.0+
 #
 
+obj-y += fsp_car.o
+obj-y += fsp_dram.o
 obj-y += fsp_support.o
arch/x86/lib/fsp/fsp_car.S renamed from arch/x86/cpu/queensbay/tnc_car.S +0 -0
similarity index 100%
rename from arch/x86/cpu/queensbay/tnc_car.S
rename to arch/x86/lib/fsp/fsp_car.S
arch/x86/lib/fsp/fsp_dram.c renamed from arch/x86/cpu/queensbay/tnc_dram.c +0 -0
similarity index 100%
rename from arch/x86/cpu/queensbay/tnc_dram.c
rename to arch/x86/lib/fsp/fsp_dram.c
Signature · 1 line
2.2.0.rc0.207.ga3a616c
#34 lore raw

PATCH 13/23 x86: Make CAR and DRAM FSP code common

Quoted 45 lines · Simon Glass

For now this code seems to be the same for all FSP platforms. Make it common until we see what differences are required.

---

 arch/x86/cpu/queensbay/Makefile                           | 2 +-
 arch/x86/lib/fsp/Makefile                                 | 2 ++
 arch/x86/{cpu/queensbay/tnc_car.S => lib/fsp/fsp_car.S}   | 0
 arch/x86/{cpu/queensbay/tnc_dram.c => lib/fsp/fsp_dram.c} | 0
 4 files changed, 3 insertions(+), 1 deletion(-)
 rename arch/x86/{cpu/queensbay/tnc_car.S => lib/fsp/fsp_car.S} (100%)
 rename arch/x86/{cpu/queensbay/tnc_dram.c => lib/fsp/fsp_dram.c} (100%)
arch/x86/cpu/queensbay/Makefile +1 -1
index b3e7d87..d8761fd 100644
@@ -4,6 +4,6 @@
 # SPDX-License-Identifier:     GPL-2.0+
 #
 
-obj-y += tnc_car.o tnc_dram.o tnc.o topcliff.o
 obj-y += fsp_configs.o
+obj-y += tnc.o topcliff.o
 obj-$(CONFIG_PCI) += tnc_pci.o
arch/x86/lib/fsp/Makefile +2 -0
index 1b9b0e2..3a2bac0 100644
@@ -4,4 +4,6 @@
 # SPDX-License-Identifier:     GPL-2.0+
 #
 
+obj-y += fsp_car.o
+obj-y += fsp_dram.o
 obj-y += fsp_support.o
arch/x86/lib/fsp/fsp_car.S renamed from arch/x86/cpu/queensbay/tnc_car.S +0 -0
similarity index 100%
rename from arch/x86/cpu/queensbay/tnc_car.S
rename to arch/x86/lib/fsp/fsp_car.S
arch/x86/lib/fsp/fsp_dram.c renamed from arch/x86/cpu/queensbay/tnc_dram.c +0 -0
similarity index 100%
rename from arch/x86/cpu/queensbay/tnc_dram.c
rename to arch/x86/lib/fsp/fsp_dram.c

arch/x86/lib/fsp/fsp_dram.c

Quoted 1 line
arch/x86/lib/fsp/fsp_dram.c renamed from arch/x86/cpu/queensbay/tnc_dram.c +0 -1
--
#35 lore raw

PATCH 14/23 x86: Move common FSP functions into a common file

In reply to Simon Glass

Since these board functions seem to be the same for all boards which use FSP, move them into a common file. We can adjust this later if future FSPs need more flexibility.

---

 arch/x86/cpu/queensbay/tnc.c      | 27 ------------
 arch/x86/cpu/queensbay/tnc_pci.c  | 15 -------
 arch/x86/cpu/queensbay/topcliff.c | 32 +-------------
 arch/x86/include/asm/u-boot-x86.h | 17 ++++++++
 arch/x86/lib/fsp/Makefile         |  1 +
 arch/x86/lib/fsp/fsp_common.c     | 88 +++++++++++++++++++++++++++++++++++++++
 6 files changed, 108 insertions(+), 72 deletions(-)
 create mode 100644 arch/x86/lib/fsp/fsp_common.c
arch/x86/cpu/queensbay/tnc.c +0 -27
index f9b3bfa..30ab725 100644
@@ -43,30 +43,3 @@ int arch_cpu_init(void)
 
 	return 0;
 }
-
-int print_cpuinfo(void)
-{
-	post_code(POST_CPU_INFO);
-	return default_print_cpuinfo();
-}
-
-void reset_cpu(ulong addr)
-{
-	/* cold reset */
-	outb(0x06, PORT_RESET);
-}
-
-void board_final_cleanup(void)
-{
-	u32 status;
-
-	/* call into FspNotify */
-	debug("Calling into FSP (notify phase INIT_PHASE_BOOT): ");
-	status = fsp_notify(NULL, INIT_PHASE_BOOT);
-	if (status != FSP_SUCCESS)
-		debug("fail, error code %x\n", status);
-	else
-		debug("OK\n");
-
-	return;
-}
arch/x86/cpu/queensbay/tnc_pci.c +0 -15
index 9b0b725..6c291f9 100644
@@ -44,18 +44,3 @@ void board_pci_setup_hose(struct pci_controller *hose)
 
 	hose->region_count = 4;
 }
-
-int board_pci_post_scan(struct pci_controller *hose)
-{
-	u32 status;
-
-	/* call into FspNotify */
-	debug("Calling into FSP (notify phase INIT_PHASE_PCI): ");
-	status = fsp_notify(NULL, INIT_PHASE_PCI);
-	if (status != FSP_SUCCESS)
-		debug("fail, error code %x\n", status);
-	else
-		debug("OK\n");
-
-	return 0;
-}
arch/x86/cpu/queensbay/topcliff.c +2 -30
index b01422a..25032cc 100644
@@ -5,43 +5,15 @@
  */
 
 #include <common.h>
-#include <errno.h>
-#include <malloc.h>
-#include <pci.h>
 #include <pci_ids.h>
-#include <sdhci.h>
 
 static struct pci_device_id mmc_supported[] = {
 	{ PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_TCF_SDIO_0 },
 	{ PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_TCF_SDIO_1 },
-	{ }
 };
 
 int cpu_mmc_init(bd_t *bis)
 {
-	struct sdhci_host *mmc_host;
-	pci_dev_t devbusfn;
-	u32 iobase;
-	int ret;
-	int i;
-
-	for (i = 0; i < ARRAY_SIZE(mmc_supported); i++) {
-		devbusfn =  pci_find_devices(mmc_supported, i);
-		if (devbusfn == -1)
-			return -ENODEV;
-
-		mmc_host = (struct sdhci_host *)malloc(sizeof(struct sdhci_host));
-		if (!mmc_host)
-			return -ENOMEM;
-
-		mmc_host->name = "Topcliff SDHCI";
-		pci_read_config_dword(devbusfn, PCI_BASE_ADDRESS_0, &iobase);
-		mmc_host->ioaddr = (void *)iobase;
-		mmc_host->quirks = 0;
-		ret = add_sdhci(mmc_host, 0, 0);
-		if (ret)
-			return ret;
-	}
-
-	return 0;
+	return fsp_cpu_mmc_init("Topcliff SDHCI", mmc_supported,
+				ARRAY_SIZE(mmc_supported));
 }
arch/x86/include/asm/u-boot-x86.h +17 -0
index b98afa8..44c24ff 100644
@@ -45,6 +45,23 @@ ulong board_get_usable_ram_top(ulong total_size);
 void dram_init_banksize(void);
 int default_print_cpuinfo(void);
 
+struct pci_device_id;
+
+/**
+ * fsp_cpu_mmc_init() - set up PCI MMC devices
+ *
+ * This finds all the matching PCI IDs and sets them up as MMC devices.
+ *
+ * @name:		Name to use for devices
+ * @mmc_supported:	PCI IDs to search for
+ * @num_ids:		Number of elements in @mmc_supported
+ */
+int fsp_cpu_mmc_init(const char *name, struct pci_device_id mmc_supported[],
+		     int num_ids);
+
+/* Set up a UART which can be used with printch(), printhex8(), etc. */
+int setup_early_uart(void);
+
 void setup_pcat_compatibility(void);
 
 void isa_unmap_rom(u32 addr);
arch/x86/lib/fsp/Makefile +1 -0
index 3a2bac0..5b12c12 100644
@@ -5,5 +5,6 @@
 #
 
 obj-y += fsp_car.o
+obj-y += fsp_common.o
 obj-y += fsp_dram.o
 obj-y += fsp_support.o
arch/x86/lib/fsp/fsp_common.c new file +88 -0

88 lines not on this page · raw message

Signature · 1 line
2.2.0.rc0.207.ga3a616c
#36 lore raw

PATCH 14/23 x86: Move common FSP functions into a common file

Hi Simon,

Quoted 114 lines · Simon Glass

Since these board functions seem to be the same for all boards which use FSP, move them into a common file. We can adjust this later if future FSPs need more flexibility.

---

 arch/x86/cpu/queensbay/tnc.c      | 27 ------------
 arch/x86/cpu/queensbay/tnc_pci.c  | 15 -------
 arch/x86/cpu/queensbay/topcliff.c | 32 +-------------
 arch/x86/include/asm/u-boot-x86.h | 17 ++++++++
 arch/x86/lib/fsp/Makefile         |  1 +
 arch/x86/lib/fsp/fsp_common.c     | 88 +++++++++++++++++++++++++++++++++++++++
 6 files changed, 108 insertions(+), 72 deletions(-)
 create mode 100644 arch/x86/lib/fsp/fsp_common.c
arch/x86/cpu/queensbay/tnc.c +0 -27
index f9b3bfa..30ab725 100644
@@ -43,30 +43,3 @@ int arch_cpu_init(void)
 
        return 0;
 }
-
-int print_cpuinfo(void)
-{
-       post_code(POST_CPU_INFO);
-       return default_print_cpuinfo();
-}
-
-void reset_cpu(ulong addr)
-{
-       /* cold reset */
-       outb(0x06, PORT_RESET);
-}
-
-void board_final_cleanup(void)
-{
-       u32 status;
-
-       /* call into FspNotify */
-       debug("Calling into FSP (notify phase INIT_PHASE_BOOT): ");
-       status = fsp_notify(NULL, INIT_PHASE_BOOT);
-       if (status != FSP_SUCCESS)
-               debug("fail, error code %x\n", status);
-       else
-               debug("OK\n");
-
-       return;
-}
arch/x86/cpu/queensbay/tnc_pci.c +0 -15
index 9b0b725..6c291f9 100644
@@ -44,18 +44,3 @@ void board_pci_setup_hose(struct pci_controller *hose)
 
        hose->region_count = 4;
 }
-
-int board_pci_post_scan(struct pci_controller *hose)
-{
-       u32 status;
-
-       /* call into FspNotify */
-       debug("Calling into FSP (notify phase INIT_PHASE_PCI): ");
-       status = fsp_notify(NULL, INIT_PHASE_PCI);
-       if (status != FSP_SUCCESS)
-               debug("fail, error code %x\n", status);
-       else
-               debug("OK\n");
-
-       return 0;
-}
arch/x86/cpu/queensbay/topcliff.c +0 -23
index b01422a..25032cc 100644
@@ -5,43 +5,15 @@
  */
 
 #include <common.h>
-#include <errno.h>
-#include <malloc.h>
-#include <pci.h>
 #include <pci_ids.h>
-#include <sdhci.h>
 
 static struct pci_device_id mmc_supported[] = {
        { PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_TCF_SDIO_0 },
        { PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_TCF_SDIO_1 },
-       { }
 };
 
 int cpu_mmc_init(bd_t *bis)
 {
-       struct sdhci_host *mmc_host;
-       pci_dev_t devbusfn;
-       u32 iobase;
-       int ret;
-       int i;
-
-       for (i = 0; i < ARRAY_SIZE(mmc_supported); i++) {
-               devbusfn =  pci_find_devices(mmc_supported, i);
-               if (devbusfn == -1)
-                       return -ENODEV;
-
-               mmc_host = (struct sdhci_host *)malloc(sizeof(struct sdhci_host));
-               if (!mmc_host)
-                       return -ENOMEM;
-
-               mmc_host->name = "Topcliff SDHCI";
-               pci_read_config_dword(devbusfn, PCI_BASE_ADDRESS_0, &iobase);
-               mmc_host->ioaddr = (void *)iobase;

arch/x86/cpu/queensbay/topcliff.c line 19

Quoted 10 lines
arch/x86/cpu/queensbay/topcliff.c +2 -7
-               mmc_host->quirks = 0;
-               ret = add_sdhci(mmc_host, 0, 0);
-               if (ret)
-                       return ret;
-       }
-
-       return 0;
+       return fsp_cpu_mmc_init("Topcliff SDHCI", mmc_supported,
+                               ARRAY_SIZE(mmc_supported));
 }

I don't think this function should be moved to fsp_common.c as it has nothing related to FSP. We can move this whole function to drivers/mmc/, something like intel_mmc.c or intel_sdhc.c.

Quoted 15 lines
arch/x86/include/asm/u-boot-x86.h +7 -0
index b98afa8..44c24ff 100644
@@ -45,6 +45,23 @@ ulong board_get_usable_ram_top(ulong total_size);
 void dram_init_banksize(void);
 int default_print_cpuinfo(void);
 
+struct pci_device_id;
+
+/**
+ * fsp_cpu_mmc_init() - set up PCI MMC devices
+ *
+ * This finds all the matching PCI IDs and sets them up as MMC devices.
+ *

arch/x86/include/asm/u-boot-x86.h ulong board_get_usable_ram_top(ulong total_size); · line 64

Quoted 10 lines
arch/x86/include/asm/u-boot-x86.h +10 -0
+ * @name:              Name to use for devices
+ * @mmc_supported:     PCI IDs to search for
+ * @num_ids:           Number of elements in @mmc_supported
+ */
+int fsp_cpu_mmc_init(const char *name, struct pci_device_id mmc_supported[],
+                    int num_ids);
+
+/* Set up a UART which can be used with printch(), printhex8(), etc. */
+int setup_early_uart(void);
+

Where is the setup_early_uart() function implementation?

Quoted 99 lines
arch/x86/include/asm/u-boot-x86.h +0 -0
 void setup_pcat_compatibility(void);
 
 void isa_unmap_rom(u32 addr);
arch/x86/lib/fsp/Makefile +1 -0
index 3a2bac0..5b12c12 100644
@@ -5,5 +5,6 @@
 #
 
 obj-y += fsp_car.o
+obj-y += fsp_common.o
 obj-y += fsp_dram.o
 obj-y += fsp_support.o
arch/x86/lib/fsp/fsp_common.c new file +79 -0
new file mode 100644
index 0000000..846c136
@@ -0,0 +1,88 @@
+/*
+ * Copyright (C) 2014, Bin Meng <[email protected]>
+ *
+ * SPDX-License-Identifier:    GPL-2.0+
+ */
+
+#include <common.h>
+#include <errno.h>
+#include <malloc.h>
+#include <sdhci.h>
+#include <asm/io.h>
+#include <asm/pci.h>
+#include <asm/post.h>
+#include <asm/processor.h>
+#include <asm/fsp/fsp_support.h>
+
+int print_cpuinfo(void)
+{
+       post_code(POST_CPU_INFO);
+       return default_print_cpuinfo();
+}
+
+void reset_cpu(ulong addr)
+{
+       /* cold reset */
+       outb(0x06, PORT_RESET);
+}
+
+
+int board_pci_post_scan(struct pci_controller *hose)
+{
+       u32 status;
+
+       /* call into FspNotify */
+       debug("Calling into FSP (notify phase INIT_PHASE_PCI): ");
+       status = fsp_notify(NULL, INIT_PHASE_PCI);
+       if (status != FSP_SUCCESS)
+               debug("fail, error code %x\n", status);
+       else
+               debug("OK\n");
+
+       return 0;
+}
+
+void board_final_cleanup(void)
+{
+       u32 status;
+
+       /* call into FspNotify */
+       debug("Calling into FSP (notify phase INIT_PHASE_BOOT): ");
+       status = fsp_notify(NULL, INIT_PHASE_BOOT);
+       if (status != FSP_SUCCESS)
+               debug("fail, error code %x\n", status);
+       else
+               debug("OK\n");
+
+       return;
+}
+
+int fsp_cpu_mmc_init(const char *name, struct pci_device_id mmc_supported[],
+                    int num_ids)
+{
+       struct sdhci_host *mmc_host;
+       pci_dev_t devbusfn;
+       u32 iobase;
+       int ret;
+       int i;
+
+       for (i = 0; i < num_ids; i++) {
+               devbusfn = pci_find_devices(mmc_supported, i);
+               if (devbusfn == -1)
+                       return -ENODEV;
+
+               mmc_host = malloc(sizeof(struct sdhci_host));
+               if (!mmc_host)
+                       return -ENOMEM;
+
+               mmc_host->name = (char *)name;
+               pci_read_config_dword(devbusfn, PCI_BASE_ADDRESS_0, &iobase);

arch/x86/lib/fsp/fsp_common.c

Quoted 10 lines
arch/x86/lib/fsp/fsp_common.c new file +9 -1
+               mmc_host->ioaddr = (void *)iobase;
+               mmc_host->quirks = 0;
+               ret = add_sdhci(mmc_host, 0, 0);
+               if (ret)
+                       return ret;
+       }
+
+       return 0;
+}
--

Regards,
Bin

#37 lore raw

PATCH 14/23 x86: Move common FSP functions into a common file

Hi Bin,

Quoted 123 lines · Bin Meng

Hi Simon,

Quoted 120 lines · Simon Glass

Since these board functions seem to be the same for all boards which use FSP, move them into a common file. We can adjust this later if future FSPs need more flexibility.

---

 arch/x86/cpu/queensbay/tnc.c      | 27 ------------
 arch/x86/cpu/queensbay/tnc_pci.c  | 15 -------
 arch/x86/cpu/queensbay/topcliff.c | 32 +-------------
 arch/x86/include/asm/u-boot-x86.h | 17 ++++++++
 arch/x86/lib/fsp/Makefile         |  1 +
 arch/x86/lib/fsp/fsp_common.c     | 88 +++++++++++++++++++++++++++++++++++++++
 6 files changed, 108 insertions(+), 72 deletions(-)
 create mode 100644 arch/x86/lib/fsp/fsp_common.c
arch/x86/cpu/queensbay/tnc.c +0 -27
index f9b3bfa..30ab725 100644
@@ -43,30 +43,3 @@ int arch_cpu_init(void)
 
        return 0;
 }
-
-int print_cpuinfo(void)
-{
-       post_code(POST_CPU_INFO);
-       return default_print_cpuinfo();
-}
-
-void reset_cpu(ulong addr)
-{
-       /* cold reset */
-       outb(0x06, PORT_RESET);
-}
-
-void board_final_cleanup(void)
-{
-       u32 status;
-
-       /* call into FspNotify */
-       debug("Calling into FSP (notify phase INIT_PHASE_BOOT): ");
-       status = fsp_notify(NULL, INIT_PHASE_BOOT);
-       if (status != FSP_SUCCESS)
-               debug("fail, error code %x\n", status);
-       else
-               debug("OK\n");
-
-       return;
-}
arch/x86/cpu/queensbay/tnc_pci.c +0 -15
index 9b0b725..6c291f9 100644
@@ -44,18 +44,3 @@ void board_pci_setup_hose(struct pci_controller *hose)
 
        hose->region_count = 4;
 }
-
-int board_pci_post_scan(struct pci_controller *hose)
-{
-       u32 status;
-
-       /* call into FspNotify */
-       debug("Calling into FSP (notify phase INIT_PHASE_PCI): ");
-       status = fsp_notify(NULL, INIT_PHASE_PCI);
-       if (status != FSP_SUCCESS)
-               debug("fail, error code %x\n", status);
-       else
-               debug("OK\n");
-
-       return 0;
-}
arch/x86/cpu/queensbay/topcliff.c +0 -29
index b01422a..25032cc 100644
@@ -5,43 +5,15 @@
  */
 
 #include <common.h>
-#include <errno.h>
-#include <malloc.h>
-#include <pci.h>
 #include <pci_ids.h>
-#include <sdhci.h>
 
 static struct pci_device_id mmc_supported[] = {
        { PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_TCF_SDIO_0 },
        { PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_TCF_SDIO_1 },
-       { }
 };
 
 int cpu_mmc_init(bd_t *bis)
 {
-       struct sdhci_host *mmc_host;
-       pci_dev_t devbusfn;
-       u32 iobase;
-       int ret;
-       int i;
-
-       for (i = 0; i < ARRAY_SIZE(mmc_supported); i++) {
-               devbusfn =  pci_find_devices(mmc_supported, i);
-               if (devbusfn == -1)
-                       return -ENODEV;
-
-               mmc_host = (struct sdhci_host *)malloc(sizeof(struct sdhci_host));
-               if (!mmc_host)
-                       return -ENOMEM;
-
-               mmc_host->name = "Topcliff SDHCI";
-               pci_read_config_dword(devbusfn, PCI_BASE_ADDRESS_0, &iobase);
-               mmc_host->ioaddr = (void *)iobase;
-               mmc_host->quirks = 0;
-               ret = add_sdhci(mmc_host, 0, 0);
-               if (ret)
-                       return ret;
-       }
-
Quoted 8 lines

arch/x86/cpu/queensbay/topcliff.c line 19

Quoted 4 lines
arch/x86/cpu/queensbay/topcliff.c +2 -1
-       return 0;
+       return fsp_cpu_mmc_init("Topcliff SDHCI", mmc_supported,
+                               ARRAY_SIZE(mmc_supported));
 }

I don't think this function should be moved to fsp_common.c as it has nothing related to FSP. We can move this whole function to drivers/mmc/, something like intel_mmc.c or intel_sdhc.c.

How about pci_mmc.c if it is generic to PCI?

Quoted 20 lines
Quoted 20 lines
arch/x86/include/asm/u-boot-x86.h +11 -0
index b98afa8..44c24ff 100644
@@ -45,6 +45,23 @@ ulong board_get_usable_ram_top(ulong total_size);
 void dram_init_banksize(void);
 int default_print_cpuinfo(void);
 
+struct pci_device_id;
+
+/**
+ * fsp_cpu_mmc_init() - set up PCI MMC devices
+ *
+ * This finds all the matching PCI IDs and sets them up as MMC devices.
+ *
+ * @name:              Name to use for devices
+ * @mmc_supported:     PCI IDs to search for
+ * @num_ids:           Number of elements in @mmc_supported
+ */
Quoted 8 lines

arch/x86/include/asm/u-boot-x86.h ulong board_get_usable_ram_top(ulong total_size); · line 64

Quoted 6 lines
arch/x86/include/asm/u-boot-x86.h +6 -0
+int fsp_cpu_mmc_init(const char *name, struct pci_device_id mmc_supported[],
+                    int num_ids);
+
+/* Set up a UART which can be used with printch(), printhex8(), etc. */
+int setup_early_uart(void);
+

Where is the setup_early_uart() function implementation?

I think you found it later. I will fix this.

Quoted 105 lines
Quoted 105 lines
arch/x86/include/asm/u-boot-x86.h +0 -0
 void setup_pcat_compatibility(void);
 
 void isa_unmap_rom(u32 addr);
arch/x86/lib/fsp/Makefile +1 -0
index 3a2bac0..5b12c12 100644
@@ -5,5 +5,6 @@
 #
 
 obj-y += fsp_car.o
+obj-y += fsp_common.o
 obj-y += fsp_dram.o
 obj-y += fsp_support.o
arch/x86/lib/fsp/fsp_common.c new file +84 -0
new file mode 100644
index 0000000..846c136
@@ -0,0 +1,88 @@
+/*
+ * Copyright (C) 2014, Bin Meng <[email protected]>
+ *
+ * SPDX-License-Identifier:    GPL-2.0+
+ */
+
+#include <common.h>
+#include <errno.h>
+#include <malloc.h>
+#include <sdhci.h>
+#include <asm/io.h>
+#include <asm/pci.h>
+#include <asm/post.h>
+#include <asm/processor.h>
+#include <asm/fsp/fsp_support.h>
+
+int print_cpuinfo(void)
+{
+       post_code(POST_CPU_INFO);
+       return default_print_cpuinfo();
+}
+
+void reset_cpu(ulong addr)
+{
+       /* cold reset */
+       outb(0x06, PORT_RESET);
+}
+
+
+int board_pci_post_scan(struct pci_controller *hose)
+{
+       u32 status;
+
+       /* call into FspNotify */
+       debug("Calling into FSP (notify phase INIT_PHASE_PCI): ");
+       status = fsp_notify(NULL, INIT_PHASE_PCI);
+       if (status != FSP_SUCCESS)
+               debug("fail, error code %x\n", status);
+       else
+               debug("OK\n");
+
+       return 0;
+}
+
+void board_final_cleanup(void)
+{
+       u32 status;
+
+       /* call into FspNotify */
+       debug("Calling into FSP (notify phase INIT_PHASE_BOOT): ");
+       status = fsp_notify(NULL, INIT_PHASE_BOOT);
+       if (status != FSP_SUCCESS)
+               debug("fail, error code %x\n", status);
+       else
+               debug("OK\n");
+
+       return;
+}
+
+int fsp_cpu_mmc_init(const char *name, struct pci_device_id mmc_supported[],
+                    int num_ids)
+{
+       struct sdhci_host *mmc_host;
+       pci_dev_t devbusfn;
+       u32 iobase;
+       int ret;
+       int i;
+
+       for (i = 0; i < num_ids; i++) {
+               devbusfn = pci_find_devices(mmc_supported, i);
+               if (devbusfn == -1)
+                       return -ENODEV;
+
+               mmc_host = malloc(sizeof(struct sdhci_host));
+               if (!mmc_host)
+                       return -ENOMEM;
+
+               mmc_host->name = (char *)name;
+               pci_read_config_dword(devbusfn, PCI_BASE_ADDRESS_0, &iobase);
+               mmc_host->ioaddr = (void *)iobase;
+               mmc_host->quirks = 0;
+               ret = add_sdhci(mmc_host, 0, 0);
+               if (ret)
+                       return ret;
Quoted 8 lines

arch/x86/lib/fsp/fsp_common.c

Quoted 5 lines
arch/x86/lib/fsp/fsp_common.c new file +4 -1
+       }
+
+       return 0;
+}
--

Regards,
Bin

Regards,
Simon

#38 lore raw

PATCH 14/23 x86: Move common FSP functions into a common file

Hi Simon,

Quoted 135 lines · Simon Glass

Hi Bin,

Quoted 123 lines · Bin Meng

Hi Simon,

Quoted 120 lines · Simon Glass

Since these board functions seem to be the same for all boards which use FSP, move them into a common file. We can adjust this later if future FSPs need more flexibility.

---

 arch/x86/cpu/queensbay/tnc.c      | 27 ------------
 arch/x86/cpu/queensbay/tnc_pci.c  | 15 -------
 arch/x86/cpu/queensbay/topcliff.c | 32 +-------------
 arch/x86/include/asm/u-boot-x86.h | 17 ++++++++
 arch/x86/lib/fsp/Makefile         |  1 +
 arch/x86/lib/fsp/fsp_common.c     | 88 +++++++++++++++++++++++++++++++++++++++
 6 files changed, 108 insertions(+), 72 deletions(-)
 create mode 100644 arch/x86/lib/fsp/fsp_common.c
arch/x86/cpu/queensbay/tnc.c +0 -27
index f9b3bfa..30ab725 100644
@@ -43,30 +43,3 @@ int arch_cpu_init(void)
 
        return 0;
 }
-
-int print_cpuinfo(void)
-{
-       post_code(POST_CPU_INFO);
-       return default_print_cpuinfo();
-}
-
-void reset_cpu(ulong addr)
-{
-       /* cold reset */
-       outb(0x06, PORT_RESET);
-}
-
-void board_final_cleanup(void)
-{
-       u32 status;
-
-       /* call into FspNotify */
-       debug("Calling into FSP (notify phase INIT_PHASE_BOOT): ");
-       status = fsp_notify(NULL, INIT_PHASE_BOOT);
-       if (status != FSP_SUCCESS)
-               debug("fail, error code %x\n", status);
-       else
-               debug("OK\n");
-
-       return;
-}
arch/x86/cpu/queensbay/tnc_pci.c +0 -15
index 9b0b725..6c291f9 100644
@@ -44,18 +44,3 @@ void board_pci_setup_hose(struct pci_controller *hose)
 
        hose->region_count = 4;
 }
-
-int board_pci_post_scan(struct pci_controller *hose)
-{
-       u32 status;
-
-       /* call into FspNotify */
-       debug("Calling into FSP (notify phase INIT_PHASE_PCI): ");
-       status = fsp_notify(NULL, INIT_PHASE_PCI);
-       if (status != FSP_SUCCESS)
-               debug("fail, error code %x\n", status);
-       else
-               debug("OK\n");
-
-       return 0;
-}
arch/x86/cpu/queensbay/topcliff.c +0 -29
index b01422a..25032cc 100644
@@ -5,43 +5,15 @@
  */
 
 #include <common.h>
-#include <errno.h>
-#include <malloc.h>
-#include <pci.h>
 #include <pci_ids.h>
-#include <sdhci.h>
 
 static struct pci_device_id mmc_supported[] = {
        { PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_TCF_SDIO_0 },
        { PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_TCF_SDIO_1 },
-       { }
 };
 
 int cpu_mmc_init(bd_t *bis)
 {
-       struct sdhci_host *mmc_host;
-       pci_dev_t devbusfn;
-       u32 iobase;
-       int ret;
-       int i;
-
-       for (i = 0; i < ARRAY_SIZE(mmc_supported); i++) {
-               devbusfn =  pci_find_devices(mmc_supported, i);
-               if (devbusfn == -1)
-                       return -ENODEV;
-
-               mmc_host = (struct sdhci_host *)malloc(sizeof(struct sdhci_host));
-               if (!mmc_host)
-                       return -ENOMEM;
-
-               mmc_host->name = "Topcliff SDHCI";
-               pci_read_config_dword(devbusfn, PCI_BASE_ADDRESS_0, &iobase);
-               mmc_host->ioaddr = (void *)iobase;
-               mmc_host->quirks = 0;
-               ret = add_sdhci(mmc_host, 0, 0);
-               if (ret)
-                       return ret;
-       }
-
Quoted 8 lines

arch/x86/cpu/queensbay/topcliff.c line 19

Quoted 4 lines
arch/x86/cpu/queensbay/topcliff.c +2 -1
-       return 0;
+       return fsp_cpu_mmc_init("Topcliff SDHCI", mmc_supported,
+                               ARRAY_SIZE(mmc_supported));
 }

I don't think this function should be moved to fsp_common.c as it has nothing related to FSP. We can move this whole function to drivers/mmc/, something like intel_mmc.c or intel_sdhc.c.

Quoted 2 lines

How about pci_mmc.c if it is generic to PCI?

Sounds good.

[snip]

Regards,
Bin

#39 lore raw

PATCH 15/23 x86: Remove unnecessary casts and fix comment typos

In reply to Simon Glass

Tidy up the FSP support code a little.

---

 arch/x86/lib/fsp/fsp_support.c | 10 +++++-----
 1 file changed, 5 insertions(+), 5 deletions(-)
arch/x86/lib/fsp/fsp_support.c +5 -5
index bf37807..8b639f7 100644
@@ -124,25 +124,25 @@ void fsp_init(u32 stack_top, u32 boot_mode, void *nvs_buf)
 	struct fsp_init_params *params_ptr;
 	struct upd_region *fsp_upd;
 
-	fsp_hdr = (struct fsp_header *)find_fsp_header();
+	fsp_hdr = find_fsp_header();
 	if (fsp_hdr == NULL) {
 		/* No valid FSP info header was found */
 		panic("Invalid FSP header");
 	}
 
-	fsp_upd = (struct upd_region *)&shared_data.fsp_upd;
+	fsp_upd = &shared_data.fsp_upd;
 	memset(&rt_buf, 0, sizeof(struct fspinit_rtbuf));
 
 	/* Reserve a gap in stack top */
 	rt_buf.common.stack_top = (u32 *)stack_top - 32;
 	rt_buf.common.boot_mode = boot_mode;
-	rt_buf.common.upd_data = (struct upd_region *)fsp_upd;
+	rt_buf.common.upd_data = fsp_upd;
 
 	/* Get VPD region start */
 	fsp_vpd = (struct vpd_region *)(fsp_hdr->img_base +
 			fsp_hdr->cfg_region_off);
 
-	/* Verifify the VPD data region is valid */
+	/* Verify the VPD data region is valid */
 	assert((fsp_vpd->img_rev == VPD_IMAGE_REV) &&
 	       (fsp_vpd->sign == VPD_IMAGE_ID));
 
@@ -150,7 +150,7 @@ void fsp_init(u32 stack_top, u32 boot_mode, void *nvs_buf)
 	memcpy(fsp_upd, (void *)(fsp_hdr->img_base + fsp_vpd->upd_offset),
 	       sizeof(struct upd_region));
 
-	/* Verifify the UPD data region is valid */
+	/* Verify the UPD data region is valid */
 	assert(fsp_upd->terminator == UPD_TERMINATOR);
 
 	/* Override any UPD setting if required */
Signature · 1 line
2.2.0.rc0.207.ga3a616c
#40 lore raw

PATCH 15/23 x86: Remove unnecessary casts and fix comment typos

Quoted 43 lines · Simon Glass

Tidy up the FSP support code a little.

---

 arch/x86/lib/fsp/fsp_support.c | 10 +++++-----
 1 file changed, 5 insertions(+), 5 deletions(-)
arch/x86/lib/fsp/fsp_support.c +4 -4
index bf37807..8b639f7 100644
@@ -124,25 +124,25 @@ void fsp_init(u32 stack_top, u32 boot_mode, void *nvs_buf)
        struct fsp_init_params *params_ptr;
        struct upd_region *fsp_upd;
 
-       fsp_hdr = (struct fsp_header *)find_fsp_header();
+       fsp_hdr = find_fsp_header();
        if (fsp_hdr == NULL) {
                /* No valid FSP info header was found */
                panic("Invalid FSP header");
        }
 
-       fsp_upd = (struct upd_region *)&shared_data.fsp_upd;
+       fsp_upd = &shared_data.fsp_upd;
        memset(&rt_buf, 0, sizeof(struct fspinit_rtbuf));
 
        /* Reserve a gap in stack top */
        rt_buf.common.stack_top = (u32 *)stack_top - 32;
        rt_buf.common.boot_mode = boot_mode;
-       rt_buf.common.upd_data = (struct upd_region *)fsp_upd;
+       rt_buf.common.upd_data = fsp_upd;
 
        /* Get VPD region start */
        fsp_vpd = (struct vpd_region *)(fsp_hdr->img_base +
                        fsp_hdr->cfg_region_off);
 
-       /* Verifify the VPD data region is valid */
+       /* Verify the VPD data region is valid */
        assert((fsp_vpd->img_rev == VPD_IMAGE_REV) &&
               (fsp_vpd->sign == VPD_IMAGE_ID));
 

arch/x86/lib/fsp/fsp_support.c void fsp_init(u32 stack_top, u32 boot_mode, void *nvs_buf)

Quoted 9 lines
arch/x86/lib/fsp/fsp_support.c +1 -2
@@ -150,7 +150,7 @@ void fsp_init(u32 stack_top, u32 boot_mode, void *nvs_buf)
        memcpy(fsp_upd, (void *)(fsp_hdr->img_base + fsp_vpd->upd_offset),
               sizeof(struct upd_region));
 
-       /* Verifify the UPD data region is valid */
+       /* Verify the UPD data region is valid */
        assert(fsp_upd->terminator == UPD_TERMINATOR);
 
        /* Override any UPD setting if required */
--
#41 lore raw

PATCH 16/23 x86: Allow FSP Kconfig settings for all x86

In reply to Simon Glass

While queensbay is the first chip with these settings, others will want to use them too. Make them common.

---

 arch/x86/Kconfig               | 38 ++++++++++++++++++++++++++++++++++++++
 arch/x86/cpu/queensbay/Kconfig | 38 --------------------------------------
 2 files changed, 38 insertions(+), 38 deletions(-)
arch/x86/Kconfig +38 -0
index 1523c91..73a7392 100644
@@ -344,6 +344,44 @@ config TSC_FREQ_IN_MHZ
 	help
 	  The running frequency in MHz of Time-Stamp Counter (TSC).
 
+config HAVE_FSP
+	bool "Add an Firmware Support Package binary"
+	help
+	  Select this option to add an Firmware Support Package binary to
+	  the resulting U-Boot image. It is a binary blob which U-Boot uses
+	  to set up SDRAM and other chipset specific initialization.
+
+	  Note: Without this binary U-Boot will not be able to set up its
+	  SDRAM so will not boot.
+
+config FSP_FILE
+	string "Firmware Support Package binary filename"
+	depends on HAVE_FSP
+	default "fsp.bin"
+	help
+	  The filename of the file to use as Firmware Support Package binary
+	  in the board directory.
+
+config FSP_ADDR
+	hex "Firmware Support Package binary location"
+	depends on HAVE_FSP
+	default 0xfffc0000
+	help
+	  FSP is not Position Independent Code (PIC) and the whole FSP has to
+	  be rebased if it is placed at a location which is different from the
+	  perferred base address specified during the FSP build. Use Intel's
+	  Binary Configuration Tool (BCT) to do the rebase.
+
+	  The default base address of 0xfffc0000 indicates that the binary must
+	  be located at offset 0xc0000 from the beginning of a 1MB flash device.
+
+config FSP_TEMP_RAM_ADDR
+	hex
+	default 0x2000000
+	help
+	  Stack top address which is used in FspInit after DRAM is ready and
+	  CAR is disabled.
+
 source "arch/x86/cpu/coreboot/Kconfig"
 
 source "arch/x86/cpu/ivybridge/Kconfig"
arch/x86/cpu/queensbay/Kconfig +0 -38
index f6b5201..397e599 100644
@@ -11,44 +11,6 @@ config INTEL_QUEENSBAY
 
 if INTEL_QUEENSBAY
 
-config HAVE_FSP
-	bool "Add an Firmware Support Package binary"
-	help
-	  Select this option to add an Firmware Support Package binary to
-	  the resulting U-Boot image. It is a binary blob which U-Boot uses
-	  to set up SDRAM and other chipset specific initialization.
-
-	  Note: Without this binary U-Boot will not be able to set up its
-	  SDRAM so will not boot.
-
-config FSP_FILE
-	string "Firmware Support Package binary filename"
-	depends on HAVE_FSP
-	default "fsp.bin"
-	help
-	  The filename of the file to use as Firmware Support Package binary
-	  in the board directory.
-
-config FSP_ADDR
-	hex "Firmware Support Package binary location"
-	depends on HAVE_FSP
-	default 0xfffc0000
-	help
-	  FSP is not Position Independent Code (PIC) and the whole FSP has to
-	  be rebased if it is placed at a location which is different from the
-	  perferred base address specified during the FSP build. Use Intel's
-	  Binary Configuration Tool (BCT) to do the rebase.
-
-	  The default base address of 0xfffc0000 indicates that the binary must
-	  be located at offset 0xc0000 from the beginning of a 1MB flash device.
-
-config FSP_TEMP_RAM_ADDR
-	hex
-	default 0x2000000
-	help
-	  Stack top address which is used in FspInit after DRAM is ready and
-	  CAR is disabled.
-
 config HAVE_CMC
 	bool "Add a Chipset Micro Code state machine binary"
 	help
Signature · 1 line
2.2.0.rc0.207.ga3a616c
#42 lore raw

PATCH 16/23 x86: Allow FSP Kconfig settings for all x86

Quoted 99 lines · Simon Glass

While queensbay is the first chip with these settings, others will want to use them too. Make them common.

---

 arch/x86/Kconfig               | 38 ++++++++++++++++++++++++++++++++++++++
 arch/x86/cpu/queensbay/Kconfig | 38 --------------------------------------
 2 files changed, 38 insertions(+), 38 deletions(-)
arch/x86/Kconfig +38 -0
index 1523c91..73a7392 100644
@@ -344,6 +344,44 @@ config TSC_FREQ_IN_MHZ
        help
          The running frequency in MHz of Time-Stamp Counter (TSC).
 
+config HAVE_FSP
+       bool "Add an Firmware Support Package binary"
+       help
+         Select this option to add an Firmware Support Package binary to
+         the resulting U-Boot image. It is a binary blob which U-Boot uses
+         to set up SDRAM and other chipset specific initialization.
+
+         Note: Without this binary U-Boot will not be able to set up its
+         SDRAM so will not boot.
+
+config FSP_FILE
+       string "Firmware Support Package binary filename"
+       depends on HAVE_FSP
+       default "fsp.bin"
+       help
+         The filename of the file to use as Firmware Support Package binary
+         in the board directory.
+
+config FSP_ADDR
+       hex "Firmware Support Package binary location"
+       depends on HAVE_FSP
+       default 0xfffc0000
+       help
+         FSP is not Position Independent Code (PIC) and the whole FSP has to
+         be rebased if it is placed at a location which is different from the
+         perferred base address specified during the FSP build. Use Intel's
+         Binary Configuration Tool (BCT) to do the rebase.
+
+         The default base address of 0xfffc0000 indicates that the binary must
+         be located at offset 0xc0000 from the beginning of a 1MB flash device.
+
+config FSP_TEMP_RAM_ADDR
+       hex
+       default 0x2000000
+       help
+         Stack top address which is used in FspInit after DRAM is ready and
+         CAR is disabled.
+
 source "arch/x86/cpu/coreboot/Kconfig"
 
 source "arch/x86/cpu/ivybridge/Kconfig"
arch/x86/cpu/queensbay/Kconfig +0 -32
index f6b5201..397e599 100644
@@ -11,44 +11,6 @@ config INTEL_QUEENSBAY
 
 if INTEL_QUEENSBAY
 
-config HAVE_FSP
-       bool "Add an Firmware Support Package binary"
-       help
-         Select this option to add an Firmware Support Package binary to
-         the resulting U-Boot image. It is a binary blob which U-Boot uses
-         to set up SDRAM and other chipset specific initialization.
-
-         Note: Without this binary U-Boot will not be able to set up its
-         SDRAM so will not boot.
-
-config FSP_FILE
-       string "Firmware Support Package binary filename"
-       depends on HAVE_FSP
-       default "fsp.bin"
-       help
-         The filename of the file to use as Firmware Support Package binary
-         in the board directory.
-
-config FSP_ADDR
-       hex "Firmware Support Package binary location"
-       depends on HAVE_FSP
-       default 0xfffc0000
-       help
-         FSP is not Position Independent Code (PIC) and the whole FSP has to
-         be rebased if it is placed at a location which is different from the
-         perferred base address specified during the FSP build. Use Intel's
-         Binary Configuration Tool (BCT) to do the rebase.
-
-         The default base address of 0xfffc0000 indicates that the binary must
-         be located at offset 0xc0000 from the beginning of a 1MB flash device.
-
-config FSP_TEMP_RAM_ADDR

arch/x86/cpu/queensbay/Kconfig config INTEL_QUEENSBAY

Quoted 10 lines
arch/x86/cpu/queensbay/Kconfig +0 -7
-       hex
-       default 0x2000000
-       help
-         Stack top address which is used in FspInit after DRAM is ready and
-         CAR is disabled.
-
 config HAVE_CMC
        bool "Add a Chipset Micro Code state machine binary"
        help
--
#43 lore raw

PATCH 17/23 x86: Define cache line size

In reply to Simon Glass

This avoids a warning in the Realtek Ethernet driver. The value may not matter on x86.

---

 arch/x86/include/asm/cache.h | 2 ++
 1 file changed, 2 insertions(+)
arch/x86/include/asm/cache.h +2 -0
index 508b63f..fff1edd 100644
@@ -7,6 +7,8 @@
 #ifndef __X86_CACHE_H__
 #define __X86_CACHE_H__
 
+#define CONFIG_SYS_CACHELINE_SIZE	16
+
 /*
  * If CONFIG_SYS_CACHELINE_SIZE is defined use it for DMA alignment.  Otherwise
  * use 64-bytes, a safe default for x86.
Signature · 1 line
2.2.0.rc0.207.ga3a616c
#44 lore raw

PATCH 17/23 x86: Define cache line size

Hi Simon,

Quoted 14 lines · Simon Glass

This avoids a warning in the Realtek Ethernet driver. The value may not matter on x86.

---

 arch/x86/include/asm/cache.h | 2 ++
 1 file changed, 2 insertions(+)
arch/x86/include/asm/cache.h +0 -0
index 508b63f..fff1edd 100644

arch/x86/include/asm/cache.h line 10

Quoted 4 lines
arch/x86/include/asm/cache.h +1 -0
@@ -7,6 +7,8 @@
 #ifndef __X86_CACHE_H__
 #define __X86_CACHE_H__
 
+#define CONFIG_SYS_CACHELINE_SIZE      16

I think we should either fix the Realtek ethernet driver, or just move this '#define CONFIG_SYS_CACHELINE_SIZE 16' to include/configs/board.h as a workaround. Simply defining cache line size to 16 to avoid the driver warning does not look good to me, esecially it is not a correct number in a generic arch header file.

arch/x86/include/asm/cache.h

Quoted 5 lines
arch/x86/include/asm/cache.h +1 -1
+
 /*
  * If CONFIG_SYS_CACHELINE_SIZE is defined use it for DMA alignment.  Otherwise
  * use 64-bytes, a safe default for x86.
--

Regards,
Bin

#45 lore raw

PATCH 18/23 x86: Allow a UART to be set up before the FSP is ready

In reply to Simon Glass

Since the FSP is a black box it helps to have some sort of debugging available to check its inputs. If the debug UART is in use, set it up after CAR is available.

---

 arch/x86/include/asm/u-boot-x86.h | 3 +++
 arch/x86/lib/fsp/fsp_support.c    | 4 ++++
 2 files changed, 7 insertions(+)
arch/x86/include/asm/u-boot-x86.h +3 -0
index 44c24ff..85fafc0 100644
@@ -62,6 +62,9 @@ int fsp_cpu_mmc_init(const char *name, struct pci_device_id mmc_supported[],
 /* Set up a UART which can be used with printch(), printhex8(), etc. */
 int setup_early_uart(void);
 
+/* Set up a UART which can be used with printch(), printhex8(), etc. */
+int setup_early_uart(void);
+
 void setup_pcat_compatibility(void);
 
 void isa_unmap_rom(u32 addr);
arch/x86/lib/fsp/fsp_support.c +4 -0
index 8b639f7..5f96da1 100644
@@ -124,6 +124,10 @@ void fsp_init(u32 stack_top, u32 boot_mode, void *nvs_buf)
 	struct fsp_init_params *params_ptr;
 	struct upd_region *fsp_upd;
 
+#ifdef CONFIG_DEBUG_UART
+	setup_early_uart();
+#endif
+
 	fsp_hdr = find_fsp_header();
 	if (fsp_hdr == NULL) {
 		/* No valid FSP info header was found */
Signature · 1 line
2.2.0.rc0.207.ga3a616c
#46 lore raw

PATCH 18/23 x86: Allow a UART to be set up before the FSP is ready

Hi Simon,

Quoted 16 lines · Simon Glass

Since the FSP is a black box it helps to have some sort of debugging available to check its inputs. If the debug UART is in use, set it up after CAR is available.

---

 arch/x86/include/asm/u-boot-x86.h | 3 +++
 arch/x86/lib/fsp/fsp_support.c    | 4 ++++
 2 files changed, 7 insertions(+)
arch/x86/include/asm/u-boot-x86.h +0 -0
index 44c24ff..85fafc0 100644

arch/x86/include/asm/u-boot-x86.h int fsp_cpu_mmc_init(const char *name, struct pci_device_id mmc_supported[], · line 67

Quoted 6 lines
arch/x86/include/asm/u-boot-x86.h +3 -0
@@ -62,6 +62,9 @@ int fsp_cpu_mmc_init(const char *name, struct pci_device_id mmc_supported[],
 /* Set up a UART which can be used with printch(), printhex8(), etc. */
 int setup_early_uart(void);
 
+/* Set up a UART which can be used with printch(), printhex8(), etc. */
+int setup_early_uart(void);
+

Duplicated setup_early_uart() here .. The first one was wrongly introduced in patch#14 in this series.

Quoted 9 lines
arch/x86/include/asm/u-boot-x86.h +0 -0
 void setup_pcat_compatibility(void);
 
 void isa_unmap_rom(u32 addr);
arch/x86/lib/fsp/fsp_support.c +0 -0
index 8b639f7..5f96da1 100644
@@ -124,6 +124,10 @@ void fsp_init(u32 stack_top, u32 boot_mode, void *nvs_buf)
        struct fsp_init_params *params_ptr;

arch/x86/lib/fsp/fsp_support.c void fsp_init(u32 stack_top, u32 boot_mode, void *nvs_buf)

Quoted 10 lines
arch/x86/lib/fsp/fsp_support.c +4 -1
        struct upd_region *fsp_upd;
 
+#ifdef CONFIG_DEBUG_UART
+       setup_early_uart();
+#endif
+
        fsp_hdr = find_fsp_header();
        if (fsp_hdr == NULL) {
                /* No valid FSP info header was found */
--

Regards,
Bin

#47 lore raw

PATCH 19/23 x86: spi: Support ValleyView in ICH SPI driver

In reply to Simon Glass

The base address is found in a different way and the protection bit is also in a different place. Otherwise it is very similar.

---

 drivers/spi/ich.c | 56 ++++++++++++++++++++++++++++++++++++++++---------------
 drivers/spi/ich.h | 11 ++++++-----
 2 files changed, 47 insertions(+), 20 deletions(-)
drivers/spi/ich.c +41 -15
index fdff158..da85779 100644
@@ -7,6 +7,7 @@
  */
 
 #include <common.h>
+#include <errno.h>
 #include <malloc.h>
 #include <spi.h>
 #include <pci.h>
@@ -21,6 +22,7 @@
 struct ich_ctlr {
 	pci_dev_t dev;		/* PCI device number */
 	int ich_version;	/* Controller version, 7 or 9 */
+	bool use_sbase;		/* Use SBASE instead of RCB */
 	int ichspi_lock;
 	int locked;
 	uint8_t *opmenu;
@@ -145,7 +147,7 @@ struct spi_slave *spi_setup_slave(unsigned int bus, unsigned int cs,
 	 * ICH 7 SPI controller only supports array read command
 	 * and byte program command for SST flash
 	 */
-	if (ctlr.ich_version == 7) {
+	if (ctlr.ich_version == 7 || ctlr.use_sbase) {
 		ich->slave.op_mode_rx = SPI_OPM_RX_AS;
 		ich->slave.op_mode_tx = SPI_OPM_TX_BP;
 	}
@@ -181,7 +183,8 @@ static int get_ich_version(uint16_t device_id)
 	if ((device_id >= PCI_DEVICE_ID_INTEL_COUGARPOINT_LPC_MIN &&
 	     device_id <= PCI_DEVICE_ID_INTEL_COUGARPOINT_LPC_MAX) ||
 	    (device_id >= PCI_DEVICE_ID_INTEL_PANTHERPOINT_LPC_MIN &&
-	     device_id <= PCI_DEVICE_ID_INTEL_PANTHERPOINT_LPC_MAX))
+	     device_id <= PCI_DEVICE_ID_INTEL_PANTHERPOINT_LPC_MAX) ||
+	    device_id == PCI_DEVICE_ID_INTEL_VALLEYVIEW_LPC)
 		return 9;
 
 	return 0;
@@ -204,14 +207,14 @@ static int ich9_can_do_33mhz(pci_dev_t dev)
 	return speed == 1;
 }
 
-static int ich_find_spi_controller(pci_dev_t *devp, int *ich_versionp)
+static int ich_find_spi_controller(struct ich_ctlr *ich)
 {
 	int last_bus = pci_last_busno();
 	int bus;
 
 	if (last_bus == -1) {
 		debug("No PCI busses?\n");
-		return -1;
+		return -ENODEV;
 	}
 
 	for (bus = 0; bus <= last_bus; bus++) {
@@ -225,24 +228,33 @@ static int ich_find_spi_controller(pci_dev_t *devp, int *ich_versionp)
 		device_id = ids >> 16;
 
 		if (vendor_id == PCI_VENDOR_ID_INTEL) {
-			*devp = dev;
-			*ich_versionp = get_ich_version(device_id);
-			return 0;
+			ich->dev = dev;
+			ich->ich_version = get_ich_version(device_id);
+			if (device_id == PCI_DEVICE_ID_INTEL_VALLEYVIEW_LPC)
+				ich->use_sbase = true;
+			return ich->ich_version == 0 ? -ENODEV : 0;
 		}
 	}
 
 	debug("ICH SPI: No ICH found.\n");
-	return -1;
+	return -ENODEV;
 }
 
 static int ich_init_controller(struct ich_ctlr *ctlr)
 {
 	uint8_t *rcrb; /* Root Complex Register Block */
 	uint32_t rcba; /* Root Complex Base Address */
+	uint32_t sbase_addr;
+	uint8_t *sbase;
 
 	pci_read_config_dword(ctlr->dev, 0xf0, &rcba);
 	/* Bits 31-14 are the base address, 13-1 are reserved, 0 is enable. */
 	rcrb = (uint8_t *)(rcba & 0xffffc000);
+
+	/* SBASE is similar */
+	pci_read_config_dword(ctlr->dev, 0x54, &sbase_addr);
+	sbase = (uint8_t *)(sbase_addr & 0xfffffe00);
+
 	if (ctlr->ich_version == 7) {
 		struct ich7_spi_regs *ich7_spi;
 
@@ -262,7 +274,10 @@ static int ich_init_controller(struct ich_ctlr *ctlr)
 	} else if (ctlr->ich_version == 9) {
 		struct ich9_spi_regs *ich9_spi;
 
-		ich9_spi = (struct ich9_spi_regs *)(rcrb + 0x3800);
+		if (ctlr->use_sbase)
+			ich9_spi = (struct ich9_spi_regs *)sbase;
+		else
+			ich9_spi = (struct ich9_spi_regs *)(rcrb + 0x3800);
 		ctlr->ichspi_lock = ich_readw(&ich9_spi->hsfs) & HSFS_FLOCKDN;
 		ctlr->opmenu = ich9_spi->opmenu;
 		ctlr->menubytes = sizeof(ich9_spi->opmenu);
@@ -282,12 +297,13 @@ static int ich_init_controller(struct ich_ctlr *ctlr)
 		      ctlr->ich_version);
 		return -1;
 	}
-	debug("ICH SPI: Version %d detected\n", ctlr->ich_version);
 
 	/* Work out the maximum speed we can support */
 	ctlr->max_speed = 20000000;
 	if (ctlr->ich_version == 9 && ich9_can_do_33mhz(ctlr->dev))
 		ctlr->max_speed = 33000000;
+	debug("ICH SPI: Version %d detected at %p, speed %ld\n",
+	      ctlr->ich_version, ctlr->base, ctlr->max_speed);
 
 	ich_set_bbar(ctlr, 0);
 
@@ -298,7 +314,7 @@ void spi_init(void)
 {
 	uint8_t bios_cntl;
 
-	if (ich_find_spi_controller(&ctlr.dev, &ctlr.ich_version)) {
+	if (ich_find_spi_controller(&ctlr)) {
 		printf("ICH SPI: Cannot find device\n");
 		return;
 	}
@@ -312,10 +328,20 @@ void spi_init(void)
 	 * Disable the BIOS write protect so write commands are allowed.  On
 	 * v9, deassert SMM BIOS Write Protect Disable.
 	 */
-	pci_read_config_byte(ctlr.dev, 0xdc, &bios_cntl);
-	if (ctlr.ich_version == 9)
-		bios_cntl &= ~(1 << 5);
-	pci_write_config_byte(ctlr.dev, 0xdc, bios_cntl | 0x1);
+	if (ctlr.use_sbase) {
+		struct ich9_spi_regs *ich9_spi;
+
+		ich9_spi = (struct ich9_spi_regs *)ctlr.base;
+		bios_cntl = ich_readb(&ich9_spi->bcr);
+		bios_cntl &= ~(1 << 5);	/* clear Enable InSMM_STS (EISS) */
+		bios_cntl |= 1;		/* Write Protect Disable (WPD) */
+		ich_writeb(bios_cntl, &ich9_spi->bcr);
+	} else {
+		pci_read_config_byte(ctlr.dev, 0xdc, &bios_cntl);
+		if (ctlr.ich_version == 9)
+			bios_cntl &= ~(1 << 5);
+		pci_write_config_byte(ctlr.dev, 0xdc, bios_cntl | 0x1);
+	}
 }
 
 int spi_claim_bus(struct spi_slave *slave)
drivers/spi/ich.h +6 -5
index d2e4b85..1419b23 100644
@@ -37,18 +37,19 @@ struct ich9_spi_regs {
 	uint8_t opmenu[8];		/* 0x98 */
 	uint32_t bbar;
 	uint8_t _reserved3[12];
-	uint32_t fdoc;
+	uint32_t fdoc;			/* 0xb0 */
 	uint32_t fdod;
 	uint8_t _reserved4[8];
-	uint32_t afc;
+	uint32_t afc;			/* 0xc0 */
 	uint32_t lvscc;
 	uint32_t uvscc;
 	uint8_t _reserved5[4];
-	uint32_t fpb;
+	uint32_t fpb;			/* 0xd0 */
 	uint8_t _reserved6[28];
-	uint32_t srdl;
+	uint32_t srdl;			/* 0xf0 */
 	uint32_t srdc;
-	uint32_t srd;
+	uint32_t scs;
+	uint32_t bcr;
 } __packed;
 
 enum {
Signature · 1 line
2.2.0.rc0.207.ga3a616c
#48 lore raw

PATCH 19/23 x86: spi: Support ValleyView in ICH SPI driver

Hi Simon,

Quoted 31 lines · Simon Glass

The base address is found in a different way and the protection bit is also in a different place. Otherwise it is very similar.

---

 drivers/spi/ich.c | 56 ++++++++++++++++++++++++++++++++++++++++---------------
 drivers/spi/ich.h | 11 ++++++-----
 2 files changed, 47 insertions(+), 20 deletions(-)
drivers/spi/ich.c +2 -0
index fdff158..da85779 100644
@@ -7,6 +7,7 @@
  */
 
 #include <common.h>
+#include <errno.h>
 #include <malloc.h>
 #include <spi.h>
 #include <pci.h>
@@ -21,6 +22,7 @@
 struct ich_ctlr {
        pci_dev_t dev;          /* PCI device number */
        int ich_version;        /* Controller version, 7 or 9 */
+       bool use_sbase;         /* Use SBASE instead of RCB */
        int ichspi_lock;
        int locked;
        uint8_t *opmenu;

drivers/spi/ich.c struct spi_slave *spi_setup_slave(unsigned int bus, unsigned int cs, · line 153

Quoted 8 lines
drivers/spi/ich.c +1 -1
@@ -145,7 +147,7 @@ struct spi_slave *spi_setup_slave(unsigned int bus, unsigned int cs,
         * ICH 7 SPI controller only supports array read command
         * and byte program command for SST flash
         */
-       if (ctlr.ich_version == 7) {
+       if (ctlr.ich_version == 7 || ctlr.use_sbase) {
                ich->slave.op_mode_rx = SPI_OPM_RX_AS;
                ich->slave.op_mode_tx = SPI_OPM_TX_BP;
        }

So the Valleyview SPI controller (version 9) has the same behavior that was seen on Tunnel Creek (version 7). I wonder whether the same behavior was seen on chromebook_link which is also version 9? Or is this only because the Minnowmax board has the same SST flash mounted on board, just like the Crown Bay so that we need set these RX/TX flags. If SPI controller on chromebook_link also has the simliar behavior, we should consider set these flags for all Intel SPI controller variants. This way, the 'use_sbase' variable may not be necessary (see below for more comments).

drivers/spi/ich.c static int get_ich_version(uint16_t device_id) · line 187

Quoted 7 lines
drivers/spi/ich.c +2 -1
@@ -181,7 +183,8 @@ static int get_ich_version(uint16_t device_id)
        if ((device_id >= PCI_DEVICE_ID_INTEL_COUGARPOINT_LPC_MIN &&
             device_id <= PCI_DEVICE_ID_INTEL_COUGARPOINT_LPC_MAX) ||
            (device_id >= PCI_DEVICE_ID_INTEL_PANTHERPOINT_LPC_MIN &&
-            device_id <= PCI_DEVICE_ID_INTEL_PANTHERPOINT_LPC_MAX))
+            device_id <= PCI_DEVICE_ID_INTEL_PANTHERPOINT_LPC_MAX) ||
+           device_id == PCI_DEVICE_ID_INTEL_VALLEYVIEW_LPC)

To avoid bigger and bigger test logic, should we consider using DT to pass such information?

Quoted 45 lines
drivers/spi/ich.c +9 -6
                return 9;
 
        return 0;
@@ -204,14 +207,14 @@ static int ich9_can_do_33mhz(pci_dev_t dev)
        return speed == 1;
 }
 
-static int ich_find_spi_controller(pci_dev_t *devp, int *ich_versionp)
+static int ich_find_spi_controller(struct ich_ctlr *ich)
 {
        int last_bus = pci_last_busno();
        int bus;
 
        if (last_bus == -1) {
                debug("No PCI busses?\n");
-               return -1;
+               return -ENODEV;
        }
 
        for (bus = 0; bus <= last_bus; bus++) {
@@ -225,24 +228,33 @@ static int ich_find_spi_controller(pci_dev_t *devp, int *ich_versionp)
                device_id = ids >> 16;
 
                if (vendor_id == PCI_VENDOR_ID_INTEL) {
-                       *devp = dev;
-                       *ich_versionp = get_ich_version(device_id);
-                       return 0;
+                       ich->dev = dev;
+                       ich->ich_version = get_ich_version(device_id);
+                       if (device_id == PCI_DEVICE_ID_INTEL_VALLEYVIEW_LPC)
+                               ich->use_sbase = true;
+                       return ich->ich_version == 0 ? -ENODEV : 0;
                }
        }
 
        debug("ICH SPI: No ICH found.\n");
-       return -1;
+       return -ENODEV;
 }
 
 static int ich_init_controller(struct ich_ctlr *ctlr)
 {
        uint8_t *rcrb; /* Root Complex Register Block */
        uint32_t rcba; /* Root Complex Base Address */
+       uint32_t sbase_addr;

drivers/spi/ich.c static int ich_find_spi_controller(pci_dev_t *devp, int *ich_versionp) · line 257

Quoted 10 lines
drivers/spi/ich.c +6 -0
+       uint8_t *sbase;
 
        pci_read_config_dword(ctlr->dev, 0xf0, &rcba);
        /* Bits 31-14 are the base address, 13-1 are reserved, 0 is enable. */
        rcrb = (uint8_t *)(rcba & 0xffffc000);
+
+       /* SBASE is similar */
+       pci_read_config_dword(ctlr->dev, 0x54, &sbase_addr);
+       sbase = (uint8_t *)(sbase_addr & 0xfffffe00);
+

Again, DT can be used to determine the base address.

drivers/spi/ich.c static int ich_init_controller(struct ich_ctlr *ctlr) · line 280

Quoted 12 lines
drivers/spi/ich.c +4 -1
        if (ctlr->ich_version == 7) {
                struct ich7_spi_regs *ich7_spi;
 
@@ -262,7 +274,10 @@ static int ich_init_controller(struct ich_ctlr *ctlr)
        } else if (ctlr->ich_version == 9) {
                struct ich9_spi_regs *ich9_spi;
 
-               ich9_spi = (struct ich9_spi_regs *)(rcrb + 0x3800);
+               if (ctlr->use_sbase)
+                       ich9_spi = (struct ich9_spi_regs *)sbase;
+               else
+                       ich9_spi = (struct ich9_spi_regs *)(rcrb + 0x3800);

Ditto.

Quoted 33 lines
drivers/spi/ich.c +3 -4
                ctlr->ichspi_lock = ich_readw(&ich9_spi->hsfs) & HSFS_FLOCKDN;
                ctlr->opmenu = ich9_spi->opmenu;
                ctlr->menubytes = sizeof(ich9_spi->opmenu);
@@ -282,12 +297,13 @@ static int ich_init_controller(struct ich_ctlr *ctlr)
                      ctlr->ich_version);
                return -1;
        }
-       debug("ICH SPI: Version %d detected\n", ctlr->ich_version);
 
        /* Work out the maximum speed we can support */
        ctlr->max_speed = 20000000;
        if (ctlr->ich_version == 9 && ich9_can_do_33mhz(ctlr->dev))
                ctlr->max_speed = 33000000;
+       debug("ICH SPI: Version %d detected at %p, speed %ld\n",
+             ctlr->ich_version, ctlr->base, ctlr->max_speed);
 
        ich_set_bbar(ctlr, 0);
 
@@ -298,7 +314,7 @@ void spi_init(void)
 {
        uint8_t bios_cntl;
 
-       if (ich_find_spi_controller(&ctlr.dev, &ctlr.ich_version)) {
+       if (ich_find_spi_controller(&ctlr)) {
                printf("ICH SPI: Cannot find device\n");
                return;
        }
@@ -312,10 +328,20 @@ void spi_init(void)
         * Disable the BIOS write protect so write commands are allowed.  On
         * v9, deassert SMM BIOS Write Protect Disable.
         */
-       pci_read_config_byte(ctlr.dev, 0xdc, &bios_cntl);
-       if (ctlr.ich_version == 9)

drivers/spi/ich.c void spi_init(void) · line 338

Quoted 10 lines
drivers/spi/ich.c +8 -2
-               bios_cntl &= ~(1 << 5);
-       pci_write_config_byte(ctlr.dev, 0xdc, bios_cntl | 0x1);
+       if (ctlr.use_sbase) {
+               struct ich9_spi_regs *ich9_spi;
+
+               ich9_spi = (struct ich9_spi_regs *)ctlr.base;
+               bios_cntl = ich_readb(&ich9_spi->bcr);
+               bios_cntl &= ~(1 << 5); /* clear Enable InSMM_STS (EISS) */
+               bios_cntl |= 1;         /* Write Protect Disable (WPD) */
+               ich_writeb(bios_cntl, &ich9_spi->bcr);

Basically the register bit layout is the same as the non-sbase controller, only the register address is differnt (0xFC vs. 0xDC). Again we can use DT to pass this to the driver.

Quoted 29 lines
drivers/spi/ich.c +6 -0
+       } else {
+               pci_read_config_byte(ctlr.dev, 0xdc, &bios_cntl);
+               if (ctlr.ich_version == 9)
+                       bios_cntl &= ~(1 << 5);
+               pci_write_config_byte(ctlr.dev, 0xdc, bios_cntl | 0x1);
+       }
 }
 
 int spi_claim_bus(struct spi_slave *slave)
drivers/spi/ich.h +3 -3
index d2e4b85..1419b23 100644
@@ -37,18 +37,19 @@ struct ich9_spi_regs {
        uint8_t opmenu[8];              /* 0x98 */
        uint32_t bbar;
        uint8_t _reserved3[12];
-       uint32_t fdoc;
+       uint32_t fdoc;                  /* 0xb0 */
        uint32_t fdod;
        uint8_t _reserved4[8];
-       uint32_t afc;
+       uint32_t afc;                   /* 0xc0 */
        uint32_t lvscc;
        uint32_t uvscc;
        uint8_t _reserved5[4];
-       uint32_t fpb;
+       uint32_t fpb;                   /* 0xd0 */
        uint8_t _reserved6[28];

drivers/spi/ich.h struct ich9_spi_regs {

Quoted 10 lines
drivers/spi/ich.h +3 -3
-       uint32_t srdl;
+       uint32_t srdl;                  /* 0xf0 */
        uint32_t srdc;
-       uint32_t srd;
+       uint32_t scs;
+       uint32_t bcr;
 } __packed;
 
 enum {
--

Regards,
Bin

#49 lore raw

PATCH 19/23 x86: spi: Support ValleyView in ICH SPI driver

Hi Bin,

Quoted 12 lines · Bin Meng

Hi Simon,

Quoted 9 lines · Simon Glass

The base address is found in a different way and the protection bit is also in a different place. Otherwise it is very similar.

---

 drivers/spi/ich.c | 56 ++++++++++++++++++++++++++++++++++++++++---------------
 drivers/spi/ich.h | 11 ++++++-----
 2 files changed, 47 insertions(+), 20 deletions(-)

Just a note on this one...for v2 I have done nothing. I think we should move it to device tree as you say but it needs some more thought, as we have register offsets and device types to think about. I will try a few things and test on link also. Once I have this I will send a v3. So this patch will have to sit here until that is done, hopefully only a few days.

Thanks for the quick reviews!

Regards,
Simon

#50 lore raw

PATCH 19/23 x86: spi: Support ValleyView in ICH SPI driver

Hi Simon,

Quoted 16 lines · Simon Glass

Hi Bin,

Quoted 12 lines · Bin Meng

Hi Simon,

Quoted 9 lines · Simon Glass

The base address is found in a different way and the protection bit is also in a different place. Otherwise it is very similar.

---

 drivers/spi/ich.c | 56 ++++++++++++++++++++++++++++++++++++++++---------------
 drivers/spi/ich.h | 11 ++++++-----
 2 files changed, 47 insertions(+), 20 deletions(-)
Quoted 7 lines

Just a note on this one...for v2 I have done nothing. I think we should move it to device tree as you say but it needs some more thought, as we have register offsets and device types to think about. I will try a few things and test on link also. Once I have this I will send a v3. So this patch will have to sit here until that is done, hopefully only a few days.

OK, I think we can just apply this patch for now along with other patches in this series. We can revisit this driver when adding DT and DM support.

Quoted 2 lines

Thanks for the quick reviews!

You are welcome!

Regards,
Bin

#51 lore raw

PATCH 19/23 x86: spi: Support ValleyView in ICH SPI driver

Hi Bin,

Quoted 27 lines · Bin Meng

Hi Simon,

Quoted 16 lines · Simon Glass

Hi Bin,

Quoted 12 lines · Bin Meng

Hi Simon,

Quoted 9 lines · Simon Glass

The base address is found in a different way and the protection bit is also in a different place. Otherwise it is very similar.

---

 drivers/spi/ich.c | 56 ++++++++++++++++++++++++++++++++++++++++---------------
 drivers/spi/ich.h | 11 ++++++-----
 2 files changed, 47 insertions(+), 20 deletions(-)
Quoted 7 lines

Just a note on this one...for v2 I have done nothing. I think we should move it to device tree as you say but it needs some more thought, as we have register offsets and device types to think about. I will try a few things and test on link also. Once I have this I will send a v3. So this patch will have to sit here until that is done, hopefully only a few days.

Quoted 3 lines

OK, I think we can just apply this patch for now along with other patches in this series. We can revisit this driver when adding DT and DM support.

Oh OK we can do it that way. I actually have some partial work to convert the ICH driver to DM, so I'll go back to that soon.

Applied to u-boot-x86.

Regards,
Simon

#52 lore raw

PATCH 20/23 scsi: bootstage: Measure time taken to scan the bus

In reply to Simon Glass

On some hardware this time can be significant. Add bootstage support for measuring this. The result can be obtained using 'bootstage report' or passed on to the Linux via the device tree.

---

 common/cmd_scsi.c   | 2 ++
 include/bootstage.h | 1 +
 2 files changed, 3 insertions(+)
common/cmd_scsi.c +2 -0
index cbc107e..a0a62eb 100644
@@ -217,8 +217,10 @@ void scsi_init(void)
 		       (busdevfunc >> 8) & 0x7);
 	}
 #endif
+	bootstage_start(BOOTSTAGE_ID_ACCUM_SCSI, "ahci");
 	scsi_low_level_init(busdevfunc);
 	scsi_scan(1);
+	bootstage_accum(BOOTSTAGE_ID_ACCUM_SCSI);
 }
 #endif
 
include/bootstage.h +1 -0
index df13ab2..6b7588d 100644
@@ -194,6 +194,7 @@ enum bootstage_id {
 	BOOTSTAGE_ID_MAIN_CPU_READY,
 
 	BOOTSTAGE_ID_ACCUM_LCD,
+	BOOTSTAGE_ID_ACCUM_SCSI,
 
 	/* a few spare for the user, from here */
 	BOOTSTAGE_ID_USER,
Signature · 1 line
2.2.0.rc0.207.ga3a616c
#53 lore raw

PATCH 20/23 scsi: bootstage: Measure time taken to scan the bus

Quoted 31 lines · Simon Glass

On some hardware this time can be significant. Add bootstage support for measuring this. The result can be obtained using 'bootstage report' or passed on to the Linux via the device tree.

---

 common/cmd_scsi.c   | 2 ++
 include/bootstage.h | 1 +
 2 files changed, 3 insertions(+)
common/cmd_scsi.c +2 -0
index cbc107e..a0a62eb 100644
@@ -217,8 +217,10 @@ void scsi_init(void)
                       (busdevfunc >> 8) & 0x7);
        }
 #endif
+       bootstage_start(BOOTSTAGE_ID_ACCUM_SCSI, "ahci");
        scsi_low_level_init(busdevfunc);
        scsi_scan(1);
+       bootstage_accum(BOOTSTAGE_ID_ACCUM_SCSI);
 }
 #endif
 
include/bootstage.h +0 -0
index df13ab2..6b7588d 100644

include/bootstage.h enum bootstage_id {

Quoted 8 lines
include/bootstage.h +1 -1
@@ -194,6 +194,7 @@ enum bootstage_id {
        BOOTSTAGE_ID_MAIN_CPU_READY,
 
        BOOTSTAGE_ID_ACCUM_LCD,
+       BOOTSTAGE_ID_ACCUM_SCSI,
 
        /* a few spare for the user, from here */
        BOOTSTAGE_ID_USER,
--
#54 lore raw

PATCH 20/23 scsi: bootstage: Measure time taken to scan the bus

In reply to Simon Glass
Quoted 16 lines · Simon Glass

On some hardware this time can be significant. Add bootstage support for measuring this. The result can be obtained using 'bootstage report' or passed on to the Linux via the device tree.

---

 common/cmd_scsi.c   | 2 ++
 include/bootstage.h | 1 +
 2 files changed, 3 insertions(+)
common/cmd_scsi.c +0 -0
index cbc107e..a0a62eb 100644

common/cmd_scsi.c void scsi_init(void) · line 223

Quoted 7 lines
common/cmd_scsi.c +2 -0
@@ -217,8 +217,10 @@ void scsi_init(void)
                       (busdevfunc >> 8) & 0x7);
        }
 #endif
+       bootstage_start(BOOTSTAGE_ID_ACCUM_SCSI, "ahci");
        scsi_low_level_init(busdevfunc);
        scsi_scan(1);
+       bootstage_accum(BOOTSTAGE_ID_ACCUM_SCSI);

This does not cover the case if the platform calls scsi_scan at boot. The first time is the important one as that will include disk spin-up time.

Perhaps they shouldn't be and "scsi scan" should always be in boot scripts.

Rob

#55 lore raw

PATCH 20/23 scsi: bootstage: Measure time taken to scan the bus

Hi Rob,

Quoted 29 lines · Rob Herring
Quoted 16 lines · Simon Glass

On some hardware this time can be significant. Add bootstage support for measuring this. The result can be obtained using 'bootstage report' or passed on to the Linux via the device tree.

---

 common/cmd_scsi.c   | 2 ++
 include/bootstage.h | 1 +
 2 files changed, 3 insertions(+)
common/cmd_scsi.c +0 -0
index cbc107e..a0a62eb 100644

common/cmd_scsi.c void scsi_init(void) · line 223

Quoted 7 lines
common/cmd_scsi.c +2 -0
@@ -217,8 +217,10 @@ void scsi_init(void)
                       (busdevfunc >> 8) & 0x7);
        }
 #endif
+       bootstage_start(BOOTSTAGE_ID_ACCUM_SCSI, "ahci");
        scsi_low_level_init(busdevfunc);
        scsi_scan(1);
+       bootstage_accum(BOOTSTAGE_ID_ACCUM_SCSI);

This does not cover the case if the platform calls scsi_scan at boot. The first time is the important one as that will include disk spin-up time.

Quoted 2 lines

Perhaps they shouldn't be and "scsi scan" should always be in boot scripts.

scsi_init() is called in common/board_r.c, which already covers the boot scan case.

Regards,
Bin

#56 lore raw

PATCH 20/23 scsi: bootstage: Measure time taken to scan the bus

Hi,

Quoted 32 lines · Bin Meng

Hi Rob,

Quoted 29 lines · Rob Herring
Quoted 16 lines · Simon Glass

On some hardware this time can be significant. Add bootstage support for measuring this. The result can be obtained using 'bootstage report' or passed on to the Linux via the device tree.

---

 common/cmd_scsi.c   | 2 ++
 include/bootstage.h | 1 +
 2 files changed, 3 insertions(+)
common/cmd_scsi.c +0 -0
index cbc107e..a0a62eb 100644

common/cmd_scsi.c void scsi_init(void) · line 223

Quoted 7 lines
common/cmd_scsi.c +2 -0
@@ -217,8 +217,10 @@ void scsi_init(void)
                       (busdevfunc >> 8) & 0x7);
        }
 #endif
+       bootstage_start(BOOTSTAGE_ID_ACCUM_SCSI, "ahci");
        scsi_low_level_init(busdevfunc);
        scsi_scan(1);
+       bootstage_accum(BOOTSTAGE_ID_ACCUM_SCSI);

This does not cover the case if the platform calls scsi_scan at boot. The first time is the important one as that will include disk spin-up time.

Quoted 5 lines
Quoted 2 lines

Perhaps they shouldn't be and "scsi scan" should always be in boot scripts.

scsi_init() is called in common/board_r.c, which already covers the boot scan case.

I think platform data is missing. Rob if you are able to test this I could send an updated patch?

Regards,
Simon

#57 lore raw

PATCH 21/23 x86: Enable bootstage features

In reply to Simon Glass

Allow measuring of boot time using bootstage.

---

 include/configs/x86-common.h | 3 +++
 1 file changed, 3 insertions(+)
include/configs/x86-common.h +3 -0
index ecedfc3..66d4894 100644
@@ -245,6 +245,9 @@
 #define CONFIG_BOOTP_GATEWAY
 #define CONFIG_BOOTP_HOSTNAME
 
+#define CONFIG_BOOTSTAGE
+#define CONFIG_CMD_BOOTSTAGE
+
 #define CONFIG_CMD_USB
 
 #define CONFIG_EXTRA_ENV_SETTINGS \
Signature · 1 line
2.2.0.rc0.207.ga3a616c
#58 lore raw

PATCH 21/23 x86: Enable bootstage features

Quoted 13 lines · Simon Glass

Allow measuring of boot time using bootstage.

---

 include/configs/x86-common.h | 3 +++
 1 file changed, 3 insertions(+)
include/configs/x86-common.h +0 -0
index ecedfc3..66d4894 100644

include/configs/x86-common.h

Quoted 10 lines
include/configs/x86-common.h +3 -1
@@ -245,6 +245,9 @@
 #define CONFIG_BOOTP_GATEWAY
 #define CONFIG_BOOTP_HOSTNAME
 
+#define CONFIG_BOOTSTAGE
+#define CONFIG_CMD_BOOTSTAGE
+
 #define CONFIG_CMD_USB
 
 #define CONFIG_EXTRA_ENV_SETTINGS \
--
#59 lore raw

PATCH 22/23 x86: Add some documentation on how to port U-Boot on x86

In reply to Simon Glass

Some information has been gleaned on tools and procedures for porting U-Boot to different x86 platforms. Add a few notes to start things off.

---

 doc/README.x86 | 63 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 63 insertions(+)
doc/README.x86 +63 -0
index 809a291..0e4628a 100644
@@ -164,6 +164,69 @@ mtrr - List and set the Memory Type Range Registers (MTRR). These are used to
 	 mode to use. U-Boot sets up some reasonable values but you can
 	 adjust then with this command.
 
+Development Flow
+----------------
+
+These notes are for those who want to port U-Boot to a new x86 platform.
+
+Since x86 CPUs boot from SPI flash, a SPI flash emulator is a good investment.
+The Dediprog em100 can be used on Linux. The em100 tool is available here:
+
+   http://review.coreboot.org/p/em100.git
+
+On Minnowboard Max the following command line can be used:
+
+   sudo em100 -s -p LOW -d u-boot.rom -c W25Q64DW -r
+
+A suitable clip for connecting over the SPI flash chip is here:
+
+   http://www.dediprog.com/pd/programmer-accessories/EM-TC-8
+
+This allows you to override the SPI flash contents for development purposes.
+Typically you can write to the em100 in around 1200ms, considerably faster
+than programming the real flash device each time. The only important
+limitation of the em100 is that it only supports SPI bus speeds up to 20MHz.
+This means that images must be set to boot with that speed (Intel-specific
+feature).
+
+If your chip/board uses an Intel Firmware Support Package (FSP) it is fairly
+easy to fit it in. You can follow the Minnowboard Max implementation, for
+example. Hopefully you will just need to create new files similar to those
+in arch/x86/cpu/baytrail which provide Bay Trail support.
+
+If you are not using an FSP you have more freedom and more responsibility.
+The ivybridge support works this way, although it still uses a ROM for
+graphics and still has binary blobs containing Intel code. You should aim to
+support all important peripherals on your platform including video and storage.
+Use the device tree for configuration where possible.
+
+For the microcode you can create a suitable device tree file using the
+microcode tool:
+
+  ./tools/microcode-tool -d microcode.dat create <model>
+
+or if you only have header files and not the full Intel microcode.dat database:
+
+  ./tools/microcode-tool -H BAY_TRAIL_FSP_KIT/Microcode/M0130673322.h \
+	-H BAY_TRAIL_FSP_KIT/Microcode/M0130679901.h \
+	create all
+
+These are written to arch/x86/dts/microcode/ by default.
+
+Note that it is possible to just add the micrcode for your CPU if you know its
+model. U-Boot prints this information when it starts
+
+   CPU: x86_64, vendor Intel, device 30673h
+
+so here we can use the M0130673322 file.
+
+If you platform can display POST codes on two little 7-segment displays on
+the board, then you can use post_code() calls from C or assembler to monitor
+boot progress. This can be good for debugging.
+
+If not, you can try to get serial working as early as possible. The early
+debug serial port may be useful here. See setup_early_uart() for an example.
+
 TODO List
 ---------
 - Audio
Signature · 1 line
2.2.0.rc0.207.ga3a616c
#60 lore raw

PATCH 22/23 x86: Add some documentation on how to port U-Boot on x86

Hi Simon,

Quoted 6 lines · Simon Glass

Some information has been gleaned on tools and procedures for porting U-Boot to different x86 platforms. Add a few notes to start things off.

---

A minor comment below.

Quoted 26 lines
 doc/README.x86 | 63 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 63 insertions(+)
doc/README.x86 +15 -0
index 809a291..0e4628a 100644
@@ -164,6 +164,69 @@ mtrr - List and set the Memory Type Range Registers (MTRR). These are used to
         mode to use. U-Boot sets up some reasonable values but you can
         adjust then with this command.
 
+Development Flow
+----------------
+
+These notes are for those who want to port U-Boot to a new x86 platform.
+
+Since x86 CPUs boot from SPI flash, a SPI flash emulator is a good investment.
+The Dediprog em100 can be used on Linux. The em100 tool is available here:
+
+   http://review.coreboot.org/p/em100.git
+
+On Minnowboard Max the following command line can be used:
+
+   sudo em100 -s -p LOW -d u-boot.rom -c W25Q64DW -r
+
+A suitable clip for connecting over the SPI flash chip is here:

doc/README.x86 mtrr - List and set the Memory Type Range Registers (MTRR). These are used to · line 191

Quoted 10 lines
doc/README.x86 +10 -0
+
+   http://www.dediprog.com/pd/programmer-accessories/EM-TC-8
+
+This allows you to override the SPI flash contents for development purposes.
+Typically you can write to the em100 in around 1200ms, considerably faster
+than programming the real flash device each time. The only important
+limitation of the em100 is that it only supports SPI bus speeds up to 20MHz.
+This means that images must be set to boot with that speed (Intel-specific
+feature).
+

It would be better to document what this Intel-specific feature is in order to support this SPI bus frequency.

Quoted 32 lines
doc/README.x86 +32 -0
+If your chip/board uses an Intel Firmware Support Package (FSP) it is fairly
+easy to fit it in. You can follow the Minnowboard Max implementation, for
+example. Hopefully you will just need to create new files similar to those
+in arch/x86/cpu/baytrail which provide Bay Trail support.
+
+If you are not using an FSP you have more freedom and more responsibility.
+The ivybridge support works this way, although it still uses a ROM for
+graphics and still has binary blobs containing Intel code. You should aim to
+support all important peripherals on your platform including video and storage.
+Use the device tree for configuration where possible.
+
+For the microcode you can create a suitable device tree file using the
+microcode tool:
+
+  ./tools/microcode-tool -d microcode.dat create <model>
+
+or if you only have header files and not the full Intel microcode.dat database:
+
+  ./tools/microcode-tool -H BAY_TRAIL_FSP_KIT/Microcode/M0130673322.h \
+       -H BAY_TRAIL_FSP_KIT/Microcode/M0130679901.h \
+       create all
+
+These are written to arch/x86/dts/microcode/ by default.
+
+Note that it is possible to just add the micrcode for your CPU if you know its
+model. U-Boot prints this information when it starts
+
+   CPU: x86_64, vendor Intel, device 30673h
+
+so here we can use the M0130673322 file.
+
+If you platform can display POST codes on two little 7-segment displays on

doc/README.x86 mtrr - List and set the Memory Type Range Registers (MTRR). These are used to

Quoted 10 lines
doc/README.x86 +6 -1
+the board, then you can use post_code() calls from C or assembler to monitor
+boot progress. This can be good for debugging.
+
+If not, you can try to get serial working as early as possible. The early
+debug serial port may be useful here. See setup_early_uart() for an example.
+
 TODO List
 ---------
 - Audio
--

Regards,
Bin

#61 lore raw

PATCH 23/23 x86: Add support for Intel Minnowboard Max

In reply to Simon Glass

This is a relatively low-cost x86 board in a small form factor. The main peripherals are uSD, USB, HDMI, Ethernet and SATA. It uses an Atom 3800 series CPU. So far only the dual core 2GB variant is supported.

This uses the existing FSP support. Binary blobs are required to make this board work. The microcode update is included as a patch (all 3000 lines of it).

---

 arch/x86/Kconfig                                 |   12 +
 arch/x86/cpu/Makefile                            |    1 +
 arch/x86/cpu/baytrail/Kconfig                    |    9 +
 arch/x86/cpu/baytrail/Makefile                   |   10 +
 arch/x86/cpu/baytrail/early_uart.c               |   82 +
 arch/x86/cpu/baytrail/fsp_configs.c              |  156 +
 arch/x86/cpu/baytrail/pci.c                      |   47 +
 arch/x86/cpu/baytrail/valleyview.c               |   37 +
 arch/x86/dts/Makefile                            |    3 +-
 arch/x86/dts/microcode/m0130673322.dtsi          | 3284 ++++++++++++++++++++++
 arch/x86/dts/minnowmax.dts                       |   45 +
 arch/x86/dts/serial.dtsi                         |    2 +-
 arch/x86/include/asm/arch-baytrail/fsp/azalia.h  |   39 +
 arch/x86/include/asm/arch-baytrail/fsp/fsp_vpd.h |   95 +
 arch/x86/include/asm/arch-baytrail/gpio.h        |   13 +
 board/intel/minnowmax/Kconfig                    |   31 +
 board/intel/minnowmax/MAINTAINERS                |    6 +
 board/intel/minnowmax/Makefile                   |    7 +
 board/intel/minnowmax/minnowmax.c                |   32 +
 board/intel/minnowmax/start.S                    |    9 +
 configs/minnowmax_defconfig                      |   13 +
 doc/README.x86                                   |   49 +-
 include/configs/minnowmax.h                      |   69 +
 23 files changed, 4043 insertions(+), 8 deletions(-)
 create mode 100644 arch/x86/cpu/baytrail/Kconfig
 create mode 100644 arch/x86/cpu/baytrail/Makefile
 create mode 100644 arch/x86/cpu/baytrail/early_uart.c
 create mode 100644 arch/x86/cpu/baytrail/fsp_configs.c
 create mode 100644 arch/x86/cpu/baytrail/pci.c
 create mode 100644 arch/x86/cpu/baytrail/valleyview.c
 create mode 100644 arch/x86/dts/microcode/m0130673322.dtsi
 create mode 100644 arch/x86/dts/minnowmax.dts
 create mode 100644 arch/x86/include/asm/arch-baytrail/fsp/azalia.h
 create mode 100644 arch/x86/include/asm/arch-baytrail/fsp/fsp_vpd.h
 create mode 100644 arch/x86/include/asm/arch-baytrail/gpio.h
 create mode 100644 board/intel/minnowmax/Kconfig
 create mode 100644 board/intel/minnowmax/MAINTAINERS
 create mode 100644 board/intel/minnowmax/Makefile
 create mode 100644 board/intel/minnowmax/minnowmax.c
 create mode 100644 board/intel/minnowmax/start.S
 create mode 100644 configs/minnowmax_defconfig
 create mode 100644 include/configs/minnowmax.h
arch/x86/Kconfig +12 -0
index 73a7392..49bd76f 100644
@@ -41,6 +41,14 @@ config TARGET_CROWNBAY
 	  Intel Platform Controller Hub EG20T, other system components and
 	  peripheral connectors for PCIe/SATA/USB/LAN/SD/UART/Audio/LVDS.
 
+config TARGET_MINNOWMAX
+	bool "Support Intel Minnowboard MAX"
+	help
+	  This is the Intel Minnowboard MAX. It contains an Atom E3800
+	  processor in a small form factor with Ethernet, micro-SD, USB 2,
+	  USB 3, SATA, serial console, some GPIOs and HDMI 1.3 video out.
+	  It requires some binary blobs - see README.x86 for details.
+
 endchoice
 
 config RAMBASE
@@ -388,12 +396,16 @@ source "arch/x86/cpu/ivybridge/Kconfig"
 
 source "arch/x86/cpu/queensbay/Kconfig"
 
+source "arch/x86/cpu/baytrail/Kconfig"
+
 source "board/coreboot/coreboot/Kconfig"
 
 source "board/google/chromebook_link/Kconfig"
 
 source "board/intel/crownbay/Kconfig"
 
+source "board/intel/minnowmax/Kconfig"
+
 config MMCONF_BASE_ADDRESS
 	hex
         default 0xe0000000
arch/x86/cpu/Makefile +1 -0
index 62e43c0..5acf8bb 100644
@@ -12,6 +12,7 @@ extra-y	= start.o
 obj-$(CONFIG_X86_RESET_VECTOR) += resetvec.o start16.o
 obj-y	+= interrupts.o cpu.o call64.o
 
+obj-$(CONFIG_INTEL_BAYTRAIL) += baytrail/
 obj-$(CONFIG_SYS_COREBOOT) += coreboot/
 obj-$(CONFIG_NORTHBRIDGE_INTEL_SANDYBRIDGE) += ivybridge/
 obj-$(CONFIG_NORTHBRIDGE_INTEL_IVYBRIDGE) += ivybridge/
arch/x86/cpu/baytrail/Kconfig new file +9 -0
new file mode 100644
index 0000000..e86cc01
@@ -0,0 +1,9 @@
+#
+# Copyright (C) 2015 Google, Inc
+#
+# SPDX-License-Identifier:	GPL-2.0+
+#
+
+config INTEL_BAYTRAIL
+	bool
+	select HAVE_FSP
arch/x86/cpu/baytrail/Makefile new file +10 -0
new file mode 100644
index 0000000..8914e8b
@@ -0,0 +1,10 @@
+#
+# Copyright (C) 2015 Google, Inc
+#
+# SPDX-License-Identifier:	GPL-2.0+
+#
+
+obj-y += early_uart.o
+obj-y += fsp_configs.o
+obj-y += pci.o
+obj-y += valleyview.o
arch/x86/cpu/baytrail/early_uart.c new file +82 -0

82 lines not on this page · raw message

arch/x86/cpu/baytrail/fsp_configs.c new file +156 -0

156 lines not on this page · raw message

arch/x86/cpu/baytrail/pci.c new file +47 -0

47 lines not on this page · raw message

arch/x86/cpu/baytrail/valleyview.c new file +37 -0
new file mode 100644
index 0000000..ab89b54
@@ -0,0 +1,37 @@
+/*
+ * Copyright (C) 2014, Bin Meng <[email protected]>
+ *
+ * SPDX-License-Identifier:	GPL-2.0+
+ */
+
+#include <common.h>
+#include <pci_ids.h>
+#include <asm/post.h>
+
+static struct pci_device_id mmc_supported[] = {
+	{ PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_VALLEYVIEW_SDIO },
+	{ PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_VALLEYVIEW_SDCARD },
+};
+
+int cpu_mmc_init(bd_t *bis)
+{
+	printf("mmc init\n");
+	return fsp_cpu_mmc_init("ValleyView SDHCI", mmc_supported,
+				ARRAY_SIZE(mmc_supported));
+}
+
+int arch_cpu_init(void)
+{
+	int ret;
+
+	post_code(POST_CPU_INIT);
+#ifdef CONFIG_SYS_X86_TSC_TIMER
+	timer_set_base(rdtsc());
+#endif
+
+	ret = x86_cpu_init_f();
+	if (ret)
+		return ret;
+
+	return 0;
+}
arch/x86/dts/Makefile +2 -1
index 97ed884..4e0171a 100644
@@ -1,5 +1,6 @@
 dtb-y += chromebook_link.dtb \
-	crownbay.dtb
+	crownbay.dtb \
+	minnowmax.dtb
 
 targets += $(dtb-y)
 
arch/x86/dts/microcode/m0130673322.dtsi new file +3284 -0

2,615 lines not on this page · raw message

arch/x86/dts/minnowmax.dts new file +45 -0

45 lines not on this page · raw message

arch/x86/dts/serial.dtsi +1 -1
index 9b097f4..6865eed 100644

Lines of this file are not shown. View the raw message.

arch/x86/include/asm/arch-baytrail/fsp/azalia.h new file +39 -0
new file mode 100644
index 0000000..d96a20f

Lines of this file are not shown. View the raw message.

arch/x86/include/asm/arch-baytrail/fsp/fsp_vpd.h new file +95 -0

95 lines not on this page · raw message

arch/x86/include/asm/arch-baytrail/gpio.h new file +13 -0
new file mode 100644
index 0000000..ab4e059

Lines of this file are not shown. View the raw message.

board/intel/minnowmax/Kconfig new file +31 -0
new file mode 100644
index 0000000..7c2b927

Lines of this file are not shown. View the raw message.

board/intel/minnowmax/MAINTAINERS new file +6 -0
new file mode 100644
index 0000000..d655761

Lines of this file are not shown. View the raw message.

board/intel/minnowmax/Makefile new file +7 -0
new file mode 100644
index 0000000..1a61432

Lines of this file are not shown. View the raw message.

board/intel/minnowmax/minnowmax.c new file +32 -0
new file mode 100644
index 0000000..6e82b16

Lines of this file are not shown. View the raw message.

board/intel/minnowmax/start.S new file +9 -0
new file mode 100644
index 0000000..2c941a4

Lines of this file are not shown. View the raw message.

configs/minnowmax_defconfig new file +13 -0
new file mode 100644
index 0000000..7bc9085

Lines of this file are not shown. View the raw message.

doc/README.x86 +43 -6

49 lines not on this page · raw message

include/configs/minnowmax.h new file +69 -0

69 lines not on this page · raw message

The rest of this diff is not shown. View the raw message.

Signature · 1 line
2.2.0.rc0.207.ga3a616c

Part of the diff is not shown here. View the raw message.

#62 lore raw

PATCH 23/23 x86: Add support for Intel Minnowboard Max

Hi Simon,

Quoted 74 lines · Simon Glass

This is a relatively low-cost x86 board in a small form factor. The main peripherals are uSD, USB, HDMI, Ethernet and SATA. It uses an Atom 3800 series CPU. So far only the dual core 2GB variant is supported.

This uses the existing FSP support. Binary blobs are required to make this board work. The microcode update is included as a patch (all 3000 lines of it).

---

 arch/x86/Kconfig                                 |   12 +
 arch/x86/cpu/Makefile                            |    1 +
 arch/x86/cpu/baytrail/Kconfig                    |    9 +
 arch/x86/cpu/baytrail/Makefile                   |   10 +
 arch/x86/cpu/baytrail/early_uart.c               |   82 +
 arch/x86/cpu/baytrail/fsp_configs.c              |  156 +
 arch/x86/cpu/baytrail/pci.c                      |   47 +
 arch/x86/cpu/baytrail/valleyview.c               |   37 +
 arch/x86/dts/Makefile                            |    3 +-
 arch/x86/dts/microcode/m0130673322.dtsi          | 3284 ++++++++++++++++++++++
 arch/x86/dts/minnowmax.dts                       |   45 +
 arch/x86/dts/serial.dtsi                         |    2 +-
 arch/x86/include/asm/arch-baytrail/fsp/azalia.h  |   39 +
 arch/x86/include/asm/arch-baytrail/fsp/fsp_vpd.h |   95 +
 arch/x86/include/asm/arch-baytrail/gpio.h        |   13 +
 board/intel/minnowmax/Kconfig                    |   31 +
 board/intel/minnowmax/MAINTAINERS                |    6 +
 board/intel/minnowmax/Makefile                   |    7 +
 board/intel/minnowmax/minnowmax.c                |   32 +
 board/intel/minnowmax/start.S                    |    9 +
 configs/minnowmax_defconfig                      |   13 +
 doc/README.x86                                   |   49 +-
 include/configs/minnowmax.h                      |   69 +
 23 files changed, 4043 insertions(+), 8 deletions(-)
 create mode 100644 arch/x86/cpu/baytrail/Kconfig
 create mode 100644 arch/x86/cpu/baytrail/Makefile
 create mode 100644 arch/x86/cpu/baytrail/early_uart.c
 create mode 100644 arch/x86/cpu/baytrail/fsp_configs.c
 create mode 100644 arch/x86/cpu/baytrail/pci.c
 create mode 100644 arch/x86/cpu/baytrail/valleyview.c
 create mode 100644 arch/x86/dts/microcode/m0130673322.dtsi
 create mode 100644 arch/x86/dts/minnowmax.dts
 create mode 100644 arch/x86/include/asm/arch-baytrail/fsp/azalia.h
 create mode 100644 arch/x86/include/asm/arch-baytrail/fsp/fsp_vpd.h
 create mode 100644 arch/x86/include/asm/arch-baytrail/gpio.h
 create mode 100644 board/intel/minnowmax/Kconfig
 create mode 100644 board/intel/minnowmax/MAINTAINERS
 create mode 100644 board/intel/minnowmax/Makefile
 create mode 100644 board/intel/minnowmax/minnowmax.c
 create mode 100644 board/intel/minnowmax/start.S
 create mode 100644 configs/minnowmax_defconfig
 create mode 100644 include/configs/minnowmax.h
arch/x86/Kconfig +8 -0
index 73a7392..49bd76f 100644
@@ -41,6 +41,14 @@ config TARGET_CROWNBAY
          Intel Platform Controller Hub EG20T, other system components and
          peripheral connectors for PCIe/SATA/USB/LAN/SD/UART/Audio/LVDS.
 
+config TARGET_MINNOWMAX
+       bool "Support Intel Minnowboard MAX"
+       help
+         This is the Intel Minnowboard MAX. It contains an Atom E3800
+         processor in a small form factor with Ethernet, micro-SD, USB 2,
+         USB 3, SATA, serial console, some GPIOs and HDMI 1.3 video out.
+         It requires some binary blobs - see README.x86 for details.
+
 endchoice
 
 config RAMBASE

arch/x86/Kconfig source "arch/x86/cpu/ivybridge/Kconfig" · line 400

Quoted 5 lines
arch/x86/Kconfig +2 -0
@@ -388,12 +396,16 @@ source "arch/x86/cpu/ivybridge/Kconfig"
 
 source "arch/x86/cpu/queensbay/Kconfig"
 
+source "arch/x86/cpu/baytrail/Kconfig"
+

I wonder if we need put this before queensbay, per alphabetical order?

Quoted 110 lines
arch/x86/Kconfig +2 -0
 source "board/coreboot/coreboot/Kconfig"
 
 source "board/google/chromebook_link/Kconfig"
 
 source "board/intel/crownbay/Kconfig"
 
+source "board/intel/minnowmax/Kconfig"
+
 config MMCONF_BASE_ADDRESS
        hex
         default 0xe0000000
arch/x86/cpu/Makefile +1 -0
index 62e43c0..5acf8bb 100644
@@ -12,6 +12,7 @@ extra-y       = start.o
 obj-$(CONFIG_X86_RESET_VECTOR) += resetvec.o start16.o
 obj-y  += interrupts.o cpu.o call64.o
 
+obj-$(CONFIG_INTEL_BAYTRAIL) += baytrail/
 obj-$(CONFIG_SYS_COREBOOT) += coreboot/
 obj-$(CONFIG_NORTHBRIDGE_INTEL_SANDYBRIDGE) += ivybridge/
 obj-$(CONFIG_NORTHBRIDGE_INTEL_IVYBRIDGE) += ivybridge/
arch/x86/cpu/baytrail/Kconfig new file +9 -0
new file mode 100644
index 0000000..e86cc01
@@ -0,0 +1,9 @@
+#
+# Copyright (C) 2015 Google, Inc
+#
+# SPDX-License-Identifier:     GPL-2.0+
+#
+
+config INTEL_BAYTRAIL
+       bool
+       select HAVE_FSP
arch/x86/cpu/baytrail/Makefile new file +10 -0
new file mode 100644
index 0000000..8914e8b
@@ -0,0 +1,10 @@
+#
+# Copyright (C) 2015 Google, Inc
+#
+# SPDX-License-Identifier:     GPL-2.0+
+#
+
+obj-y += early_uart.o
+obj-y += fsp_configs.o
+obj-y += pci.o
+obj-y += valleyview.o
arch/x86/cpu/baytrail/early_uart.c new file +50 -0
new file mode 100644
index 0000000..c54deb9
@@ -0,0 +1,82 @@
+/*
+ * Copyright (C) 2015 Google, Inc
+ *
+ * SPDX-License-Identifier:    GPL-2.0+
+ */
+
+#include <common.h>
+#include <debug_uart.h>
+#include <errno.h>
+#include <asm/io.h>
+
+#define PCI_DEV_CONFIG(segbus, dev, fn) ( \
+               (((segbus) & 0xfff) << 20) | \
+               (((dev) & 0x1f) << 15) | \
+               (((fn)  & 0x07) << 12))
+
+/* Platform Controller Unit */
+#define LPC_DEV                        0x1f
+#define LPC_FUNC               0
+
+/* Enable UART */
+#define UART_CONT              0x80
+
+/* SCORE Pad definitions */
+#define UART_RXD_PAD                   82
+#define UART_TXD_PAD                   83
+
+/* Pad base: PAD_CONF0[n]= PAD_BASE + 16 * n */
+#define GPSCORE_PAD_BASE       (IO_BASE_ADDRESS + IO_BASE_OFFSET_GPSCORE)
+
+/* IO Memory */
+#define IO_BASE_ADDRESS                        0xfed0c000
+#define  IO_BASE_OFFSET_GPSCORE                0x0000
+#define  IO_BASE_OFFSET_GPNCORE                0x1000
+#define  IO_BASE_OFFSET_GPSSUS         0x2000
+#define IO_BASE_SIZE                   0x4000
+
+static inline unsigned int score_pconf0(int pad_num)
+{
+       return GPSCORE_PAD_BASE + pad_num * 16;
+}
+
+static void score_select_func(int pad, int func)
+{
+       uint32_t reg;
+       uint32_t pconf0_addr = score_pconf0(pad);
+
+       reg = readl(pconf0_addr);
+       reg &= ~0x7;
+       reg |= func & 0x7;

arch/x86/cpu/baytrail/early_uart.c line 60

Quoted 10 lines
arch/x86/cpu/baytrail/early_uart.c new file +10 -0
+       writel(reg, pconf0_addr);
+}
+
+static void pci_write_config32(int dev, unsigned int where, u32 value)
+{
+       unsigned long addr;
+
+       addr = CONFIG_MMCONF_BASE_ADDRESS | dev | (where & ~3);
+       writel(value, addr);
+}

I don't see where CONFIG_MMCONF_BASE_ADDRESS value is programmed into the chipset. There has to be a register to enable the PCIe ECAM. Is this programmed by FSP's temp_ram_init()? If yes, then we need document this somewhere (in BayTrail Kconfig help?)

arch/x86/cpu/baytrail/early_uart.c line 67

Quoted 7 lines
arch/x86/cpu/baytrail/early_uart.c new file +7 -0
+
+/* This can be called after memory-mapped PCI is working */
+int setup_early_uart(void)
+{
+       if (!IS_ENABLED(CONFIG_DEBUG_UART))
+               return -ENOSYS;
+

setup_early_uart() is called only when CONFIG_DEBUG_UART is defined, so there is no need to check this.

arch/x86/dts/minnowmax.dts

Quoted 3,612 lines
arch/x86/cpu/baytrail/early_uart.c new file +15 -0
+       /* Enable the legacy UART hardware. */
+       pci_write_config32(PCI_DEV_CONFIG(0, LPC_DEV, LPC_FUNC), UART_CONT, 1);
+
+       /*
+        * Set up the pads to the UART function. This allows the signals to
+        * leave the chip
+        */
+       score_select_func(UART_RXD_PAD, 1);
+       score_select_func(UART_TXD_PAD, 1);
+
+       debug_uart_init();
+       printascii("Debug UART ready\r\n");
+
+       return 0;
+}
arch/x86/cpu/baytrail/fsp_configs.c new file +156 -0
new file mode 100644
index 0000000..86b6926
@@ -0,0 +1,156 @@
+/*
+ * Copyright (C) 2013, Intel Corporation
+ * Copyright (C) 2014, Bin Meng <[email protected]>
+ *
+ * SPDX-License-Identifier:    Intel
+ */
+
+#include <common.h>
+#include <asm/arch/fsp/azalia.h>
+#include <asm/fsp/fsp_support.h>
+
+/* ALC262 Verb Table - 10EC0262 */
+static const uint32_t verb_table_data13[] = {
+       /* Pin Complex (NID 0x11) */
+       0x01171cf0,
+       0x01171d11,
+       0x01171e11,
+       0x01171f41,
+       /* Pin Complex (NID 0x12) */
+       0x01271cf0,
+       0x01271d11,
+       0x01271e11,
+       0x01271f41,
+       /* Pin Complex (NID 0x14) */
+       0x01471c10,
+       0x01471d40,
+       0x01471e01,
+       0x01471f01,
+       /* Pin Complex (NID 0x15) */
+       0x01571cf0,
+       0x01571d11,
+       0x01571e11,
+       0x01571f41,
+       /* Pin Complex (NID 0x16) */
+       0x01671cf0,
+       0x01671d11,
+       0x01671e11,
+       0x01671f41,
+       /* Pin Complex (NID 0x18) */
+       0x01871c20,
+       0x01871d98,
+       0x01871ea1,
+       0x01871f01,
+       /* Pin Complex (NID 0x19) */
+       0x01971c21,
+       0x01971d98,
+       0x01971ea1,
+       0x01971f02,
+       /* Pin Complex (NID 0x1A) */
+       0x01a71c2f,
+       0x01a71d30,
+       0x01a71e81,
+       0x01a71f01,
+       /* Pin Complex */
+       0x01b71c1f,
+       0x01b71d40,
+       0x01b71e21,
+       0x01b71f02,
+       /* Pin Complex */
+       0x01c71cf0,
+       0x01c71d11,
+       0x01c71e11,
+       0x01c71f41,
+       /* Pin Complex */
+       0x01d71c01,
+       0x01d71dc6,
+       0x01d71e14,
+       0x01d71f40,
+       /* Pin Complex */
+       0x01e71cf0,
+       0x01e71d11,
+       0x01e71e11,
+       0x01e71f41,
+       /* Pin Complex */
+       0x01f71cf0,
+       0x01f71d11,
+       0x01f71e11,
+       0x01f71f41,
+};
+
+/*
+ * This needs to be in ROM since if we put it in CAR, FSP init loses it when
+ * it drops CAR.
+ *
+ * TODO(sjg at chromium.org): Move to device tree when FSP allows it
+ *
+ * VerbTable: (RealTek ALC262)
+ * Revision ID = 0xFF, support all steps
+ * Codec Verb Table For AZALIA
+ * Codec Address: CAd value (0/1/2)
+ * Codec Vendor: 0x10EC0262
+ */
+static const struct pch_azalia_verb_table azalia_verb_table[] = {
+       {
+               {
+                       0x10ec0262,
+                       0x0000,
+                       0xff,
+                       0x01,
+                       0x000b,
+                       0x0002,
+               },
+               verb_table_data13
+       }
+};
+
+const struct pch_azalia_config azalia_config = {
+       .pme_enable = 1,
+       .docking_supported = 1,
+       .docking_attached = 0,
+       .hdmi_codec_enable = 1,
+       .azalia_v_ci_enable = 1,
+       .rsvdbits = 0,
+       .azalia_verb_table_num = 1,
+       .azalia_verb_table = azalia_verb_table,
+       .reset_wait_timer_us = 300
+};
+
+void update_fsp_upd(struct upd_region *fsp_upd)
+{
+       struct memory_down_data *mem;
+
+       /*
+        * Configure everything here to avoid the poor hard-pressed user
+        * needing to run Intel's binary configuration tool. It may also allow
+        * us to support the 1GB single core variant easily.
+        *
+        * TODO(sjg at chromium.org): Move to device tree
+        */
+       fsp_upd->mrc_init_tseg_size = 8;
+       fsp_upd->mrc_init_mmio_size = 0x800;
+       fsp_upd->emmc_boot_mode = 0xff;
+       fsp_upd->enable_sdio = 1;
+       fsp_upd->enable_sdcard = 1;
+       fsp_upd->enable_hsuart0 = 1;
+       fsp_upd->azalia_config_ptr = (uint32_t)&azalia_config;
+       fsp_upd->enable_i2_c0 = 0;
+       fsp_upd->enable_i2_c2 = 0;
+       fsp_upd->enable_i2_c3 = 0;
+       fsp_upd->enable_i2_c4 = 0;
+       fsp_upd->enable_xhci = 0;
+       fsp_upd->igd_render_standby = 1;
+
+       mem = &fsp_upd->memory_params;
+       mem->enable_memory_down = 1;
+       mem->dram_speed = 1;
+       mem->dimm_width = 1;
+       mem->dimm_density = 2;
+       mem->dimm_tcl = 0xb;
+       mem->dimm_trpt_rcd = 0xb;
+       mem->dimm_twr = 0xc;
+       mem->dimm_twtr = 6;
+       mem->dimm_trrd = 6;
+       mem->dimm_trtp = 6;
+       mem->dimm_tfaw = 0x14;
+}
arch/x86/cpu/baytrail/pci.c new file +47 -0
new file mode 100644
index 0000000..7032c97
@@ -0,0 +1,47 @@
+/*
+ * Copyright (C) 2014, Bin Meng <[email protected]>
+ *
+ * SPDX-License-Identifier:    GPL-2.0+
+ */
+
+#include <common.h>
+#include <debug_uart.h>
+#include <pci.h>
+#include <asm/pci.h>
+#include <asm/fsp/fsp_support.h>
+
+DECLARE_GLOBAL_DATA_PTR;
+
+void board_pci_setup_hose(struct pci_controller *hose)
+{
+       hose->first_busno = 0;
+       hose->last_busno = 0;
+
+       /* PCI memory space */
+       pci_set_region(hose->regions + 0,
+                      CONFIG_PCI_MEM_BUS,
+                      CONFIG_PCI_MEM_PHYS,
+                      CONFIG_PCI_MEM_SIZE,
+                      PCI_REGION_MEM);
+
+       /* PCI IO space */
+       pci_set_region(hose->regions + 1,
+                      CONFIG_PCI_IO_BUS,
+                      CONFIG_PCI_IO_PHYS,
+                      CONFIG_PCI_IO_SIZE,
+                      PCI_REGION_IO);
+
+       pci_set_region(hose->regions + 2,
+                      CONFIG_PCI_PREF_BUS,
+                      CONFIG_PCI_PREF_PHYS,
+                      CONFIG_PCI_PREF_SIZE,
+                      PCI_REGION_PREFETCH);
+
+       pci_set_region(hose->regions + 3,
+                      0,
+                      0,
+                      gd->ram_size,
+                      PCI_REGION_MEM | PCI_REGION_SYS_MEMORY);
+
+       hose->region_count = 4;
+}
arch/x86/cpu/baytrail/valleyview.c new file +37 -0
new file mode 100644
index 0000000..ab89b54
@@ -0,0 +1,37 @@
+/*
+ * Copyright (C) 2014, Bin Meng <[email protected]>
+ *
+ * SPDX-License-Identifier:    GPL-2.0+
+ */
+
+#include <common.h>
+#include <pci_ids.h>
+#include <asm/post.h>
+
+static struct pci_device_id mmc_supported[] = {
+       { PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_VALLEYVIEW_SDIO },
+       { PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_VALLEYVIEW_SDCARD },
+};
+
+int cpu_mmc_init(bd_t *bis)
+{
+       printf("mmc init\n");
+       return fsp_cpu_mmc_init("ValleyView SDHCI", mmc_supported,
+                               ARRAY_SIZE(mmc_supported));
+}
+
+int arch_cpu_init(void)
+{
+       int ret;
+
+       post_code(POST_CPU_INIT);
+#ifdef CONFIG_SYS_X86_TSC_TIMER
+       timer_set_base(rdtsc());
+#endif
+
+       ret = x86_cpu_init_f();
+       if (ret)
+               return ret;
+
+       return 0;
+}
arch/x86/dts/Makefile +2 -1
index 97ed884..4e0171a 100644
@@ -1,5 +1,6 @@
 dtb-y += chromebook_link.dtb \
-       crownbay.dtb
+       crownbay.dtb \
+       minnowmax.dtb
 
 targets += $(dtb-y)
 
arch/x86/dts/microcode/m0130673322.dtsi new file +3284 -0
new file mode 100644
index 0000000..90bf2fb
@@ -0,0 +1,3284 @@
+/*
+ * ---
+ * This is a device tree fragment. Use #include to add these properties to a
+ * node.
+ *
+ * Date:
+ */
+
+compatible = "intel,microcode";
+intel,header-version = <1>;
+intel,update-revision = <0x322>;
+intel,date-code = <0x4012014>;
+intel,processor-signature = <0x30673>;
+intel,checksum = <0x17b0d914>;
+intel,loader-revision = <1>;
+intel,processor-flags = <0x1>;
+
+/* The first 48-bytes are the public header which repeats the above data */
+data = <
+       0x01000000      0x22030000      0x14200104      0x73060300
+       0x14d9b017      0x01000000      0x01000000      0xd0cb0000
+       0x00cc0000      0x00000000      0x00000000      0x00000000
+       0x00000000      0xa1000000      0x01000200      0x22030000
+       0x00000000      0x00000000      0x31031420      0x11320000
+       0x01000000      0x73060300      0x00000000      0x00000000
+       0x00000000      0x00000000      0x00000000      0x00000000
+       0x00000000      0xf4320000      0x00000000      0x00000000
+       0x00000000      0x00000000      0x00000000      0x00000000
+       0x0ae10178      0x7c98f9d1      0x41962d85      0x19391270
+       0xcf3c0336      0xc1f13d6f      0xe46abaf6      0x3b65ca6b
+       0xdb666815      0x5a17bfc4      0x4fca009d      0x099ae8b3
+       0x198e2c7d      0x7c665bbf      0xc07a1a7a      0x7dbcee26
+       0x867296b2      0xc885b6ce      0xe602baff      0x68544b14
+       0xc928c400      0x3add156d      0x531946f9      0x92a03216
+       0xda352322      0xd967ee1f      0x3c5170a7      0xf6de834e
+       0x5a2ed8b3      0x9fb8f050      0x450de17f      0xfd5ef070
+       0x4954575f      0xa3a071ab      0xb56e2afb      0xe2b48302
+       0x6655a958      0x57c9a438      0x1b2f688a      0x09309bc4
+       0x0be95612      0x529c1633      0xc48515d9      0x29eb78df
+       0x9933409f      0xda58dea9      0x58c805fd      0xbc110f5a
+       0x40780ec0      0x6ad59bb3      0xc7387fb8      0x591c1490
+       0xf9335932      0x32130e0b      0xef4b3c96      0xacd903f2
+       0x5b362539      0xe7f85529      0xcb17c41f      0xe7e440d8
+       0xfaf7e925      0x969b76fb      0x5edab8c7      0xf00012e8
+       0x121c2971      0xe5b18959      0xadfd07c0      0x1f09c9d7
+       0x9781006a      0x39550073      0x6c438b6d      0x436f60bc
+       0x11000000      0x8514b971      0x40df7b4a      0x6a6b7285
+       0x7978ef59      0x319bddf5      0x04c68e5a      0xe1c28b10
+       0x172f63dc      0x306fb95d      0x31d881e8      0x69f8e08d
+       0x617a99e1      0x1ab6b574      0x2951fa5b      0xcc7e3e94
+       0xff379d19      0x5c035dec      0xe28ed726      0x22b8a5ac
+       0xd08b3ac5      0x45c03b9e      0xcea4083c      0xc26758aa
+       0xbe7cf81e      0x43d898f3      0x5c45a635      0xc9cac095
+       0xb89aea20      0x2c02b40e      0xe3a8b48d      0xeabfb60e
+       0x776ed2a9      0x080ae6d5      0x7f64b1df      0x00e40ee6
+       0x0f1c10f4      0x792e5423      0x787f5459      0x63a8b02c
+       0x3fd6a255      0x049cae26      0x0949f5ff      0x9aebb236
+       0xecc01775      0x91b57b84      0xe0e45ea3      0x5a8bf79e
+       0x356a843a      0x2406795f      0x8aaae5d8      0x6a8c877c
+       0xa8b2b8f4      0x04cf8f49      0x422d9e2c      0xf09f9896
+       0xe9b92215      0x9c98fb44      0x88556b7f      0x519d6f4c
+       0x9e8a016b      0xcb18d16c      0x419b4ee7      0x080b49c8
+       0xc51b875e      0x46aabc9c      0x262d27eb      0x93ea189d
+       0xdd0da69d      0x3e5b17e8      0xcc78509a      0x00b07e6e
+       0x363d5a70      0x64572070      0x8a84abc4      0x1cb03838
+       0x965fd76a      0x540aafc9      0x83a91654      0x1a722e67
+       0x4bf98ce1      0x2b3c2ff9      0x972cebd4      0xf3a68395
+       0x2613e422      0xf8d031d7      0xb1c79a0f      0xfd44f65b
+       0xa7012a9b      0xd9a15a60      0xc311fc0c      0x6f52f878
+       0x3d68381d      0xd2a035d7      0xb790c50e      0x9f1e5010
+       0x41877064      0xa9d1e4ae      0xfe9abbd5      0x60c2c748
+       0x8167e5ad      0x022dbfb3      0x75abe483      0x51c37170
+       0x09b8590d      0xc1bb323d      0x2c7336b1      0xd4d0d49b
+       0xc7f6152b      0x7919d596      0x1e1ff62e      0xc49604a0
+       0x33857369      0xeaa3f382      0x98b8cd86      0x176e1bf3
+       0x1a68867b      0x6af0a11c      0x69a82b25      0x48c72525
+       0xa00aae2d      0xb09f67f4      0x1a99f83d      0x7266cca3
+       0x8d03a7da      0x2e1d7c49      0x01ac68ae      0x93188770
+       0x0609e769      0x982ed28d      0xe40999e0      0x8932ebab
+       0x5637ad5a      0x2725e8ad      0x56d7caaf      0xc351faa2
+       0x09dbd737      0x0d2f3bf0      0x0623330d      0xdd547489
+       0xcca7e722      0xa9096d13      0x95b17818      0xc092cb81
+       0x72c6eefc      0x1811c37e      0x78161497      0x8be0c4c6
+       0xd63aeb19      0x91ab68df      0x8f2e5e4d      0xf4c74566
+       0x7677a553      0x19698ac3      0xedca0620      0x77f32470
+       0x031e011b      0x751f6696      0xb277d06e      0x3eae2742
+       0x133e621a      0x38fa3172      0x9398cc1c      0xf42a507b
+       0x4547d933      0x63a91eb0      0xf5bcf6a4      0x926ba056
+       0x0adf5bce      0x140f53e4      0x7ff6bb5c      0x87dd79ba
+       0xbba240ac      0x694f743d      0x709cdb20      0x5b4d4401
+       0xc9693610      0x55f9f268      0x1142bc3f      0xf8fe3689
+       0x04a93c4c      0x33dedc46      0xdc73c725      0x2f5ba264
+       0x5b7a6a69      0x024b64f5      0x6e8bfa12      0x62bf2aa7
+       0x520f5a07      0x3c7c4292      0xb7ad2613      0x1f78fc87
+       0xd5284e4e      0x2c730f33      0x8861e947      0x8bacef7d
+       0xbafa2608      0x14ed0b5b      0x3b9bfb02      0x24ced271
+       0x002b2941      0x22d4431c      0x855f4248      0x5ec46e29
+       0x6f1f42fb      0x5dd24fe0      0x290961f6      0xf392dbaf
+       0xa1a8d9c2      0x61e18f4e      0xfda59a70      0x5498daa5
+       0x5ae7ea6f      0xf058c635      0x6817ebee      0x8e30dc8b
+       0x7c8d79be      0x5fb15b9b      0xeed64741      0xe2642a94
+       0x680d7e6e      0x3cbad7aa      0x808c415f      0xe9323aa2
+       0xaadf5b25      0xf60abf13      0xd5c47967      0xc248d0b3
+       0x0f232cbd      0x84092449      0x5744384b      0x5e153ded
+       0x8bb19817      0x34430271      0x917d2315      0x1fc790c7
+       0xc21b5db6      0xec578b1f      0x903a286e      0xca0c59bc
+       0x03e95c7a      0x8c659e99      0x7b09da0a      0xd61e7517
+       0x90b1c519      0x8deac92c      0xf99c7bec      0xb6257d92
+       0x3d61c16e      0xebd58be0      0xb470e655      0xa44bbf4f
+       0xfebe5313      0x4662110a      0x5d42ccd9      0x140845ec
+       0xc80329a9      0x915ca966      0x71e33828      0xe46c870a
+       0x7da9a490      0x255544da      0xa20fb8df      0xf94062b3
+       0xb2df5870      0xebf31e88      0x6e723e2f      0xe6ba9cf1
+       0x7e7084c2      0x1782ac71      0x0a0b0127      0xe9234e38
+       0x881356d6      0xb27a54b6      0x5594730e      0x9a14bd8f
+       0x6dba7da9      0x1069e285      0x02a52798      0x61ea7d86
+       0x665b2572      0x29d41eb5      0x1d211169      0x1218b345
+       0xbfbd264c      0x5b8b0625      0xbbfdcf39      0x6768dfce
+       0x0b5f10cb      0xe159414c      0x74356ed6      0x70077f49
+       0x672107e8      0x11616856      0x824e6f2f      0x99614958
+       0x5857305d      0x416a193f      0x010d266c      0xe5194f03
+       0x152d6516      0xeb83872e      0x4923cc1f      0x1191d1ca
+       0x23feb738      0x6817c1d7      0xe49129ed      0x4a53132a
+       0xdb46b95b      0x3f970366      0x93f1a518      0xae8d72ae
+       0xb689d915      0x0bdfda17      0x2ac7238d      0x1c4291e7
+       0xc5b11085      0x3c51c1ba      0x9fd63edd      0xe464d740
+       0xc17f2789      0x0adef6b9      0xf9aaf83e      0xfb2a9798
+       0x7f16268b      0x4c8ca6c5      0x2b17be52      0x00c91157
+       0xb69eb5db      0xe55ed94a      0xdf13b5a5      0xbb52d1e3
+       0x651bb017      0xc7795724      0x0dfd4711      0x02d2d6e0
+       0xc835e771      0x8ab5dd50      0x7caca109      0xd5c18d6e
+       0xbef0e727      0xaff2dd07      0xf1062a32      0x26d14796
+       0x97f6e36c      0xf845278e      0x185eb5b3      0xcde4e201
+       0x13166ab7      0xcdcebcdc      0x143ef0c7      0x2349893f
+       0x9dfcb70e      0x7ef72725      0x141c5b71      0x7da0f5d3
+       0x76bebb67      0x28bc0a83      0xb67ecf0f      0xd60a1303
+       0x9391b279      0x6ad41154      0x317896b0      0x1237efa6
+       0x7b2a2e6c      0x3ad9a110      0xb44357d4      0xb32e39fe
+       0x2358d28e      0x76e847d9      0x3e85db01      0x6c74e466
+       0x9e4e6b32      0x13072a53      0x5972132e      0xd97cb04d
+       0x55ee6a0b      0xc1434b92      0x772f6a1d      0x0f81f7a6
+       0x072aa8f7      0x179da0e0      0x976bd78c      0x2e43c16b
+       0x4f4a6b51      0x92d9c61b      0xa9c15fe4      0x3f8a527a
+       0x3a232408      0x543d7957      0x21cbd682      0x896de3b0
+       0xba6b3df6      0x2ec86e51      0x2be889e3      0xae764ff0
+       0x3a2f0003      0x7a5f7949      0x577fb5ce      0xb5cbd1a6
+       0xc910ffe2      0x7fd76712      0xfc1e93ff      0xbee7b15c
+       0x5db2356d      0x9721a3fd      0x0d408aed      0x4df4c922
+       0x45d5be91      0x6c79b1fc      0xf0bf73bd      0x3f6a73b6
+       0xdcc1b51e      0x2049fe2d      0xf2b2ad4b      0xd0484d3a
+       0x1f097d3f      0xced1bf3d      0x10f4416b      0x73cb307c
+       0x4b4d94b4      0x2918ece0      0x0cfe69f3      0xb7e86cfb
+       0xa6c373b4      0x0d862b62      0x1735cd72      0xef23c127
+       0x09809c16      0x86cfb70b      0xe67c6903      0x743223a7
+       0x13c7d27f      0xb70a58cc      0x82c57566      0x2ead3c65
+       0xf9409863      0xf2b578ef      0x1622a34d      0x5ae8e861
+       0xf4384016      0x443ff5f4      0x088b8510      0xd738d1c5
+       0x577d624b      0x5adf3973      0x5f79add3      0xed7e7145
+       0x29008fc0      0xd5b278cf      0x5b4c08c2      0xb063af5c
+       0x67d41bd9      0x2d11424a      0x727924de      0x8903a86f
+       0xb122d314      0xd9675c8b      0xc2eb1382      0x4c4185da
+       0x257a0fe1      0xc3fd536b      0xadbfc223      0xc940dab4
+       0x2e83d4b0      0xf1135ad4      0xfeb1cc1a      0x9178ae04
+       0x996d72ba      0x07f6bf0f      0x6588f833      0x44f95205
+       0xee4e6897      0xa9006735      0xa5f5502c      0xeb61aca6
+       0xf2ceddb5      0x40ef9001      0xf862c3d7      0x73deaad3
+       0x7b1d8b1d      0x467bcbcf      0x7f76f969      0x6c8e7f8c
+       0xfb8e27c3      0x5075ce65      0x1c8628a8      0x7b6e3e32
+       0x4885fc9f      0xa9fa768c      0x15426120      0x1df9d006
+       0x31c52df4      0x1457f5c6      0xde5f2daa      0xfa250108
+       0xbcf7e460      0x565d4679      0x82c94142      0xae76342a
+       0x85aca7c7      0x8bc49e03      0x73f03da3      0x1e500b4c
+       0x250288a2      0x25a39951      0x66087700      0x6317754b
+       0x6ff62bdc      0xa519ad4f      0xa537b8ac      0xea6292ab
+       0xb5d66b68      0x15997d1f      0x0fdbf04a      0xaa2b1a25
+       0x74b72321      0xf8b1753a      0x33658d1e      0xb1cc5d96
+       0x5b0da6af      0x48f24997      0xb031146e      0xfe98e8d1
+       0x9bd75bf0      0x0ae088fe      0xb8fce721      0x964bc398
+       0xe82daef6      0x393884b5      0xa814f792      0xb3667bde
+       0x1d1cf32d      0xce862720      0x7b69e921      0xabd26f33
+       0x61fad35f      0xd7144eeb      0x74016bce      0x1d56277b
+       0x7f934eed      0xb1a3396a      0xd5090c7a      0x4ea94d12
+       0x1455ac10      0x7c37294c      0x06c60a9a      0xa735ab29
+       0xbffb880f      0x59e2cb48      0x54cca9d7      0xb569da05
+       0x595e72ec      0x7c82f204      0x7690420d      0xe02fbb37
+       0x4dbf4e68      0x221eda99      0x31868046      0xda435487
+       0xb4c0dcc4      0x37610096      0x35569b02      0xefcd4ecf
+       0x7b6917bf      0x45946a25      0x5d42a84a      0x8c3801b7
+       0x5ac838fa      0x7a7f252d      0xbccf3cb5      0x99a54c4c
+       0x39145831      0xfd5c1af3      0xcabb180c      0x8f0fe9dd
+       0xabd42357      0x3b6d9aa9      0x0e87ede1      0x65ea46ae
+       0xd89b618e      0x1e5cc772      0xfb43c9b4      0xdad3fdb2
+       0x96be6600      0x4887696e      0x82a4e73a      0xb2ca2cf0
+       0xc6840738      0x397d27a9      0xce971271      0x067e4de6
+       0xb593f079      0x6a77de2f      0xf9a92497      0xdc3e94aa
+       0x03239a80      0x7f38430a      0xf7f87908      0x682a8425
+       0x2d491962      0xb5737b4b      0xa26434e5      0x238ced20
+       0x1ed9fcbe      0x283a8f7b      0x18f33cf6      0x29f27cd5
+       0xd95018aa      0x883dbd25      0xfb216723      0xe939d42c
+       0xf4b1207d      0x54f5e102      0xbe2e46eb      0xb2ca8219
+       0xab181ad4      0x3a7dc3e6      0xf3713256      0x53f081ab
+       0xd630a7a3      0x07c40bc3      0x7a1fde0c      0xb368bab8
+       0xc0baaad3      0xf070baac      0xe4ab7a4f      0x82a8cf5e
+       0x9c3d7bb5      0xfe5f74a3      0x02548e86      0x2710ff5d
+       0x1b42a8c4      0x34d4f5d8      0x8dfde8f2      0xf2949298
+       0xe9d711bf      0x44d91e17      0x51ba8b32      0xbc3f60cc
+       0xa0d6c440      0xf71959b4      0x3b5f0603      0x02465794
+       0xff5d9b8a      0xd4a4abcf      0x8123626c      0x883ed4e4
+       0x9eaeaa09      0x91c38865      0xa0aaeebf      0xc48983ab
+       0x1df7a001      0x7519a65e      0x5ef3cd1d      0x8348225d
+       0x0f318b0b      0xbab1d51b      0x15ba9b84      0xef8c57bf
+       0x15d0a8c1      0x0b542fb4      0x1d51ccc8      0x6c297041
+       0xf3bee946      0x6a8c3d64      0x6e16361d      0xed50ca69
+       0x8c1f66ba      0xff7220e0      0x84a87cba      0x15d75922
+       0x77546d82      0x7bd456e3      0x10166195      0x55604f1f
+       0x894280d2      0x0ed406c4      0xc1b4058e      0x645252e5
+       0x670ea74e      0xd5b07337      0x9944e2cf      0xf2ac2579
+       0xd00c3ae8      0x2df3146d      0x4ee1c72a      0x3a3621cf
+       0x8c099145      0xf5f530e6      0x210da136      0x7908cec6
+       0xc6e47e22      0xe9bcbe4e      0x94cbcb12      0xb81f0792
+       0x1111f81e      0x4df4ac93      0x335c69be      0x9e3546b9
+       0x06c046b4      0x6f29a99c      0xbcd48ee7      0xeb011efe
+       0x41e80474      0xcee30bf4      0xad4e2ae0      0x6929a359
+       0xbdaa88e3      0x9e68a38e      0x16bbdac7      0x020d8d61
+       0x7bab6738      0x559cddbd      0xa6ae3d0c      0xe032c355
+       0xcb45a045      0x9f7680b2      0xc1cb73da      0x466052f7
+       0x488cb929      0xd93f0307      0xb2c9d81c      0xe25fdcd9
+       0xfe8b08c4      0xae6230bd      0x5238b335      0x3474b2a5
+       0x480ce0b7      0xd9a2942f      0xe830fa5b      0x3efa774f
+       0x84e53e93      0xf49e7d79      0x59897b26      0x75b1080f
+       0xc2212b0f      0xe5fe56bd      0x4556e908      0x1bd0bb17
+       0x2f159d20      0x866477e5      0x4e95a374      0xbdc9fd65
+       0x2ff87073      0x5d7dceea      0x69ada0c7      0x89f16ad0
+       0x97da55d8      0xe4457728      0x5ab7613e      0xf6bbe6ec
+       0x56b83617      0x9119b521      0x4fabf948      0x2e1ab994
+       0xd16363f0      0xaee14b3f      0x5461ea55      0x55d95d02
+       0xf72c902c      0x1ede6c56      0x697006d9      0x4d15007f
+       0x0c1cb5e5      0x55d3d5d5      0x1f18d76f      0x55c9f017
+       0x3e1d3b5b      0x8f775636      0x97e6bf8f      0x360a9fb5
+       0x1e080721      0xf9825356      0x30e900f3      0x55453bfe
+       0xbd8f1df0      0x35b43ba8      0x45db013f      0x20484d34
+       0x944ca654      0x79c2c151      0xd4e9b39b      0x1b2e79b6
+       0x554314d6      0xce4ee44d      0xd0394232      0x9da4db20
+       0xa70beed6      0x4ae4ed10      0x4c244770      0x4b91208c
+       0x39a01e0b      0x5eea0a55      0x4b36ffbe      0x6fd18df2
+       0x43fd13e3      0xa99302bc      0x63762b5d      0xd014d6b4
+       0xbf0e53d2      0x0f5b5aa5      0x3c23f5b7      0x16335036
+       0xe011bd10      0x66e596a3      0xf463e3ad      0x9670c0a3
+       0x4004e177      0xbd2b3260      0x01967017      0x1159a682
+       0x62931eb8      0xc581df9e      0x6710932f      0xfb2bb0b2
+       0xb8a0339c      0xc66f0fff      0x333f5ee3      0xc06f8586
+       0x7b9f47f1      0x9aaedaa3      0x6044562a      0x26c73565
+       0x82c6e5b2      0x39d4eed0      0x83b7432e      0x0c4f0e4a
+       0x4d9df788      0x989e7f41      0x61cacc3b      0xdc34efeb
+       0x240b22a8      0x70a508b0      0x7554f517      0x7269f02b
+       0xd27ffcf6      0x96a5879f      0x0650f7e4      0xdc1fc1ac
+       0x80781334      0x04ab3381      0x8bad17c1      0x18311833
+       0x65f06ee9      0xfaac30e1      0xe39b8b54      0x20b988ce
+       0xa6a818f3      0x75ac753b      0x66f815a4      0x224d7121
+       0x63dc6031      0xcfeed2c7      0x3ccd07d7      0x9df44157
+       0xb9dcca97      0xcf5178f1      0x10e8fb28      0xa1faa527
+       0x8851846e      0x01f56075      0x2dd4fff2      0x40786960
+       0x41aa9e6c      0xf7c85573      0x64a36432      0x4449e726
+       0x7aa7bb0d      0x08f596cc      0x248e1eb3      0x5c5567cb
+       0x62ffd012      0x2d79ce59      0xf9ed4239      0xe98e107a
+       0x4da25561      0xc6f83333      0x1ca0482d      0xcc3f3b69
+       0xa9f48711      0x99139510      0xc5777d2b      0x9c80814d
+       0xab47fbe4      0xf302d145      0x20aecccc      0x3be9e431
+       0x7dc34793      0x4d38171c      0xaa34e505      0xc32e492b
+       0x4f31bd0b      0xb7549889      0xdb3da9cf      0x084d0791
+       0xa4c63c9f      0x62e770e9      0x862fdb93      0x52c45b9e
+       0xf21019a5      0xdde6aa07      0xcb46386e      0x830693a8
+       0x651510c8      0xf3af66a4      0x78775e07      0xc9f22414
+       0x5769f089      0xac2ae873      0x044357d8      0x9fdc76f8
+       0xea16ade5      0x144e9211      0x181ade72      0xba50ce80
+       0x4573571a      0x5437c668      0x39c3b81d      0x013d766d
+       0xc1754b48      0xa611fa3b      0x725eae72      0x04b02ca9
+       0x186a2541      0xa2784e47      0x8b7601bb      0x7f9132e3
+       0x3295d5b5      0x4b470dee      0xaf5ec559      0xc4c442d6
+       0x5b07293d      0x9a68b079      0xc1408c0c      0xc2371025
+       0x4af99e8c      0x332c416a      0xec04321b      0xb8493ffb
+       0x51eab7de      0x26d7e9db      0x7880126e      0x439be5e3
+       0x7e8910f0      0xa8ba727b      0x88cb04df      0x70750495
+       0xc13413f6      0x684312db      0x0579d5b1      0x05fe44f7
+       0x627e04f3      0xe85b47da      0xbf646f0b      0x2ddf4932
+       0x1bcb6fc0      0x611de27d      0xb3ee1bed      0x247dad06
+       0xa7107d34      0xba434b88      0x6eb90466      0x45a65871
+       0xa9a67088      0x6af3b796      0xf5b73689      0xcab03ca4
+       0xca1f25e6      0xd4b7c32b      0x5908c88d      0xac6c1fa3
+       0x653184a5      0x062bc0bf      0x383de594      0x17064fc6
+       0x0650dbad      0xaec15153      0xab0572ff      0xab8c6f3c
+       0x37a93f91      0xbe51b8c5      0xabcd8573      0x05b3ad78
+       0xad6c9ecc      0xf302c7ab      0x4b3b88f7      0x805a0107
+       0xa5821ddd      0xc36f10ad      0x374b1056      0x79e69f8c
+       0x8368b6cf      0xf69458a7      0x9fad691d      0xb937724e
+       0xc542bfb1      0x37c0178d      0xc4707414      0xd6c7fa86
+       0xb3933710      0x227800f4      0x6dca3e39      0xd88bdb91
+       0x03755bda      0xa7f2d11d      0x4ab40803      0xf353e7ed
+       0xf2464ee4      0x8e58cea4      0xd05807fd      0xd8d8da5f
+       0x1a461333      0x5e84830d      0xb94ea4bc      0x5bf3506f
+       0x76461ba7      0xabe88c54      0x124c2e39      0xc3b01867
+       0xc6b0d4d1      0x9cc3c7be      0x8039ce38      0xfceb0e88
+       0xa965c5ce      0x9ff3811a      0x1af1c60e      0xae9c5f9b
+       0xee28bd50      0x202cbd2e      0x340a1312      0xa8f7115e
+       0xb000cf3a      0x21ff4052      0xa555f08f      0x1bead4d7
+       0xac14e135      0x449e208c      0x05ef8d94      0xb555a613
+       0x9d65a902      0x3ad8cc2a      0x55170533      0x75782927
+       0xefd4b5e5      0x6127ef1e      0x23fb5114      0x7ca3e1bc
+       0xc08957ba      0x44c4e2cd      0xc0b97ef9      0xea99db5a
+       0x53fdeb31      0x61721ee2      0xe41ef3c1      0x5f4788f5
+       0xa8543eca      0x3f36d642      0xda6eccef      0x0341c756
+       0xbfe7d2b9      0x66bb5cef      0xbfb43507      0xbd9c878e
+       0x94f307bc      0x7cd56198      0xf98596ba      0x21e9c50b
+       0xb9c9d725      0xf16211c2      0xe594b398      0x7e01aefc
+       0x745e5ddb      0x00bae556      0xc317ed35      0x4269b4c6
+       0x02f6b67d      0xccb4aa57      0x8a3fa0fa      0xcc660149
+       0x57cf5e87      0x4ed03819      0x77286134      0x631cc0a5
+       0x877fe8e0      0xa48856dc      0xe1c57e93      0xef04482a
+       0x40cd9ac8      0xc7f43528      0x473306c8      0x01eb339e
+       0x52612a88      0x65c3212f      0x7cc5f5e6      0xd3efbc2a
+       0xf2537dbc      0xa9428ffd      0x76ff40f9      0x0ad4a8e6
+       0x2020fbab      0xf8c5bbe4      0xb409e5a0      0x358d7b37
+       0x08220bd3      0xd3707d96      0x5e2f5edc      0x638feed5
+       0x045afa36      0x4f1604b4      0xd4dc85c7      0x37f97cef
+       0xe1c8f5a6      0xd16fdbbc      0x986137fd      0x25b3e84c
+       0x7f73be76      0xe25dbdcb      0x1f13d28a      0x7a31215b
+       0x241967d2      0x2c5b4063      0xe8339988      0x13689262
+       0x0b6d2b79      0x58773464      0xe822e560      0x77d6ba8e
+       0x6ae6c07f      0x105e1e88      0x0045bc6d      0x88ad198e
+       0xa350b9de      0xd5d0b3e6      0xc4e1cd14      0x47ca431a
+       0x2ee94476      0xa2aae1f9      0xfa2042a7      0x37b0cf82
+       0xb1aca28e      0x9a019883      0xbfb11afb      0x754ffff9
+       0xf065a9b5      0x916e14f2      0x93fba80f      0x1dd82da0
+       0xe41c950a      0x12b374bb      0x0f4d533f      0xbef539e2
+       0x1eb5c86a      0x577dd484      0x98900e2f      0xcaec8695
+       0x6a6ab336      0x135e9e68      0xc9b62a35      0xb8982b6c
+       0x5bcdb533      0x389b1517      0xbb106e40      0xd402a301
+       0x7446687b      0x35eda3ec      0xd44ceb2a      0xcfa4e441
+       0x29664690      0x598a273e      0xf2a144b1      0x68f81403
+       0xca53e666      0x064e69a4      0x87bb8ca8      0x58193c68
+       0x9b34b17a      0xde2bffc7      0xf72594dc      0x388d3f3f
+       0x638a1273      0x5ccf3567      0xcf1017a9      0xe616a6fd
+       0x64cab73c      0xd209b022      0x6f08cd26      0xc30f57b1
+       0xac2295b2      0x0c05b1c8      0xf7915ad8      0x9bcf836f
+       0x56d8b57a      0xc8b65a2c      0x11868dd3      0xea4764f8
+       0xa7bd30e8      0x8c895321      0xd276a894      0x86042daa
+       0xaf6cd261      0x18cc4ea4      0x2c2185f6      0x2bf3ae70
+       0xf3023c31      0x49f4b0e2      0x1e00afc3      0x2053b3c6
+       0xb188c9cc      0x7437a27a      0x1b29925e      0xbc488906
+       0x81cd9003      0x332fcf9b      0xeb20987a      0x831f912a
+       0x857387da      0xaf1edccb      0xfe01d809      0x05351b4a
+       0x31ec96ac      0x4f064e52      0x10ec8119      0x96c2d29f
+       0xc6e1f3fe      0x15b0d45f      0xdca23bc6      0x7b672563
+       0xa94fdc1b      0x7dd22f4f      0xd4d2260f      0xc9e055ff
+       0x89e066cc      0x98200d25      0xcba82cf7      0xffb8475b
+       0x26550a20      0xf5b4f84a      0x506cb84b      0x00d92997
+       0x7a5c5535      0xe11194eb      0x1ff21f4b      0x725d2be5
+       0xbe89242f      0x0b18afa7      0x6f5b1433      0x829bdaf9
+       0x42db07b9      0x479493cb      0xabd2ead3      0xea6afa58
+       0xf994c740      0x4cb77f7e      0xb946cbdc      0xfe558e82
+       0xa2ed5c20      0x7012b99c      0x72a41e08      0x2058815b
+       0x0528d06d      0xe6dbd7e1      0x3d1f6f9e      0xca78b63c
+       0x91fa57a2      0xb6d524a7      0x1a61863d      0x89c25c5f
+       0x16960596      0x6ebed63e      0xfcd617d1      0x0a927121
+       0x887fdc75      0xec27c8de      0x8c91a821      0xd6bb116d
+       0x51fe2c18      0x4af774d9      0x7aa13fdb      0xfc6ff59d
+       0x27dd287b      0xe7e3151c      0x835552ea      0xe628aa1c
+       0xe0edda2a      0x1957ade4      0x52336fae      0x9cecef28
+       0x2be84cbf      0xa5959450      0x65299682      0x8151d4f8
+       0x716a5209      0x0a8ca663      0x2187bc46      0x000767f5
+       0xe7295b8d      0xa8bc7a6c      0x2b4d2f10      0xf251372f
+       0x92ff27ff      0x9bfd83e8      0x8e2b593e      0x8915fd15
+       0x1e44eed0      0x4a3a4679      0xce135f45      0xf996ec1b
+       0xfd86c8ac      0x25b008fa      0x8973cf58      0x481512ae
+       0xf2bc46f1      0x8b3a92bf      0xbf2a7b24      0xb19e88be
+       0x1823f658      0xa8486c11      0x237771c0      0x6f5f0da2
+       0xb05a42e3      0xb562583c      0xa13d37f7      0xe8eede16
+       0xc5154af2      0xfdf7f9b9      0x0b907685      0x1f567e56
+       0x19987b40      0xc82974ab      0xf02ae429      0x9c356634
+       0xb85ba9e9      0xda2141b7      0xd44e331f      0x1dd722d3
+       0x68fd2f4e      0x4e7f88a2      0xab7314b3      0x3dd05c4e
+       0x1bb4093f      0xff73db9b      0xf917c6e0      0xae822501
+       0x05cab9fe      0x67c91c76      0x1ebd2575      0x1ae193fd
+       0x6f154ae6      0x13780ac7      0x6ff5bf0c      0x6b664594
+       0x494a71d1      0x9bc35a0f      0xb34f175b      0x0069468c
+       0x9b125042      0x7df22e49      0xf39cf8ed      0xbe020df1
+       0xe206848b      0x8c428e75      0xc76c05d4      0x0089e2c4
+       0x5bf9a75a      0x30677869      0x544797ed      0x68456dbd
+       0x45b8f0aa      0xac5c82d1      0x05aefb75      0x6d5c28bf
+       0x009ddb3b      0x551ff144      0xd19127ea      0xfc860071
+       0x30c93457      0xa4c4b56a      0x6928a07c      0x9f63e6a7
+       0x9fa2b174      0x7c1b2fa4      0x4a5a1f25      0x24acb022
+       0x0c3c11f4      0xc7d4cec8      0x4484a031      0x6d3cc1c7
+       0x2eb86733      0x8cd4f77d      0x7b551519      0x124b6805
+       0x57385eef      0x3efd3da9      0xea300d5d      0xe64fc82d
+       0x7d33386b      0x3933c4d3      0xe3cb61f8      0xc6fe8846
+       0xbe0df669      0x8646e4cf      0x194a444a      0x404c81af
+       0x9448791e      0x586f2132      0x3def508a      0xa3edebe5
+       0x2f3b0b5c      0xc974f91f      0x400ec25b      0xf1513ffb
+       0xc13b8859      0x32ac4d39      0xf8f334b2      0xab53ba5d
+       0x9e196996      0xf14d8046      0x22fcb441      0xf27ac4c8
+       0xbbdf5623      0x255df428      0xd95a2352      0x8d26f0dd
+       0x60a301d1      0x4a2e3e49      0x4654b081      0xf775e35f
+       0x592b5eba      0x6a3f9583      0x6ec3d395      0xc8ab02e8
+       0xf343f806      0x62745498      0xb499dbf3      0xd427334a
+       0xdf0b61e7      0xda67999e      0x14f9be12      0xf164898a
+       0xd6347aa7      0x079a537e      0x294542e1      0x687b7b6b
+       0x8478cffc      0xf335963f      0x6c1b9ac2      0x68ff2779
+       0xe3d3f8a8      0x5453c548      0xd968189b      0x13ad95b4
+       0xd71bee24      0x3939f36e      0xb19b3595      0x001961aa
+       0x5f2f001a      0x77137eea      0x477698a0      0x1c07c440
+       0x9606b6d3      0x6ce95229      0x25445629      0x5a935f13
+       0x3e2154aa      0x6876442c      0xd9175c78      0xc94d2535
+       0xf2070dd4      0xd4d1f50b      0xa04d18e5      0x3456cfa4
+       0xc7610f62      0xb705a1a8      0xb8766e3e      0x225642de
+       0x4be5b1b5      0x44d32453      0x80b8a9d4      0x7297d633
+       0x09e8aa04      0x540929ec      0xbcc58c41      0x6dcf7b61
+       0x6992928c      0xcd40ff22      0x13e4a724      0xd331d5f3
+       0xa512aeb5      0x1c1c4ae8      0x5f0fe5d2      0x3d539538
+       0x383c214c      0xd0a983e9      0x977e8682      0xf38a571d
+       0xdb92de78      0x04ba543f      0xb531e880      0xfea55473
+       0xd6d17b05      0xbdd676ed      0xfc7d4f68      0x8b5170ed
+       0xa738734f      0x8a25fff2      0xb1b0239f      0x60545acb
+       0xcfb00725      0x35f58585      0xcce4ed42      0x05da1c3f
+       0x29428b1b      0x099680c9      0xb4608916      0xa9f177b7
+       0x3b393c9d      0x92d19426      0x472dfe73      0x7b12de81
+       0x557ec0f2      0x166fa28f      0xfb6855da      0x592d3e69
+       0x373a1dba      0x9c76abae      0x13c7f717      0xbc53e796
+       0xb2d39602      0xf1efa3b2      0x00046c93      0x1faf82fa
+       0x55dec395      0x22a034c8      0x576bd5f2      0x97c36a45
+       0x08a1a923      0x9ac2f22c      0xb029e4bf      0x6c4ca958
+       0xed7276cb      0xa0924918      0x1894c9d8      0xdb993c42
+       0xc31c6e18      0xbadc738b      0x57f95d64      0x4d766a25
+       0xea41493b      0x60c19727      0xe7c63d8a      0xcbc52763
+       0x7882b244      0xe2da61e5      0xd19111df      0x526d01d2
+       0x4e7021db      0xa13fb9fb      0x23e082cd      0xb426b603
+       0x9cac0cdc      0x44a94870      0xd0adbbe2      0x9b77a80b
+       0xe1845f75      0xa1704da3      0x2d1c6207      0xba3ee883
+       0x0c3089d8      0x0cba7fdb      0xcb069fb0      0x38738df4
+       0x89971c2a      0xfbaeb7e6      0x459e1365      0x45fba877
+       0x02046ea3      0xd9d0bdb7      0x83c74383      0xc248e9d5
+       0xaae85a56      0x33092ec7      0x6bece02b      0x3b7af1d3
+       0xc92b6e83      0xba032588      0x70e61198      0xa5eb1239
+       0x4d9a6456      0x7d3fe964      0xdb3eb780      0x7e188648
+       0x511a6402      0x48c4ade9      0xba7e9153      0x09490df7
+       0x11b5ea7c      0x4e63145f      0x07ca7947      0xc337360a
+       0x2b399632      0x5d1fef78      0x9b1e439e      0x8daa70b7
+       0xf55a59bb      0xc3a8c84c      0x4d18eb22      0x74568737
+       0xf0419b6a      0xbab459a5      0x0cb07a0a      0xeeb8e086
+       0x0a9241a7      0x419c5ce5      0xec841275      0x3ec13615
+       0x49e42b6f      0x2dae6c7d      0x3fc35088      0x1b92ff9e
+       0x573b1cda      0x54381503      0x29a5b7b6      0x82994130
+       0xffb93c4c      0xc0a66aa1      0x68889181      0x0826e555
+       0xe81cdf31      0x740109a6      0xb8835558      0xaa5d9aac
+       0x0d97ea3b      0x89f744c6      0x2b702162      0x992fe0ea
+       0xab3a585a      0x3e7554db      0x9d97ebdc      0x9939bce8
+       0x486a5f50      0x804ccd06      0xff2e15cc      0x67bf77cb
+       0xf9beadd4      0x2da33477      0x18adbaf0      0xdb00dae4
+       0xe727033c      0xd10ce1ac      0x4f8c4a29      0x281bf150
+       0x764e1387      0x8c65a901      0x841521e3      0x31d9dfd7
+       0x1e7ba122      0xe8fd6d3b      0x4bfe880b      0xd2c1c20f
+       0x9a07169f      0xedbb94b8      0xe9cbcd9e      0x33cac378
+       0xa42fef1e      0xf0e5ff32      0xa86b9038      0x7dbec0cd
+       0x7ad1abe8      0x5e3e4e8f      0xc4dfe8cd      0x86630ba1
+       0x02003c6f      0xbcb50d9c      0x65d874b1      0x01a09ddd
+       0xc97d3d65      0x2d02bedf      0x6fc63309      0x214b421b
+       0x72e0a28d      0xd9c8a577      0x1c8665a1      0xd33b4583
+       0xfa004d9b      0x5c2470b7      0xc671fed3      0xe033617a
+       0x5a86c333      0x13388e4e      0x3bccdcda      0xc62fd60b
+       0xcae17379      0xf6d84d27      0xaaa52422      0x5771e380
+       0xeb1feaf3      0x3c28e7fe      0xa0fded4c      0x5f63a3c7
+       0x3b42ed09      0x1748d617      0xbc2d4fd6      0x3416fabc
+       0xc1e60e41      0x48ffe41d      0x4ea5532b      0xba7dba76
+       0x21378ac1      0x7425d0f3      0x426b3153      0xdc57d14a
+       0x54997f9a      0xeda2a56a      0xfcec5ef5      0x6fd7acb3
+       0xf2691009      0xc1a219e3      0x09a82589      0xc6e1792c
+       0xb4674578      0x0aaf55d2      0x23c7e9dc      0x7607d612
+       0x580fc695      0xd24b2629      0x0a8726a1      0x3544e0a2
+       0xc1de7011      0x30982b80      0x9cf4f328      0x02b22d26
+       0x78e33c10      0x2ce6bb5a      0x92280ed7      0x2ce5b007
+       0x64552836      0xda4a7b51      0xa6122870      0x00b28bb1
+       0xb98cda46      0x84cbe910      0xeccb62a8      0xe13c3645
+       0x2f4494e4      0xed0da7b1      0xb8aa8a1a      0x1adcbc0a
+       0xdab03e90      0x904d9041      0xaa8fe377      0x087cf59e
+       0xa123b5aa      0x633c29c0      0x36d915d6      0x8f5cacbb
+       0x8834d1b5      0xa2c12731      0xfab5176b      0xe1888d76
+       0x4875b9d7      0x5747b32c      0x73fc6d36      0x202ffb90
+       0x62900e06      0xa5f2a41f      0x497589c6      0x7ec701fd
+       0x45801f09      0x1833e8fd      0x734acfc5      0x2f65bdb8
+       0xe6add84d      0x4ad6dfaa      0xf59dd63b      0xb2150e00
+       0xed32ddd6      0x370ce8d7      0x5fec9315      0xb8e6ba73
+       0xccb15a6b      0x302a0084      0x9e49e2ce      0x7af3bc8b
+       0x488e6ee3      0xcdbf0b31      0x762ce0d4      0xc50a111c
+       0xd07d6e3e      0x18c391a2      0x1a7a559d      0x10b4b3bd
+       0xd0703a3d      0x4e431eb9      0xf78edbe3      0x896604ba
+       0xc0e8d4c9      0xd42f2292      0x5414ea6f      0x0ce7d429
+       0xbb659e0d      0x46fa830f      0xdad39c12      0x0f65fa5b
+       0xa002e598      0x5408cfcf      0xc1c3a5e0      0x28ca35fc
+       0x52b2b588      0xb76e1f54      0xb6c355c7      0x08e3ba79
+       0xfd89c1f8      0x6ebf03a9      0x51ebb756      0x729e1c5c
+       0x1ed0cce2      0x29733f1c      0x42b76fcc      0xd94022b4
+       0x3efc8ac9      0x3f23eae1      0xa0ccf230      0x9da59cf1
+       0x5f6db360      0x922686e1      0xc9138d5d      0xda43fd20
+       0xe0757988      0xa315c62f      0xe3642291      0xc45d9701
+       0x2c394ee3      0xab92e7bf      0xf6037b8e      0x1f523243
+       0xe91791d1      0x19961c4d      0x35d3b069      0x1596143c
+       0x203bca40      0xd26d72c1      0x94c059c2      0xae0df468
+       0x3b0909a4      0x34aa916f      0xe0c254e6      0xd0969c55
+       0xa9b0b923      0x80a9dd5c      0xe79b8d8a      0x3599f269
+       0x623c20dd      0x41e11b9c      0x40fcee5d      0x65dfa8f5
+       0xbffa7357      0xa5b8f59e      0x2bb8191f      0x226a1b43
+       0x910b6d4f      0x73837092      0xd666f5da      0x14fd4426
+       0xd41a8547      0x6f4e928d      0x8096c2f2      0x525ba180
+       0xc6a28d43      0x960b7cb0      0xb76dacbc      0x024de046
+       0xc8e3c937      0x0217493b      0x1516dc22      0xe19e70d0
+       0x655321c8      0xa46a9105      0x61ec2a61      0x1400405b
+       0xcd0a758d      0xdc792982      0xbd994932      0x6565c8b2
+       0x187be349      0x0afa44ad      0x714870fc      0xede1b8dc
+       0x2c4ac6b5      0x7d9793ea      0xe0bc3c0d      0xaa56f23a
+       0x7fd4e2ec      0x2131ad26      0x2cd34428      0x45e9dec0
+       0xc15b692a      0xae73e713      0x37c5c3d4      0x70ff213c
+       0x4d6322fe      0xa29a9b4a      0xca7d3c65      0x1024df74
+       0x308f4a3f      0x4f48c7d9      0x0c71a17b      0x540441ed
+       0xbc2f36a8      0x2592d7d4      0xbb643dd3      0xb8fb607b
+       0x6b2b339b      0x9a40ecc7      0x59226bdc      0x42a5c04c
+       0x6a1dc320      0x14e3c7c4      0x39cb912c      0xcf5eb477
+       0xa3a43975      0x79f92cc3      0xe9d4cdfd      0x02dc8fb3
+       0x240b6842      0xe9ff7bed      0x8f5269b3      0xc4f44baa
+       0x1f1c74b8      0xb5c39051      0x291cce82      0xfc129a8b
+       0x0fae02cf      0x31b4d4cc      0x1dfe9722      0x093cd430
+       0x96c2a838      0x19b3a068      0xa7ead8c3      0xa2b3b92c
+       0x2e1dc49f      0xe2f84217      0x670e73d3      0xd7c3710e
+       0x94e4a7c9      0x33e063ab      0x35176206      0x910504bf
+       0xb04b61d3      0xbed9c702      0x5d6c4cc3      0x63276a86
+       0x0bfe5143      0x7ed925a1      0xc455934b      0x402a8b04
+       0x01c03292      0x5de0933c      0xd932d260      0xb5b3b5ce
+       0xde53664e      0xeaec4fc0      0x506030ac      0x6fbd8304
+       0x0b0e4881      0x99c16b3a      0x6fc976ad      0xeae57df9
+       0xc53a953c      0xca681bc7      0x905e49e1      0x405d42c5
+       0xef39b878      0x57ded0df      0x56b98e32      0x392ce7d0
+       0xaa7fbfb5      0x6ff550e8      0xf346ae82      0x2b25a8dc
+       0x3ff980eb      0x302aff14      0x1a43c7ae      0x23f8ec16
+       0xf774024b      0x1c4e163d      0x6b6f9408      0x0646b4e5
+       0x2e55bfcb      0x14e3f7bf      0x86fec07a      0xda898470
+       0xd99a274a      0x8630e98f      0x8c843f0e      0xa840c028
+       0x950d7fb1      0xeca930fd      0xd281c9e3      0x29b3aed6
+       0xc419314d      0xa6147b28      0xb504311a      0x91c07531
+       0xe19ac720      0xfa8cfb5c      0xf8158bcd      0x42202a1d
+       0xfff43b87      0xdc6fa0d9      0x8a599eeb      0xac3a8df2
+       0x83ffa50f      0x346a8ff1      0x0947d1ca      0x318a8949
+       0xe409dd30      0xf73ac9cd      0x9504c972      0xa2392b4c
+       0x5594ac9f      0x7a45c3e8      0x181d42db      0x085e24a9
+       0x6cb3e60b      0x3568d771      0xfa96b628      0x945817e8
+       0xca9d28da      0xcd3a174b      0x7f84ca3d      0x90381d0e
+       0x09a6f9d7      0x11396376      0x4d158586      0xcc451745
+       0x9844225c      0xa45b8a9c      0x0c64efde      0x7429ee29
+       0x308c39b5      0xa3454fb6      0xf949f709      0x09391206
+       0x0168257e      0x94e10cb6      0x48e49996      0x92928443
+       0x4a826036      0x9a777b3f      0xf77adfdf      0xc111b354
+       0xa7ece533      0x050706ac      0x91ed3fd2      0xca15baf6
+       0xd1714105      0xb564c842      0x886800cc      0xd57309e1
+       0x38e4fa43      0xb74fe550      0x26f300bc      0x6349cbe6
+       0x4bc132ae      0x310c1d40      0x3353100c      0x0a308892
+       0xea6ab62d      0x0a438e7c      0xb000cf51      0xa21aadb3
+       0xd3628343      0xee7f1a6f      0x3ee28d91      0xa846f25a
+       0xc898e7c0      0x1198f67e      0x2401caf3      0x78d7acfc
+       0xbc592220      0x1efd847f      0x1e3e935d      0xdb9025f6
+       0x41ab6bb6      0x08a10f85      0x160dc5b4      0x4f0ed74e
+       0x8c3db59d      0x34034397      0xe26017c3      0x03fe3b41
+       0xc4480582      0x7c0c85de      0x4957c26d      0x9eb32143
+       0x28676ce2      0xe3627f34      0x71e3afb1      0x7e978fbe
+       0x3b3ee0f9      0xb5ae1bcf      0x474dc4cc      0x470e2114
+       0x2490e60c      0xbb534e7c      0x7a8ad252      0x7cc08810
+       0x9ea23718      0x04ecf4e1      0x732a9f10      0x62c69e22
+       0x5a94fb4e      0xc1da497b      0x3ab3f2b9      0x09ff7310
+       0xd7749df9      0x170471dd      0xaa551e91      0x2d605856
+       0x66a13f75      0x0be4b8a2      0xe64a0c3f      0x288e5671
+       0x5ee690c8      0x9e1c4b10      0x9f055568      0x8c6ff177
+       0xa7229231      0x19e678db      0xd90be83f      0x0cf70d67
+       0x47462463      0x327fdd91      0x51986170      0x3ad883b2
+       0xa32fa5f2      0x82167691      0x74b6c59e      0x3eae0a3a
+       0x569386dc      0x6d67fc33      0xa0943958      0x40b2939f
+       0x334acedf      0x91b6a866      0x5debd880      0xa6f3712d
+       0xbe8ca5c8      0x4b43fa68      0x72b677d7      0xa42b4d60
+       0xc719163c      0xa469fbb9      0xb484def6      0x508ddfd1
+       0x23bf14bd      0x857a13ad      0xf7a47090      0xe6816794
+       0xbf6d3db3      0xd19fe091      0xb9421e39      0x35b184c2
+       0xa5c94a6c      0x13b2b25c      0x5c7b45cf      0x648fdd47
+       0x8832d949      0x0e2380c2      0x2f8e4f88      0xc01022aa
+       0x4dec89bb      0x0a2c5bff      0xa97e58f8      0x304dddd1
+       0x468828ac      0x603da881      0x646ddc90      0x1afa151b
+       0x985bf8ad      0x6e3635d5      0x181268c6      0x420e1647
+       0x913af569      0x14075a17      0x803aba15      0x2a2562b7
+       0x2f0627db      0x52785b48      0x36ce7fc3      0x6057349e
+       0x4affb11c      0x84e82be9      0xa0f60f66      0x1d176256
+       0x9f1dba85      0x2852129f      0x4592540a      0xae083e7e
+       0x744edf82      0x75a1e1b7      0x518fbebc      0xf1828d15
+       0xfa1e31b7      0x88ebf51e      0x0a648385      0x956c002d
+       0xc8b660cd      0xa82eeb58      0x0754bcf9      0xc4873df1
+       0xf06c843b      0x7e5ac181      0x59661ea5      0xef2ae542
+       0x0fea9691      0x9493a352      0xb401f705      0x85573914
+       0x4e1eefc9      0x45e51c5f      0xd713688c      0x97efca3f
+       0x292d0e73      0x8db44fd8      0x9f4479e0      0xc049ff9a
+       0xfac5ddbb      0x4d610fdf      0xa9e01cdf      0x93b4dafd
+       0x925004b9      0xb0796ea4      0x7e166ac1      0xd030c4ea
+       0xa9f34c73      0x276cbadb      0xf3b9c282      0xa5bd6a69
+       0x53df3f11      0xded46173      0x70bff329      0x0ddd0e77
+       0x52e4a782      0xf01b024c      0xda90618a      0x34a2dd05
+       0xc144d1fe      0xbaca12a5      0xbbd28cf1      0xc54d84f5
+       0x0e7cb67b      0xe009e900      0x23657441      0x2214b4fe
+       0x37693ee7      0x62e093d0      0xf79ca670      0xf1bc6cec
+       0x1b91f787      0xc9d234c4      0x2a193a4c      0x8c2bfaf4
+       0x75f4514b      0x03501d9a      0x5554de35      0x5ff35a26
+       0x670ad976      0xbc8151eb      0x725fb971      0x5768e86f
+       0x7fdcf5ad      0xe814f3ce      0xe8b9510a      0x55bf074a
+       0x415fc288      0xa1a360c5      0xf5fef671      0x2d6253fd
+       0x7fa09b81      0x2bb2e018      0x7159e648      0x10d5d59d
+       0x462047cd      0x77583e64      0x47f1074c      0xc3c0e0d3
+       0x023a55b5      0x4ad55057      0xe6d4b9d2      0x9cdd844f
+       0x87eff8f4      0xd95c1e55      0x7499004e      0x2a43a598
+       0x0c1472b4      0x33c90a5c      0xc4703c62      0xf293e2d9
+       0xc3153c7e      0x6eeffef9      0x115e14ec      0x4ad27157
+       0x888d87c3      0x33edc70f      0x7c38ce66      0x61c10a52
+       0x5db41c48      0x8e309060      0x7b847b63      0x6b619cd1
+       0x12855e03      0x52c3281e      0x704f969e      0xf9ab7862
+       0xb143fc54      0x1ac23fd5      0x89dcd807      0x40a7ffc7
+       0xc84245b8      0x0248d94d      0x29aca158      0x92d7b241
+       0x751588ff      0xe8203587      0xc5bd7cdc      0x9de82608
+       0xb075493c      0x5d43c228      0xff6a5345      0xa64cae5c
+       0x4a1a9a26      0x08c60b16      0x9399ba46      0x3f535d1c
+       0x3b9a6ab1      0xa446115c      0xa77bd99c      0x2431dc72
+       0x729a637f      0x13f960d4      0x230d4e9f      0x0c608153
+       0x9b9670fc      0x72494838      0x14832ade      0x65aba892
+       0xd6434455      0x17697982      0x68b9bb34      0x1d700b3f
+       0x6d0dda39      0x30e0d15e      0x87de41fa      0x9fc55b16
+       0x0f5730d3      0xc3ea8127      0xeee64f5f      0xa02c5baf
+       0x64e18d74      0x31de5660      0x5cf8d724      0x6c07ceca
+       0x409e862a      0xd4ee7999      0x90c22c99      0x59cd395f
+       0x09c36563      0x1993b09f      0xb0c4e064      0x8d6870a5
+       0xe2e8e337      0xe8bef0cd      0x708d869e      0xdf808519
+       0x6fa61e32      0x27161ea8      0x063c783c      0x2aa55c1a
+       0xa6fcc8a3      0x918b284d      0xbb7870b9      0x788102c3
+       0x3e49edfa      0x6c5eae4e      0x1c9fc361      0x554ca60b
+       0xa08364d3      0xa7bd4442      0x204822a5      0x000b71a2
+       0xd4dff005      0x43265901      0xbdb99200      0xc438e254
+       0xa4982e58      0x02812101      0xfacbff1d      0xeec56aaa
+       0xa5525774      0x21ada574      0xffe2f703      0x15d30ea7
+       0x600696f9      0xc7ff3f59      0xdb57c175      0xa16f78df
+       0x54a15622      0xe3742dcf      0x06d32994      0xd48463a2
+       0x44c7c25a      0x41d6ded1      0x3b314de0      0x09992482
+       0xbeb183c5      0xa0a65c27      0x842075b7      0x9b97e3c6
+       0xd9545fc7      0x16d00629      0xd85640df      0xe79e694a
+       0xe818d277      0x1c3d4623      0x23a9a926      0x83ac1b3d
+       0x39e890c8      0xb3738b84      0x54b772ef      0x74518f0c
+       0x7190098e      0xe26aff75      0xf6237011      0xbd3400fe
+       0xda1b8fa6      0xdbf5566b      0x5155cef3      0xddbf1973
+       0x34e2cb2e      0x535fd6b8      0xbfd337aa      0x6dd1fb0e
+       0x52b04fbb      0xab5eca05      0xdb740dc1      0x104e6131
+       0xbf4dcb75      0xaeff3524      0x4257c6b9      0xbf1c8cbb
+       0x0a69ed82      0x90d991c7      0xea075cba      0x5e3c8330
+       0x823116f8      0xba8f8a2d      0xcb98a1e9      0x8b2655c6
+       0xd2f11133      0x3422f3ba      0x3e3a5742      0xdb9714fd
+       0x91701f60      0xeba19983      0x8bf9f157      0xec87cd03
+       0xb63260fa      0x207c345c      0x0c838d5a      0x736415ba
+       0x9638ab07      0xb32c72bc      0x304d191b      0x7775adc8
+       0x57ece662      0x0467bb66      0xb7cf80e8      0x4c635024
+       0x176946c3      0x29cba0ae      0xf214b3f2      0x6e727126
+       0x87b3747c      0x4c19b86b      0xfcc66fce      0x86681713
+       0x636387f1      0x589e78f3      0x2e8abf1c      0x22c828f7
+       0x99653c62      0x8e3bd31c      0x79187a73      0xc6d0e5e2
+       0x8005a045      0x78a38c60      0xe1e8ff4b      0x1102d320
+       0xaaf4ba7a      0x7223d041      0x45f73e81      0xaf7168af
+       0x218ab3ae      0x8b1956a7      0x4db00173      0x482c3bc2
+       0xd982b945      0x4bd7757d      0x0c5ef18e      0x74e66de3
+       0xcf421ae1      0xf2ddc098      0xcec27e0c      0xe79e711c
+       0x6f76e136      0xa8d72245      0x196390a6      0xbf56633d
+       0xd1156298      0x5712cd8b      0xaed801ae      0xa345fab5
+       0xfde1ba97      0x437a0b29      0xfc5628a4      0x93acf698
+       0x83ce0bff      0x212f15c3      0x723ef016      0xe793bd50
+       0x8bc51b39      0x42f17ad2      0x1df73878      0x19af3c24
+       0xf55b6f93      0x506138d0      0x164c542a      0x8d4e1a26
+       0x6c606f83      0x6fbebdf5      0x0e4ad76e      0xabd88e6b
+       0x0e0d74e6      0xd139e08d      0x8b6cf03b      0x04a527b1
+       0xe619c7a8      0xbf0d57f6      0xb38a5f5f      0x3f328013
+       0x374c0a9d      0xff36910c      0xe950a494      0xfc477720
+       0x37bd9390      0x4667497e      0x724eb66b      0x86bda8f7
+       0x52efc959      0x32d5c2bd      0xddbb49ca      0x9c1eef2c
+       0x508d8b81      0xc33d7001      0x360ae3c7      0x1197f6c2
+       0x25efc933      0x4ad234a5      0x9e9c8658      0xc16d4aff
+       0xbc428573      0x30e8b4c0      0x728c2c48      0xf34e1e70
+       0xd62187c5      0xca869f89      0x34685a33      0x85d9b877
+       0x9f77605f      0x93724d34      0x5fc8e8d1      0x70dd81a6
+       0x643e543b      0xe4ad6c73      0xd6b4e5cd      0x387519c3
+       0x719d8c6a      0xb2e0565f      0x02235c90      0x230c9b5e
+       0xe76841a3      0xc2833be0      0x4dab4a72      0x0ae6c0a9
+       0x0b5e12e2      0x4cda3610      0x954b6ff8      0x6d89a683
+       0x3583e633      0xdc540da7      0xe2955deb      0x0f290d9d
+       0xb01e57c4      0x977f4588      0x24b95f0c      0x45529128
+       0x4528b5ee      0x27511439      0xd088d9bc      0x7c471853
+       0xf03b8455      0xbda4a828      0xf49736df      0x50eb17c3
+       0x2affe0e6      0x6727858c      0x6500b8f0      0x0483aa89
+       0x0e1f6a41      0x72666733      0x85617ce8      0xa0c86838
+       0xbccd2eed      0x06e8462d      0xc947bf5c      0x4d2d0a53
+       0x02e70008      0x5039a596      0xb0118cc1      0x690ba325
+       0x057ca95e      0x032cc1ba      0x3dae2c88      0x4eaa740e
+       0xf07b09b5      0x6b2c2135      0xeca746b7      0x76019533
+       0x4cf477b7      0x31848299      0x6b5c7df9      0xc0db5ff1
+       0x7cd3e08d      0xe25fa562      0x260d66a4      0xda30cf2c
+       0x14ab6c70      0x029a8dd5      0x7cd5fe2d      0x98ea5852
+       0x555cf635      0x6c72ccbd      0x64120bef      0xd9e19613
+       0xf26ac6e8      0xafea03a4      0xc14a11d7      0xb2f8420e
+       0xe319634a      0x8a8fedd9      0x6ce0da89      0x74269f31
+       0xd7e0d776      0x86ae9513      0x48bdea80      0xb2e4c581
+       0xab25566e      0x9ccb71a5      0x7cedb09f      0xd2bdade6
+       0x39c96ad5      0xe8ebbeec      0xac8a2e2a      0x915be930
+       0x95e7c98b      0xd00e1d3b      0xdacd08ac      0xd9f515fd
+       0x45cd3946      0x828a2cc3      0xfbe1bd9a      0xc5e1ebcd
+       0xac69128c      0xcd6423ba      0xd8653b60      0x48f0614f
+       0x0c1ebbbe      0x7ab89792      0x9a4b0097      0x2bda854d
+       0xf17ab2c9      0xcde54eb9      0x4b53a030      0xe2399c4c
+       0x19454a2f      0x473fe390      0x3a42c16c      0xc4c106a9
+       0xf5d96e73      0x2ab4078c      0x5d20e7ba      0x47880aab
+       0xff5e0d78      0xa374bdc2      0xc17109ea      0x39fce648
+       0x00821cbe      0xc54a60ee      0xd753386e      0x7b28fc16
+       0xb6309bbe      0xaefd0548      0x41168500      0xee5989a3
+       0xe0177f09      0xc9fc9eb6      0x09a6e188      0x45776a0d
+       0xf19a4830      0xc6774893      0x814b2e43      0xf8be5e3c
+       0x22fa8237      0x75c98f46      0xb1c52edc      0x443d54f8
+       0x6a1a886e      0xc7f33598      0xaa794644      0x685e5ca2
+       0x97a735ba      0x3c1a391c      0x13f6f89a      0x660d7041
+       0x333c3eef      0x40541bb9      0x5c3724d5      0xc348023e
+       0x89791dd9      0xe72fba89      0x5af98b2c      0xb534fd29
+       0x64d0e6b1      0xa578e77f      0xf311215e      0x634cc8cb
+       0xbc534e51      0xdfce3ac7      0x90f88f51      0xb3f7dd48
+       0x20b3e0ae      0xf4456e85      0xacb3925b      0x2eb3ce78
+       0x37e61d82      0x724b9cbc      0x1462d9c1      0xd3f49dc4
+       0xc1ffcc00      0x7c3e3f86      0x6f283bf8      0xf43671ab
+       0x90cbfb35      0x55390829      0xc8fd0d31      0xc687c45d
+       0x724ee656      0xfc1eab3c      0x3c8c2f04      0x3caa3af4
+       0xbe220358      0x4d5b49a2      0x12cf4893      0x867173fb
+       0xccd4b513      0x7c94a1bb      0x86c42c18      0x2b2070f3
+       0xd2a70638      0x9d7c07e3      0xd02ed59e      0xd349488f
+       0x1e85754d      0x333db889      0x0d0defdf      0xef282e45
+       0xac3f6c29      0xd65a68d1      0x5d0914e4      0x395ec78a
+       0xb056aa6b      0x4d98d059      0x7ae08f88      0x25c923d2
+       0x79670f38      0xa881d62f      0x89cd5015      0xfb01da43
+       0x5861244c      0x05e201eb      0x41d71eda      0xb2babb53
+       0xc3845fb3      0x1f3b5c56      0xde6c10ac      0x73adb998
+       0x714aac3f      0x4ad9fc65      0x3acdd014      0xeb319d58
+       0x48842806      0x47ec1040      0xbfdf0052      0x3c478ec6
+       0x83b43a0f      0x9e727e69      0x9f4d5925      0x9f45c13e
+       0x30b8572b      0x26edf8cb      0x577e8b9d      0x9b98d7b3
+       0xa44a9bbb      0x903e39eb      0x51226dbc      0x933a52b7
+       0x14c6dc86      0xbc24db59      0x21054454      0x98fc5fa6
+       0x2c9d8606      0x19178173      0xeda24205      0x90dfaca4
+       0x21d562ad      0x7e3ad05e      0x2b3a40a4      0x46513f35
+       0x0d13a598      0x8bf71ca2      0x6a36c430      0xe66f5587
+       0xc9f13bd6      0xb6534a8b      0x8a3fbfd6      0x38cdfe6c
+       0x1a1c89f8      0x6d782709      0x7919c451      0x6ccc96fa
+       0x334029b2      0xa638356e      0x001e709f      0xb2132b06
+       0x483f1933      0x189ab8f9      0x4ba0ec13      0x490aee0a
+       0xda63f1fc      0x5679d38a      0xcf1e92f3      0xe7257fbe
+       0xfeb733d7      0x0704860a      0x34ce2032      0x663b948f
+       0x544cc928      0x8c23d5aa      0x67986469      0x93f9ac08
+       0x4fa9a13f      0x9eb311d4      0x41a64161      0x29d1050a
+       0xa5285c24      0xb53d03a6      0xc5de26f3      0x7876d1c5
+       0xbdcdcb4b      0x79d1196c      0xe9890732      0x3e58a8c0
+       0x874f03c7      0xfdfc9cac      0x5d57fa57      0xa3ef01df
+       0x47bcff48      0x8beb1aae      0xf4bb4f9b      0xa5c83b64
+       0xd69ab0ce      0x40f6691d      0x2eb8fb7d      0x22640f8d
+       0xac1ba157      0x3687d705      0x7fac8727      0x4ad75cd8
+       0x7016d2e9      0x25c36c08      0x7e4248ea      0x292bda19
+       0x2acf589d      0x0ef7726d      0x835f9e62      0x3f9a1973
+       0xbb6d2588      0x078ff6b4      0xaec22b5d      0xc740501e
+       0xa2ab115a      0xea993e64      0xa0cc3ed1      0x934e4e0e
+       0xd732b66d      0x5fd28c47      0xe4ccb898      0xc6a101c0
+       0x78274bae      0x625df6a1      0xaf774052      0x3b7c08d2
+       0x6180ac39      0x3e5aa769      0x6ec74578      0x6b5d27b9
+       0x98e58a17      0x119dd7d4      0x39429c5a      0xe3d5b391
+       0xbb8fddb8      0x5929801c      0x68cef71c      0xc36fa301
+       0xeace4850      0x29f4f97d      0xa58bad79      0x2823998f
+       0x0fe1352b      0x5960ded0      0x69308816      0x0d7e33c8
+       0x2fb13bfa      0xff6a326f      0x69cb631a      0x839ea2a1
+       0x528a8065      0x34cbebfa      0xd4432cc4      0xe13b550b
+       0xe046569f      0x87b41fb1      0x7751107c      0x0ef6e60b
+       0x856ffc50      0x11995683      0x77c2ebf1      0x4dec97f9
+       0x3a28ebc0      0xb7bfa04a      0x40cdceb0      0xd559dd06
+       0x61c2cd6a      0x8a906fa2      0xd55f43d6      0x7fb3ac35
+       0x8cea4e81      0x1d359c2e      0xec447c57      0x3414f7f1
+       0x18243b84      0xdf76849f      0xd753044a      0x7af2d51e
+       0xaee26ecc      0xae6946b2      0x7478c675      0x88b22f49
+       0x4de13fc9      0xd35c5956      0xeebb60b6      0xa15b1736
+       0xa6e78d78      0xfd5e30b3      0xb4fade2d      0x964eb418
+       0xe9035f51      0x22ab8242      0xfaa64053      0xdfe03834
+       0x47beb588      0xb82a0887      0x11182e85      0x2f2f9a67
+       0x4b612f11      0xae04077e      0x7f783c25      0x883a34e1
+       0x32d43beb      0x6f0536f7      0x85c1537e      0xfb26199a
+       0x45417e88      0x4af2c8cf      0x0a334486      0x2a3e6838
+       0x31b8725b      0x63d64541      0x7e516a0e      0x7e42e766
+       0x4cf30198      0x68abecff      0x7fb49c43      0x8f5b558b
+       0x32b99abe      0x67337248      0x224c3411      0x4e7c41b7
+       0xd3aee3a2      0xca19e704      0x2a430b7d      0xe9aee453
+       0xf4ce492d      0x48fab2a9      0x42ec2076      0x0182cea5
+       0x8a6373c7      0x18f41b5d      0xdd062fd5      0xb1db44a7
+       0x285ad917      0xeaaabbd1      0x359b1b23      0xcc123c8e
+       0x38b70cb9      0xb01ae722      0xa6e72010      0xb647530e
+       0xf9651d41      0x366d6d0f      0x4b656a6d      0xd36637f0
+       0x4b5ab8bf      0xc22fdb1e      0xc57c8250      0x799f4e60
+       0xb55bd50b      0xe8a3432b      0xe752e4e0      0xd0c86482
+       0x122991f1      0x5bec598e      0xbcb89abd      0x739f61d0
+       0xd230ae2a      0xd0b99c05      0x2a998a6d      0xab715831
+       0xb7dd1939      0x57db0ea7      0xed1f4952      0x49274caa
+       0x35e319b0      0xed2c9cb3      0x601caa20      0xfe782688
+       0x64b6d30b      0xcd5c325c      0x2c836157      0xa3552f79
+       0x188094db      0xa42dd7e8      0xc09c2dda      0x02d98d8d
+       0xed270d28      0xb0f38ada      0x5d7b4261      0xb41df8d8
+       0x7341b6ae      0x024ce90a      0x0727ae4c      0xa8dd3a0d
+       0x390f84d5      0x43f5bd12      0xd11fb61f      0x6fc330e1
+       0x7f2d7fa6      0xf758a4e0      0xceb1f3c3      0x2f341836
+       0x98fb470f      0x5bf68e58      0x1917a5b2      0x75f33be6
+       0x16e22316      0x8aa810a0      0x1fc6c9b2      0x22179249
+       0x3de701e9      0xec48d8b6      0xe85248c1      0x314ce9c1
+       0xddeb2f47      0x0187909e      0xaa755f62      0xb2019460
+       0xb2016a9c      0x91f789be      0xe5925997      0xe4864300
+       0x1fd13759      0x0ad97c1d      0x7cf08c01      0x7eac2dd6
+       0xcf61a7f3      0xaf9e108f      0x939a2fd9      0x0cb48e78
+       0xe6ea1a8b      0x0b968273      0xef1c9310      0xf60e82b7
+       0xe76e9bed      0xb8fa9668      0xf889765b      0x0e51eed6
+       0x6b6566ea      0xa8f7e2c5      0x9d8c283a      0x879afdcf
+       0x944873c5      0x58afcfa2      0x2e60600e      0x59666667
+       0xc812b833      0x5842d0be      0xdbdc0829      0x786bcff9
+       0x5857ba06      0x6968c729      0xf5447949      0xdb1ceeb0
+       0xaf04d1f5      0x30614f7f      0x3e80fdc9      0x8a6e1ce0
+       0xa267d7d5      0x8896143e      0x24e59072      0x68122e1d
+       0x3ce24add      0xda677bdc      0x8c3f74ef      0xfa60e825
+       0xf5c136cc      0x2cc5f249      0xa1c6b642      0x47a2305f
+       0x52cadbc8      0x4d0c32f6      0x07f4d344      0x1f496d59
+       0x5699b970      0xb8cbe564      0x707f7a2e      0x818bfd45
+       0x800a8be0      0xd3de4f1f      0x62de0a3a      0x6b342869
+       0x054daa7c      0xc72b945f      0x1612f126      0xdb4ad492
+       0xa28c467b      0x78542799      0x61607353      0x39f1c142
+       0xebf30ad6      0xabe076d0      0x5125cce4      0x5584149c
+       0x65fa33f4      0x878a918f      0x8c7e5c37      0x334c4284
+       0xbfd816e1      0x0f0f3460      0xd54519fd      0x03701ca9
+       0x64885229      0x00e841d0      0x756a9472      0x0c16c5f6
+       0x65560e81      0x129b6995      0x91c9dd1e      0xe9730dae
+       0xce47f2a2      0xead8a0ee      0xcd58078f      0x7ca2df31
+       0x0ebbf13d      0x3c74e061      0xb7f3980a      0x0d354b88
+       0xfd8db90c      0xec6726d0      0x6bfce0f5      0xea98b7a0
+       0xac5ddde2      0xb372a14c      0x47b09ed5      0x531bd5c3
+       0xcfaf5a0a      0x51d6394f      0xe9efdfa8      0x37c79445
+       0xb13ebf62      0x46715efb      0x31e6a0d7      0xfa48ab48
+       0xc6552f2c      0x3067b978      0x0afa4ab7      0xc2c17055
+       0x68dd427d      0xeac01e43      0xe90f12d8      0x6d97c3b1
+       0xe0d339b0      0x2f3c84cd      0xca3eb3b1      0xbc0d86e1
+       0x3566f657      0x083374b0      0x199c677f      0xa4a8a4d3
+       0x224dd5a8      0x8f304abf      0xe1019878      0x9b290d4c
+       0x5cef7341      0x59ff7e48      0xc91663ac      0xb0b1bede
+       0xe9d8a9a5      0x8f34cb70      0x588d00d6      0xb7fe69b6
+       0x29036caa      0xd21d7998      0x4edc3ee9      0xdbd94f37
+       0x99c63455      0xac94efda      0x545635dc      0xb787b5e1
+       0x8228666b      0xc7cd8170      0x4f1924a5      0x437884c1
+       0xfa9236fb      0x1f0f949c      0xd1dc0597      0x56082a24
+       0x04e51919      0x05dd926f      0x06d264ac      0xaa672d38
+       0x5a3e396b      0xab48a57c      0x53489bd1      0xb36b3ba2
+       0x55164db6      0x5b52c5f9      0x68aa8b7f      0x922ce829
+       0x09e6e5bd      0xbc488a86      0xc0fb6dab      0x98e7754b
+       0x4c9ad717      0xe3ae7045      0x0b498742      0x80a4384b
+       0x0dfe0b99      0x70eab3b9      0xbee30b9f      0x4237ca85
+       0xe67662b1      0xdae3dce5      0x47c84a45      0xf72febf2
+       0xa58dfdc8      0x77ae88d4      0x038c76b7      0xae699990
+       0xf5f10de7      0x65d4c59a      0x004a8b4b      0x67c788ec
+       0x71c918d7      0x0ec70171      0x7041de53      0x43591e1c
+       0x807242f8      0xa27fe146      0x0055fc7e      0x2f08467e
+       0x5e04a068      0x54dab094      0x4f6e8c7a      0x20ac2825
+       0x47949a42      0x9181486c      0x038e3132      0x7c1c51be
+       0x97544f38      0xe2d27588      0x64889c21      0xdad9a1a9
+       0xf1d328a4      0x7d47991f      0x2faa1b85      0x2430cab0
+       0x0e849f91      0x213686c1      0xa2635f37      0xee7983ae
+       0x87871273      0x6867d60f      0x04cb29ae      0x4e0ee4ee
+       0xfbd2666a      0xfd7fe017      0x870b26ee      0xc42e104b
+       0x78919117      0x19590e66      0x9e1a5039      0x9609471b
+       0x4057fde6      0xc1f27544      0x30af8a8b      0x2ea267a6
+       0xcfd886b6      0xe632b1f3      0x3f10bc50      0xf38a1bd8
+       0x7ae1e284      0xe3876d7a      0xb4ce64f8      0xf74b4100
+       0xa97686da      0x17ebacde      0x2ab068e8      0xcebd1076
+       0xee8f81d8      0x0d394301      0x6f32c277      0xa926dc1c
+       0xd5d2ea55      0xdc016b6b      0x6a96022f      0x0143e314
+       0x23836eed      0xa3e18369      0xd2a155bd      0x8022cef6
+       0x080b32a8      0x74ba38f0      0xd1ca2089      0x7c80219e
+       0xf536af16      0xd7a337e3      0xa33600a6      0x39c7754d
+       0x7d215312      0x1dd65026      0x8cb496c7      0x89dfd508
+       0x9f945a1c      0x45caec32      0x020a1edc      0x5917baa3
+       0x296b4b1a      0xcfaa2023      0x63e7a0e5      0xc48b19ae
+       0x78d98b1e      0xc5d6be01      0xfe4ef13d      0xea6c9915
+       0xb8190f09      0xf1793822      0x9acf1593      0xc7710fa0
+       0x6b9a9f3d      0x0220ee2a      0x5d63043d      0x7292a0d5
+       0xba9a1682      0x6f1e7c19      0xed7cc52e      0x6bb89645
+       0x4370269c      0x9cb2c1a1      0xa7135973      0xfd1f3bbb
+       0x50e6eb67      0xf2b9bd22      0xd891f6a7      0x4e0a7449
+       0xc3dc0005      0x878e3333      0x3b4b8686      0xb215c65c
+       0x5d8d24c0      0x8d203496      0xff20d243      0x0a6c1253
+       0x2385c79f      0x52e8d6dc      0xda4bb8b7      0xfab66d97
+       0x05a4a795      0x6876e856      0x9dabedc2      0x53550c20
+       0xb3bba16e      0x853bf1cf      0xb85b906d      0x3f374468
+       0x62e07c2c      0x6903a495      0xdb119586      0x07e91546
+       0xa8388945      0x5a4e1dda      0xf054cdad      0x4b052880
+       0xe9bbc9ec      0xe3555e11      0xd4d6479a      0xcad6a986
+       0x31d9c4ae      0x510ff951      0xcb2f3164      0xbe283401
+       0x0c390b9e      0x0c9cb487      0xe64e8ffe      0x611a63c0
+       0xa1d700a5      0x3f864335      0xd1fdf32d      0x7a3aeb09
+       0xabbc8c4d      0x4d703604      0x6532c8e7      0xccebc529
+       0xf3c0f514      0x1567f19d      0x591abf6c      0x6c7fc459
+       0x0858b061      0x092b2489      0x33c1a9cd      0xd6cc8e2e
+       0x7c1ffeb3      0x3f45cf40      0x1fbcbd39      0xc6f0e628
+       0xb88bab4d      0xc699de42      0xb62d850c      0xf71a6768
+       0x2866b891      0x13093fcc      0xc730c502      0x2deaeff4
+       0xb1bc8535      0x4303997b      0xb31ebd2f      0x82debe94
+       0x843fa02d      0xba29f80d      0x03cb58c1      0xef1d2017
+       0x0b5aadf0      0x6c5c3286      0xf084faeb      0x8b96a39b
+       0x67cb38f8      0xf686ee62      0xbfdc22a1      0xee3f779c
+       0x8ec73c8c      0xb448536d      0x67bb5d68      0x4369ea8d
+       0x4b5367cd      0x2dbbc0be      0x8f5986e7      0x798c8392
+       0xd3aac078      0x0081c0bd      0x94d9d70b      0x40bdeae8
+       0x6b528e89      0xb0713745      0x063e535f      0x7d696463
+       0x64f0666b      0x68a82e8c      0xc749dd19      0x875883cc
+       0x3d35728d      0x4c0e5d8d      0x135f11b3      0xb649b37f
+       0x8aead5cb      0xdfbd573e      0x563bf917      0xcdb75f08
+       0x024b93fb      0xc6477eea      0xd88ce51d      0x95f7d77f
+       0x0b561446      0x2fb6992c      0x4b48c8b1      0x940da60f
+       0xf1be60b9      0x66d8641b      0x17a0ce15      0x49d22f40
+       0xb8c494da      0x91930bb1      0xcd317991      0x4c5b4c23
+       0xafda60eb      0x212c9f04      0xe4732f4e      0xf731ae57
+       0x19165943      0x2d9288c3      0xc9c45dd3      0x2e05b148
+       0x225a256a      0xc0249ea2      0xe96733d1      0x56a6803f
+       0x20458549      0x28210fd6      0x13da740e      0xf0f0be41
+       0x029c1fa9      0xb1daf3f7      0x1bf0c9aa      0x6f0d5221
+       0x998b3616      0xa02212a3      0xe76b39b1      0xba0823e6
+       0x146da6a4      0x858a3e0e      0x58e75b32      0x732f75ed
+       0x8d88385e      0xe0e7ed55      0xc08ca86d      0x97e2ef67
+       0xbb048208      0xd384c40b      0x8595bc69      0x65581977
+       0x7b091c4c      0x60bfbbb5      0x23bcf38f      0x32e4621a
+       0x7f790d95      0x72c3267c      0x34dd0c12      0x27438915
+       0x5619893a      0x09d55159      0xdba7eef9      0x7413634f
+       0xf4883417      0x59a2f28e      0x491f5779      0x0c138f9c
+       0xc52a03de      0xcb1f92d0      0xb6cfcd21      0xbba95c83
+       0x5302f12d      0xfc4c030f      0x18722dde      0x131cd3b1
+       0xa19a1cdb      0x103d9216      0x403e45db      0x5cab72f3
+       0x17e18f5c      0xbad9d0d9      0xd0d2e010      0x798106fc
+       0x3abace6c      0x2c3131c6      0xf9529b61      0x27cfa158
+       0x8890951f      0x87ccf0f3      0xa112b1e8      0x3e0eb033
+       0xd7469e14      0xb6ccd2ca      0x3d238069      0xb32f057e
+       0x8d2c939b      0x18d8aa3d      0xdb3cdb2b      0x861ba258
+       0x46e7b170      0x4830d004      0xeea1b8b2      0x44e29b51
+       0x0cdd8591      0xf93ad973      0x9383c44d      0x24e323be
+       0xaaac87a1      0x84eb09d7      0x1f66b641      0x303f92b4
+       0x81a63a86      0x516321e4      0xe33dfe2e      0x371a4624
+       0x8f936425      0x596976ca      0x7b1947ef      0x83a9db29
+       0xc5f337b0      0xe4d51b73      0xb35b56ce      0xb9cac5ba
+       0x51705ecf      0x93e7d63f      0x5ee7d916      0x479f25b9
+       0xe90bb406      0xfcd6e78d      0xbd8ed9b7      0xbca7c8b7
+       0xdf95f4cb      0xc28baeba      0xb4534bbb      0x98b4f840
+       0xf2218357      0x726e4f81      0x7591ebc4      0xc0523d15
+       0x6bc82550      0xedfbcfa0      0x57280f50      0xbe7e420c
+       0xd1152012      0xbf3ee0a2      0x11825710      0x18e728d1
+       0xb8af00b5      0x2d1e940d      0x1c9ade8f      0x923ed269
+       0xfd8c2580      0xf6477ff7      0x476a486e      0xd09c18dd
+       0xaede7959      0x55fb68fc      0xe5692f7f      0x0bf4bd18
+       0xf5fede2b      0x07bb05e7      0x1bb8ec54      0xa46bba84
+       0x15051826      0x762ce6ae      0xa0246225      0x35c38cab
+       0xbbd00a24      0x8205d3f4      0x4cb33ba4      0x293013fd
+       0xd4f67965      0xe9c1951b      0xff108efa      0xb8e68197
+       0x36d51e4c      0x2959f7f9      0xf2e4206f      0xc9973e09
+       0xb61ce3fa      0x9543be90      0x63642668      0xcaaf02be
+       0x7346a8eb      0x4111f5b5      0xa453cc2b      0xdb524b49
+       0x4d528cfa      0x71e5fc4d      0x62cbbab2      0x8423f40b
+       0x1a4db908      0x560c41c2      0x03982d88      0xa49c553a
+       0x529f6acc      0x82dae294      0x6c5dbaa4      0xfb4ae1f2
+       0x36e31345      0xb5cba88e      0x3704c623      0xe35245ea
+       0xa412107c      0x35faf59c      0x08ceb649      0xbd67a6b9
+       0xe37ddfdf      0x21303abc      0xb7de5e8e      0x88d9366f
+       0x49bdd73c      0xeca0cd02      0xfe1e01eb      0x30a56c2d
+       0x0cae1f5b      0xe77521c7      0x5ca59eaf      0x1288aa13
+       0xc60bc96f      0xf7292504      0x2b037e4d      0xf34757b4
+       0xedcdc492      0x39044092      0x5d710fbb      0xb8658511
+       0xe23e4d57      0x595d4d3f      0xc0f80105      0xfe952879
+       0xe81e2cb6      0x4f5a8fed      0x3bd0d700      0x211887d3
+       0x6ea6e78a      0xe066640c      0x0d29c725      0xdabbeedd
+       0xd2aca4d4      0x65c4a06a      0x6645b62f      0xb1de0cd7
+       0x022e07ea      0xe9f9248b      0x0a2251da      0xdf34159c
+       0x7894bab3      0x72e465eb      0x37448fca      0xbfbc1911
+       0xa79e4938      0x48b83ec3      0xb9c6833f      0x19d24abb
+       0xa434e777      0x77947277      0x2309612e      0x546a6ebb
+       0x4c96447e      0xab918dce      0x5075ba1d      0x0aa55a7c
+       0xadcce25b      0x837819d4      0x90d62a9d      0xf116ede5
+       0xb056cc7f      0xb036353e      0xb7c1af8d      0x014c2cd1
+       0x356f1593      0x008c2634      0xf7cd0cb0      0x02b0576c
+       0x5364c954      0x5b40800b      0x60054bd7      0xef31bb60
+       0x1a85370a      0x458c4348      0x435b8da2      0xd8df0e06
+       0xde0cf1b8      0xd3c6171c      0x0bc14938      0xdc874128
+       0x694f96cc      0x7b6687e0      0x9ca59f25      0x617aea60
+       0x63ebcc8d      0x4bb44d00      0xce46d01c      0x4ab07a75
+       0x64757638      0xe5903811      0x3562895b      0x760627ce
+       0x8939cc7f      0x225db9b1      0x730062d9      0x7a5a7a15
+       0x49678fc3      0x8620cb95      0x9439dee1      0x501f2cae
+       0x3d08a33c      0x352de5c1      0xe7b24442      0x6ec76b79
+       0xc575a1e8      0xb7024b20      0xc9dbb9f0      0xfe2303c0
+       0xba3716ae      0x0cf37bdc      0x1c68a4a7      0x7ba0d609
+       0x43003a93      0x17dd96c3      0xb884aa37      0x15b2d65f
+       0xf6016133      0xd1fd7e04      0xc0a22822      0xf8c26247
+       0x818c35fa      0x4e2b3605      0x83923c44      0x4ddd4397
+       0x6faf6a11      0x50438703      0x67796dac      0x3443b780
+       0x484f5bb9      0x8ead98ea      0x472ae543      0x94b0b17b
+       0x1307833e      0xcb0e8286      0xb02e1ab1      0x36a89f9a
+       0x372e82f0      0x84741303      0x111ad8ae      0xb1eeacb7
+       0xd7d8ccd6      0x5f779f32      0x0d65184c      0x0a398467
+       0xc07c099f      0x0704ffdc      0xa10b2f17      0x4c926dc9
+       0xd80829ee      0x0821015a      0x512e6d0e      0x57b514dd
+       0x509cdfd6      0x7e08ef24      0xf536c381      0x65483797
+       0x439311fd      0xabed0f15      0x51a372c2      0xdd24c506
+       0x839cdd63      0x0c21c8dd      0x513d9eb4      0x43c6a95e
+       0x5d543848      0x64843a49      0x687bbf41      0x93d3bce3
+       0xcf85eea3      0x5f3a6fc4      0xe7b45979      0x4c5848ce
+       0x924188e3      0xbcbded12      0x0cc18c86      0xf3fd5723
+       0x148dddb6      0x77cb388f      0x30afd47c      0xa306c453
+       0x1da0b234      0x0f206f46      0xf25975bb      0x9c75d28f
+       0xc60ad2fe      0x0067c5b0      0x497a1617      0x81d330e6
+       0x2c5362ef      0x86a54b1e      0x80ad976e      0x0a86ed37
+       0x1183b84e      0x2e2ce6e5      0x10b02598      0xd56fb0b7
+       0xe3e0bca5      0x755d2333      0xe0be1b85      0x6c976f4a
+       0x555a1465      0x8ab38399      0x51d4a5c8      0xec3d86e1
+       0x2a85d0dd      0x0d31c16f      0x603f2d48      0x274d5d68
+       0x292e7df9      0xe444f292      0x329946f1      0x132c3230
+       0xb2c3ec05      0x88362f92      0x763dc2fa      0x7ee6f3ab
+       0x7ca649e8      0xafee8a8b      0xeef65517      0x4789c1e3
+       0x85bd4cb3      0xc87762d3      0xfa528ba7      0xa8e20dde
+       0xd369c227      0x97e7f300      0x8256f4ce      0xdd5d2901
+       0x1e37c55e      0xbb6e22fa      0xd9424392      0x8798d9a5
+       0xc118ddb2      0xc3c91c40      0xe68ead77      0x8cf3655b
+       0x4381e8fc      0xc94f312a      0x0b372483      0x70b620df
+       0x53820813      0xb50d6f0c      0x64a53e9e      0x6f7f19f3
+       0x6315f718      0x9aafff2e      0xf3b5a338      0xf1f3293c
+       0x750ac26c      0xefe3ddf9      0xdc7369eb      0x024dafe0
+       0xf56354fe      0xf0afaf86      0x7da1df00      0x7447ffa2
+       0x4afd091f      0x24f39c82      0x3b3c8aa3      0xd90fc65d
+       0x10d90b8a      0xf05d49fd      0x281320fe      0x75f62523
+       0x0537b558      0xf52ae61c      0x77961852      0xbd0db386
+       0xcb650cb6      0x7387ec69      0x320764c4      0xf5013b3f
+       0x4f4239c8      0x4983a307      0xf510f405      0x7e355790
+       0x4f8480d2      0x50dd84ca      0x66947bed      0x56efdfe0
+       0xa593407d      0xdac216de      0x642a5f74      0x92bb9c2f
+       0xf37abdd9      0xa24b1b64      0xca1f722c      0xaa5de969
+       0xb6cb128a      0x697f787b      0x5bd74fb3      0x6de74e39
+       0x2bc9a4aa      0x634455ab      0xa82aecc4      0x69647f0d
+       0x4be06592      0x0c220c92      0xb08adf1f      0xd4571d2a
+       0x0fadece6      0x297c124f      0x2830a499      0x3cc8363f
+       0x44e34d3a      0x27b4d820      0x98be7f08      0x43417964
+       0x8a3af8ac      0x89c42336      0xe55d19dd      0x00ee1f6e
+       0x47d48658      0x55986f58      0x11ccb046      0xf3b97a07
+       0x7ed364a3      0x106cfcd0      0xc1533857      0x3add2c15
+       0x143852c7      0x55b38512      0x49a85ce8      0xd61a285d
+       0x513bd0b9      0x21bde48e      0x4f231482      0x93aa6dde
+       0x88035659      0xa83e3d2b      0x542513f8      0xe6e74a1c
+       0x06092343      0xd37c8770      0x41553ead      0x09980a79
+       0xb0e45895      0x80db4662      0xa6ce0960      0x965cfa7e
+       0xfea96644      0x2a79157e      0xf020e115      0x61823e96
+       0xf14f63d7      0xd753d1bd      0xd24a060d      0xfd2691b9
+       0x18da9d0e      0x9f3c93c4      0x2730e0f2      0xb47e2afa
+       0x920fda38      0xb5d89646      0xfb4728e5      0x7e78c2cb
+       0xe46f812c      0xe51cc5c0      0x9d2957fc      0x548798a1
+       0x240c2103      0xd650ff70      0x15c49ff6      0x99587c0a
+       0x1bb4a5ca      0xd6db66e7      0xec2d3ac5      0x54164690
+       0xe61bd6f8      0xc7a45cf8      0xee25f4f4      0xd1eb3ae7
+       0x90085a1b      0x46a7a74b      0x829717f2      0x7f0769cd
+       0x3ef72792      0x0c8617a7      0xa86becad      0x9dfe5329
+       0x1a33c5a6      0x47d4c75b      0x2e10b45f      0xbd11762e
+       0x15b72a9b      0x015c7f84      0x379c6bd2      0x27525345
+       0xff3ac5a6      0xac916082      0xf5c24317      0xcc43fc64
+       0x7f092c8d      0x931d9a0c      0x5a07f13e      0x3e1aa46b
+       0x717a343f      0xd51221c4      0xc9422fcd      0x63f7af00
+       0xde81a497      0x0322d271      0x972a4065      0xd75df029
+       0x343a94a0      0x8c225f7d      0xb4abe87e      0x3cb8ba1b
+       0x0babab14      0xf29704e7      0xd7134233      0x391f1a35
+       0x33aca565      0xe6ae586b      0x0470a42c      0x570efddf
+       0xfea26a3b      0xcee8d934      0x99ece522      0xb8af1375
+       0xfe4dea4b      0xb96a32c2      0x3469ef9c      0x029fade7
+       0xc4e77d55      0xc0449b95      0x63336e95      0x8d46c2e0
+       0xd86d6e23      0xd365b781      0xe73ba0fe      0x10a354c5
+       0x2d4511a0      0x077206cf      0x1c0dbd55      0x03396771
+       0x8bce27af      0x70355b4b      0xc2275e58      0x3cfa4df5
+       0xc8b3b9b8      0xf3fd510f      0x6b055de5      0xb3fef295
+       0x42b95a20      0x5b5e75e7      0x0aaaa734      0x636d50ae
+       0x8329283e      0x446e76f3      0x6adc320d      0x69a3e9df
+       0x1da68939      0x6f071783      0x498dfee5      0xaece51ed
+       0x4f8a72a8      0x4f2f2f65      0xdac3ba47      0xcbab0287
+       0xf966cb4d      0xba27861f      0x54c79a21      0x44e2359a
+       0x6e6b0e7f      0xceae84fb      0xb1530a59      0xecb8cd96
+       0xff60633e      0xed748fe3      0xf1ab0d95      0x59997216
+       0x6894cf41      0x948fc7bc      0xfb162ae5      0xeb9951a1
+       0x99d0a7a3      0x9234587f      0xcd42615b      0x6f9ad0e8
+       0xeb936dbe      0xbe72b62c      0x44ab5e9f      0xed736b08
+       0xffaedca9      0x103b89bb      0x7896b40e      0x13a5a924
+       0x56786357      0x02ab80ec      0x72ef47fd      0x81bf0fd7
+       0x6661b300      0xaefadc79      0x9968433a      0x16f3718b
+       0xe997a663      0xbbb55a49      0xf9b9a710      0x5727271f
+       0x20e9bf55      0x358e3986      0xd1214e1f      0x4d42c46f
+       0xa6bf8194      0x0c14a853      0x7b51aeb0      0x2f3d4de4
+       0x3d6ffef6      0x4e94ba19      0x71a9c861      0xcade2398
+       0xe0b3eb18      0xc9f028b0      0x7d29d2d0      0x372ec60a
+       0x288a5bfd      0x4fc2bab3      0xc01dd045      0x8222e147
+       0xe06676de      0x750bbfea      0x586ffb3d      0x2addb655
+       0x767a6528      0x78abceec      0x1646cb38      0x21e26890
+       0xd2a7937b      0x2463457c      0x764103fb      0xd540867f
+       0x3566875f      0x007449ba      0xf9c0c523      0x2c51c86c
+       0x437e1196      0x69fc0059      0xe0103408      0x19f23997
+       0x23fdf335      0x7262eef4      0xcbe09390      0x583d0099
+       0xe862084d      0x19fffbab      0xd2958a5a      0xcb165416
+       0x32f3a97c      0xe502303a      0x16c4eda5      0xa1bcfd1d
+       0xc4f35053      0xfd037f66      0xdeac9fee      0xbfb167b1
+       0x39804db6      0x0bc2011d      0xf56bcd68      0x368cb345
+       0x52fcb352      0xc306c535      0xf6bff09c      0xa429cbf7
+       0x7e504be4      0xd2240214      0xf09ee41f      0xcbcf1fe4
+       0x70f96a85      0x8394bf28      0x3cc19a50      0x49581f96
+       0x58da5ae0      0x94708c48      0x63febeaa      0x4f656940
+       0xa7fd6879      0x65524f66      0x5f7ee0df      0x11d487f9
+       0xb494641e      0x7eb57255      0x5aa208c0      0x5666243a
+       0x7d5970b5      0x71ea69a1      0x67059c9d      0xd3bde5bc
+       0xe952b3fe      0x27bbf258      0x197504f4      0x5da6649d
+       0xecddf4de      0x2d040d3d      0xbc9d3ab6      0xd8cdfb81
+       0xb36ab627      0x7a548111      0xaaeefa4c      0x0e55b263
+       0x4f9da6e6      0x26a137dd      0xdea03395      0x23b87267
+       0x5b3cc98a      0x206de858      0x8d2e5cd2      0xb60f14e6
+       0xfc10356f      0xeecae1d5      0x39783cbe      0x1a1c9a70
+       0xb52c6f05      0x64adf10b      0xe12d9f3b      0xb3fb7cf1
+       0x9051fdea      0xc16ed3bc      0x697199b0      0x08f34342
+       0x2fb2bab6      0x729ed2b8      0x7691088b      0x82bc9cc1
+       0xafce7ac3      0xe167bbb9      0x362e5d43      0x945510ec
+       0xf32dce5e      0x4aec9a82      0xb80520d3      0xd8fcbe40
+       0xf4877350      0xcfdd487e      0x8c9ff8b5      0x84ce70df
+       0xffa6abd3      0xf9d2f273      0x342dbff8      0xa72580e3
+       0x6ffccdc3      0x0c7ccc0f      0x6b24afd4      0x82b71a25
+       0x1ba361f2      0x6ed8a67d      0x243ce000      0xd16b2e19
+       0x86d3c3e6      0xca209063      0xaff0b983      0xf411f71f
+       0x0f2ca724      0xa6fb0fb6      0xfa663640      0xe40fe20e
+       0xf8e2a5cc      0x1a0e8862      0x11de13a4      0xc811e4a7
+       0xfe6fa8e6      0xfefce644      0x8f7fcde9      0x94477c62
+       0xec9b942f      0xfda6b166      0x91330c4d      0xd059d679
+       0x96b0f7a1      0x22df13ce      0x3f36c3e9      0xc814e342
+       0x7b7dce7c      0x1000640a      0x8cbe7a56      0x622fa655
+       0x209d82d7      0x55668514      0x1534f8af      0xc2b7dc1f
+       0xd89da0dc      0x3ddfe751      0x0532dfe4      0xd39c360c
+       0x090f91d6      0x48587117      0x8ee383fe      0xf5ffdee4
+       0xd8bca448      0xd26d6d82      0xe8adcc12      0x8b14b8c1
+       0x7f872f36      0xb8cb0e16      0x76d60c06      0xf62ddbec
+       0x3ec7c151      0xe418a789      0x920a3bf8      0xc5b62e09
+       0x4974ea7e      0x0d8d7962      0x5bbb246a      0x37183d1c
+       0xf25c63dd      0xb15730a5      0x903e3400      0xdab426eb
+       0x0323289f      0x9bc16f49      0x2dfd02a1      0x3ab916a1
+       0xcb6f770a      0x342021b2      0xf9f5c9c0      0x9c8d53a5
+       0x3d53f39b      0x8e693c58      0xebecc732      0xbf30c538
+       0x96648d11      0x60f62751      0x29745559      0x8e365fb3
+       0x7d0b1179      0xea5abbb2      0xe45c4af0      0x53056b1d
+       0xac7b03dd      0x7015c355      0xf17f8dfd      0xe1ace271
+       0x9abacdc0      0x5ccedc75      0x478c717d      0xc01dfdad
+       0x26fb551f      0x73e61f00      0x8bc0b111      0xb6855743
+       0x28690dc2      0xf13b6766      0xc098861c      0x5c0ffa55
+       0x271e7d0c      0x66b47b80      0x9921a158      0xd9c560d0
+       0xb29b6ee7      0x50a9bc97      0xbec4d91e      0xdb2c1fcc
+       0xdf215786      0x1541e380      0x59cae516      0x2342b2ee
+       0x8088cd9b      0x7312579d      0xb17be14a      0xa1638c41
+       0x805c6b18      0xb8a56151      0x56f0a6da      0x96b114d2
+       0x0845ea7c      0x23e8f7eb      0x4e88e7ce      0x84640f2c
+       0xacf8eebe      0x4039725a      0x49bf9982      0xfbcfcbd9
+       0xfbbfb1c1      0x8041659b      0x5b8ee4f3      0x1b6d7a38
+       0xeb634fc4      0xbf818ab6      0x8076c921      0xc50be762
+       0x24c43f4b      0x3252acca      0xa7528630      0x9885b151
+       0x9154b37f      0xfd9d3ab1      0x4f93c117      0x578fba44
+       0xa56851fc      0x9d8083de      0x769f6fb4      0xd89fec27
+       0x747c8071      0xe6b2b747      0x8196e2a8      0x3ed6c699
+       0x8716f1df      0x65325e96      0xfbc715d5      0xb06f9171
+       0x7aa9cbdd      0x84bda56b      0xdeab06ee      0x80432d8b
+       0xd76f0a57      0xe0ed5f9a      0x70f991a2      0xf1a9e557
+       0xcbecbcdd      0xcf0d91fc      0x6751fd67      0x590f206a
+       0xa26d8130      0x1df02179      0x826303ce      0x6cd58190
+       0x1219d005      0x4bb2f3b2      0x0dbd8193      0xd8d8f582
+       0xa5867eed      0x2d6b8ec9      0x5f85ec18      0x7983775a
+       0x214ca0c1      0x9af3febb      0x213d6568      0x2f8e8c43
+       0x92add018      0x6e33e00f      0x6fa6834f      0xc3c2cbbc
+       0x1c65c8c5      0x1827f812      0x868d3a09      0xdac83ade
+       0x57623da5      0x5ff83257      0x0992e621      0x25cc9ca9
+       0x10580130      0xff2ae8fe      0x40a58253      0xffdc24d5
+       0x3e4dbe68      0x291b11f7      0xb3594b9a      0x570c7b6d
+       0x38d31bd4      0x7155ba24      0x84d56490      0xd98842d5
+       0xe037d2f6      0xdd2ba821      0xbeb861d5      0x0fda5758
+       0x5921c665      0x98c7676d      0x8eee487b      0xac0f2411
+       0xb332d321      0xa0816c65      0x76edde5c      0xab868b36
+       0x3f8da4fd      0x516af4e7      0xabf748a8      0xbe7820fc
+       0xbf763827      0xa03a3566      0x8a63e804      0xb4f8f901
+       0x5d262ee9      0xaf905cf5      0x896d0c94      0x5f992cab
+       0x81c2faf9      0xda3c686a      0xb01a06dc      0x45ef0c90
+       0xf2ca525f      0x0e74fe18      0x36ecdb11      0x494125d2
+       0x226b4aab      0x3e92ae29      0x5bb48774      0xc2c2ef90
+       0xa9e77d5a      0x409db546      0x7728f003      0x72229503
+       0x2e8febab      0x8322cfbc      0x5eaf74e9      0x621837f8
+       0xc70668d1      0xb25c1325      0xd741c010      0xf52e3166
+       0x71ef7a87      0x74cc93a4      0x7c25ecf4      0xb8b8e20f
+       0x3658c239      0xbc58fba7      0xf13ec858      0x9271b2a1
+       0x37084dd5      0x6fc92e82      0x44a6abe6      0x92b9238a
+       0x9ad3a57e      0xd75daf92      0x8ea573d6      0x69ce1fb6
+       0xe80df5f2      0xcc1c6ae7      0x6d565a77      0x6981ae63
+       0x18af1922      0x6e8a7af8      0x10716aa0      0xa7da9970
+       0x1abbc7cd      0x114f814a      0x4ebb0c07      0xc8fe6a69
+       0x93d7bc2e      0x0a16181c      0x0379c950      0x4b2e8c18
+       0x670b83f8      0x82a75eda      0x6eb772dd      0x42cfe197
+       0xd91ec29c      0x29fb4812      0xab693ead      0xb2f25a1c
+       0x0b9df6cf      0xb7a1aba2      0x1d7d90bf      0x7de14655
+       0x649965f6      0x11fbe065      0xa54ac5a3      0x418bd3df
+       0x4223c00f      0x7bfcf9ae      0xbd979739      0x6a2ee697
+       0x54e7d9c8      0x73803bdb      0x06654716      0x72225136
+       0xfaef3873      0x0b4b40dd      0xd3b98b57      0xc56cbab5
+       0x32174c47      0x4d4d8c32      0xd6f1bf93      0xeefb6950
+       0xb84ed0da      0x590723d4      0x2d006f09      0xc4bc139c
+       0x55434982      0x8734189f      0x0e314a50      0x94340d09
+       0x021c24a4      0x0b0f022d      0xa61f9025      0x71eb72b6
+       0x744ccea1      0x2030b859      0x78203d74      0x0b8a8389
+       0xd5211777      0x2609edfc      0x6134eede      0xec74584f
+       0x0bdb2d06      0xb1768f76      0x56221895      0xfc49bdae
+       0xbcc6e6ed      0xfeb19c0c      0x18652996      0xaa1a0164
+       0x3ffdcb94      0x2dc1b090      0xb68bf220      0xc33b967d
+       0xc907a1aa      0xa3968cb1      0xb3cc65e5      0x33e2b077
+       0x2bb22904      0xe0fe8fc2      0x4affcc46      0x6b0f0bbc
+       0x5d1bef41      0x2de11c7f      0xb0d864ee      0x6e96d8dd
+       0x59c1c108      0xb2544572      0xab3400af      0x604aefcd
+       0x81be22c3      0x6741e6ca      0x3a93dc1c      0x7b10e639
+       0x0add7a92      0x39fc1df3      0x884f150b      0xd666a96d
+       0x87da0c1a      0xf0f73c15      0xc0c00957      0x011ba61d
+       0xa77e9463      0x96020e4e      0x92416e99      0x881e89c4
+       0x46981327      0x3bc624f4      0x57f226f5      0xac340cd8
+       0x3ce239b2      0xec6b33bc      0xa9123e11      0x70640b6b
+       0xc30f59f0      0x411576fe      0x5ab12c3b      0x3cc20b85
+       0x924b3be2      0xd1fc7a28      0xa4b0cf7a      0x88098404
+       0xbbd331e3      0xff2b6047      0x2a1ab042      0xdf220849
+       0xaf774ae3      0x5a8da79d      0xf18450c8      0x8e6e235f
+       0x1dd3c039      0x1a867ae2      0xe4ccd1f4      0x50dd3f39
+       0x8be186ba      0xc7e30fe2      0x17552d4d      0xffac16e4
+       0x4094bbc4      0xc18a2513      0x650e707f      0x8ecdbba2
+       0xf53e8e7d      0x047dbce2      0x7fc2a89f      0x07628f94
+       0x2a8bfc67      0x0d738727      0x7b5c2fd4      0x2c89d27f
+       0x47f37a64      0xc63debc9      0x15d6c414      0x242c300a
+       0x645d95ab      0x29e1a49d      0xaf77fab1      0x643b4cd5
+       0x3e0f63db      0x4f7cc43a      0x33d6797b      0x497d4332
+       0x7160786f      0xe0c5b75d      0xfb08ecb2      0x26063065
+       0x9835bf7c      0xf5465591      0x63155d2d      0x14babba1
+       0x384a0879      0x460db3b1      0xcd37760b      0xad675a77
+       0xf1dceded      0x69df690a      0x44c6f456      0x87d6a7a4
+       0x4e0d6504      0xf967f55f      0xca9bb20d      0xd5eb41f6
+       0xa9aa9b2a      0xa907387b      0x965b6f23      0xdcd47eb5
+       0x43b5b1a0      0xec876728      0xee7339e8      0x10c5ee16
+       0x1bd8c0bb      0x7235ae07      0x063e3564      0x388d0bb5
+       0x80f9a9f6      0xaf96f714      0x6895c899      0x00ad21bd
+       0xee67961b      0x873781a9      0x22cf435a      0xee90cf3e
+       0xc9a4fadd      0x9bc1af4c      0x35c0e803      0x211ce71a
+       0xb9af86bb      0x97828ab5      0x9dbd002a      0x1cc981c7
+       0xefb36876      0xea739a75      0x5d5abcc1      0xd42260f2
+       0x95083e0a      0x31fb0b51      0xf243ab8f      0x628b1913
+       0xe74eb210      0x620b7d9f      0xc81666d2      0xc8fd1ce1
+       0xf054bd9e      0x78ba7618      0xe1df4e38      0x5e381b3a
+       0xcc68da1b      0xb3ce70ac      0x7ecda229      0xf8778140
+       0xae823fa1      0x12af1708      0xc9373879      0x1e687d29
+       0x96062069      0xf1bfde2b      0x999ff6c0      0x8cbeddf0
+       0xc825a2bb      0x78106bbb      0x87a964fc      0xb358ec2f
+       0x4d959300      0x0fe9706a      0xabb1d003      0x72b65294
+       0x43816b1f      0x6c83b958      0x5549567c      0xb474aa55
+       0x98851640      0x751a670f      0x25900026      0x2ab174e3
+       0x1952c3dd      0x38b47c29      0x32c0af52      0x460c8fad
+       0x85a1004e      0x8cbddcd7      0x66578310      0x4904dcfb
+       0x04b7a746      0x00c91fb7      0xb1ab2edb      0xd0178ae2
+       0xc4b8b57e      0x981d4753      0xfdd8939a      0xa8a05055
+       0x47c8c30e      0x0fab4f6b      0x6ea54079      0x23dc4151
+       0xc23e83aa      0x2ed2ce8a      0xff95b763      0x08df1d51
+       0xd16d104e      0x0fa3ee3b      0xdcfe8541      0xa0622490
+       0x085e5c0f      0xd9bc007b      0x24794e89      0xce341d16
+       0xf090a98c      0x317150a2      0xcc036257      0x3296722d
+       0x9c8d4f58      0x7ca5f53b      0xb0e4f9d4      0x1f178bbe
+       0xc0dcde7c      0x18551596      0x0507b8e2      0x3c40a8ca
+       0xc632f82b      0x5d1965f9      0x92a00465      0x13a8ca32
+       0xc0b6756f      0x669d706c      0x58056b22      0xaa25fd37
+       0x128b731c      0xb141ed31      0x0a8d3ddf      0x48b63bd1
+       0xd24c5c4e      0x0ccd96b8      0x4b1ff726      0x309be62b
+       0x26002e68      0x436f2bd0      0xacb62068      0xce098f50
+       0x330e6160      0x434da66d      0xce14054a      0x0a877e41
+       0x705eb2fb      0x8433fc7e      0xc1bd475b      0xb550de6d
+       0xf4faf808      0x9f9b6ebe      0x0ff98ef7      0xace2766f
+       0x01cc9606      0xd9654327      0x3544cf5b      0xbffbcd80
+       0xb4a5948f      0xcded4d04      0x69ef5a24      0xf5ae46de
+       0xe2139499      0x549f82bf      0x2cdfc6b7      0x5fdd2462
+       0x63c68a37      0x8bce0d04      0x9c66ae30      0x9fd94951
+       0x5774366d      0xd671675a      0x5582f253      0x436c5b6b
+       0xfc151e77      0x1974df45      0x5ea9eac2      0x30689b8a
+       0x9806681a      0xb74d3ec8      0x4f207181      0x668b4951
+       0xb06514b2      0xeccffed1      0x16188ff2      0x5914d385
+       0xed4b7023      0xfb0640e8      0x179adcda      0x6e806687
+       0xb4f0ac07      0x35813615      0x143e66b4      0x1b012a50
+       0x384f31c5      0x1500dbca      0x06e47afe      0xa8a17374
+       0x9d0f5c57      0x4574db82      0x91b3680e      0x794683a7
+       0x30c25d5d      0xf8748c08      0x2e601dfc      0x553152f7
+       0xec5d489a      0x4bd37616      0xdc04dc7b      0xf0a35ba2
+       0xb36975db      0xbfe6f98a      0x6d744996      0x5507380b
+       0x4191e01a      0x0092c384      0xcf3a4388      0x6b0e89c7
+       0xded7b820      0x1fbd6bba      0x3af210b1      0xfc4a608e
+       0xa920eb22      0x22db2d65      0x7d6f0447      0x090f3679
+       0xc4c759cd      0x9758aac6      0xa63251a9      0x47b7a974
+       0x65421071      0xdca8495e      0x96f879d7      0x1d22ea6f
+       0x46dd72ba      0xe0c59ccc      0x15737309      0x6d945f11
+       0xbcb15c8a      0xb11ef0b9      0xe2072633      0xccbd61dc
+       0xfcb51c44      0xd2315c65      0x3087a6f8      0x5609ee34
+       0x94c7f951      0x0a057b31      0x6e6f2733      0x179facec
+       0x36c005b9      0x60184919      0x50b3db1f      0x7a827d7f
+       0x88755ecc      0x3fb0d6c3      0x63b150d4      0xe2ec3004
+       0xe0ee30f1      0x118d7040      0x2f4689e7      0xa78be0be
+       0x3c9bb853      0x75c326cc      0x84097407      0xb0107b5e
+       0x83a56a91      0x14e60445      0x0fa72553      0x1385e6ce
+       0x9b8bbdcd      0xe6aa6a9b      0xc2072ccc      0xee916592
+       0xe44082e1      0x43dbf6d8      0x09f821fc      0xdc84b023
+       0x0e6a518b      0x945fb180      0x185d0841      0x9ece88f8
+       0x844558c2      0xed85f422      0xeceb983c      0x6db16826
+       0x7612b243      0xee3bf226      0xb8eebb7b      0x22e16615
+       0xc892bb7a      0xdc475a47      0xae390e93      0xe00baa1b
+       0x725fca23      0xbb868b3a      0x17c62a69      0xeccd3731
+       0xbe1a4223      0x05c8fd7e      0xa8354afa      0xbbb09f8c
+       0x31a77e83      0x01f17a68      0x5f37c847      0xa0fdd7db
+       0x9f8da870      0x98f02167      0x1e966884      0x00e19b81
+       0x50c91add      0x6aba2a55      0x60be9575      0x3da40b37
+       0xde13ff4d      0x5b7a79ec      0x4700ffd9      0xfee5ea61
+       0xaf4d1d1e      0xfccb6f04      0xcf5076d2      0x48c4c98a
+       0xd6a8915e      0xe4a58522      0x6bf3a6a9      0x4e7c2f15
+       0xcd7e8d2f      0x843b56b1      0xa35f1a5d      0x1ca226dc
+       0x917fb163      0x44751f0a      0xd96fa8aa      0x5028dccc
+       0x7792dd96      0x2a9d749d      0xe48385fb      0xde111e91
+       0x805e6581      0x3d9b9fad      0x5b750544      0x03785b71
+       0x9b583214      0x80022658      0xcf1f3730      0xa1be7be7
+       0x6c1e26f2      0x26de584b      0xb4fc8e35      0x072b520b
+       0x55db3ac9      0x81e9d490      0x4b5ea53e      0xd5628e00
+       0x71bfcac3      0x79956bbf      0x275fab80      0x2ad497ed
+       0x423854b2      0x686451ad      0xfd59d64e      0x9f2049d7
+       0xcb0f8f32      0x74d7545d      0x4f9c1df8      0x6fbf0afa
+       0x7ef06915      0xc5117549      0xf20088b4      0x731a5ccf
+       0xe78bbe74      0xdcb4996e      0x7062a6f1      0xa624b59a
+       0x7b2d5e41      0xc1065234      0xa7c32078      0x367e7134
+       0x86f55f58      0x3084ee83      0x0c599d1f      0x69380e2e
+       0xe59482b3      0x7096432e      0x81124388      0x5be8d01e
+       0xeb25ec24      0x8b47e9ad      0x432216fd      0xdc496dea
+       0xcb05fefe      0xe76eb9ab      0x8ed568d2      0xfa963d68
+       0x70ed6f4e      0xb2b88d58      0x15fc42bb      0xe992ec48
+       0x359856b3      0x4a0f7741      0x3f0b6eca      0x07c16950
+       0xcb9dae59      0x209570c2      0xf196555d      0xbf7c0a0f
+       0x4a814210      0xf8f206c7      0x8bbb0763      0x360fa596
+       0x13d46195      0x901170e8      0x6dc2e376      0xbfa00989
+       0xd12cab90      0xf4f4699d      0xbc88b362      0x4827dbd5
+       0x7cde5cf5      0xe45dff5e      0x2d661b05      0x8902d99e
+       0x6c9f3584      0x0db3f864      0x1132773f      0x3e944120
+       0x27058ae1      0xef978864      0xe58eff42      0x020ae503
+       0x77fe075b      0x9c577e08      0x210b42b9      0xcb8160c0
+       0x09f99f36      0x6a0b6bee      0x6f18b0ef      0x5452ee3f
+       0x6c8c4a4d      0x480cb803      0x892f3973      0x066dbb63
+       0xf7f845c8      0x7ceeee7e      0x7c26c5ce      0xec89119a
+       0xc64bdc20      0xf46e4324      0xff34c833      0x555b4b3c
+       0x23ff2701      0x52360759      0xf60acad8      0x241ccb7b
+       0x29e14901      0xcc068e2b      0xedd0ee02      0xc33a425d
+       0x7d889b28      0x88577f8d      0xaaf614b1      0x8e8c8eb5
+       0x81a363f8      0x29f5bcc6      0x08aeb8e9      0x6f9ee222
+       0x1c50045b      0x792c9434      0x62bc2601      0xc9289175
+       0x374fc38c      0xbae91a86      0x3268e89b      0x5b008f10
+       0x0ea6b759      0x9d43ce10      0x09b30dd2      0x643e2b94
+       0x5c19bafb      0x29515176      0x56a81f95      0x60a80534
+       0x22fa0a73      0x1259cf8d      0x323fa5b3      0x6322f1d0
+       0x30581c47      0x50458048      0xd711c1b6      0x4a34236e
+       0xb60a2e40      0x58df96c9      0x947b90d7      0xd327d664
+       0x5fe528db      0xf6d9c575      0xb0a251b9      0xed961301
+       0x2fee3cf9      0xb687e226      0x78fc46c2      0x29e9fef4
+       0x84bff086      0xd0482ed1      0x018996f1      0xb8b9cdf8
+       0x20885e68      0xa6f848e2      0xfddabc3e      0x5c9a7f67
+       0x7cbc3e40      0x5197ebe2      0x41a15775      0x8024fd2a
+       0x7864106f      0x7cfaf482      0x27798720      0x4956355f
+       0x30f7195e      0x6ea09dd6      0x6f2b5f3c      0xf38df38e
+       0xcae7e8cb      0xf8a80b0b      0xbeb227ba      0xbbfa2428
+       0xbbba3ab6      0xbf83edbc      0x2cdcaa9b      0x2b0841a7
+       0x79d52e5e      0x40260460      0xb27709be      0x07e3bf6a
+       0xbdccc2b9      0x369d0069      0x9d745e50      0xff251486
+       0x1e14957f      0xf7253467      0x9a31eeb9      0x4d77108a
+       0x44fefc47      0xd02d4082      0x232e3fc1      0xce39396b
+       0xd7a13714      0x2bd57e7e      0x00876803      0xee73377e
+       0x78bb6240      0x2ae63c46      0x11e009d2      0x922539cd
+       0xf3bef05a      0xf0c664c3      0x6e132a0b      0xb0c5bddd
+       0x40c66494      0xd7d0d02a      0xa73110d0      0x4b409d78
+       0x6f49bf88      0xcfc9d22e      0x4836da89      0xde5a80be
+       0xb9c8bdb3      0xe99b2e9d      0xf1b05e68      0x8ab599fc
+       0x22675035      0x3c8480c0      0xfa3cd457      0xba617098
+       0x422eca1c      0x0cdc0d01      0x4779b95e      0xccfa0bfa
+       0xd22674a4      0x76462be6      0x3015ab3b      0x7891688e
+       0x1c83bf8b      0xaa55839a      0x7a71a83f      0xad451c1b
+       0xf8b8bf06      0xc75a91be      0xcac50366      0x87e365ae
+       0x9013ac11      0xe9cec5a5      0xef4d88f5      0x15c27162
+       0x3dcaf8ae      0xe023891b      0x7b6f1706      0x2f1198e4
+       0x048e34ba      0xb647b5e8      0xa1826caa      0xed3bc134
+       0x43b14d28      0xf0c49b54      0x1a6362d4      0xc77fa378
+       0x3bb12e79      0xcba4cd2b      0x620f2476      0x7729add6
+       0x9876c439      0x5f7d8795      0x858f7ac8      0x68b94589
+       0x1321d70b      0x5353a2fc      0x912a5ea4      0x390cf0f5
+       0x37320473      0x51b3cacf      0xe45046d2      0x9188dcc5
+       0xb3713b54      0xc9b936e3      0xe9f24574      0x5977a68c
+       0xc23c56bd      0xcfc39ca9      0xc891b8d0      0x3683ef22
+       0xc1ce304a      0x3ebf1ce1      0x52cd1cc0      0x3777d973
+       0xde614072      0xf2efe226      0xbe1f9f9b      0x92a1896b
+       0x9ca62763      0xcf5703be      0xa6d9c56a      0x185260d6
+       0xd9e3b86f      0x5c47180b      0x71a7a219      0xe9974375
+       0xf22af4d3      0xfbc92962      0x968c3fe4      0xc584b60e
+       0xb9abee26      0x7e9737d8      0x5947da83      0x2f8ccad0
+       0x7b4ee942      0x51ad62dc      0xf517400c      0xe2bf9e37
+       0x63057e05      0xe1bfabf8      0xbf118805      0xc038de9c
+       0x7aa57b7b      0x05584eff      0xb15ea286      0x26c6a6c0
+       0x8e1392e8      0x7dbf22e1      0x3546f5bd      0x0f84ed9b
+       0x0b01da4d      0x6dc47417      0xadc6f687      0x4160c045
+       0xdc26765f      0x63b70c6e      0x8f177107      0x6a5f13cd
+       0xb56fce56      0x5d1f5ed1      0x62f6a18e      0xf7235691
+       0x222fa999      0xd48b1435      0xe597d406      0x8dacf828
+       0x694ecd8c      0xe5283c02      0x60bcdcd3      0xfb9eb384
+       0x9895492c      0xd38172dd      0xe7b6dff6      0x0ead5894
+       0x910e2675      0x97d9ee09      0x270b2d8a      0xd03e25e0
+       0x9e7bbb69      0x57ab1d31      0xf2e7a13d      0x9c8e5baf
+       0x65fa03f4      0xc66bcbfc      0xf2d8bfe1      0x23059412
+       0xa3ae7654      0x3a4734a3      0x32c0a8d3      0x4e007b8a
+       0x5ce30660      0xbd10c57c      0x5365f540      0xeaed3002
+       0xc377d84d      0x87097a59      0x929edec9      0x5878368b
+       0xbd450478      0xc3fab275      0x128fdced      0xb706fbb5
+       0x146f1d41      0x86782651      0xa530ca29      0xa3e1b6be
+       0x25390048      0x572b4a05      0x8c9b4c90      0xb05428cd
+       0x33fabab5      0xd16e513e      0x1d6cc812      0x4d80a6ed
+       0xd6a5a07e      0xc0ee4c19      0x544b75d1      0x3f887360
+       0xb2f46d1d      0x21609cbd      0xe340211d      0xe9202fb6
+       0x3023b005      0x3341ead9      0x76c99537      0xc9d76547
+       0xfb736c3f      0xf6385346      0x93fe2a05      0x92de6df5
+       0x7793acd1      0x68249b3e      0xc22cae3b      0x668988e0
+       0xdc1ea28c      0x7ef72b95      0x974098f9      0xb214701c
+       0xc2de7d98      0xeb1d443e      0x5975f0ec      0x21d67037
+       0x721e8e99      0x42105562      0x74b1e821      0x20193b2c
+       0x743a7bb3      0x24643c9c      0x240b331c      0xdf125e2e
+       0xcb4b0205      0x19edb174      0x505eb85c      0x1830bf22
+       0x6bf7a528      0x86a7281d      0xfee3488d      0x6c26f4ab
+       0xbff4ce7a      0xff7cfaf1      0x5df6fd66      0x523f0802
+       0xf8a87595      0x463b5c19      0x72c564fd      0x2e4797d6
+       0x1f04a1af      0x0be96baf      0x44552094      0x2a158f50
+       0x83dac587      0xad4c881d      0x3178e710      0xe938d1be
+       0xab715a65      0xc34b451e      0x1942832e      0x91557ecb
+       0xdaf0606d      0xa64623d9      0x84e11fbb      0xa9c9d11b
+       0x577a15b1      0xd49a2f23      0x6f204e0b      0x0a6e6a2f
+       0xdaf13637      0x6b4ef557      0xdcaac9a3      0xad97c404
+       0x8471691a      0x50ca3cf5      0xde57c446      0x70aa02f1
+       0x84baa6de      0x0232bc79      0xa06427af      0xd2ce56be
+       0x5da13949      0x254f5f4c      0x3fc3fd02      0x00b5f8eb
+       0x54a0d4b8      0x5e3ec3b1      0xc6718376      0x5acce6d8
+       0x614c56e0      0x89a6b00e      0x6cb4e087      0xa9822fe9
+       0xdea290c6      0xb294582f      0x36f9640e      0x30d0afc4
+       0xef7d75b9      0xfd9aae2d      0xd6729573      0xac442321
+       0x158224fc      0xfd6632df      0x10cebf98      0xc3864dd8
+       0x31577c58      0x49e71f9c      0xb96d876c      0xd867604e
+       0xba74c3f0      0xad69752f      0x716eb51a      0x469d9d03
+       0xda4b2e16      0x9e80a908      0x9bcb18e8      0x2f1c595a
+       0xe823ecfa      0xdfd5badc      0xe460e9e0      0xae418438
+       0x457811b4      0x29df713a      0xd90b0d29      0x415ba2de
+       0xa0af6489      0x4922a50e      0x2efa0b0b      0x9394e4cc
+       0x0ef8f59b      0x0f851711      0xa4670f3b      0xcc6bbfc6
+       0xae194dfe      0x78e51752      0x4c65a2d2      0x1b0741cd
+       0xc9f401c0      0x4a678062      0x290d2bc5      0x1a4279c4
+       0xb5f9160f      0x40ef7c77      0xa9bcfba9      0xaec75f21
+       0x53d6258e      0x8587eb74      0x0721d492      0x2c6a6e2d
+       0x8e6cb70e      0xa6bee309      0x6faf5706      0xf8eee239
+       0x52c85943      0x8c198893      0x3db37858      0x557fbf2e
+       0x92f1a0e5      0xbd279594      0x46d65132      0x90a2c32a
+       0xd11db660      0xc73b3922      0x9d1075ff      0xdb80a1cb
+       0x54158743      0x39694d0a      0x4a0ddc7c      0x721f9dc9
+       0x04b1b044      0x3bb40aed      0x6be7a88a      0x429a3b09
+       0xa6e9dfa8      0xba412f0c      0x354f08d2      0xa4569516
+       0x928cca34      0x398b1a99      0xb7e80291      0xe67d7b71
+       0xa6582bf0      0x556ebb23      0xdc6d9f6a      0x11b3b753
+       0xbdf31ae5      0xd3399560      0x6148cec8      0x5188689e
+       0xde18f46b      0x3da414ad      0x4c44ad29      0x68582541
+       0x75c8b1e6      0x7ba572de      0xd753ed20      0x4a9c4578
+       0xf1c9159d      0xcfd9da31      0x46799fbe      0x1aee4426
+       0xdcdf7b57      0x327db61b      0xa160ea1c      0x84a01fc2
+       0xbe0aa020      0x5963688b      0x24f32751      0x885b4177
+       0x26cde88c      0x39e6df90      0x1c7fee90      0x882a5c0c
+       0x56f1f2e0      0x10bb9f52      0x4f0502aa      0xeae6e5b9
+       0x65e7ee25      0x8ed230ac      0x38b5e02c      0x5f5311f7
+       0x929491c0      0xdd923e62      0x5bc6166e      0xa3c89f4e
+       0x5844fb12      0x0c40f02f      0xdda07582      0x8ca1b803
+       0x9398b0d0      0x4dba17f9      0xb9879c85      0x26956147
+       0x3c26a130      0x58cdc52b      0x21fa4801      0x9d965ce6
+       0xb9942dac      0xd83d1518      0x36e630dc      0x50bb2822
+       0xcd472a65      0x6feee2f4      0x4853b680      0x7f54945f
+       0xa522c561      0x28134f6a      0x89b46cb2      0x4fe0047e
+       0xad602b28      0x4942494f      0x1536ea37      0x40ea6278
+       0x5020bdb1      0xad3c9f7e      0x1356d0ce      0x411700c8
+       0x1ba61954      0x65dece8c      0xb788efb9      0x26efcd5e
+       0x9833fa21      0xea0052b8      0x119a994f      0xa71b168b
+       0x164a96e0      0x0bd1b4e9      0xaae1e562      0xb550f48c
+       0x3a3b55e1      0x4d921246      0xcb28af65      0xdd2388ff
+       0xa63988c3      0x7dfa5a8b      0xc7c44102      0xc75e9f3a
+       0x5e4305db      0xacb34d1c      0x9b50976b      0xad3f6379
+       0x6cd20ee3      0xba806f21      0xcd0fcf4a      0x18a55973
+       0xbafe5266      0x03ee9b8c      0xa35fbfde      0x7f2eb71b
+       0x23d9aa11      0x0e183c35      0xefb0ae3e      0xc6093786
+       0x5b380af5      0x64838229      0x3bd69926      0xe9758e1d
+       0xde439e4a      0x0cbc4bdd      0xda5858e8      0xbe8afc07
+       0x676379e1      0xccc4c628      0x763e3b38      0xb4823c67
+       0x9f4aa538      0xd8d33f50      0x41291e48      0xaed28ade
+       0x6c72eea8      0xa751f4e8      0x3a75dba2      0x5073e3bd
+       0xf10b4756      0xdf46ab98      0x9ad689f1      0xc2ba74a4
+       0xf2ce9419      0x4cf9732e      0x75cf58ca      0x249e3c52
+       0x95d10a93      0x51120008      0x7438d467      0x0a5e7f2d
+       0xb7a44e46      0xe31e5dee      0x26e2ed14      0x8f16a7d2
+       0xfcda431c      0xab32ada3      0x3a863c94      0x5fe91346
+       0x2a92c590      0xb8c17e6b      0xcaf753fe      0x50283647
+       0x533c8f3c      0x1233e1c1      0x7a5b2eb0      0x79b4ba22
+       0x3164670c      0x201c500d      0xafeac6bf      0x2fbb0884
+       0x915de3b0      0xbf733b7f      0xc45d1a42      0xa3b86d4a
+       0x333ef605      0x6348522a      0xd28d1d19      0xa2cad790
+       0xf8ad449c      0x05aacdcf      0x64500018      0xb1d8cb18
+       0x9e4a2ecc      0x091282c7      0xfd64bcf8      0xe1e7c24d
+       0xfcd0f386      0x0c9faa0e      0xa82f265c      0x83cafc3e
+       0xcad43563      0xc110837c      0x2a2da74f      0xbd98e00b
+       0x5c24553d      0x41c75caa      0xe75cb110      0xa004b946
+       0xd4daa77c      0x88d07273      0x0c75c7eb      0xaf05657a
+       0xbe1f8336      0x122a7acc      0xe0e5c29d      0xd5896217
+       0xfb2f909a      0xa74b6458      0xb33a1a38      0x815f7832
+       0x9584b271      0x9a3bb26e      0x39aa6d36      0x2fba41db
+       0x133797be      0x9993699e      0xdb50268d      0xccd54ff0
+       0xb7a33011      0x71db612b      0xef9a4429      0x7217f1d0
+       0x0ee420ba      0x1f7eb025      0x26572853      0x72712e17
+       0x5bd7be37      0x74b2288e      0x3ffd1f1f      0xed566562
+       0x744f4159      0xdbedb36b      0x69e25131      0x604ccb70
+       0x50d83542      0xe4704ddb      0xdc5144aa      0x33467434
+       0x1c7c4f2b      0xac774e8e      0xce9c4d1b      0xa0e3c7f7
+       0xffbecc1c      0xa1c25fb2      0x0e9f6039      0xbe9ed6d0
+       0xf958fb6a      0xaec3fba8      0x2944e767      0x77dc717e
+       0x06e9fe1d      0xaf3a4928      0x7d4f3f29      0xead3972b
+       0x65670bc4      0xd058cc70      0x9fb58c45      0xf5f08926
+       0x9aed1955      0xb1a5d161      0x14b5aa11      0x66e14cee
+       0x28d7aae3      0xae45fcec      0x92dc7dc3      0xe9eda97f
+       0xbee84f22      0xea6f71ac      0x6347c2b8      0xe919afff
+       0x2c409d7c      0xa9800c52      0xd8033a17      0xc3794565
+       0xb5311fe8      0x80d8a030      0xf9cf179a      0x508ea242
+       0x4464cd33      0x91da91a8      0x6c0806cd      0xb5473d09
+       0x0a0b99b3      0xdaf528eb      0xca1e99e7      0x064055ef
+       0xc2dce623      0x0b4c15ac      0x23c13327      0x3f9fc266
+       0x335d9c40      0xaca940c2      0xc18c0797      0xd5027a07
+       0xb0a4d322      0x2e601275      0x6cc88888      0x658eaf8d
+       0x509e2247      0xbae254d6      0xf097f138      0xa163751e
+       0x19558f7c      0xb66f0cd4      0x87b1d966      0x81dd2cad
+       0xf0c25e6d      0xb8e72dd1      0x00f15f42      0x6d2c1c68
+       0x43c7e436      0x68eedad4      0xc2686b38      0x6ff30211
+       0x197c7734      0x905b8602      0x6ab9d204      0x0d16385c
+       0xb1cb5e16      0x8249a5c4      0x29d1ce0e      0x779f7b63
+       0x63042725      0x12ce98e3      0x11282058      0xca3a9eb2
+       0xdb8294e7      0x423e41ac      0xc3ab2774      0xca658d6d
+       0x519f8896      0xaf6010f0      0xd57a94aa      0xcc17df91
+       0x7d25cf8b      0x041e6835      0xa056d9e0      0xf90f3964
+       0x7f99ae59      0xd80125d7      0x9961d6e5      0x41b3da06
+       0x65c254e4      0x787d2c61      0x16aafb02      0x157ab4a8
+       0xdee3674a      0x1ed1b601      0x2e36dae9      0xad57ad38
+       0xaaf25b15      0xd3c37a01      0x68ca9eba      0x2a1bc480
+       0xba157917      0xc00017c0      0x190bd74a      0xd6c6c1cd
+       0x4efd4f71      0x388ed702      0xc8812950      0xd0019ca4
+       0xd44cc835      0xd838fd6a      0x1432ce88      0xce98d932
+       0xaea21cf4      0x54a44cdf      0xdb4dc5ad      0x1d23a7ae
+       0x5ae126ad      0x100dcb50      0xa9727413      0xcf1c61cc
+       0x72f9d2f8      0x4d32d201      0xe27586a8      0x0a1cc932
+       0x21858469      0xf1cda3f2      0x59703f35      0xbd81f9f4
+       0xad6ac9cc      0x25665703      0x1212d5cc      0x98a243d3
+       0x8f47e113      0xd98feef4      0x3c93e832      0xfd67097a
+       0x0c73fea5      0x6132ec59      0x1dc9bdb7      0x791f79eb
+       0x84d83574      0xbd5817e6      0x7d5a0f8d      0x18482a08
+       0x53ac8e4f      0xadd3378f      0xd48540ac      0x4082f5d2
+       0x3ff5badc      0x24855b3d      0x7bb948f8      0x72637822
+       0x0687e93b      0x61290b4b      0xd9f20b3f      0xcc0e5beb
+       0x141ca01f      0xecd1337b      0x8576ec65      0xb6f825a2
+       0x8b84e8b6      0x5bac53f1      0xd4edd06a      0x76ae712b
+       0xdc00a887      0x798c2ee1      0xe74a5ab5      0x1539fa68
+       0xa30817da      0x06f7c53a      0x1930c59d      0xd4232359
+       0x0dfb1427      0x58d7180b      0x53bf57f9      0x5f001d08
+       0xd08128ed      0x3208b7be      0x5c2aba8c      0x0abbd0d0
+       0x424f2041      0x7982f731      0x010ec811      0xa3489c82
+       0x71ffdfa7      0xda0ed41f      0x8a9e806b      0xfa9bddcb
+       0x7a9e1a41      0x53c7603f      0x9e3df28d      0xd06dd100
+       0x2cc64f4a      0x0dfdccf2      0xb4eb9101      0xf56d506d
+       0xdaeed218      0x45523a16      0x4d6d68ba      0xff9a8f72
+       0x5358b2f1      0x2511a591      0x9ea2c2fb      0x08cafc7d
+       0x7ed34bb1      0x0cf2301e      0x62b6c05d      0xc05095ec
+       0x52128c55      0x030576af      0xef5f37a5      0xdf5ae47a
+       0x39e55496      0xb2c2129e      0xb2d67d77      0xc5adf049
+       0x15a1cb4f      0x981948e5      0x7d18acc0      0xec7abb43
+       0x23f7e366      0xa919a355      0x23872683      0xb7b6d84b
+       0x4767dab1      0xd133feb1      0x2e5536cd      0x587683d4
+       0xa181575c      0x4329e640      0x1244ae40      0x5be82f66
+       0x4b28dc4b      0x4106c9a9      0x517fad7e      0x9e334ca8
+       0x3c3ba741      0xe902a475      0x91d046a8      0x31361f96
+       0x911b83bc      0x6607fac7      0xdfbc6390      0x7213aab0
+       0x8ca8a47a      0x4f3d1f3a      0x3ee76c84      0x22bac3f0
+       0x475f3cab      0x05d05569      0x92b3f912      0xc632a733
+       0xd79b7448      0x595b82fa      0x6013b96e      0x6d03b5eb
+       0xe37045fb      0x6e4add26      0x11f116da      0x4ac8bd3b
+       0xacb5f8a9      0x8fb943d6      0xa9ac31c7      0xf1ba9752
+       0x43a6b29a      0xf123766f      0x536fcc32      0xcf8168ad
+       0xd8fb1e4d      0xb9562fa5      0xfe6d8dea      0xd31ab16c
+       0xf7dfc381      0xb70f11cb      0x371c6688      0xac3fccee
+       0xf130a51b      0xc5b8cad7      0x0cb13762      0x64ae00f2
+       0x45cfad12      0x753d6a4a      0xc6f69472      0x695fba60
+       0x49d1f754      0x9db947f2      0x2364ae20      0x197492e4
+       0xc5b9562e      0x34963cec      0xdc26402a      0xa1c88d01
+       0x58e27195      0x9d60f5c4      0x3e200a43      0x7e9827f2
+       0x0a4feee5      0xd401e139      0x17352152      0xd509564a
+       0x4b3142ed      0xef7567fd      0x9a619dbf      0x56ec2cb7
+       0xc64bb290      0x3d69fd89      0x897325a1      0x74e2cb7c
+       0xf270fdac      0x2beb6a4f      0x5b60de30      0x49df7517
+       0x294966cf      0x87f5f667      0x4a9e1f6a      0xabc332c3
+       0xfaf358aa      0x5baa6cfb      0x36b99bfa      0x40259687
+       0x584539e2      0x2710ce99      0xec1959aa      0x642c8413
+       0xfc005d36      0x2b2e6245      0x0012d041      0x09f6b626
+       0x70fe9e2b      0x3cf30c5c      0x69d0a3ed      0xfe621601
+       0xb6fa9267      0xe9b507dc      0x49f35866      0x4b97647a
+       0x9e721adb      0x89e6e8d6      0x407a2f49      0xd977cbaa
+       0xd9359f5d      0x7b69702d      0x22d6e818      0x57eaa5a3
+       0xdd5063b0      0x4d7d2312      0x7a865203      0xb7f0905f
+       0xdd2c2b87      0x7215803c      0x1abe5307      0x2926f38b
+       0xf6b0cacc      0x96f50647      0xb612feb7      0x6915bfcc
+       0x058b5cb0      0xc39e47d5      0x7513abdd      0x9e43972a
+       0x1e55f640      0x896db1c5      0xd9382d2c      0xa52c1f99
+       0x8afaf5cf      0x36500aa3      0x2e65fa1a      0xbb40d668
+       0x81188e3f      0x143fba69      0x3f61fc90      0x438d759c
+       0x893bb96a      0x069f349f      0xffdc43c7      0x6ebfa943
+       0x671b4751      0x629cec23      0xe717fb9c      0x53fadc0a
+       0xddc1e212      0xb99788ba      0x78378cf8      0x2ed91106
+       0xec1de376      0x98d86b3a      0x312a190f      0x0208a0da
+       0x6dcb469f      0xe6407c6b      0x1c7fea86      0x83841afa
+       0xa9caaffe      0x86e3fd0a      0x918af9b0      0x0fabdf39
+       0xdd9fc8f7      0xf9ddd98f      0x3dd0acce      0x2064360b
+       0x29006620      0x5d7733c2      0x682c4093      0xf038a8b4
+       0x3a688845      0xf9d0b9d2      0x27f51a57      0xb63b063c
+       0x533b082b      0x7f0d0dd1      0x7abdb018      0xea6f6176
+       0x13394ac6      0x825339bb      0x1835fd8d      0xaa46df84
+       0x0751fe4b      0xbc9fb7c7      0x233873ff      0xca200e1c
+       0x668fd5a5      0xda059135      0x2baf8828      0x7a2efc0e
+       0x7c63d98c      0xe71ea373      0x0f218e88      0xa031f88f
+       0xf32bccf3      0xf15eadad      0x6df44be6      0xb2536e4b
+       0x2903a9aa      0x42ef8689      0x444432f2      0xd27a6c4c
+       0x0992a32e      0xaf6e65d2      0xcbefdf23      0xe602151e
+       0x21beace6      0xd9b992b2      0xe43286cb      0xdb315c09
+       0x0de7672d      0x9d518ff0      0x75c4e9a0      0x64b2f70a
+       0x9deb697d      0x5bcf59b8      0x2e4b9a8a      0xd9294b49
+       0x3fee760e      0xfba8fec6      0x1c140305      0xe400487f
+       0xc4cd4a38      0x14e6f1c6      0xdf98e7f8      0xfa6c4992
+       0x62908c82      0x37393196      0xc02464b8      0x4b119742
+       0x83e5e79d      0x15ddd908      0xf75d1820      0x363025b9
+       0xd9e1a04b      0x9e110da7      0xd8caf954      0x30f62bc6
+       0x875fd2b7      0x8b67bc8e      0xd5c77d4c      0x1a8ce00a
+       0x7cfb14dd      0x3a39fd65      0xaecc2b5f      0xb017dbb5
+       0x6a57b4f3      0xa27b6509      0xcdb06076      0x000d6366
+       0x66e4f311      0xf22e25d7      0xf91d9bc5      0x5f9d3a05
+       0x3b37c96c      0xb0596f50      0x53c24ede      0xb620106a
+       0x5e675314      0xd98d5b02      0x75261f6e      0x5610c20f
+       0xedcbe43f      0xbe85b8c2      0x16f7ffb4      0x55eb91fc
+       0x2605ab1b      0x5ad3b426      0x3658d764      0x639c0560
+       0x987249ed      0xdc470fa2      0x0d112f6e      0xd8ab77f7
+       0xaed9455f      0xd9f6a341      0xb9b21249      0x3ff2b69f
+       0x37ad61d4      0xdd6a089f      0x609233f7      0x46a923f4
+       0xe5c23e8b      0x6aff8687      0x5e8ece1e      0xc65e1e4f
+       0xfb96cf51      0x9b697cce      0xb08e02e2      0xf874e0e9
+       0xbc983fa6      0x870375e3      0xc88bcd2b      0xc6bb19ae
+       0xaa0c99e3      0xb301ab7f      0x024ba529      0x4449828a
+       0xd226454a      0x0a610f3a      0xf302a0f4      0x021a3cc2
+       0xa9e4b6ea      0x0b690b92      0x3379c01c      0x36265ea4
+       0x29fbc8a3      0xe6279573      0x3cdb8a1e      0x005b5332
+       0xbab71a8e      0x9677db73      0xa8a6d6ea      0xf0afbd3d
+       0x576fbee6      0x49a54473      0xfa7c6e95      0xcb914daf
+       0x58266856      0xa6b53a63      0x7136515a      0x2a3da411
+       0xb1c994e0      0xbdaecd7b      0x5b436ff8      0x6334ec5f
+       0x0172b5d2      0x57acd652      0xca4efacd      0x87e7d313
+       0x78ac87c8      0xaf7602aa      0x3769ff6e      0x86d39747
+       0xd32a7aa7      0x840cb30c      0x3e7da9b1      0x3c905b44
+       0x90290dd7      0xebc85f3e      0x32693a53      0xc7140058
+       0x6ca5cf6c      0xdabfbc3b      0x3d559486      0xe5ce93b9
+       0x8d3c428a      0x9d18b8ee      0x404f58d3      0x151b4a78
+       0x2f393e9e      0x69c59344      0x7879e974      0xc32217f5
+       0xb946562f      0x1d1b8745      0x3666cd1a      0xc6a1e2ef
+       0xe22d2e5e      0x9e7ed504      0xe6c32118      0xb2919117
+       0xb2bad34c      0xe7177e87      0x47b68328      0xe579fe7b
+       0xd0d33f00      0x96923c90      0x5ff2bf45      0xff074961
+       0x4dce1092      0xe8a89464      0xc0b1ea51      0xd65f0f12
+       0x6b2389bb      0x48fa0960      0x82722b27      0x62625540
+       0xd4ff4985      0x768b7c26      0xb36a4ec6      0xf6a66375
+       0x1c89e246      0xb629fce9      0x6aa72399      0xd783733f
+       0x6478b123      0xa374412c      0x11b5cfc8      0x73cf2286
+       0x443f5601      0xd817fca7      0xb2ce2d63      0xf6c63479
+       0xd16b0550      0xf2a52ac4      0x7843803c      0x1ac3b58b
+       0x7f96b915      0x732403a1      0x64634349      0xd2ec0bf9
+       0x10410c08      0xe95d8dfa      0xaaeb33a5      0x57893eaa
+       0xb59afac2      0xe9fd6dd2      0x50d11a7f      0xde479c58
+       0x9dac27dc      0xebba7d8b      0x17fa1420      0x74a1678c
+       0x71ccdaa3      0x5e44b0bb      0x5927a75a      0x7b7580a8
+       0x33330c9a      0x40192652      0xba6308de      0xecc81fbe
+       0x41d48824      0x6ce4e0c7      0x145e9225      0xf8484bee
+       0xc8675611      0x750ec207      0xfa5f5b85      0x618b9f8a
+       0x007cdb05      0x67f98d4b      0x1035f305      0x8d700e9b
+       0x9857a0bf      0x4b774ad8      0x8960c81e      0x344a9462
+       0xee2680d0      0xebb5f6cf      0x7397c9f2      0xcafa01ec
+       0xaf69f3f4      0x0a1699cb      0x90ed82f8      0xc5c8ac04
+       0xe50bd06d      0xf75741c6      0xea52365c      0xd0c03f33
+       0xb5e4e95c      0xebf55379      0x0aae6e4a      0x29f8b91b
+       0xef8ad2b9      0x7bebf2ca      0xb194b728      0x7df7b083
+       0x0ea527c4      0x6d55939f      0xb9242c58      0xb3e1f570
+       0x4fba0507      0x82d7259b      0xb5be7b54      0x0aff6ff9
+       0x88391023      0xfe352956      0x4a6bfb30      0xa00c9644
+       0xc478d534      0x0cdb509d      0x9611713c      0xd7c442be
+       0x8d16889f      0x93abfefe      0x435fa757      0x40d95d3d
+       0x11b7bdce      0xd074874b      0xdce6add2      0x0b652a4e
+       0x595a88e6      0x307a223d      0xb624b9bd      0x855ba51f
+       0xad43c800      0x1fcf6afd      0x4bdd921a      0xd6777384
+       0x8da9f15f      0x5fb03ee2      0x5e6d04e2      0xb33751cf
+       0x55d9d38e      0x41589fad      0x6d311b4a      0x43046a7a
+       0x8d9c7304      0xe25f9788      0x8b459e1b      0xc9a3cfe2
+       0xe6ab721e      0x4de3c89c      0x5c2d2398      0x085d8d69
+       0x4e27ce73      0x1cc1f44e      0x05aeaebe      0x8cedb916
+       0x370b4d46      0x1bc29579      0x33d08b75      0x06b77cff
+       0x155693d7      0x125d3f0b      0xd8714e15      0x3b7427ba
+       0x13f6684d      0x834ee449      0xc5a45189      0xb2ad214c
+       0xa61be586      0x4e4727cd      0x563d1c31      0xd4ba1cc3
+       0xdb08cd16      0x4940a42c      0x43dfd0cc      0x9d43222c
+       0x638a0d11      0xc33d3992      0x98bf11f0      0x1aebf6b5
+       0x1e206582      0x5647f772      0x9255ad74      0x75915665
+       0x0fe7dd12      0x9def740a      0x9361bdf1      0xc1409fc0
+       0xd3bac631      0x7492ee87      0xe1e99dde      0x2fbaf552
+       0xfc24f52c      0xc080882a      0x0a2417c8      0xcea3da70
+       0x4fe34fad      0xb4e55427      0xd5d54d76      0xf36686ba
+       0xd6ab1798      0x1868e364      0xa380f948      0x0eaee02a
+       0xad5a44e8      0xb6d119f4      0x82a43444      0xafad0e68
+       0x595c3ab7      0x385746b3      0x32df6d2a      0x0b01b2de
+       0x51d3d6bc      0x107d8620      0x6d215143      0x29d0e901
+       0xbc57a3ec      0xd584ba34      0x8c244547      0x23d396fa
+       0xffb03cb4      0x8396c1a7      0x3f251905      0x8bc769b3
+       0x68f4696c      0xfc297895      0x9ec65e40      0x22deb20b
+       0x5d1def76      0xa7a095b1      0x3aa6a458      0x6ca11880
+       0xcde44ece      0x62b59f4c      0x067f272d      0x9a5aae97
+       0xc60a8d62      0xeb0f40c9      0x83ebae30      0x07dc9cb0
+       0x05dbdc76      0x0c108eb1      0x314f9247      0x7bfd6072
+       0xf648e1c0      0xae70bd5e      0x7c27b4d1      0xb0cff1c3
+       0x8c2dd93c      0x580a4b19      0xfaa1ee8b      0x4173a23f
+       0x838fa15b      0x2b0fe3c5      0x8059250d      0x659a445d
+       0x2a1c1968      0xbf13412b      0x1a9f915e      0xaf80263d
+       0x24508a66      0xe381d252      0x4e0f55a2      0x7ce1f4fb
+       0xc145da4d      0xbd4b29c3      0x27540ac2      0x23ad4b42
+       0x8e6bcda5      0x20061c20      0x1d3cb3fd      0x5c5498f3
+       0xc468681d      0x4c28ef55      0xf0165c1d      0x2dd6d032
+       0x7e347ccc      0xe04db59c      0x7caa883b      0x1f43df4f
+       0xc300031c      0x85f19e9b      0x22811fa7      0x2622940e
+       0x6299f57b      0x5c106568      0xd7da296e      0xccd36b39
+       0xe349afc0      0xd2c2463e      0xf7f55aef      0x0e0a7e3d
+       0x6b6fc6d1      0x8854098e      0xc87edace      0x8190c437
+       0x333b8ec6      0xe49b3a5b      0x4aecd4e3      0x14cc5f22
+       0xa11faf96      0x3d1cd023      0xae614c70      0x0ab662b4
+       0x908d8082      0x76316cd0      0x3068ec32      0x829b047d
+       0xf08d1b94      0x3b2b33f6      0x03df9ae8      0x40f632d0
+       0x3590085b      0xa33aad24      0x39597da2      0x99415f4e
+       0x7aed6e11      0x61a920ab      0xca851d8b      0x2606f821
+       0xeb7c0e8b      0x8bd6edb1      0x725b39f6      0x3afa6248
+       0x03540044      0xfb118ecf      0x8e18bd5a      0x2a85cc05
+       0x4ecac12f      0xf53a4d25      0x8e3fc6fe      0x32233799
+       0xc7ebb5e6      0x058fdcaa      0xe6db17ed      0x2751405c
+       0xa195a515      0x34410c51      0x4517154e      0xbbb5674f
+       0x28050e40      0x8fd71724      0xbe78711c      0xc1b18693
+       0xd202b9d2      0xdf4e0b62      0x460349da      0x71463aef
+       0xb2fb55d3      0x54a972dd      0x49379f09      0x7a7fdff3
+       0xbd82d4f8      0xd2894393      0xa82bca57      0xe61ca9b4
+       0x9e08e6a0      0x53dffe9d      0xe7ae1c5c      0x65bff365
+       0x7564aef8      0xd94abd3b      0x18d1ba52      0x64a759f0
+       0x65c5dd4f      0x6f9d433a      0x57cb5a25      0xc1862d25
+       0xcf50223f      0x90c2724d      0xf5527605      0xb085f18a
+       0x41e2b17d      0xfb1cabc4      0xd8ab04cc      0x761c2166
+       0x8365afd4      0xc3276657      0x14f64be6      0x5dd779b7
+       0x3b3f1faa      0x358d01e8      0x4c821ddd      0x7ada9f95
+       0x2970bad5      0x3b54a4bd      0x3ca7f039      0xcb67aabc
+       0x3b264655      0x96401a5e      0xa3990376      0x90834685
+       0x8ba56352      0xee98c564      0x4a0534ed      0x7d70fad6
+       0x5d73a1e7      0x23fd8de5      0x39c52296      0xefef1540
+       0x7bc934dc      0xeed157b4      0x898d8bfa      0x5761e88f
+       0x73af2674      0x2fb88d9e      0x28de1281      0x9aa76119
+       0xa3ac21ea      0x28ce635c      0x7596d79a      0xd3295e0b
+       0x7826630d      0xd815ef01      0x27cf2899      0xf3de6a01
+       0xcbb32e58      0x6c57be3c      0x292f819f      0xaa4623d6
+       0xb96ab772      0x90a6f778      0x44b9933b      0xa43e7543
+       0xb9f417b7      0x7a6537a5      0xf36a6da2      0x0a9bb3fb
+       0x177c1f28      0x0512c07f      0xdda55932      0x060dda31
+       0x14465771      0xf3f96780      0xb459e5e3      0x49aaefbd
+       0xb07db15d      0x2ac82807      0x8404060d      0x417d036b
+       0x70946fb1      0xe39e68f5      0x5f9b3035      0xf0335e7f
+       0x2ba457c6      0x2d97ba3a      0xc05156e7      0xbbc9afb2
+       0xd25981ea      0xe70d060b      0x805c231d      0xae471b34
+       0x31964d8d      0x3f34e35a      0x8355ee21      0x73822024
+       0x9ce5f2d6      0xdff19812      0xae55cbaa      0x55f5ecbd
+       0xfe558210      0x09b95751      0x41ee7cb8      0xd2b9fa15
+       0x342c07e5      0x7ee50e8e      0xb6154e01      0xdbf4df3a
+       0xd43e2c77      0xc3ff0498      0xd8106f33      0x9bdb25bd
+       0x40cb843e      0x106b08a9      0x3227ce7b      0x58bb7cb6
+       0xb84e3244      0x3f1d0e20      0x76dcbcfd      0xb750bce7
+       0xa8c11f3f      0x161a8610      0xdc1ef5bd      0x14270b6e
+       0x285e7898      0x68375db6      0x01d23b44      0x35a17fb0
+       0x7c9ad882      0x7bda2e0b      0xca67bfcf      0x6e2dd9ab
+       0x227a6aba      0x5d295397      0x5061f96e      0x47a20c68
+       0xf5427e3d      0x3a0a3165      0x2438fd9c      0x2dc91147
+       0xeabab62a      0xdc358e4d      0x7e1fcc9b      0xdc2a328e
+       0x6e6bf75c      0x68c45517      0x594fe5a7      0x2feac658
+       0x1f0a4d49      0x97575e83      0xcccbdab8      0xc13f3b64
+       0x8bfe659f      0xa4ebf545      0x2c3cf874      0x7d78ceba
+       0x46ac5d6e      0x09309533      0x78ffb6e3      0x7336541e
+       0x3d270f70      0xd71e72b4      0x9772402a      0x4ed185b7
+       0x213da698      0x78a54587      0x18054eb4      0x99179a25
+       0xf758337b      0x94629a30      0xec6bf4e0      0x255ac299
+       0xe56f52b1      0x1c2a6136      0xfb7cc1f6      0x87b53b53
+       0x079ca1f7      0x3a8c340f      0xeb70ef48      0xfd1caae4
+       0x564445e7      0xc1d5c663      0x658fb5fa      0x62d2debe
+       0xc0907042      0xb5402269      0x16965193      0xc038c21f
+       0x780f8b76      0x33ffeb3d      0x03ad9602      0x4a7b6432
+       0x93c2b2f5      0x40720fcd      0xf44c164f      0xcbd43d01
+       0xcf7098cd      0xc43242fa      0xc530a6b3      0xcc33c1f7
+       0xde3d648c      0xf1def13d      0x2a22f5d1      0x77704fc6
+       0x08ed5552      0x3e2295d0      0x00584764      0x6af8585e
+       0x43f845da      0xa92e38df      0xd98c12b4      0xb4fac901
+       0x0b05a079      0xa05f215a      0x27d635c6      0x9fc897e5
+       0x0eb91a30      0x43bdad4c      0x705df05f      0x6b7864b7
+       0x1b6380ba      0x4a64e8ec      0x517b7b68      0x67336d4b
+       0xc6d51eab      0xfac40c57      0xb977cbcd      0x0674e5dc
+       0x74ce2339      0x891cc5f5      0x3230ca78      0xa8a653a0
+       0xa8d4b370      0x496d2f7f      0x6ca677c5      0x54260ac2
+       0x630e1143      0xcbf6f819      0x546b2874      0x02267559
+       0xa2e23914      0x7c9a0393      0x1704bcb3      0x6d680415
+       0x91da300d      0xe2ce21d2      0xc38faf3e      0xcc8be7cb
+       0x14496036      0xc98e253a      0x05ca6582      0x8c566616
+       0xd26204dc      0x3335bd81      0xa94e5af0      0x76fbb455
+       0x23b27f08      0xc4db6f93      0x5cb5401c      0x7cb2ed29
+       0x7cbbad8b      0xfc1e8f5e      0x2bc79e28      0xf69228fe
+       0xbde16357      0xc9ac3b53      0xa6afbc74      0x984bb3f4
+       0x98a8b9d6      0xdd21c848      0x33e65c3a      0xc53c772c
+       0x633022f8      0xa324bd5a      0xd260a77a      0x668ca5d3
+       0x4b79a6b3      0xbfd19bbe      0xca2eb497      0x8e7eb5c9
+       0x169b2184      0x0503d4f6      0x24f35c00      0x0ac930ab
+       0xf694120f      0xcee12db4      0x9305757c      0x798a2db2
+       0xed27ebec      0x2f35829b      0x4294e805      0xa7994ad7
+       0x49fd229c      0x5d63fe52      0xb7cd7641      0x1a68af3b
+       0x6f952e97      0x1c02f4de      0xca3a1515      0xed5bf092
+       0x123c32ea      0x602030aa      0x7811cd1f      0x1b6c38dc
+       0xeb7712b4      0x4aa767e1      0x6b49d384      0x7ba4ee1a
+       0x87f02cd2      0xb8e6b0b1      0x090e9f89      0x95f8b90e
+       0x8d76892c      0x0be06870      0x9ec963c1      0x75d67c9d
+       0xdde23799      0xf9e3be20      0x549442fc      0x09cb0906
+       0x95ee6c4b      0x25a2d9b7      0x98154023      0xdda91829
+       0x0c46879b      0xfbf0e362      0xb7223786      0x7cfbc839
+       0x3b251e5c      0x8be187a6      0xa24f9da6      0xc3192693
+       0x7a8ac8b9      0xc493ca03      0xc736b974      0x369db725
+       0x85a6e92f      0x26dbef75      0xa61a71e9      0x38a08fb9
+       0x4a214ed6      0x57fc6f4b      0x9cf91617      0x322e13fe
+       0x5ac816a3      0x748a9728      0xdc777bd6      0x69fb5335
+       0x258439e8      0xf171a221      0xfa7a07af      0x26447b9f
+       0xadcf3734      0x5af34b97      0xf8b4b0dd      0x08c79517
+       0x28861618      0x64692555      0x19fe9897      0xe3bda02c
+       0x77df51ff      0x93dedf7a      0xc7cb57c4      0x02ee5928
+       0xd4aeb644      0x01d511e6      0x6512bd02      0x5d8f90f8
+       0xe77ccfe0      0xe6ee3ecd      0x5403139e      0x6f7075e5
+       0xb6484511      0x3bd42a35      0x5dcea90c      0x5bb1c6e1
+       0xb69b5847      0xfe106914      0x74442ce9      0x10997c57
+       0x1595af7f      0x9f04a8bb      0xa7d2870e      0x19e57681
+       0x54b276be      0x11c3e3f9      0xc5401783      0x9c413cda
+       0xa6aa9e8d      0x23ff8569      0xf1797ea7      0x86ce3e8e
+       0x9ef0a776      0x56a1c30d      0xf5e18916      0xb11464d1
+       0x7f313c1e      0x49c15cff      0xe2dcfb73      0x637819d8
+       0x2d6ce0e2      0x2170cd43      0xb750902d      0x5eb02cd2
+       0x6cadb7d4      0x89b96f3b      0x8d749ca2      0x8ac7abb7
+       0x31fbdb51      0x7a6df774      0xfb9139f0      0x56f3d9c3
+       0x0f104f2f      0xfaba3c49      0xe53aefff      0x932237d0
+       0x8ee10e80      0xadad6e20      0x19883a1a      0xf45a543b
+       0xd560ff0a      0x8c7b4e03      0xe35696d6      0x9e0ec159
+       0xfc2cbae5      0x6ce2cddc      0x14a72474      0x89757fe3
+       0x6b788e7b      0xc16fa200      0xad36bdf7      0x57bdc4d1
+       0x55146f2b      0xa57db4c5      0x313952e1      0x2c55d0d2
+       0x32ab0208      0x10f846bc      0xdcba1674      0x436485bb
+       0x932704de      0xcd7e2e1c      0x59f78879      0x7ca21395
+       0xbcc07be6      0x2b101e5b      0x38924c37      0xb90928f4
+       0x8f824214      0x55699b67      0x54cba493      0xe71c27a3
+       0xdde01c05      0x48d822fd      0x734ed8fe      0x29dbf298
+       0x9ef3a499      0xfb517934      0x19c8ce8b      0x38b8bf00
+       0x75da50eb      0x237f3b1d      0xa8940707      0xa98a4149
+       0x35ec2d39      0xee862d31      0x36659949      0x8f3dffc2
+       0x70afb227      0x94f443c1      0xb6f9308e      0x0e8ebd54
+       0x92b8960f      0x56d21560      0x8453d1ca      0x74c680c0
+       0x2d706dfc      0xd0b81c18      0xbac65445      0x40a34988
+       0x498145a9      0xf436ae10      0x9b72fec6      0xb4100aed
+       0xe305983c      0x349fe379      0xbf31cfa7      0xba624703
+       0x4a491754      0xf973a686      0xa2ba725c      0xd0a23615
+       0x31903086      0x4ae46e45      0x0f705e05      0x4ea6bbc8
+       0xbf299e43      0x0689709c      0x9fc93571      0x07cbc14f
+       0x542ef992      0x80ce91f1      0xf86014aa      0x17d533d1
+       0xb55e63e2      0xe02e0e4c      0x88a5ed22      0x6302126a
+       0x56b32e90      0x5fec4381      0xe2e98b3f      0x30693509
+       0x862e1d75      0x2da30e3c      0xad992d90      0xc62cae4b
+       0x379c77ba      0x467ea8f1      0x8a820048      0x74cc474e
+       0x6bca3803      0x18aaa3f3      0x1fafd26a      0x0865f360
+       0xe3479d10      0x6cefb2b9      0xf6612730      0x2e0f222a
+       0x749a89e0      0x75b1fa05      0xe2ea0874      0x5d422c20
+       0x24707d46      0x6d475835      0xed1e556e      0x6aa4543e
+       0x28b36c16      0x22d83c4a      0x8c3e6d51      0x42a94c9f
+       0x0c603d0e      0xa8c7f417      0x845997ff      0xdc79494e
+       0xa130d628      0xc2df082a      0xa3a2c27e      0x3f93b00f
+       0x1521a7e5      0xca15bae4      0x57e4e836      0xb915a471
+       0xd9147115      0xad52f80e      0x5fd2a2be      0x15972ed7
+       0xb69ec21c      0x502f2627      0xfb46a1ca      0xea685d34
+       0x9226f7f2      0x4b41927d      0x7965eaa0      0xb702e76f
+       0x79a54721      0x5b8e984a      0x37efcd59      0xfeabf30a
+       0xd4ad7db5      0xbb2282ab      0x8a5c840b      0x2ba370c5
+       0xdef5758d      0xa69a9aa1      0x46082250      0x6e8e8477
+       0xf6280c61      0xf99e4a14      0xcf3c5cbd      0xcce657f0
+       0xca635eae      0x0be182b5      0x58e8b43a      0x5c717ce5
+       0xaa7aaff7      0xc329c6b6      0xf1cc91ef      0x8d7cc520
+       0xda155783      0xd5e2e54c      0xf466f010      0xc5dfac4a
+       0x606ad5de      0xf4992f1a      0x1344c9ce      0x4aea9020
+       0xa30447c7      0x0a99ad18      0xd3caa96c      0xfe5b0b4e
+       0x7b50bbd1      0x33e50575      0xa22d1d06      0x73a1820d
+       0xce4c4c8c      0x2cde7764      0x511d1c26      0xad0cf826
+       0x086dc311      0x3060ef7d      0xe6fdc617      0x3050b179
+       0x1dbb5316      0x4145fcb7      0x2eb62505      0x2e1359e2
+       0x79cab612      0xaa9282c9      0x7eede562      0xb016f7ed
+       0x1445fefb      0x809b2e00      0xfafaa754      0x69ac113c
+       0x548a6e3a      0x6d444c14      0xb3d355d8      0xbbadcd2b
+       0x3032d634      0x7df39948      0x4c1f9098      0xa9d138ce
+       0x42823bbe      0x2ef39e3f      0xaaf9ef1d      0x63369afb
+       0x2bb76c9d      0xb7d38558      0x354160ce      0xc04c6378
+       0x6c71ab10      0x7914af1a      0x1c1a4694      0x2f9fce8a
+       0xe28f18d3      0x3acaa573      0x2503b236      0x90ca20e1
+       0xd2c77ccc      0xc3005311      0x836d9430      0xe91d8463
+       0xb53e4cb7      0x4e373c67      0xd06ef659      0x27e1a21c
+       0x285c0391      0x32046fa9      0x8b1b9c92      0x49a22f4e
+       0x81411430      0x050110e3      0x56144e6a      0x47fb824a
+       0xdb2e9a6a      0xb5fe97a9      0xabd37259      0x93da3055
+       0x19fb35e6      0x66661115      0xa27149a2      0xfb7d94b5
+       0xa315f9af      0xd7d97596      0x134d7d09      0xd5cde0e9
+       0xbc3f143a      0x1b2061ea      0xd7b15227      0xe8f506e3
+       0x0aa17e92      0xc8565276      0xc7d90586      0x22a26c8e
+       0x6d462029      0xe7b1ad73      0xd11fa609      0x67643f2c
+       0x64f1ef34      0xa0e7e0b6      0x9687611d      0x09c2d32b
+       0xb494937a      0xcc36510c      0x70555bfd      0xfa25e917
+       0x7d88b6da      0x30f3b531      0xd19b224a      0x999d0f7a
+       0x9fe0da18      0x45947b87      0x536dbf3b      0xa6f5182d
+       0xdf11f95d      0xa5abcdbf      0x7528110b      0xf54fe792
+       0x71a97619      0x680bd3ff      0x6981ea39      0x683ff854
+       0x302fbbe4      0x12129f84      0xf63cd448      0x69fe289b
+       0x568da933      0x2f1e1146      0xe7404e52      0xcd329394
+       0x02e41762      0x94456d4d      0xe9416a20      0x4e5920e7
+       0xe8db71fe      0x527a5313      0xe42c7d9e      0x58c8c1fb
+       0x28949bc1      0x312fdf97      0x3569f41f      0x3ed5f092
+       0x44baef39      0x5c11d5ad      0xb5d172cf      0xa9e4cfa3
+       0xbc5ed197      0x2f290ead      0x747f53ed      0xadf1b698
+       0x1b90440a      0x4cdfe154      0x9b24b832      0xeb97d794
+       0xc90fe91e      0x4fef1271      0x8bf96025      0xbdb49f79
+       0x63910640      0x26a05cce      0x3318e422      0xb2fc61de
+       0xf14cedd1      0x4bd7687a      0x8c4c91dc      0x48a857a2
+       0xb47aac94      0x787526e2      0x99349c7a      0x0bd6ba75
+       0xbfbc4b0b      0x040fbec9      0xd00de44b      0xc4c7f0f5
+       0x74a8653b      0xbd3cc036      0xa601a4f3      0xb82c0da0
+       0x2709b674      0x73065351      0xaf4cd23f      0x3481ea0f
+       0x6a1fa77c      0x26a9d280      0x95f4a170      0x393e7590
+       0x015b3d73      0x36d91e55      0x61a7f3f5      0xf6d39c21
+       0xd9ee4701      0xe57af451      0x5e141761      0xf6b6e472
+       0xa6efc965      0x9606aa1b      0xfb8ce005      0x831ab2d1
+       0xfe7a1af6      0x5e326881      0xa0ad32ae      0x15f86ecc
+       0xa1a634d2      0x3a40c4a9      0x88e10130      0x2e6c4556
+       0x8526aa32      0xa81b0d30      0x19c83936      0xdcaa556b
+       0x6dc8064e      0x5709ad31      0x1b6fba18      0x9ebe34b1
+       0x28abc3e6      0xd76c3908      0x4374657e      0x6f0fc085
+       0x4f19a108      0xb774421d      0x405228d5      0x123dbbab
+       0x18535471      0xfc6bde41      0xd4b2d82e      0x65b85772
+       0x64731e41      0x29e886f6      0x4c2c7eda      0x91586a5f
+       0x15b2407b      0x5fa08a72      0x56898e51      0x5424e976
+       0x19ce4a36      0x0ada4656      0xe634446a      0x478da533
+       0x36f1c763      0x01ec46c3      0x5e1d1040      0xf6da1918
+       0x831f8f94      0x43ddb630      0x80b5d4e5      0xfc403ba5
+       0x40dcdd4e      0xa19d0aa9      0x6c32fad7      0x7cdd6f3d
+       0x8e9c123a      0x42c4edd0      0xc8247030      0xf0e6cebb
+       0xf8d1425f      0xcfa8e403      0x67646391      0x9dee9f9b
+       0x5683c4f6      0xd958ae1c      0xc62eedfa      0xbd67ea10
+       0x253398d4      0x18b7f92a      0xf101a7de      0x60066732
+       0x4ca1e3dc      0x6e1eb0a0      0x115aa9e1      0x8370aae0
+       0xe46756d8      0xa02eb1aa      0x854dbb8a      0x6334873e
+       0x87613a81      0xb5bd56df      0x491371d1      0x02bbace8
+       0x2a2e45f9      0x91bdc460      0x2bcf90b6      0x81df2f07
+       0x34aa2dd5      0x5b54a117      0xb7a5bd42      0x713e2287
+       0x1ea184d6      0x176bdda0      0xa19c0d86      0x4180fd5c
+       0xd018a4cc      0x60120a37      0x8f6e094b      0xfebe1b15
+       0x42866bb7      0x4a9f772e      0x0bcf9cad      0xd936a924
+       0xec6cf0a1      0x1f9ccf16      0x81f8229f      0xdcef1733
+       0xb4a31fca      0xefbf0a0a      0x057e0b4b      0x59491c96
+       0x70ce99bb      0x908ce274      0x637ae09c      0x479fdd52
+       0x11ea6250      0x7778cdf6      0xd0ffe2ca      0x539b18dc
+       0xbcdab649      0x3066399b      0xd685edc0      0x79d8d588
+       0x32942aa1      0xd03531f7      0x5d024d56      0x4dc99729
+       0xd1efff53      0xdf3ce9a1      0x31462a0e      0xe5427113
+       0x395e2980      0xcf5c9d4e      0x91e11088      0x7e4d31e2
+       0x5ff91ae8      0x9340e815      0xfcb89789      0xcb1b2f58
+       0x655aa934      0x2eb022da      0x419104a9      0x6b648411
+       0x582048e2      0xa0db392a      0x1e1d6443      0xf3c7a401
+       0x1e737591      0x452af94c      0xfcb74331      0x2da70f75
+       0xa8b59eb9      0x736224c8      0x5ba81657      0xfb36eac0
+       0x4e0336b4      0x8925a32c      0xa4d60fde      0x8a95ff27
+       0x57a7e536      0x7e6a2f58      0xd9e9751e      0x817cc66a
+       0xca4bd134      0x627382fe      0x00e56736      0x74844fbc
+       0xab1f8265      0xa32955e3      0x41cd361a      0xb3ae6366
+       0x1f77ea37      0x2200c6ef      0x81854e76      0x49ed4e92
+       0xb57a7fbd      0x7b9de6d2      0x128feedf      0x57bb65fd
+       0x20ccd650      0xdcde5458      0xd5461b27      0x465147f4
+       0x70719068      0x2cb48f5d      0x6edc0d43      0x83dbda97
+       0xf077ea64      0xf61423e2      0x39a55177      0xb23ff07c
+       0xa02e4ca4      0x9e6250d3      0x77f1df9c      0x238c632e
+       0xce253a6a      0x096327c5      0x87f1db29      0xd75ac0de
+       0x456704b5      0x9ee7046e      0xd693dfe0      0xf995c6b9
+       0xa354d140      0xf16bf090      0xaf511cdd      0xdc56d21e
+       0xd7cc4d4c      0x5398cc1e      0xe5444b3b      0xe192f473
+       0xd09ae67d      0x8af2775e      0xc1af44a9      0x57bc4586
+       0xa6ff5419      0xdd4ba49d      0xec4864fa      0xda9d0357
+       0x84dfbe33      0xf41ba9c4      0x99e2bda8      0x9fba720b
+       0xa7dd9e92      0xa0d43386      0x3e0f9ef2      0x6e388282
+       0x8f47ea95      0xac920523      0xa98ae8a5      0xf6a6a4d4
+       0xc3fa2e55      0x74a21b36      0x9c0b14b2      0xc6b8a79a
+       0x367b7036      0x24b9f255      0x0b543b75      0xb630fa41
+       0x1b260452      0x7daf6714      0xdb8a13d9      0xede8f6bc
+       0x47a21d0c      0x01d9ca54      0x4a8e5cd4      0x257cd217
+       0x7504cecc      0x973bbf11      0x992b731e      0xaab55b65
+       0x77e2f058      0xf580b58e      0xb10419fe      0x679aa4df
+       0x296c1d64      0x751380f0      0x8f70f0de      0x3f78bdb8
+       0x1ee68ad6      0x7d5d50e4      0x823710a4      0x18b98d13
+       0x86bdf798      0x953b8131      0xb5da3d24      0x2eccd3b1
+       0x828a154c      0xed51b913      0x566e58ef      0xab8ff1b4
+       0xc744d227      0xe705bbc6      0x6032eb64      0x5495e4a5
+       0xe83add11      0x08429de8      0xa2e397dc      0x4f00c90b
+       0xcb7672e8      0xa1d55607      0x0741ca2a      0x323d64f2
+       0xa700ef1e      0x6ccb2967      0x07c29e41      0x018440a9
+       0xbb1880cc      0x35502720      0x8a13a96e      0xe2bfcd29
+       0xa76ad3aa      0xd95be915      0x6dd66033      0x41d655f3
+       0x02009028      0xb44ec634      0x82e61d87      0x216e624a
+       0x7fc79105      0xac0307cb      0xd22fa331      0x63746b2f
+       0xe51ab72d      0x9b550c82      0xb28dbc01      0xd569d017
+       0xd168d372      0x8d6bfe6b      0x5820751c      0x820a4e23
+       0x13cfd07a      0x678c8319      0xd1e65476      0x752967ee
+       0xafb28392      0x390d5488      0x53668098      0xa0c92673
+       0xaf0549c2      0x644f51c3      0xd59df083      0x7cb37a42
+       0x12261017      0x038c15b3      0xccc30b03      0x85ee24ce
+       0x1e029b23      0xb6bb2845      0xb62a305e      0x2d0cf4e9
+       0x182b887f      0xec423ce7      0x8c1c0b25      0xc83b4737
+       0x71fb9023      0x63d639f6      0x16c1ce44      0x66ac8331
+       0xd9aa0975      0xba3d445c      0x5d097729      0xb353a034
+       0x23811786      0xb81394b5      0x5323f1b3      0x7a3e1576
+       0x3f2867ad      0x0bc88c8e      0x74b60d63      0xd56335de
+       0x0d40f71c      0x55ec2524      0xea3a2c78      0x19e5e0ae
+       0x9bf3d033      0xf57bbc94      0x05b6ac55      0x4c368744
+       0xae8c68f2      0xf23aad06      0xcf94d185      0x2360ff3d
+       0x0e8a87f9      0xb97c8d33      0xa7122e6e      0x5ad4dc50
+       0x6145ff8e      0x617389df      0xe8a0e09b      0x4d40ce6f
+       0xee2b65fa      0x4104d368      0xf4bc9d85      0x0b67abbc
+       0x7bbad9ff      0x26b293a2      0x06055372      0xbbb05665
+       0x0560311d      0x421dc535      0x9c451ac7      0x38c83a74
+       0xc8921ff8      0x634d52c5      0x6e66dae7      0x1c86fae3
+       0x5a0645bd      0x6e5fddc9      0x86852d55      0x76207d9a
+       0x6a4b7990      0x661c00eb      0xb268e55b      0x17daec24
+       0xa2854da4      0x9b1f3f63      0xdd200bc5      0x0b50aecf
+       0x8242f913      0xc7ab6eea      0xaa977c22      0x748d0d1b
+       0x4490aae4      0xaa293e18      0x69aa0720      0x6115eb81
+       0xa5b187fe      0x828bfe34      0x5fb6d155      0xe764d755
+       0x08833186      0x8475cce3      0x718bfb48      0x063b287b
+       0x7ea71b59      0xbedbfd29      0x3736aa07      0xe2dfd533
+       0xf2ea49a3      0x96b0983a      0xc1f60b14      0x511bed9e
+       0xac976686      0x9c60ce3d      0xfffd0b07      0x59d7cf79
+       0x477942b4      0xff2f43cf      0xeb4b899b      0x37a47783
+       0x8e6602a7      0xb6bfc410      0x7685c6e4      0xb7ec103a
+       0xd54fdb01      0x3933d261      0x725982d1      0x86ada0a9
+       0x83788370      0xbafb1498      0x13972979      0x2157be41
+       0x5e976c80      0x05501107      0xb3b66da9      0xeebcb8fb
+       0x42ac1fee      0x1dba34a9      0x3f5a7582      0x362e7ed7
+       0xaa69be91      0x419f4d18      0xb09a9967      0x31aba127
+       0xaa247bff      0xb31f4958      0xe79562af      0xfb73878c
+       0x47dc697a      0x5d08fa9b      0x91dcd3c2      0x53e52d33
+       0xc84ddc84      0xdb5f8e17      0xe51889e2      0xb1aff523
+       0x4ffa0702      0x2c72b35a      0x9a4246fc      0x62420517
+       0xaad11acc      0x18190bf9      0x11e140de      0xacc99086
+       0x39347992      0x191a53d7      0xbe92c4ef      0x9a934b5d
+       0x64cf7353      0xe30a3e8d      0x0aa6db52      0xb0a7e26d
+       0xc8fe2f52      0x2e274a07      0x0c94b6ba      0xf80eaf3c
+       0x1ba3e94e      0x5853ffe3      0x11652833      0xce7b0839
+       0xd1893c23      0xd06d2078      0xa65f020e      0x281e6a7d
+       0xdf1da5a2      0xcdf69d20      0x74fa9b92      0xd98d6000
+       0xb732496c      0xbd12f87e      0x561dc55a      0x651d42ff
+       0x5736b74a      0x2c48a906      0xfdcbaf15      0xf76606e1
+       0x80dd0254      0x8105e60b      0x143200b2      0x0f02f524
+       0x1580d2c6      0x7281c6fc      0xc971cd31      0xd4a57180
+       0x5051e5ec      0x193c72eb      0x930332c4      0x488d7403
+       0xa93e425c      0x93e8ca97      0xa0a55070      0xafd8f8fc
+       0xc424f1bf      0x11050ed2      0x855d0923      0xa0fcef35
+       0x61f9e84a      0xc2196706      0x7221d5f7      0x96d036a5
+       0x137ca3fb      0xfd632623      0x30b10850      0xdda390eb
+       0x270fc9af      0xe6a8d748      0xf55bc288      0x8cc912d1
+       0xf2d9cd15      0x5ded2f07      0x2de9b076      0xf5088354
+       0x885becf4      0x959ef88a      0x0d9ea589      0x2ceb0a27
+       0x8925270e      0xca5ecd99      0x8ba9265c      0x209eb0b7
+       0x2e8b51d8      0xc598e096      0x23c17aa7      0xf600bcae
+       0x7b33f831      0x223e1501      0x361c9f12      0xe6aeea94
+       0xa5c6948f      0xd1daf8cc      0x0b0e0b54      0xb0cea6c7
+       0xa437fbc8      0xdb4139ab      0xcbbad47a      0x124e2117
+       0xfb80c5dd      0xef085f4a      0xd24c5fa8      0x2548a1db
+       0x5e6cdeb2      0x8e4f0290      0x78cd8245      0x1ebb5eb6
+       0xd9bf1208      0xf20eaf0a      0x544df94d      0xebc9c742
+       0xbc5b4bbe      0x33f6fcaf      0x32efb07a      0x55d91b59
+       0x2c0ed1bf      0x39985cb7      0x4cab882f      0x530cdaca
+       0xccc78cfd      0xdd834c48      0x7ce7898d      0xf7458891
+       0x933c2ae8      0xa06c5762      0x2eb03e35      0x8e938b71
+       0x3636f142      0x0026efb8      0x183d71c4      0x7e8ff92a
+       0x63265ea6      0x0f1352b8      0x73f8a8fa      0x6594e921
+       0x401f88db      0x64abd8e6      0x994140c7      0xb2258b0c
+       0x9bd6e6a1      0x92bab589      0x5919a943      0x29ab4d8e
+       0x33cbb8d4      0x57084d92      0x006c4d50      0x57c49e54
+       0xec1ecfe6      0xeaa8109a      0x269d94a5      0x4a664f84
+       0x2bda2944      0xdafb85c7      0x2a7b4b8c      0xd8f124d6
+       0xbbac0e70      0xeac5a129      0x308d7e39      0x99a023a9
+       0xf616fc22      0x76fcc40f      0x7f745409      0x83872303
+       0x0b067846      0xdf90a414      0xb6d9b6e1      0x8d0f93d8
+       0x6f76a627      0x02f89060      0x392cb9e0      0x6acf19a9
+       0x7cffe4d1      0x9928b4a0      0x87a031bf      0xecff42d5
+       0xa376e023      0x69d2e1e3      0x1fb67afd      0x5396049a
+       0x45538549      0xec0e6f60      0xf1ab27e5      0xc679e764
+       0xee430c38      0xa6b0c2dc      0x92824db1      0x65d5ffe7
+       0x448b17d7      0x9c67c8e0      0x14b36e2a      0x283de0a8
+       0xc59bb35d      0x8faf1ca7      0x4265db7f      0xb0e74749
+       0x0924d389      0xc22bf3fa      0x017c143d      0x93b4e0d4
+       0xf8aa8e07      0x07e0293d      0x5b40bba8      0x619c8946
+       0xc817ee7a      0x82fd526b      0x3e5b0f9a      0x5b352d98
+       0xc786d63a      0xcbec5c0d      0xd05e9640      0x7cab758e
+       0xaa9bd61d      0x205ff53f      0x2f093865      0x55ef390d
+       0x4b008d12      0x0344c52d      0x64820f87      0x8e9c5202
+       0xdd3f2276      0xf3b46630      0x80e85ea0      0x9aea428f
+       0xa205b11f      0xa8506b8f      0x2c89f419      0xb0b9694b
+       0x21029e6a      0x5e05869b      0x3baf3c6f      0xde680ae1
+       0xd65b5eb0      0x99a6937c      0x52a78fe0      0x6f577b06
+       0x8dea8d63      0x2417d49c      0x1a0ecb5d      0x91f22002
+       0xc540298f      0xea9f8f6d      0x01ccfdb5      0x287138c1
+       0xef206774      0x9d5deed8      0xba844833      0xf612317d
+       0xe0bd4bb4      0x595d0440      0x73643204      0x2c21370c
+       0xf9d5df6e      0x05614527      0x73c4edee      0x33f45ded
+       0xbc47170a      0x24b94b30      0xff304e54      0x4e0c3b53
+       0x658af390      0x402418bf      0x9db7318c      0x058721ed
+       0x896bdd56      0xa956c5cd      0x3f928400      0x94c93146
+       0x56600758      0xf46f4f66      0xa5bf66d5      0x0e8b5870
+       0x8ba7e755      0x4177fee6      0x32cc8824      0x90b677d8
+       0x307e9dd3      0x853a7e3b      0xa2f064a4      0xa42dbd46
+       0x243ed6a9      0x7164eb1f      0x9e97212a      0x9757d142
+       0xde296a05      0x8699a74a      0xeb02fa7d      0xf80b41fa
+       0xd9dd2198      0xd7ffbd00      0x21b15853      0x11b78093
+       0xbb329142      0x5260fb1f      0x22fb24fe      0x7a5e7e71
+       0x71434197      0xc5ddca32      0x930c8cb9      0x65192958
+       0xad1a41f1      0xc77442ca      0x72b64ff7      0xa90bcde5
+       0x184a19de      0x71df036e      0x1b69b0ed      0x023c391f
+       0xd9847da5      0xca57d383      0x0d21255d      0x2ea68d9b
+       0x0189eeb5      0x1ea62386      0x4c8d42f0      0xac20dd55
+       0xacceef1d      0x972f56e3      0x0bc40455      0x3853c5a7
+       0xcab0d1f5      0x0d2a990b      0x525be1ba      0x5cc6daf5
+       0x4d564f06      0x834d8f94      0xc0c055e1      0xef34557b
+       0x354537de      0x7207e6b8      0x659c9298      0xa88ac04e
+       0x80d8014a      0x7f4f6e7b      0x1136e621      0xb1b62f79
+       0x8d4613ec      0x673699ee      0xdd6d7741      0xdba1ffa9
+       0xe219e1b3      0x8bf64c21      0x14aadc3b      0xc4dc4e19
+       0x47ae1e52      0xc5409e4b      0xce8d29d8      0xe0b1cf25
+       0xcaf06411      0xd5450dcc      0xf14f29ee      0xf3611dd5
+       0x52bc02f3      0x886b68aa      0x3b2853ef      0x110aafb0
+       0x6b6d765a      0x87fbaa12      0xc79f134e      0x88b910fb
+       0xe04aa148      0x33feeccf      0x3be43d3b      0x067854eb
+       0xf22561e5      0x56c3abc3      0xcf0ff408      0x6291d940
+       0xe26819d9      0xcfd04da7      0x94ab2808      0x156dcd0a
+       0xb6d1c47b      0xdca4aa76      0x877f870d      0x4e06ec17
+       0xbb560b01      0xbe1b62e7      0xd98b51b2      0x7083e3d5
+       0x427ab621      0xe5fce36f      0x606dc14a      0xe4b70b49
+       0x982d2446      0xf2d2e82a      0x60836061      0x681317fe
+       0x1667e3c8      0xf6eef490      0x1ad768d2      0xbc86ae5c
+       0xfbb392de      0x868caaaf      0x8429b5ff      0x266b6d5b
+       0x372e8f2e      0x6e875cce      0x3a972f08      0xabddef20
+       0xc777c559      0xd8f924a4      0xad39137e      0x4c16a4f0
+       0x91d51877      0xae645599      0x4d09feb1      0x0cdededf
+       0x5749b5b8      0x513c9745      0xf4da62f7      0x6583b20d
+       0xb599bb89      0xaf6bea53      0x7275f6b3      0xdefc5092
+       0x01a3734f      0xd95f4c5f      0x37bce97c      0x63610b99
+       0x30555fe4      0x20af2f26      0xf84b2652      0x67ef6d87
+       0x2119805a      0xcc79747f      0xaa479405      0x63a02857
+       0x1953fc39      0x4f952879      0x886bfe97      0xf0067752
+       0xa08b5005      0xcd9a5ebb      0xb04486e6      0x560c79ae
+       0xe8faf52c      0x64a9a961      0xae9a5f1b      0x74cb5ef7
+       0xf8d0269d      0x2fb63c57      0xd78a9a90      0x99cc0a42
+       0x46bb0252      0xe56b026b      0xfb5ff703      0xdc8e0588
+       0xe5d9e280      0xa73ec2b3      0xe21bccb0      0xe22ee743
+       0xd1bb3217      0x5d4b3f92      0x0a627d8b      0xf2fd974a
+       0xad0a57c4      0x261ba12e      0x1670f842      0x996ab25d
+       0xf6f8043d      0xa6cbb362      0xcac3044e      0x6fe01268
+       0xa54ab676      0x54d7444a      0xf3be5437      0x6b2b737c
+       0xbe10300c      0xea505599      0xd60a15f6      0xd971ecc0
+       0x9c480c46      0x2233038d      0x66d38df9      0xcb566912
+       0x63cffade      0x75811ca6      0x8dbfa4cc      0xee5fc07b
+       0x23329e49      0x39ee07e5      0x5de33ff1      0x601f8348
+       0xb60a8bc3      0x832d3660      0xd1bee11b      0x1a38d12c
+       0xaf00744f      0x21c2639b      0x0fd34252      0xcd63a9f1
+       0x60f34993      0xf8728afe      0x75f8bb5c      0x74a250ca
+       0xb9f51490      0x6ac643a6      0x4011a0e5      0x77288317
+       0x57f772b9      0x92c0715c      0xd5d0e030      0xde335025
+       0x669f6b14      0x55c74853      0xf3ac7cd5      0x38284e8c
+       0xb0fda481      0xf9b7f045      0x839293cc      0xdf91a0a0
+       0x18d20454      0xf73214fc      0x09577b9d      0xb5febd00
+       0xd9b96c88      0xb454ea2c      0x6204a932      0x736edf8a
+       0x9724f56e      0x3092f58d      0xac17cced      0x5ae87e39
+       0x28dd2a0d      0x3806d96f      0x5e7c8c68      0x72df4471
+       0x0207de38      0xf026ecac      0x13258e9a      0x34a8e8ce
+       0xdd7d7286      0x8d7553af      0x11ebac36      0xfb9965ff
+       0x9beda82d      0x1cd898cf      0x1b791830      0xe96ca8f0
+       0xa0d274d6      0xdd6fea3a      0x7537177f      0xdd93627c
+       0x60b64e47      0x10f30724      0x12489cf7      0x4587e1ac
+       0xe7835522      0x61d48d9d      0x6afd081d      0xafbbcf2c
+       0xe31d79cd      0x49ae4218      0x7c2c4a33      0x4fdf949d
+       0x52ccd576      0xef2c3d62      0xfd5b75db      0xe6a5c2e9
+       0x04fc9c6e      0x47fde414      0x8a87ebfa      0x850904e4
+       0x2f49b552      0xb5f186fd      0x772a4ba3      0x48d0be3c
+       0x846c7d78      0xc1c2a1d7      0xb9375f9d      0x302ed828
+       0xf79208f1      0x8fdc4f71      0xc749ed51      0x1cd0c28c
+       0xee5a5f7e      0x7f02b7ca      0xdc3b531f      0x99c0119d
+       0x428e5474      0x10515459      0x8d804d27      0xb7c00220
+       0x264c2695      0x7aa6e5af      0xef807715      0xa444f446
+       0xe51c7755      0xcd825b6c      0x39afa440      0x88638e46
+       0x4ea4366d      0xddfc9854      0x99696f2d      0x210592ea
+       0xf4763dcf      0x7358acdb      0xedfc8523      0xe46031c8
+       0xc9762414      0xa71a348b      0x084b6c82      0x9162e0d7
+       0xda6a5b8a      0x68ca14d5      0x6385741f      0xb103d4c2
+       0x44299ef8      0x9aba89fa      0x2c87dcfd      0x476865df
+       0x1189dbb2      0xdcd9d19c      0xac2bbd51      0xa71526f5
+       0x745222d7      0x4813ca98      0xcfa5802c      0x5d2b3907
+       0x8a17d1b8      0xea56f907      0x3ea58d71      0x933fa242
+       0x021f46a7      0xab8d4e86      0xfa4eb33e      0xaecbd5c3
+       0xb3258e74      0xaac9f193      0x415a5518      0x28b13031
+       0xbae39e53      0x1072fd5a      0x4e0fbf55      0xb02c5d77
+       0x5949c780      0xbecf72df      0x15e52c72      0x3ffeb165
+       0xa8e73d50      0xa52fd918      0x2b3c4d7c      0xa1e9e021
+       0xd8e91949      0x63bf63ed      0x8f2e150a      0x9cbceca9
+       0x33b10a97      0x4d2c69f7      0xf26371bf      0x0b5214ec
+       0x10eb7fca      0x1958b429      0x25f190be      0xafcfb396
+       0x7aec0c45      0xf9a0f163      0x9c966818      0x28f83619
+       0xe35c61d4      0x1ad8a656      0x576dba63      0x7aa44804
+       0xf941b7b8      0xc5faf3cc      0xdf1fd628      0xc009417b
+       0x366ea78d      0xd3cb7030      0xf3f12e97      0x5298cc89
+       0xbb43c8ef      0xd0a8ef96      0x564bced6      0xbcbd865c
+       0x5c80b1d7      0x131ccb04      0x7502d06e      0x465f5cb0
+       0x93320c4c      0x9df42986      0xbdb1fe26      0x48ae8bdd
+       0xaf44e912      0x6aa468a5      0x67ecbb05      0x30b7c0a5
+       0x3ad75711      0xa2d5f63c      0x30150058      0x4d748121
+       0x70804875      0xf46b6ea6      0xa3fcbb7b      0x1af6b4c4
+       0x48496de1      0xdb1a2321      0x758eb79a      0xf35f697f
+       0xb4ff9dfa      0x38ab5b31      0xc918f6f1      0xb3a259fb
+       0x3610afe7      0xdfcaaa0b      0x00c747dc      0x96c40b4a
+       0x5c815168      0x29198fee      0xc94eeea9      0x70432b55
+       0x5de7bbd4      0x0995652d      0x4b3e846c      0x7e4c9ca1
+       0x7c0e91e6      0x401a820e      0x3ca3429a      0xd3812f44
+       0x9cb6a5eb      0xf03ce395      0xefca548b      0x8943bc10
+       0x472b2108      0x82d4a386      0x1d0ef931      0x94cd70ef
+       0x2d00d619      0x40d36f80      0x238ccc47      0xe0856568
+       0x9f06ad8b      0x95a4052f      0x287a57fb      0x9e9f9891
+       0x62bc3a31      0x24c3c1f8      0xbabdc3c4      0xfa40629d
+       0xd16f1f33      0xa9f7600d      0xbcbdb2d9      0x214f24be
+       0x623ea3b0      0x8d650418      0xe86635b7      0xb834745f
+       0x20771340      0x3c69a0b2      0x8b7c84cc      0x740e475c
+       0xe5a540eb      0x9e216852      0x1383201e      0xfbf1f572
+       0x9680d736      0x3d7f8d69      0x615ea313      0x87bc1297
+       0xe552725c      0x9bfee104      0xf2e87d90      0xde9188b4
+       0x028d268b      0x51c75c60      0xed93377f      0xc380d9d9
+       0xe858bf8c      0x5d0b4a40      0x05a3171f      0x76ae3ec0
+       0xf86e3fe6      0xc3d78254      0x7cd640c5      0x6835dacb
+       0x983bd9a8      0x05d1e564      0xc5d5e9b3      0xf81c6560
+       0x8ecba474      0x071daa33      0xf5010276      0x5432ba59
+       0x10f2dbc1      0xbe892680      0x7e92d3d7      0x8d2f0113
+       0x37fa8034      0xb13058f4      0x44684553      0x2bd0e36a
+       0x67ea83ef      0x815e7115      0x3cd123af      0xd9aec852
+       0x67c61c95      0x861d068a      0x60c7797e      0xd9733b31
+       0x9ed29f37      0x1ccc8e08      0x34bcfa7f      0x1c66914d
+       0xc64dc834      0xad884c08      0x2b22b8de      0x53d6fd78
+       0x0355dcc8      0xfd363485      0x62370358      0x0dcb046d
+       0x22fe7d2f      0x5fdd1117      0xccd6d8d1      0xe97925a4
+       0x309aca3d      0x56c31fb9      0xe6f81e08      0x24fc0560
+       0xa78d459b      0x4940b35b      0x9a4a2fdb      0x203eafb8
+       0x91e5fcab      0xfb9be08e      0x9cb903ac      0x31598d89
+       0x4f41986c      0x77206f4e      0x61811c9d      0xff51d95b
+       0x2d7b4c66      0x84ceb768      0xfb135597      0x58087b13
+       0xa1681cc2      0x14009e31      0x778c3fec      0xe3faf2fb
+       0x5092b2c9      0x8919c362      0x34e2b174      0x7bb04f44
+       0x63c39b5e      0x8ef696ff      0x2e4c612d      0x77d390e2
+       0x5dc958a1      0x528bb31a      0x1cb07e7a      0xe37c9c53
+       0x002856d7      0x6a10b962      0x423a7b39      0xc6da9227
+       0x207800e9      0xe200c119      0x0e5af6f3      0xfb580459
+       0x71dc40a0      0x70434cd9      0x13f7f455      0xdf3fd7ca
+       0x37cbc698      0xf5a5808d      0xa7bfdf32      0x8a0774c7
+       0x75b67d50      0x5a6908c9      0x23611a6d      0x8b50c483
+       0xfe1e2eba      0x7ee1c732      0x2191e47f      0x9e63eb3a
+       0x379cd875      0x4df7258d      0x166a8aa8      0x1c94586a
+       0x2456c4d3      0x000185fa      0x7a196b46      0x914e789c
+       0xf562c939      0xb3bad5db      0xc2c19b89      0x8a621ffd
+       0x0c807ce0      0x701a938f      0x69234cdd      0x36a00f09
+       0x964c43f7      0xcf71cd85      0x5f504e16      0x446c6388
+       0x25742397      0xf1a375c8      0x6bcf822c      0x1b175fd7
+       0x0fe78e56      0xfe7817d6      0x66da0366      0x904e8327
+       0x5a0749fa      0xef3ede57      0xd0fa2ac8      0x89791771
+       0xa5cd616f      0xe9ef2860      0x9b533bc3      0x1d746f03
+       0xf4bb82b5      0xacae0438      0x840b3e34      0x30371a0d
+       0x8590acf3      0xeb4ff7e4      0x40437052      0xba847bf6
+       0x24059538      0x44daca63      0x23b32e28      0x091386e0
+       0xc480e66a      0xe4a839f5      0x34929bcc      0xb9051207
+       0xd21252f9      0xc6524769      0x8c422851      0x36280aad
+       0xbf00b1a1      0x4e36c85d      0x7949e8ef      0xf76be57e
+       0x373a0ab9      0x1b7555a0      0x0c2caf56      0xc9241f75
+       0xbe5b0ee8      0x5a486f75      0xfb2c050d      0x6aeda464
+       0x3fa744ee      0xf6e055a1      0x0a7324ab      0xfab58776
+       0x09baaf66      0x459ce186      0xc6eb1894      0x56a4ce4a
+       0x58ce1069      0xf4debf5e      0x04a145b9      0x1a246583
+       0x9b07fe23      0xd4d37068      0x7321e0bf      0x2dfe17f3
+       0x426dd8a7      0xc561a2d5      0x7f515a47      0xe57d37fa
+       0xa85f0aa5      0xffb78cd7      0xf30c4551      0x3572c02b
+       0x6f4a4cbd      0x7322ecc7      0x170a7b9a      0xa1e80d28
+       0x5a366af2      0x4f24a3a7      0xfefd29ca      0x0d7b02dc
+       0x1adde2e1      0x5c426cc5      0xb1e53b76      0x5dba2c5c
+       0x1458b6ca      0x73cea912      0x39626c25      0x7547e76d
+       0xfcddbb97      0xf03d59ee      0x3cfdab3d      0x309db86e
+       0x3de8df47      0x4a570e6d      0x09c9579a      0x19ac033e
+       0x0a7a9a86      0x3662d261      0x048fa67f      0x4aa4009e
+       0xc7660654      0x524d81f1      0x3157ec52      0x857d1f10
+       0x3770162e      0x3d1ff919      0x732d2b13      0x84187da0
+       0x95722d45      0x362cada5      0x5d67637f      0xdaae8465
+       0x9f5c0699      0xab9aba98      0x6f97d3fa      0xf9cc4120
+       0x0ca1872c      0x1a832c9e      0x7b74d6ae      0x98dca967
+       0x03eb7699      0x5fd02b54      0x962c6224      0xde1ab807
+       0x800af435      0x2458a4ca      0x717de910      0x31648afc
+       0x871527de      0x3cb93892      0x45237e37      0x446b1315
+       0xecd807e8      0x70f38e30      0x140dc60e      0xaef7b7c1
+       0xadec312e      0x94d45820      0xb8960073      0xe8dd5bac
+       0x7616ab11      0x0c3cc190      0x516003e3      0x323cdb39
+       0xd679f9f4      0xd7c179d2      0xdfbc5e24      0xaa1226df
+       0x3cd41b0e      0x88f436f0      0xbd5b6cb1      0xb78c69aa
+       0x982e0ca0      0x91f852a3      0xb331636a      0x28df67ee
+       0x81b029a1      0x9e7375e3      0x56e874c0      0x8b93a735
+       0xa47eaa4e      0x772ad825      0xfb83ba8b      0xc08db79a
+       0xcb7a34be      0x14214d72      0x7d6fa82e      0xe75c7002
+       0xa6290902      0x716d04c1      0xc75f0a97      0xb68e0912
+       0x08b5ef1b      0x507ecac3      0x2d740b08      0x43b6c7bf
+       0x3965675a      0xf56dc4fd      0x1ba44239      0x36753f70
+       0x0b2452fc      0xe36bafe9      0xfc3134c3      0x2ac78286
+       0x69ba53b8      0x225b9bd9      0xaf426f79      0x99bd2d3e
+       0x0bcb8e18      0x28c87047      0x2045b3b9      0x730ec870
+       0xe6558839      0x9ca3de82      0x263a41e7      0x1c8ea255
+       0x334eb3ad      0xc36d6793      0x66add8ee      0x652c8548
+       0x79dca1a8      0xc2526972      0xd10f03e2      0xdbae6f42
+       0xe223bf69      0x10082495      0x74ba4cf9      0xeb71ef5f
+       0xafae5d4e      0x7b3663e9      0x9339468c      0x31edca72
+       0x65a07876      0xf336fc1a      0xaa505397      0x011d5253
+       0x99b88ade      0xa688f0fa      0xedac589d      0xab4d8f45
+       0x0ff866a1      0x61280e9b      0x65c5a63f      0x8b372073
+       0x7a4c88df      0xc74f7959      0x19597c51      0x97c8a27f
+       0x33eb652a      0xffd40c86      0x57a2ca0c      0xaabc6cc8
+       0x54fd2280      0xd5b59006      0x2e00f009      0x72bd86c4
+       0x24936e04      0x877188de      0x91b60401      0xb949b337
+       0xdab93e69      0xdffeab2e      0xb3aa7c79      0xb8612f31
+       0xf0c53b58      0x8896833f      0xda35944a      0x1867027a
+       0xef6bfce9      0x8213f320      0xac477eb2      0x92368362
+       0x606cfdc4      0x27c98907      0x50673ac5      0xec48f5f4
+       0x39e879f8      0x80d050c8      0x9febddbe      0x5d797725
+       0x06d8b755      0x0319d93d      0x7eae3ce5      0x8963ed64
+       0xc91772c9      0x4e031095      0x2fd03d3e      0xe774ea89
+       0x7dbc97ab      0xe8d8f361      0x6e167fa1      0xd1520c5a
+       0xb3278325      0x8acaf913      0x6ea81dd4      0x9e3b2a97
+       0x0a5b8a09      0x84000db1      0x59a30fa9      0xf0b6868d
+       0xfb62b0ed      0x8953057f      0xdbbca3c0      0xc103b876
+       0x47420e14      0x1eb22bed      0x58c8f65e      0x3a689da6
+       0x8ed1a99c      0x869ddc49      0x60015d09      0x2264c797
+       0xdc10c6ac      0x7275327e      0x8d47d2ab      0x87a75624
+       0x3dd8fcb6      0x40e67a31      0x98114b1f      0x7e3a5976
+       0x1d9e62a6      0x988c0398      0x0c7c0d8d      0x0aad4954
+       0x3c40a234      0x7b752b7b      0x79f94813      0xa0b86dec
+       0xe3f646ac      0xa993f76a      0x6f9d1f99      0xe883dabf
+       0xb8ab1b2d      0x6766ac8d      0x6b9a793a      0x02f55fa5
+       0x351a96ad      0xd190f768      0x35667fe0      0x6a85c938
+       0x72444e33      0x5140a848      0xd3062250      0xe4ce902a
+       0x44e7d9d3      0x7c8d48fe      0x4d26a61d      0xbd013c4b
+       0x540d32bb      0x9152cafd      0x09840a30      0xd7a8663a
+       0xd5a3ca17      0xfd5dbe65      0x655b226f      0x7cb9debc
+       0x59d300dd      0x13737132      0xdf0d004f      0xe98bbd9e
+       0x5626fb54      0xb6d66fbd      0x273087a8      0x032969ea
+       0xbd69c191      0x010cdfff      0xb2a9cea5      0xb8778e4c
+       0x8f0dd084      0xc75b4ce6      0x9c027c6f      0x36c58105
+       0xac424eb8      0xa15d2883      0x9e73b7b8      0x54e9aade
+       0xb9500a5a      0x97505e35      0x4c59b36c      0xb3ad1302
+       0x31e21ed1      0x78bcd74e      0x2d9fc122      0x49bae35e
+       0x5c8f01c0      0x8d29829c      0x0c672566      0x37938db5
+       0x4959e71f      0x0d2365bf      0xaab666b9      0x52b2cffc
+       0x200ee1f5      0x5dbb262b      0x9aae28df      0x3223780a
+       0xb65218cd      0x633b797d      0x93f42423      0x3268b3ae
+       0x141e506e      0xb1ed94b2      0x497b7973      0x9f2db9f6
+       0x5260bf9d      0xb30e4310      0x4a3539ec      0x275d2ae2
+       0xff43e500      0x645e30e5      0xf1527598      0xb76ec4cf
+       0x88fc44e9      0xde68932c      0xe61aff6b      0x19d042b6
+       0x11981ff8      0xb0d595d9      0x52764f82      0x7e0ca214
+       0x8cc51237      0x581f2a1a      0x482420b3      0xd47ff971
+       0xcff78344      0xc019eca7      0x3146ab02      0x107a3ee4
+       0x16dc120d      0x33a239ec      0x0ea84236      0xebc7a1f4
+       0xd1f2fa2a      0x9464c008      0x2b76a4fd      0x9b4acb99
+       0x00f6a92a      0xd68b8d15      0x25e1e58d      0xe1fe3cd1
+       0x6fbce2cd      0xf78be2dd      0x09b9c08d      0x6b32d210
+       0xd06e7c95      0xd62f47f4      0x92c717ca      0x44fe3d2d
+       0xaa13cc08      0x3d411f94      0xc2eba262      0x7521c9e4
+       0x77d6cdc7      0x22d76158      0xca2efacf      0x3e51004c
+       0xef9a82d6      0x1508d20c      0x923f18ff      0x3eaa88e6
+       0xf2f32bc7      0xe74b8483      0x82529884      0x58b38ad8
+       0xdd9f2a5f      0xdf54adc3      0xd4497667      0x789c000b
+       0x935d1743      0xa52d5f1a      0x4e27adf6      0x5c3334af
+       0x6cf71ba0      0x501f8353      0x031fd6cd      0x4831ec4f
+       0x08c847db      0x6a6e0657      0x0bd803d4      0xd7c48cfe
+       0x94b7e25f      0xc6516ebe      0x1001c08a      0x0e165da9
+       0x4e39605f      0xe3f3637a      0x013daae9      0x217168b0
+       0x6013ab5f      0xd5b7eb97      0x8ce6b6ef      0xc4259f29
+       0x470e90a9      0x7a254ff5      0x8dcbf841      0xa2541a7f
+       0x4880c5ea      0x28c750ea      0x043a0200      0xbeb9653c
+       0x46e354d1      0x64f7104e      0x05a64bf3      0x7db42752
+       0xbbd38c7b      0xca7da1d9      0x916c7ebf      0x1df5e3e1
+       0xef0897f5      0xd0456a5c      0x629b50a3      0x8caefdc3
+       0xddbf8b94      0xf6e6b341      0xd8ce3e02      0x27c96419
+       0xb2659ab5      0xe8d576df      0x9f136353      0x6f5230f5
+       0x68417adc      0x39b65378      0x4b742f21      0x96d071b1
+       0xeb046da9      0x245ecb46      0xc17eeec3      0xd7c56615
+       0x07df9b8c      0x647ee4f4      0xf15f7e7b      0x825b87eb
+       0xdc67dd20      0x43c38867      0x977868ca      0x3a299ef2
+       0xa75073f7      0x2dcd59e6      0xc6c78c75      0x63a00767
+       0x74dfba2d      0x7880c7da      0x83f72bc6      0xa9750166
+       0x716b3abe      0xc949a1ea      0x7e5fc036      0x574ee475
+       0x39c3cae9      0x8c1dacdb      0x640fcc41      0xc69437e8
+       0x5d33a950      0xa28e483a      0x4031cf9b      0x0007e3be
+       0x6e3f277f      0xe25d3025      0xdcbc4a0a      0x7451a537
+       0xb372169f      0x21ff0e91      0x1978aa74      0x6471624e
+       0x01a03f20      0xeb391a3c      0x70d18ad5      0x47c9ddcf
+       0xd9415b2f      0xd9ea29ce      0xffa0677e      0xeff7a04d
+       0x1d384ff4      0x66195704      0x22736810      0xad754f27
+       0x782ae9bb      0xffed05b6      0x5ae3f21d      0x5eb2c577
+       0x0101cf91      0xed0322ad      0x56ac50c8      0xc513b1c6
+       0x4f62ba8b      0xbaffd6b6      0x6649baa2      0x8702464e
+       0x78947007      0xd6e97d6e      0xde7c6abf      0x2bdee498
+       0xcee1db1a      0xb98149de      0x47f32f5c      0xc6c354fc
+       0x6e148fad      0xb343cf2f      0xeac6a9f0      0x33dd1560
+       0x923403bb      0x87d6e292      0x0b1cf653      0xe8b76402
+       0x5f21a955      0x236dec28      0x214663fd      0x1917539e
+       0x3f11ce80      0x1bb35a2c      0x38a358f1      0x15f67224
+       0xc65394f9      0x63cd4887      0xe8e73d2b      0x51b6204a
+       0x8eeae8f5      0x6e071c8f      0x55c23dca      0x4862eaee
+       0x0afa0037      0xc98446f3      0x09181a1c      0x41e46e02
+       0xcf13d6b9      0x85907776      0x30116b18      0x27b8c7b1
+       0xd153a5ce      0xc95c90b2      0x34392718      0x8103dbe4
+       0xe012a7be      0x6aeb8c6a      0x5bbaddbe      0x221eab21
+       0xaf769239      0x2621a689      0xe8c41061      0x5890f76b
+       0x2c4dadd4      0x2ad2e669      0x394209b5      0xb272b2ef
+       0x560031cb      0x4ab7be9c      0xcc5e92e4      0xc0de0667
+       0x7a39cf63      0x03482c6e      0xd653de11      0xe14466e1
+       0xf2dbaf25      0xc34d1c0c      0x03eeb3e3      0x8260874f
+       0xf6e2ef37      0x13626fba      0x15b7efe4      0x069cd153
+       0xbf631788      0x797668a9      0x724d831a      0x0ceeb589
+       0x9559cd31      0xb995d2d2      0x7564c4ef      0xfc45a3dc
+       0x1cd999e3      0xbe090229      0xab4f9383      0x879156a0
+       0x06e1d37b      0x3796487a      0xaf1e3884      0x1f9a59ef
+       0x6c2d8a7b      0x0a8a5ffc      0x4cd60f03      0xa60bfc63
+       0xf67c6872      0xf19b75cf      0x041cc864      0xc563566f
+       0x58ae88a0      0x3747b0c1      0x64cd86fa      0xed185c5a
+       0xb71533c9      0xf15672fa      0x2722d209      0xb71ec7d7
+       0x3143a8a5      0x61c18934      0x3a899ec5      0x4274f336
+       0xea7c52a9      0x9193cd11      0x44c471e7      0x57fff360
+       0x53923783      0x76d57ce6      0xbff32513      0x4dbe0d39
+       0xb9f80483      0x62ce4d25      0x5941e9fb      0x7dfedfe1
+       0xa33f9130      0x336e6539      0x1de31e79      0xb6855a41
+       0x4db2db67      0x02a9f1ed      0x019bcf20      0x53ad0ce3
+       0x4d049f95      0xa9de2c6f      0xa26f6997      0x28eafacb
+       0xa5220548      0xb4675e1b      0xe776ee88      0xc93e6c37
+       0x7868630d      0x1690625e      0x6eba0fd4      0x78f598ff
+       0x113fa1b7      0xcb025590      0x2ee34123      0x92241df5
+       0x6edbf0b2      0x3bc2e0a7      0x710ce59f      0x656f0eb7
+       0xa598424e      0xeca53268      0xb6a44542      0x5bf6674f
+       0xad483960      0x35290b93      0xfba74c81      0x78141ea2
+       0xd6baf9e7      0x8e5a08e6      0x4910c5b0      0x7b140d21
+       0x1958c79e      0x0dbed125      0xcfbe41dc      0x089fc4ab
+       0xbf014fa7      0xff961610      0x7a2ae6c3      0x560d3a9c
+       0x2cd77620      0x3a7c15cb      0x9464d8f1      0x249a93ff
+       0x96fe6c56      0x7231a31c      0x4bcdadd7      0x62edd9f4
+       0x8ad1916c      0x3a5fbc8d      0x2a2ccd7a      0x558980b1
+       0xb0137cfa      0x3cae6929      0x587c349c      0xbcfee701
+       0xbddd49df      0xa0da6dbe      0x4cb03dac      0x5f84ba2d
+       0x7fb3063c      0x66de2150      0xbf7dbcf2      0x1c0892aa
+       0x4be8b0ae      0x5d9845ab      0xa21455af      0xc42f2e68
+       0x9b6f438f      0x5eaf4941      0xabbf9079      0x94984a47
+       0x542bdea4      0x34cf3d67      0x854010a4      0xf39a9b19
+       0xd25ffb6a      0x04364e75      0x0af97ef8      0xe10e3620
+       0x2184d002      0x0c0ca683      0xc19963c6      0x4c428d15
+       0x47ae4151      0xd11ea57c      0x437a9ed6      0x50a6b8a2
+       0x141b16e9      0xeb4ae873      0xb51180fa      0xe3dc318d
+       0x7744a06f      0x64d297d2      0x845fac66      0x5854d172
+       0xc14dbe9d      0xccba053f      0x4620a715      0x405d728f
+       0x28b86cec      0xcba09cdc      0x92823f94      0xeae2664c
+       0x48eda6ae      0x4b60f5f6      0x1772f309      0x8af285bf
+       0x9c3ae474      0x13149ebf      0x2bc835c2      0xafcaa560
+       0xc11b6f91      0x94861d9a      0x089c0d82      0x1e04d66d
+       0xf0e497fb      0x6b2d8b6a      0x9d7f0cae      0x4a93ba71
+       0x1c006123      0xed4b5f75      0x76e7826d      0x4f884ba9
+       0xbba28011      0x1e275278      0xfa72461d      0x7e70e215
+       0x1427ba3c      0x467e4f3c      0x781c5f92      0x357b7951
+       0x9de2cce4      0x524a0de6      0x12e15f95      0x7b64fae0
+       0xf27e93cf      0xc6f48158      0x9b71dbd6      0x081dc1b3
+       0x47c9c2c8      0xf110add7      0x7881b556      0x0404bf1c
+       0x58e7d936      0x04442173      0xe1e7f0cc      0x128ce897
+       0x169c0a11      0xf30b5575      0xf2ac0bab      0x91515620
+       0xe8b809b0      0x2a73d5a0      0x9ed32dae      0xcf943a47
+       0xfc157bf9      0x1a53054d      0xf0657e2f      0xf39f6ea7
+       0x92a5834a      0xcdca0c13      0x40a7b40e      0xba0e0cdd
+       0x72f595c3      0x6b7eeaf3      0x4d0fd8ed      0x9a856082
+       0xd75402c8      0xe0f8d3b9      0xee57a2a5      0xe1ccf4a7
+       0xa4fc4fa6      0x9f2407c7      0x75f94c0e      0xbf2361de
+       0x2d3b4782      0x72c35e50      0xb97f7d4e      0xbc880223
+       0xb0b24073      0x08931201      0x40e0d18b      0x559db40c
+       0x6216a921      0x031a379c      0x29bff1ac      0x1c522c12
+       0x583bfe94      0x2519ba2a      0xd691d08e      0x905dc62f
+       0x43b421b0      0xd45caaa0      0x5f099da2      0x012fc4a5
+       0x509712b3      0x67e5d441      0xc843de50      0x7e1c756f
+       0x91368900      0xc6ec0dd4      0xa41e838f      0x58eabda5
+       0xd6ad78a9      0xa037b655      0x8af4e767      0xa9b95900
+       0xdcf1780e      0x64e28d82      0x215ad981      0x292dfcc3
+       0x708d8557      0x0a507562      0x486022ad      0x8165bc7e
+       0xabffce1d      0x78fbe480      0x77b916f6      0x88f8167d
+       0xae8b8edb      0x62698ab6      0xdbc6bbbd      0x001819a6
+       0x8c096fb3      0x40a121e9      0x7b96a718      0xf6d256ed
+       0xe5c0a484      0xa09bd764      0x6552b5a2      0x1847ae3f
+       0x0669a650      0xccabc209      0x85246d20      0x61158f3c
+       0x379d8086      0x02135988      0x1eccc6db      0xf8f38c67
+       0x8e1b0f3d      0x0f6e87e5      0x936bbb84      0xe04839eb
+       0xe26b3e5c      0x3f35ffda      0x4920e752      0x014c876a
+       0x25189061      0xbe2bc4ec      0xbb2ca0f2      0xe2c1c9b0
+       0x747df643      0x26da8dbd      0xdacc3c8a      0x7d93b22a
+       0x922d9a0a      0xf82d65b6      0xd56e5f35      0x7aea7534
+       0xf1808648      0xdfa7ec9a      0xff00f8c6      0x69091da7
+       0xbb478c83      0x64e24ae6      0xf2371faf      0xcff5732a
+       0x4da88e73      0x9c8494df      0x4c0da767      0x3e22bd67
+       0x059298eb      0x9d7611ce      0x74b4a198      0xbcbe440c
+       0xe2bb1a9f      0x0ba3e5f7      0x65a5cf9c      0x8b24b6f4
+       0x7784ca5c      0x24ffc234      0xece71bbd      0x36f8e876
+       0x1b55d68b      0x2b9163a5      0xaf8be424      0x958eeaef
+       0x5d711c41      0x66d11cbe      0xfce42868      0x4a3c819c
+       0xf66d295c      0x629402f7      0x64b2ee3d      0xc0b74538
+       0xe93a735d      0x3b9e807f      0xd1d0d7c8      0x69588f34
+       0xae92b6fe      0xf5508d03      0x45b6ccd6      0xf85a18c6
+       0xe1a28a53      0x438f9a35      0xf4fe84dd      0xe3f95791
+       0x16860340      0xefe72aee      0xb13575c6      0x3d730481
+       0x3cf2a43e      0xa6ed239e      0xd7529176      0x8ad63f3f
+       0x5efe8f4d      0xe9cad7df      0x44fefef4      0xc7198f50
+       0x85aabf5c      0x15c175c2      0x26f7a0cf      0xf06782f0
+       0x4dfadfa7      0xbc57a087      0x21406f0b      0x692a8f18
+       0xd17a358b      0x19d1b2a6      0x6c35022e      0x87d8c987
+       0xe7f2d06c      0x91c4daa6      0x4a132822      0x1e864671
+       0x5cbf0c4d      0x6a34f073      0x1c87a8e5      0xb38f1717
+       0x1cac430b      0xf733ee6e      0xdf73201f      0x71026328
+       0xee976531      0x661c9d28      0xdeefcd7f      0xdefb4607
+       0xfca9ef3a      0x3e1b9b38      0xd204c892      0x6b059f5f
+       0xd5b8665f      0x4eec24fd      0x09b21b40      0x364c708c
+       0xebe0d543      0xc3d64eed      0x8facb895      0x8f415f31
+       0x3dd25b0b      0x95f4072e      0x85e6f4c1      0x3345e2a5
+       0xa56e8dcf      0x3ed8df67      0xa8194a81      0xafe613c7
+       0x384b25b9      0xe7661836      0x5ad6476d      0xeb0ae982
+       0x19afdf2f      0x4efb8658      0xff07e358      0x96c469d2
+       0xf3030add      0xf5bf5b51      0xba03b24c      0xcb77143f
+       0x134fba20      0xa126558a      0x193cd220      0x48f43727
+       0x156f2b18      0x4e599917      0xc3ac4eac      0xcc460648
+       0x67974a2a      0xe2917a7a      0x02998a74      0x470c60d1
+       0xbacbc868      0xfef38d84      0x3e4597a9      0xa1723ab7
+       0x8ffed7b2      0xe489b151      0x34b982fa      0xf67bf8ce
+       0x043cbb33      0xe3927c98      0x3c8fb221      0xbff0644a
+       0x886d333c      0x1f4cd6b7      0xe9b744f0      0x443ef364
+       0x04847d65      0xf3c2ba04      0x60a8e656      0xab4dca06
+       0x620dbf22      0x5b0221e5      0x877973ab      0x128b5a6a
+       0x4696b5d7      0x8f034e85      0x18796215      0x8579ec7c
+       0xf8917eae      0xa98bffce      0xfc67e9de      0xa897445e
+       0x2f115777      0x990bfb90      0x1de53f71      0xfa2e5c1f
+       0x24a5b882      0x0f871a5b      0xe7fc33a0      0x6927a106
+       0xb210bc90      0x2ef851de      0x09629147      0x2553882d
+       0x77393353      0xeacf977e      0x470198f7      0xb7564a05
+       0x4d575fb4      0x1d980371      0x0feeebba      0x26ba3c12
+       0x17b21567      0xfb664d1d      0xcee1a603      0xa8881580
+       0x8a47e853      0x6511027f      0x734f6fd7      0x2977b345
+       0x7465e47c      0x0e3c4c8c      0x3185ac04      0x2450ea5d
+       0xa6e97dba      0xf52b2f4b      0x328ac24f      0x5a507ad2
+       0xac05d4f7      0xca332e1e      0x44b6cdd5      0xe22b049b
+       0x55b885d1      0x71144ba1      0xf57284d9      0x76cb0900
+       0x8266cfae      0x82bb0271      0xfe547080      0x53e4dac9
+       0x0546dcb9      0xa09a8de0      0xd55d15a9      0x7a3a96ad
+       0xd23c33ed      0x7a8fa769      0xa0542b10      0xdaf92f2c
+       0xd6433b0e      0xad7cf7b9      0x72c54814      0x38ff5c07
[… more lines in the raw message]

Lines of this file are not shown. View the raw message.

arch/x86/dts/minnowmax.dts new file +31 -0
new file mode 100644
index 0000000..7e15c26

Lines of this file are not shown. View the raw message.

The rest of this diff is not shown. View the raw message.

Although currently the ich spi driver does not use this compatible string, should this be "intel,ich9"?

arch/x86/dts/serial.dtsi

Quoted 22 lines
arch/x86/dts/minnowmax.dts new file +14 -0

Lines of this file are not shown. View the raw message.

arch/x86/dts/serial.dtsi +1 -1
index 9b097f4..6865eed 100644

Lines of this file are not shown. View the raw message.

The rest of this diff is not shown. View the raw message.

I don't see anywhere in this patch refers to this new label?

board/intel/minnowmax/Kconfig

Quoted 203 lines
arch/x86/dts/serial.dtsi +0 -0

Lines of this file are not shown. View the raw message.

arch/x86/include/asm/arch-baytrail/fsp/azalia.h new file +39 -0
new file mode 100644
index 0000000..d96a20f

Lines of this file are not shown. View the raw message.

arch/x86/include/asm/arch-baytrail/fsp/fsp_vpd.h new file +95 -0
new file mode 100644
index 0000000..82862f6

Lines of this file are not shown. View the raw message.

arch/x86/include/asm/arch-baytrail/gpio.h new file +13 -0
new file mode 100644
index 0000000..ab4e059

Lines of this file are not shown. View the raw message.

board/intel/minnowmax/Kconfig new file +29 -0
new file mode 100644
index 0000000..7c2b927

Lines of this file are not shown. View the raw message.

The rest of this diff is not shown. View the raw message.

115200 is the baud rate, not the clock. Should be removed to avoid confusion.

doc/README.x86

Quoted 130 lines
board/intel/minnowmax/Kconfig new file +2 -0

Lines of this file are not shown. View the raw message.

board/intel/minnowmax/MAINTAINERS new file +6 -0
new file mode 100644
index 0000000..d655761

Lines of this file are not shown. View the raw message.

board/intel/minnowmax/Makefile new file +7 -0
new file mode 100644
index 0000000..1a61432

Lines of this file are not shown. View the raw message.

board/intel/minnowmax/minnowmax.c new file +32 -0
new file mode 100644
index 0000000..6e82b16

Lines of this file are not shown. View the raw message.

board/intel/minnowmax/start.S new file +9 -0
new file mode 100644
index 0000000..2c941a4

Lines of this file are not shown. View the raw message.

configs/minnowmax_defconfig new file +13 -0
new file mode 100644
index 0000000..7bc9085

Lines of this file are not shown. View the raw message.

doc/README.x86 +6 -6
index 0e4628a..cd9a926 100644

Lines of this file are not shown. View the raw message.

The rest of this diff is not shown. View the raw message.

OK, get if fixed here :)

doc/README.x86

Quoted 42 lines
doc/README.x86 +28 -0

Lines of this file are not shown. View the raw message.

The rest of this diff is not shown. View the raw message.

Coreboot -> coreboot

include/configs/minnowmax.h

Quoted 88 lines
doc/README.x86 +9 -0

Lines of this file are not shown. View the raw message.

include/configs/minnowmax.h new file +69 -1
new file mode 100644
index 0000000..507afb8

Lines of this file are not shown. View the raw message.

The rest of this diff is not shown. View the raw message.

Regards,
Bin

Part of the diff is not shown here. View the raw message.

#63 lore raw

cover x86: Add bare support for Intel Minnowboard Max

In reply to Simon Glass

Hi Simon,

Quoted 56 lines · Simon Glass

This series adds support for the Intel Minnowboard Max (called Minnowmax for short). Along the way a few refactors and additions are made:

- The Intel Firmware Support Package support is moved from queensbay to a common location
- PCI support for XHCI is added
- A few tweaks are made to the PCI support
- Support for the debug UART (early debug output) is provided
- The microcode tool now also supports reading in header files

This board has been lightly tested. The following seem to work:

- USB2 on the blue port (not USB3), e.g. for keyboard
- Ethernet
- HDMI out and console
- UART
- uSD card
- SPI

SATA is detected but I have not attached a drive to try it. USB3 shows signs of life but does not detect a USB stick, and crashes when trying to use a USB Ethernet adaptor.

For SPI some parts cannot be read and others cannot be written. This seems to be a feature of the Intel hardware configuration. It may be possible to fix this using the SPI registers but I cannot work out how / lost interest trying. So far, addresses from 500000 to 700000 can be used.

I have not tried the ICH GPIO driver but it likely needs work before it will function. I2C is not supported as there is currently no U-Boot driver for this.

The zboot command can be used to start a bzImage kernel. Verified boot is supported - use mkimage to sign images as described in this walk-through:
doc/uImage.FIT/beaglebone_vboot.txt

Boot time is grim:
- 1423ms to set up display (Intel FSP)
- 454ms to scan AHCI (when no devices are connected)
- ~1000ms to power up and start cache-as-RAM init (Intel FSP) (this is not benchmarked, may be inaccurate)
- ~950ms to set up memory and initial machine configuration (Intel FSP) (this is not benchmarked, may be inaccurate)

So it takes over 4 seconds to get to booting a kernel.

Implementing the Memory Reference Code (MRC) cache should improve this slightly (perhaps a reduction of 500-1000ms). This cache is implemented for ivybridge so that code needs to be moved into a generic x86 directory and plumbed into the FSP code. This has not been done in this series. Also the video and SATA/AHCI can be disabled if preferred.

It is also possible to run as a coreboot payload. See the instructions in README.x86 for this. In this case video does not work since coreboot does not pass through the VESA display information.

Quoted 6 lines

To support the single-core 1GB variant, changes would need to be made to arch/x86/cpu/baytrail/fsp_configs.c to select different values for the memory. The microcode update may need to change also.

This series is available at u-boot-x86 branch minnow-working.

I have finished the review of this patch series. Generally they look pretty good. Glad to see we have another new Intel board supported running U-Boot 'bare'!

[snip]

Regards,
Bin