diff -pruN 1.0.0+git-20190125.36a4c85-5.1/contrib/cloud/aws-import 1.21.1+git-20220113.fbbdc3926-0ubuntu1/contrib/cloud/aws-import
--- 1.0.0+git-20190125.36a4c85-5.1/contrib/cloud/aws-import	1970-01-01 00:00:00.000000000 +0000
+++ 1.21.1+git-20220113.fbbdc3926-0ubuntu1/contrib/cloud/aws-import	2022-01-13 13:43:08.000000000 +0000
@@ -0,0 +1,139 @@
+#!/usr/bin/env python3
+
+import argparse
+from base64 import b64encode
+from concurrent.futures import ThreadPoolExecutor, as_completed
+from datetime import date
+from hashlib import sha256
+from itertools import count
+import subprocess
+
+import boto3
+
+BLOCKSIZE = 512 * 1024
+
+
+def detect_architecture(image):
+    """Detect CPU architecture"""
+    mdir = subprocess.run(['mdir', '-b', '-i', image, '::/EFI/BOOT'],
+                          capture_output=True)
+    if any(b'BOOTAA64.EFI' in x for x in mdir.stdout.splitlines()):
+        return 'arm64'
+    return 'x86_64'
+
+
+def create_snapshot(region, description, image):
+    """Create an EBS snapshot"""
+    client = boto3.client('ebs', region_name=region)
+    snapshot = client.start_snapshot(VolumeSize=1,
+                                     Description=description)
+    snapshot_id = snapshot['SnapshotId']
+    with open(image, 'rb') as fh:
+        for block in count():
+            data = fh.read(BLOCKSIZE)
+            if not data:
+                break
+            data = data.ljust(BLOCKSIZE, b'\0')
+            checksum = b64encode(sha256(data).digest()).decode()
+            client.put_snapshot_block(SnapshotId=snapshot_id,
+                                      BlockIndex=block,
+                                      BlockData=data,
+                                      DataLength=BLOCKSIZE,
+                                      Checksum=checksum,
+                                      ChecksumAlgorithm='SHA256')
+    client.complete_snapshot(SnapshotId=snapshot_id,
+                             ChangedBlocksCount=block)
+    return snapshot_id
+
+
+def import_image(region, name, architecture, image, public):
+    """Import an AMI image"""
+    client = boto3.client('ec2', region_name=region)
+    resource = boto3.resource('ec2', region_name=region)
+    description = '%s (%s)' % (name, architecture)
+    snapshot_id = create_snapshot(region=region, description=description,
+                                  image=image)
+    client.get_waiter('snapshot_completed').wait(SnapshotIds=[snapshot_id])
+    image = client.register_image(Architecture=architecture,
+                                  BlockDeviceMappings=[{
+                                      'DeviceName': '/dev/sda1',
+                                      'Ebs': {
+                                          'SnapshotId': snapshot_id,
+                                          'VolumeType': 'standard',
+                                      },
+                                  }],
+                                  EnaSupport=True,
+                                  Name=description,
+                                  RootDeviceName='/dev/sda1',
+                                  SriovNetSupport='simple',
+                                  VirtualizationType='hvm')
+    image_id = image['ImageId']
+    client.get_waiter('image_available').wait(ImageIds=[image_id])
+    if public:
+        resource.Image(image_id).modify_attribute(Attribute='launchPermission',
+                                                  OperationType='add',
+                                                  UserGroups=['all'])
+    return image_id
+
+
+def launch_link(region, image_id):
+    """Construct a web console launch link"""
+    return ("https://console.aws.amazon.com/ec2/v2/home?"
+            "region=%s#LaunchInstanceWizard:ami=%s" % (region, image_id))
+
+
+# Parse command-line arguments
+parser = argparse.ArgumentParser(description="Import AWS EC2 image (AMI)")
+parser.add_argument('--name', '-n',
+                    help="Image name")
+parser.add_argument('--public', '-p', action='store_true',
+                    help="Make image public")
+parser.add_argument('--region', '-r', action='append',
+                    help="AWS region(s)")
+parser.add_argument('--wiki', '-w', metavar='FILE',
+                    help="Generate Dokuwiki table")
+parser.add_argument('image', nargs='+', help="iPXE disk image")
+args = parser.parse_args()
+
+# Detect CPU architectures
+architectures = {image: detect_architecture(image) for image in args.image}
+
+# Use default name if none specified
+if not args.name:
+    args.name = 'iPXE (%s)' % date.today().strftime('%Y-%m-%d')
+
+# Use all regions if none specified
+if not args.region:
+    args.region = sorted(x['RegionName'] for x in
+                         boto3.client('ec2').describe_regions()['Regions'])
+
+# Use one thread per import to maximise parallelism
+imports = [(region, image) for region in args.region for image in args.image]
+with ThreadPoolExecutor(max_workers=len(imports)) as executor:
+    futures = {executor.submit(import_image,
+                               region=region,
+                               name=args.name,
+                               architecture=architectures[image],
+                               image=image,
+                               public=args.public): (region, image)
+               for region, image in imports}
+    results = {futures[future]: future.result()
+               for future in as_completed(futures)}
+
+# Construct Dokuwiki table
+wikitab = ["^ AWS region  ^ CPU architecture  ^ AMI ID  ^\n"] + list(
+    "| ''%s''  | ''%s''  | ''[[%s|%s]]''  |\n" % (
+        region,
+        architectures[image],
+        launch_link(region, results[(region, image)]),
+        results[(region, image)],
+    ) for region, image in imports)
+if args.wiki:
+    with open(args.wiki, 'wt') as fh:
+        fh.writelines(wikitab)
+
+# Show created images
+for region, image in imports:
+    print("%s %s %s %s" % (
+        region, image, architectures[image], results[(region, image)]
+    ))
diff -pruN 1.0.0+git-20190125.36a4c85-5.1/contrib/coverity/model.c 1.21.1+git-20220113.fbbdc3926-0ubuntu1/contrib/coverity/model.c
--- 1.0.0+git-20190125.36a4c85-5.1/contrib/coverity/model.c	2019-02-09 16:03:59.000000000 +0000
+++ 1.21.1+git-20220113.fbbdc3926-0ubuntu1/contrib/coverity/model.c	2022-01-13 13:43:08.000000000 +0000
@@ -7,6 +7,9 @@ typedef long off_t;
 typedef void * userptr_t;
 typedef long long time_t;
 struct tm;
+typedef unsigned short wchar_t;
+typedef void mbstate_t;
+struct digest_algorithm;
 
 /* Inhibit use of built-in models for functions where Coverity's
  * assumptions about the modelled function are incorrect for iPXE.
@@ -19,3 +22,8 @@ time_t mktime ( struct tm *tm ) {
 }
 int getchar ( void ) {
 }
+size_t wcrtomb ( char *buf, wchar_t wc, mbstate_t *ps ) {
+}
+void hmac_init ( struct digest_algorithm *digest, void *digest_ctx,
+		 void *key, size_t *key_len ) {
+}
diff -pruN 1.0.0+git-20190125.36a4c85-5.1/contrib/vm/bochsrc.txt 1.21.1+git-20220113.fbbdc3926-0ubuntu1/contrib/vm/bochsrc.txt
--- 1.0.0+git-20190125.36a4c85-5.1/contrib/vm/bochsrc.txt	2019-02-09 16:03:59.000000000 +0000
+++ 1.21.1+git-20220113.fbbdc3926-0ubuntu1/contrib/vm/bochsrc.txt	2022-01-13 13:43:08.000000000 +0000
@@ -7,10 +7,15 @@
 # directly with this option and some of them install a config option that is
 # only available when the plugin device is loaded. The value "1" means to load
 # the plugin and "0" will unload it (if loaded before).
-# These plugins are currently supported: 'biosdev', 'e1000', 'es1370',
-# 'extfpuirq', 'gameport', 'iodebug', 'ne2k', 'parallel', 'pcidev', 'pcipnic',
-# 'sb16', 'serial', 'speaker', 'unmapped', 'usb_ohci', 'usb_uhci' and 'usb_xhci'.
+#
+# These plugins will be loaded by default (if present): 'biosdev', 'extfpuirq',
+# 'gameport', 'iodebug','parallel', 'serial', 'speaker' and 'unmapped'.
+#
+# These plugins are also supported, but they are usually loaded directly with
+# their bochsrc option: 'e1000', 'es1370', 'ne2k', 'pcidev', 'pcipnic', 'sb16',
+# 'usb_ehci', 'usb_ohci', 'usb_uhci', 'usb_xhci' and 'voodoo'.
 #=======================================================================
+#plugin_ctrl: unmapped=0, e1000=1 # unload 'unmapped' and load 'e1000'
 plugin_ctrl: unmapped=1, biosdev=1, speaker=1, e1000=1, parallel=1, serial=1
 
 #=======================================================================
@@ -50,10 +55,11 @@ plugin_ctrl: unmapped=1, biosdev=1, spea
 #   carbon         use Carbon library (for MacOS X)
 #   macintosh      use MacOS pre-10
 #   amigaos        use native AmigaOS libraries
-#   sdl            use SDL library, cross platform
-#   svga           use SVGALIB library for Linux, allows graphics without X11
+#   sdl            use SDL 1.2.x library, cross platform
+#   sdl2           use SDL 2.x library, cross platform
 #   term           text only, uses curses/ncurses library, cross platform
 #   rfb            provides an interface to AT&T's VNC viewer, cross platform
+#   vncsrv         use LibVNCServer for extended RFB(VNC) support
 #   wx             use wxWidgets library, cross platform
 #   nogui          no display at all
 #
@@ -64,52 +70,50 @@ plugin_ctrl: unmapped=1, biosdev=1, spea
 # Some display libraries now support specific options to control their
 # behaviour. These options are supported by more than one display library:
 #
-# "gui_debug"   - use GTK debugger gui (sdl, x) / Win32 debugger gui (win32)
-# "hideIPS"     - disable IPS output in status bar (sdl, wx, x)
-# "nokeyrepeat" - turn off host keyboard repeat (sdl, win32, x)
+# "cmdmode"     - call a headerbar button handler after pressing F7 (sdl, sdl2,
+#                 win32, x)
+# "fullscreen"  - startup in fullscreen mode (sdl, sdl2)
+# "gui_debug"   - use GTK debugger gui (sdl, sdl2, x) / Win32 debugger gui (sdl,
+#                 sdl2, win32)
+# "hideIPS"     - disable IPS output in status bar (rfb, sdl, sdl2, term, vncsrv,
+#                 win32, wx, x)
+# "nokeyrepeat" - turn off host keyboard repeat (sdl, sdl2, win32, x)
+# "timeout"     - time (in seconds) to wait for client (rfb, vncsrv)
 #
 # See the examples below for other currently supported options.
+# Setting up options without specifying display library is also supported.
 #=======================================================================
 #display_library: amigaos
 #display_library: carbon
 #display_library: macintosh
 #display_library: nogui
-#display_library: rfb, options="timeout=60" # time to wait for client
-#display_library: sdl, options="fullscreen" # startup in fullscreen mode
+#display_library: rfb
+#display_library: sdl
+#display_library: sdl2
 #display_library: term
-#display_library: win32
+#display_library: vncsrv
+# "traphotkeys" - system hotkeys not handled by host OS, but sent to guest
+#                 (win32 in mouse capture and fullscreen mode: alt-tab, win,
+#                 alt-space, alt-esc, ctrl-esc)
+# "autoscale"   - scale small simulation window by factor 2, 4 or 8 depending
+#                 on desktop window size
+#display_library: win32, options="traphotkeys, autoscale"
 #display_library: wx
 #display_library: x
 
 #=======================================================================
-# ROMIMAGE:
-# The ROM BIOS controls what the PC does when it first powers on.
-# Normally, you can use a precompiled BIOS in the source or binary
-# distribution called BIOS-bochs-latest. The ROM BIOS is usually loaded
-# starting at address 0xf0000, and it is exactly 64k long. Another option
-# is 128k BIOS which is loaded at address 0xe0000.
-# You can also use the environment variable $BXSHARE to specify the
-# location of the BIOS.
-# The usage of external large BIOS images (up to 512k) at memory top is
-# now supported, but we still recommend to use the BIOS distributed with
-# Bochs. The start address optional, since it can be calculated from image size.
-#=======================================================================
-#romimage: file=$BXSHARE/BIOS-bochs-latest
-#romimage: file=bios/seabios-1.6.3.bin
-#romimage: file=mybios.bin, address=0xfff80000 # 512k at memory top
-romimage: file=bochs/bios/BIOS-bochs-latest
-
-#=======================================================================
 # CPU:
 # This defines cpu-related parameters inside Bochs:
 #
 #  MODEL:
 #    Selects CPU configuration to emulate from pre-defined list of all
-#    supported configurations. When this option is used, the CPUID option
-#    has no effect anymore.
+#    supported configurations. When this option is used and the value
+#    is different from 'bx_generic', the parameters of the CPUID option
+#    have no effect anymore.
 #
 #  CPU configurations that can be selected:
 # -----------------------------------------------------------------
+#  pentium                    Intel Pentium (P54C)
 #  pentium_mmx                Intel Pentium MMX
 #  amd_k6_2_chomper           AMD-K6(tm) 3D processor (Chomper)
 #  p2_klamath                 Intel Pentium II (Klamath)
@@ -117,23 +121,28 @@ romimage: file=bochs/bios/BIOS-bochs-lat
 #  p4_willamette              Intel(R) Pentium(R) 4 (Willamette)
 #  core_duo_t2400_yonah       Intel(R) Core(TM) Duo CPU T2400 (Yonah)
 #  atom_n270                  Intel(R) Atom(TM) CPU N270
+#  p4_prescott_celeron_336    Intel(R) Celeron(R) 336 (Prescott)
 #  athlon64_clawhammer        AMD Athlon(tm) 64 Processor 2800+ (Clawhammer)
 #  athlon64_venice            AMD Athlon(tm) 64 Processor 3000+ (Venice)
 #  turion64_tyler             AMD Turion(tm) 64 X2 Mobile TL-60 (Tyler)
 #  phenom_8650_toliman        AMD Phenom X3 8650 (Toliman)
-#  p4_prescott_celeron_336    Intel(R) Celeron(R) 336 (Prescott)
 #  core2_penryn_t9600         Intel Mobile Core 2 Duo T9600 (Penryn)
 #  corei5_lynnfield_750       Intel(R) Core(TM) i5   750 (Lynnfield)
 #  corei5_arrandale_m520      Intel(R) Core(TM) i5 M 520 (Arrandale)
 #  corei7_sandy_bridge_2600k  Intel(R) Core(TM) i7-2600K (Sandy Bridge)
+#  zambezi                    AMD FX(tm)-4100 Quad-Core Processor (Zambezi)
+#  trinity_apu                AMD A8-5600K APU (Trinity)
+#  ryzen                      AMD Ryzen 7 1700
 #  corei7_ivy_bridge_3770k    Intel(R) Core(TM) i7-3770K CPU (Ivy Bridge)
+#  corei7_haswell_4770        Intel(R) Core(TM) i7-4770 CPU (Haswell)
+#  broadwell_ult              Intel(R) Processor 5Y70 CPU (Broadwell)
 #
 #  COUNT:
-#    Set the number of processors:cores per processor:threads per core
-#    when Bochs is compiled for SMP emulation.
-#    Bochs currently supports up to 8 threads running simultaniosly.
-#    If Bochs is compiled without SMP support, it won't accept values
-#    different from 1.
+#    Set the number of processors:cores per processor:threads per core when
+#    Bochs is compiled for SMP emulation. Bochs currently supports up to
+#    14 threads (legacy APIC) or 254 threads (xAPIC or higher) running
+#    simultaniosly. If Bochs is compiled without SMP support, it won't accept
+#    values different from 1.
 #
 #  QUANTUM:
 #    Maximum amount of instructions allowed to execute by processor before
@@ -156,7 +165,7 @@ romimage: file=bochs/bios/BIOS-bochs-lat
 #  IGNORE_BAD_MSRS:
 #    Ignore MSR references that Bochs does not understand; print a warning
 #    message instead of generating #GP exception. This option is enabled
-#    by default but will not be avaiable if configurable MSRs are enabled.
+#    by default but will not be available if configurable MSRs are enabled.
 #
 #  MWAIT_IS_NOP:
 #    When this option is enabled MWAIT will not put the CPU into a sleep state.
@@ -205,23 +214,38 @@ cpu: cpuid_limit_winnt=0
 #    Select SYSENTER/SYSEXIT instruction set support.
 #    This option exists only if Bochs compiled with BX_CPU_LEVEL >= 6.
 #
-#  SSE:
-#    Select SSE instruction set support.
-#    Any of NONE/SSE/SSE2/SSE3/SSSE3/SSE4_1/SSE4_2 could be selected.
+#  SIMD:
+#    Select SIMD instructions support.
+#    Any of NONE/SSE/SSE2/SSE3/SSSE3/SSE4_1/SSE4_2/AVX/AVX2/AVX512
+#    could be selected.
+#
 #    This option exists only if Bochs compiled with BX_CPU_LEVEL >= 6.
+#    The AVX choises exists only if Bochs compiled with --enable-avx option.
 #
 #  SSE4A:
 #    Select AMD SSE4A instructions support.
 #    This option exists only if Bochs compiled with BX_CPU_LEVEL >= 6.
 #
+#  MISALIGNED_SSE:
+#    Select AMD Misaligned SSE mode support.
+#    This option exists only if Bochs compiled with BX_CPU_LEVEL >= 6.
+#
 #  AES:
 #    Select AES instruction set support.
 #    This option exists only if Bochs compiled with BX_CPU_LEVEL >= 6.
 #
+#  SHA:
+#    Select SHA instruction set support.
+#    This option exists only if Bochs compiled with BX_CPU_LEVEL >= 6.
+#
 #  MOVBE:
 #    Select MOVBE Intel(R) Atom instruction support.
 #    This option exists only if Bochs compiled with BX_CPU_LEVEL >= 6.
 #
+#  ADX:
+#    Select ADCX/ADOX instructions support.
+#    This option exists only if Bochs compiled with BX_CPU_LEVEL >= 6.
+#
 #  XSAVE:
 #    Select XSAVE extensions support.
 #    This option exists only if Bochs compiled with BX_CPU_LEVEL >= 6.
@@ -230,10 +254,6 @@ cpu: cpuid_limit_winnt=0
 #    Select XSAVEOPT instruction support.
 #    This option exists only if Bochs compiled with BX_CPU_LEVEL >= 6.
 #
-#  AVX:
-#    Select AVX/AVX2 instruction set support.
-#    This option exists only if Bochs compiled with --enable-avx option.
-#
 #  AVX_F16C:
 #    Select AVX float16 convert instructions support.
 #    This option exists only if Bochs compiled with --enable-avx option.
@@ -278,6 +298,10 @@ cpu: cpuid_limit_winnt=0
 #    Enable Supervisor Mode Execution Protection (SMEP) support.
 #    This option exists only if Bochs compiled with BX_CPU_LEVEL >= 6.
 #
+#  SMAP:
+#    Enable Supervisor Mode Access Prevention (SMAP) support.
+#    This option exists only if Bochs compiled with BX_CPU_LEVEL >= 6.
+#
 #  MWAIT:
 #    Select MONITOR/MWAIT instructions support.
 #    This option exists only if Bochs compiled with --enable-monitor-mwait.
@@ -286,6 +310,10 @@ cpu: cpuid_limit_winnt=0
 #    Select VMX extensions emulation support.
 #    This option exists only if Bochs compiled with --enable-vmx option.
 #
+#  SVM:
+#    Select AMD SVM (Secure Virtual Machine) extensions emulation support.
+#    This option exists only if Bochs compiled with --enable-svm option.
+#
 #  VENDOR_STRING:
 #    Set the CPUID vendor string returned by CPUID(0x0). This should be a
 #    twelve-character ASCII string.
@@ -294,6 +322,12 @@ cpu: cpuid_limit_winnt=0
 #    Set the CPUID vendor string returned by CPUID(0x80000002 .. 0x80000004).
 #    This should be at most a forty-eight-character ASCII string.
 #
+#  LEVEL:
+#    Set emulated CPU level information returned by CPUID. Default value is
+#    determined by configure option --enable-cpu-level. Currently supported
+#    values are 5 (for Pentium and similar processors) and 6 (for P6 and
+#    later processors).
+#
 #  FAMILY:
 #    Set model information returned by CPUID. Default family value determined
 #    by configure option --enable-cpu-level.
@@ -304,7 +338,7 @@ cpu: cpuid_limit_winnt=0
 #  STEPPING:
 #    Set stepping information returned by CPUID. Default stepping value is 3.
 #=======================================================================
-#cpuid: x86_64=1, mmx=1, sep=1, sse=sse4_2, apic=xapic, aes=1, movbe=1, xsave=1
+#cpuid: x86_64=1, mmx=1, sep=1, simd=sse4_2, apic=xapic, aes=1, movbe=1, xsave=1
 #cpuid: family=6, model=0x1a, stepping=5
 
 #=======================================================================
@@ -327,6 +361,37 @@ cpu: cpuid_limit_winnt=0
 memory: guest=512, host=256
 
 #=======================================================================
+# ROMIMAGE:
+# The ROM BIOS controls what the PC does when it first powers on.
+# Normally, you can use a precompiled BIOS in the source or binary
+# distribution called BIOS-bochs-latest. The default ROM BIOS is usually loaded
+# starting at address 0xfffe0000, and it is exactly 128k long. The legacy
+# version of the Bochs BIOS is usually loaded starting at address 0xffff0000,
+# and it is exactly 64k long.
+# You can use the environment variable $BXSHARE to specify the location
+# of the BIOS.
+# The usage of external large BIOS images (up to 512k) at memory top is
+# now supported, but we still recommend to use the BIOS distributed with Bochs.
+# The start address is optional, since it can be calculated from image size.
+# The Bochs BIOS currently supports only the option "fastboot" to skip the
+# boot menu delay.
+#=======================================================================
+#romimage: file=$BXSHARE/BIOS-bochs-latest, options=fastboot
+#romimage: file=$BXSHARE/bios.bin-1.13.0 # http://www.seabios.org/SeaBIOS
+#romimage: file=mybios.bin, address=0xfff80000 # 512k at memory top
+romimage: file=bochs/bios/BIOS-bochs-latest
+
+#=======================================================================
+# VGAROMIMAGE
+# You now need to load a VGA ROM BIOS into C0000.
+#=======================================================================
+#vgaromimage: file=$BXSHARE/VGABIOS-lgpl-latest
+#vgaromimage: file=bios/VGABIOS-lgpl-latest-cirrus
+#vgaromimage: file=$BXSHARE/vgabios-cirrus.bin-1.13.0 # http://www.seabios.org/SeaVGABIOS
+#vgaromimage: file=bios/VGABIOS-elpin-2.40
+vgaromimage: file=bochs/bios/VGABIOS-lgpl-latest
+
+#=======================================================================
 # OPTROMIMAGE[1-4]:
 # You may now load up to 4 optional ROM images. Be sure to use a
 # read-only area, typically between C8000 and EFFFF. These optional
@@ -349,35 +414,233 @@ optromimage1: file=../../src/bin/intel.r
 #optramimage4: file=/path/file4.img, address=0x0040000
 
 #=======================================================================
-# VGAROMIMAGE
-# You now need to load a VGA ROM BIOS into C0000.
-#=======================================================================
-#vgaromimage: file=bios/VGABIOS-elpin-2.40
-#vgaromimage: file=$BXSHARE/VGABIOS-lgpl-latest
-#vgaromimage: file=bios/VGABIOS-lgpl-latest-cirrus
-vgaromimage: file=bochs/bios/VGABIOS-lgpl-latest
-
-#=======================================================================
 # VGA:
 # This defines parameters related to the VGA display
 #
 #   EXTENSION
 #     Here you can specify the display extension to be used. With the value
 #     'none' you can use standard VGA with no extension. Other supported
-#     values are 'vbe' for Bochs VBE and 'cirrus' for Cirrus SVGA support.
+#     values are 'vbe' for Bochs VBE, 'cirrus' for Cirrus SVGA support and
+#     'voodoo' for Voodoo Graphics support (see 'voodoo' option).
 #
 #   UPDATE_FREQ
-#     The VGA update frequency is based on the emulated clock and the default
-#     value is 5. Keep in mind that you must tweak the 'cpu: ips=N' directive
-#     to be as close to the number of emulated instructions-per-second your
-#     workstation can do, for this to be accurate. If the realtime sync is
-#     enabled with the 'clock' option, the value is based on the real time.
-#     This parameter can be changed at runtime.
+#     This parameter specifies the number of display updates per second.
+#     The VGA update timer by default uses the realtime engine with a value
+#     of 5. This parameter can be changed at runtime.
+#
+#   REALTIME
+#     If set to 1 (default), the VGA timer is based on realtime, otherwise it
+#     is driven by the cpu and depends on the ips setting. If the host is slow
+#     (low ips, update_freq) and the guest uses HLT appropriately, setting this
+#     to 0 and "clock: sync=none" may improve the responsiveness of the guest
+#     GUI when the guest is otherwise idle.
+#
+#   DDC
+#     This parameter defines the behaviour of the DDC emulation that returns
+#     the monitor EDID data. By default the 'builtin' values for 'Bochs Screen'
+#     are used. Other choices are 'disabled' (no DDC emulation) and 'file'
+#     (read monitor EDID from file / path name separated with a colon).
+# Examples:
+#   vga: extension=cirrus, update_freq=10, ddc=builtin
+#=======================================================================
+#vga: extension=vbe, update_freq=5, realtime=1, ddc=file:monitor.bin
+
+#=======================================================================
+# VOODOO:
+# This defines the Voodoo Graphics emulation (experimental). Currently
+# supported models are 'voodoo1', 'voodoo2', 'banshee' and 'voodoo3'. The
+# Voodoo2 support is not yet complete, but almost usable. The Banshee and
+# Voodoo3 support is under construction, but basically usable. The 2D/3D cards
+# require an external VGA BIOS the vga extension option to be set to 'voodoo'.
+# If the i440BX PCI chipset is selected, they can be assigned to AGP (slot #5).
+# The gui screen update timing for all models is controlled by the related 'vga'
+# options.
 #
 # Examples:
-#   vga: extension=cirrus, update_freq=10
+#   voodoo: enabled=1, model=voodoo2
+#=======================================================================
+#voodoo: enabled=1, model=voodoo1
+
 #=======================================================================
-#vga: extension=vbe, update_freq=5
+# KEYBOARD:
+# This defines parameters related to the emulated keyboard
+#
+#   TYPE:
+#     Type of keyboard return by a "identify keyboard" command to the
+#     keyboard controller. It must be one of "xt", "at" or "mf".
+#     Defaults to "mf". It should be ok for almost everybody. A known
+#     exception is french macs, that do have a "at"-like keyboard.
+#
+#   SERIAL_DELAY:
+#     Approximate time in microseconds that it takes one character to
+#     be transferred from the keyboard to controller over the serial path.
+#
+#   PASTE_DELAY:
+#     Approximate time in microseconds between attempts to paste
+#     characters to the keyboard controller. This leaves time for the
+#     guest os to deal with the flow of characters.  The ideal setting
+#     depends on how your operating system processes characters.  The
+#     default of 100000 usec (.1 seconds) was chosen because it works
+#     consistently in Windows.
+#     If your OS is losing characters during a paste, increase the paste
+#     delay until it stops losing characters.
+#
+#   KEYMAP:
+#     This enables a remap of a physical localized keyboard to a
+#     virtualized us keyboard, as the PC architecture expects.
+#
+#   USER_SHORTCUT:
+#     This defines the keyboard shortcut to be sent when you press the "user"
+#     button in the headerbar. The shortcut string is a combination of maximum
+#     3 key names (listed below) separated with a '-' character.
+#     Valid key names:
+#     "alt", "bksl", "bksp", "ctrl", "del", "down", "end", "enter", "esc",
+#     "f1", ... "f12", "home", "ins", "left", "menu", "minus", "pgdwn", "pgup",
+#     "plus", "power", "print", "right", "scrlck", "shift", "space", "tab", "up"
+#     and "win".
+
+# Examples:
+#   keyboard: type=mf, serial_delay=200, paste_delay=100000
+#   keyboard: keymap=gui/keymaps/x11-pc-de.map
+#   keyboard: user_shortcut=ctrl-alt-del
+#=======================================================================
+#keyboard: type=mf, serial_delay=250
+
+#=======================================================================
+# MOUSE:
+# This defines parameters for the emulated mouse type, the initial status
+# of the mouse capture and the runtime method to toggle it.
+#
+#  TYPE:
+#  With the mouse type option you can select the type of mouse to emulate.
+#  The default value is 'ps2'. The other choices are 'imps2' (wheel mouse
+#  on PS/2), 'serial', 'serial_wheel', 'serial_msys' (one com port requires
+#  setting 'mode=mouse') 'inport' and 'bus' (if present). To connect a mouse
+#  to a USB port, see the 'usb_uhci', 'usb_ohci', 'usb_ehci' or 'usb_xhci'
+#  options (requires PCI and USB support).
+#
+#  ENABLED:
+#  The Bochs gui creates mouse "events" unless the 'enabled' option is
+#  set to 0. The hardware emulation itself is not disabled by this.
+#  Unless you have a particular reason for enabling the mouse by default,
+#  it is recommended that you leave it off. You can also toggle the mouse
+#  usage at runtime (RFB, SDL, Win32, wxWidgets and X11 - see below).
+#
+#  TOGGLE:
+#  The default method to toggle the mouse capture at runtime is to press the
+#  CTRL key and the middle mouse button ('ctrl+mbutton'). This option allows
+#  to change the method to 'ctrl+f10' (like DOSBox), 'ctrl+alt' (like QEMU)
+#  or 'f12'.
+#
+# Examples:
+#   mouse: enabled=1
+#   mouse: type=imps2, enabled=1
+#   mouse: type=serial, enabled=1
+#   mouse: enabled=0, toggle=ctrl+f10
+#=======================================================================
+mouse: enabled=0
+
+#=======================================================================
+# PCI:
+# This defines the parameters to set up the Bochs PCI emulation:
+#
+#  ENABLED:
+#  If Bochs is compiled with PCI support, it is enabled by default.
+#
+#  CHIPSET:
+#  Currently the chipsets i430FX, i440FX and i440BX (limited) are supported and
+#  the default is i440FX.
+#
+#  SLOTx:
+#  It is possible to specify the devices connected to PCI slots. Up to 5 slots
+#  are available. For combined PCI/ISA devices assigning to slot is mandatory
+#  if the PCI model should be emulated (cirrus, ne2k and pcivga). Setting up
+#  slot for PCI-only devices is also supported, but they are auto-assigned if
+#  not specified (e1000, es1370, pcidev, pcipnic, usb_ehci, usb_ohci, usb_xhci,
+#  voodoo). All device models except the network devices ne2k and e1000 can be
+#  used only once in the slot configuration. In case of the i440BX chipset, the
+#  slot #5 is the AGP slot. Currently only the 'voodoo' device can be assigned
+#  to AGP.
+#
+#  ADVOPTS:
+#  With the advanced PCI options it is possible to control the behaviour of the
+#  PCI chipset. These options can be specified as comma-separated values.
+#  By default the "Bochs i440FX" chipset enables the ACPI and HPET devices, but
+#  original i440FX doesn't support them. The options 'noacpi' and 'nohpet' make
+#  it possible to disable them.
+#
+# Example:
+#   pci: enabled=1, chipset=i440fx, slot1=pcivga, slot2=ne2k, advopts=noacpi
+#=======================================================================
+pci: enabled=1, chipset=i440fx
+
+#=======================================================================
+# CLOCK:
+# This defines the parameters of the clock inside Bochs:
+#
+#  SYNC:
+#  This defines the method how to synchronize the Bochs internal time
+#  with realtime. With the value 'none' the Bochs time relies on the IPS
+#  value and no host time synchronization is used. The 'slowdown' method
+#  sacrifices performance to preserve reproducibility while allowing host
+#  time correlation. The 'realtime' method sacrifices reproducibility to
+#  preserve performance and host-time correlation.
+#  It is possible to enable both synchronization methods.
+#
+#  RTC_SYNC:
+#  If this option is enabled together with the realtime synchronization,
+#  the RTC runs at realtime speed. This feature is disabled by default.
+#
+#  TIME0:
+#  Specifies the start (boot) time of the virtual machine. Use a time
+#  value as returned by the time(2) system call or a string as returned
+#  by the ctime(3) system call. If no time0 value is set or if time0
+#  equal to 1 (special case) or if time0 equal 'local', the simulation
+#  will be started at the current local host time. If time0 equal to 2
+#  (special case) or if time0 equal 'utc', the simulation will be started
+#  at the current utc time.
+#
+# Syntax:
+#  clock: sync=[none|slowdown|realtime|both], time0=[timeValue|local|utc]
+#
+# Example:
+#   clock: sync=none,     time0=local       # Now (localtime)
+#   clock: sync=slowdown, time0=315529200   # Tue Jan  1 00:00:00 1980
+#   clock: sync=none,     time0="Mon Jan  1 00:00:00 1990" # 631148400
+#   clock: sync=realtime, time0=938581955   # Wed Sep 29 07:12:35 1999
+#   clock: sync=realtime, time0="Sat Jan  1 00:00:00 2000" # 946681200
+#   clock: sync=none,     time0=1           # Now (localtime)
+#   clock: sync=none,     time0=utc         # Now (utc/gmt)
+#
+# Default value are sync=none, rtc_sync=0, time0=local
+#=======================================================================
+#clock: sync=none, time0=local
+
+#=======================================================================
+# CMOSIMAGE:
+# This defines a binary image file with size 128 bytes that can be loaded into
+# the CMOS RAM at startup. The rtc_init parameter controls whether initialize
+# the RTC with values stored in the image. By default the time0 argument given
+# to the clock option is used. With 'rtc_init=image' the image is the source
+# for the initial time.
+#
+# Example:
+#   cmosimage: file=cmos.img, rtc_init=image
+#=======================================================================
+#cmosimage: file=cmos.img, rtc_init=time0
+
+#=======================================================================
+# private_colormap: Request that the GUI create and use it's own
+#                   non-shared colormap.  This colormap will be used
+#                   when in the bochs window.  If not enabled, a
+#                   shared colormap scheme may be used.  Not implemented
+#                   on all GUI's.
+#
+# Examples:
+#   private_colormap: enabled=1
+#   private_colormap: enabled=0
+#=======================================================================
+private_colormap: enabled=0
 
 #=======================================================================
 # FLOPPYA:
@@ -450,14 +713,14 @@ ata3: enabled=0, ioaddr1=0x168, ioaddr2=
 #
 # This defines the type and characteristics of all attached ata devices:
 #   type=       type of attached device [disk|cdrom]
-#   mode=       only valid for disks [flat|concat|external|dll|sparse|vmware3]
-#   mode=       only valid for disks [undoable|growing|volatile|vvfat]
+#   mode=       only valid for disks [flat|concat|dll|sparse|vmware3|vmware4]
+#                                    [undoable|growing|volatile|vpc|vbox|vvfat]
 #   path=       path of the image / directory
 #   cylinders=  only valid for disks
 #   heads=      only valid for disks
 #   spt=        only valid for disks
 #   status=     only valid for cdroms [inserted|ejected]
-#   biosdetect= type of biosdetection [none|auto], only for disks on ata0 [cmos]
+#   biosdetect= type of biosdetection [auto|cmos|none]
 #   translation=type of translation of the bios, only for disks [none|lba|large|rechs|auto]
 #   model=      string returned by identify device command
 #   journal=    optional filename of the redolog for undoable, volatile and vvfat disks
@@ -520,48 +783,6 @@ ata3: enabled=0, ioaddr1=0x168, ioaddr2=
 boot: network, floppy
 
 #=======================================================================
-# CLOCK:
-# This defines the parameters of the clock inside Bochs:
-#
-#  SYNC:
-#  This defines the method how to synchronize the Bochs internal time
-#  with realtime. With the value 'none' the Bochs time relies on the IPS
-#  value and no host time synchronization is used. The 'slowdown' method
-#  sacrifices performance to preserve reproducibility while allowing host
-#  time correlation. The 'realtime' method sacrifices reproducibility to
-#  preserve performance and host-time correlation.
-#  It is possible to enable both synchronization methods.
-#
-#  RTC_SYNC:
-#  If this option is enabled together with the realtime synchronization,
-#  the RTC runs at realtime speed. This feature is disabled by default.
-#
-#  TIME0:
-#  Specifies the start (boot) time of the virtual machine. Use a time
-#  value as returned by the time(2) system call. If no time0 value is
-#  set or if time0 equal to 1 (special case) or if time0 equal 'local',
-#  the simulation will be started at the current local host time.
-#  If time0 equal to 2 (special case) or if time0 equal 'utc',
-#  the simulation will be started at the current utc time.
-#
-# Syntax:
-#  clock: sync=[none|slowdown|realtime|both], time0=[timeValue|local|utc]
-#
-# Example:
-#   clock: sync=none,     time0=local       # Now (localtime)
-#   clock: sync=slowdown, time0=315529200   # Tue Jan  1 00:00:00 1980
-#   clock: sync=none,     time0=631148400   # Mon Jan  1 00:00:00 1990
-#   clock: sync=realtime, time0=938581955   # Wed Sep 29 07:12:35 1999
-#   clock: sync=realtime, time0=946681200   # Sat Jan  1 00:00:00 2000
-#   clock: sync=none,     time0=1           # Now (localtime)
-#   clock: sync=none,     time0=utc         # Now (utc/gmt)
-#
-# Default value are sync=none, time0=local
-#=======================================================================
-#clock: sync=none, time0=local
-
-
-#=======================================================================
 # FLOPPY_BOOTSIG_CHECK: disabled=[0|1]
 # Enables or disables the 0xaa55 signature check on boot floppies
 # Defaults to disabled=0
@@ -613,9 +834,11 @@ log: bochsout.txt
 #   debug: messages useful only when debugging the code.  This may
 #          spit out thousands per second.
 #
-# For events of each level, you can choose to exit Bochs ('fatal'), 'report'
-# or 'ignore'. On some guis you have the additional choice 'ask'. A gui dialog
-# appears asks how to proceed.
+# For events of each level, you can choose to exit Bochs ('fatal'), 'ask',
+# 'warn', 'report' or 'ignore'. The choices 'ask' and 'warn' are not supported
+# by all guis, since they should bring up a dialog box. The 'warn' dialog is
+# designed to confirm errors and the 'ask' dialog is usually used for panics
+# and asks the user how to proceed.
 #
 # It is also possible to specify the 'action' to do for each Bochs facility
 # separately (e.g. crash on panics from everything except the cdrom, and only
@@ -646,10 +869,10 @@ debugger_log: -
 
 #=======================================================================
 # COM1, COM2, COM3, COM4:
-# This defines a serial port (UART type 16550A). In the 'term' you can specify
-# a device to use as com1. This can be a real serial line, or a pty.  To use
-# a pty (under X/Unix), create two windows (xterms, usually).  One of them will
-# run bochs, and the other will act as com1. Find out the tty the com1
+# This defines a serial port (UART type 16550A). In the 'term' mode you can
+# specify a device to use as com1. This can be a real serial line, or a pty.
+# To use a pty (under X/Unix), create two windows (xterms, usually).  One of
+# them will run bochs, and the other will act as com1. Find out the tty the com1
 # window using the `tty' command, and use that as the `dev' parameter.
 # Then do `sleep 1000000' in the com1 window to keep the shell from
 # messing with things, and run bochs in the other window.  Serial I/O to
@@ -660,13 +883,13 @@ debugger_log: -
 # opens socket/named pipe and waits until a client application connects to it
 # before starting simulation. This mode is useful for remote debugging (e.g.
 # with gdb's "target remote host:port" command or windbg's command line option
-# -k com:pipe,port=\\.\pipe\pipename). Note: 'socket' is a shorthand for
-# 'socket-client' and 'pipe' for 'pipe-client'. Socket modes use simple TCP
-# communication, pipe modes use duplex byte mode pipes.
+# -k com:pipe,port=\\.\pipe\pipename). Socket modes use simple TCP communication,
+#  pipe modes use duplex byte mode pipes.
 # Other serial modes are 'null' (no input/output), 'file' (output to a file
-# specified as the 'dev' parameter), 'raw' (use the real serial port - under
-# construction for win32), 'mouse' (standard serial mouse - requires
-# mouse option setting 'type=serial', 'type=serial_wheel' or 'type=serial_msys').
+# specified as the 'dev' parameter and changeable at runtime), 'raw' (use the
+# real serial port - partly implemented on win32), 'mouse' (standard serial
+# mouse - requires mouse option setting 'type=serial', 'type=serial_wheel' or
+# 'type=serial_msys').
 #
 # Examples:
 #   com1: enabled=1, mode=null
@@ -687,7 +910,7 @@ debugger_log: -
 # defined the emulated printer port sends characters printed by the guest OS
 # into the output file. On some platforms a device filename can be used to
 # send the data to the real parallel port (e.g. "/dev/lp0" on Linux, "lpt1" on
-# win32 platforms).
+# win32 platforms). The output file can be changed at runtime.
 #
 # Examples:
 #   parport1: enabled=1, file="parport.out"
@@ -697,28 +920,76 @@ debugger_log: -
 parport1: enabled=1, file="parport.out"
 
 #=======================================================================
+# SOUND:
+# This defines the lowlevel sound driver(s) for the wave (PCM) input / output
+# and the MIDI output feature and (if necessary) the devices to be used.
+# It can have several of the following properties.
+# All properties are in the format sound: property=value
+#
+# waveoutdrv:
+#      This defines the driver to be used for the waveout feature.
+#      Possible values are 'file' (all wave data sent to file), 'dummy' (no
+#      output) and the platform-dependant drivers 'alsa', 'oss', 'osx', 'sdl'
+#      and 'win'.
+# waveout:
+#      This defines the device to be used for wave output (if necessary) or
+#      the output file for the 'file' driver.
+# waveindrv:
+#      This defines the driver to be used for the wavein feature.
+#      Possible values are 'dummy' (recording silence) and platform-dependent
+#      drivers 'alsa', 'oss', 'sdl' and 'win'.
+# wavein:
+#      This defines the device to be used for wave input (if necessary).
+# midioutdrv:
+#      This defines the driver to be used for the MIDI output feature.
+#      Possible values are 'file' (all MIDI data sent to file), 'dummy' (no
+#      output) and platform-dependent drivers 'alsa', 'oss', 'osx' and 'win'.
+# midiout:
+#      This defines the device to be used for MIDI output (if necessary).
+# driver:
+#      This defines the driver to be used for all sound features with one
+#      property. Possible values are 'default' (platform default) and all
+#      other choices described above. Overriding one or more settings with
+#      the specific driver parameter is possible.
+#
+# Example for different drivers:
+#   sound: waveoutdrv=sdl, waveindrv=alsa, midioutdrv=dummy
+#=======================================================================
+#sound: driver=default, waveout=/dev/dsp. wavein=, midiout=
+
+#=======================================================================
+# SPEAKER:
+# This defines the PC speaker output mode. In the 'sound' mode the beep
+# is generated by the square wave generator which is a part of the
+# lowlevel sound support. In this mode the 'volume' parameter can be used
+# to set the output volume (0 - 15). The 'system' mode is only available on
+# Linux and Windows. On Linux /dev/console is used for output and on Windows
+# the Beep() function. The 'gui' mode forwards the beep to the related
+# gui methods (currently only used by the Carbon gui).
+#=======================================================================
+speaker: enabled=1, mode=system
+
+#=======================================================================
 # SB16:
 # This defines the SB16 sound emulation. It can have several of the
 # following properties.
 # All properties are in the format sb16: property=value
+#
 # enabled:
 #      This optional property controls the presence of the SB16 emulation.
 #      The emulation is turned on unless this property is used and set to 0.
-# midi: The filename is where the midi data is sent. This can be a
-#       device or just a file if you want to record the midi data.
-# midimode:
-#      0=no data
-#      1=output to device (system dependent. midi denotes the device driver)
-#      2=SMF file output, including headers
-#      3=output the midi data stream to the file (no midi headers and no
-#        delta times, just command and data bytes)
-# wave: This is the device/file where wave output is stored
-# wavemode:
-#      0=no data
-#      1=output to device (system dependent. wave denotes the device driver)
-#      2=VOC file output, incl. headers
-#      3=output the raw wave stream to the file
-# log:  The file to write the sb16 emulator messages to.
+# midimode: This parameter specifies what to do with the MIDI output.
+#      0 = no output
+#      1 = output to device specified with the sound option (system dependent)
+#      2 = MIDI or raw data output to file (depends on file name extension)
+#      3 = dual output (mode 1 and 2 at the same time)
+# midifile: This is the file where the midi output is stored (midimode 2 or 3).
+# wavemode: This parameter specifies what to do with the PCM output.
+#      0 = no output
+#      1 = output to device specified with the sound option (system dependent)
+#      2 = VOC, WAV or raw data output to file (depends on file name extension)
+#      3 = dual output (mode 1 and 2 at the same time)
+# wavefile: This is the file where the wave output is stored (wavemode 2 or 3).
 # loglevel:
 #      0=no log
 #      1=resource changes, midi program and bank changes
@@ -726,125 +997,50 @@ parport1: enabled=1, file="parport.out"
 #      3=all errors
 #      4=all errors plus all port accesses
 #      5=all errors and port accesses plus a lot of extra info
+# log:  The file to write the sb16 emulator messages to.
 # dmatimer:
 #      microseconds per second for a DMA cycle.  Make it smaller to fix
 #      non-continuous sound.  750000 is usually a good value.  This needs a
 #      reasonably correct setting for the IPS parameter of the CPU option.
 #
-# Examples for output devices:
-#   sb16: midimode=1, midi="", wavemode=1, wave=""           # win32
-#   sb16: midimode=1, midi=alsa:128:0, wavemode=1, wave=alsa # Linux with ALSA
+# Examples for output modes:
+#   sb16: midimode=2, midifile="output.mid", wavemode=1 # MIDI to file
+#   sb16: midimode=1, wavemode=3, wavefile="output.wav" # wave to file and device
 #=======================================================================
-#sb16: midimode=1, midi=/dev/midi00, wavemode=1, wave=/dev/dsp, loglevel=2, log=sb16.log, dmatimer=600000
+#sb16: midimode=1, wavemode=1, loglevel=2, log=sb16.log, dmatimer=600000
 
 #=======================================================================
 # ES1370:
-# This defines the ES1370 sound emulation. The parameter 'enabled' controls the
-# presence of the device. In addition to this, it must be loaded with 'plugin_ctrl'
-# and assigned to a PCI slot. The 'wavedev' parameter is similar to the 'wave'
-# parameter of the SB16 soundcard. The emulation supports recording and playback
-# (except DAC1+DAC2 output at the same time).
-#
-# Examples:
-#   es1370: enabled=1, wavedev=""       # win32
-#   es1370: enabled=1, wavedev=alsa     # Linux with ALSA
-#=======================================================================
-#es1370: enabled=1, wavedev=alsa
-
-#=======================================================================
-# KEYBOARD_SERIAL_DELAY:
-# Approximate time in microseconds that it takes one character to
-# be transfered from the keyboard to controller over the serial path.
-# Examples:
-#   keyboard_serial_delay: 200
-#=======================================================================
-keyboard_serial_delay: 250
-
-#=======================================================================
-# KEYBOARD_PASTE_DELAY:
-# Approximate time in microseconds between attempts to paste
-# characters to the keyboard controller. This leaves time for the
-# guest os to deal with the flow of characters.  The ideal setting
-# depends on how your operating system processes characters.  The
-# default of 100000 usec (.1 seconds) was chosen because it works
-# consistently in Windows.
-#
-# If your OS is losing characters during a paste, increase the paste
-# delay until it stops losing characters.
+# This defines the ES1370 sound emulation (recording and playback - except
+# DAC1+DAC2 output at the same time). The parameter 'enabled' controls the
+# presence of the device. The wave and MIDI output can be sent to device, file
+# or both using the parameters 'wavemode', 'wavefile', 'midimode' and
+# 'midifile'. See the description of these parameters at the SB16 directive.
 #
 # Examples:
-#   keyboard_paste_delay: 100000
+#   es1370: enabled=1, wavemode=1                       # use 'sound' parameters
+#   es1370: enabled=1, wavemode=2, wavefile=output.voc  # send output to file
 #=======================================================================
-keyboard_paste_delay: 100000
-
-#=======================================================================
-# MOUSE:
-# This defines parameters for the emulated mouse type, the initial status
-# of the mouse capture and the runtime method to toggle it.
-#
-#  TYPE:
-#  With the mouse type option you can select the type of mouse to emulate.
-#  The default value is 'ps2'. The other choices are 'imps2' (wheel mouse
-#  on PS/2), 'serial', 'serial_wheel' and 'serial_msys' (one com port requires
-#  setting 'mode=mouse'). To connect a mouse to an USB port, see the 'usb_uhci',
-#  'usb_ohci' or 'usb_xhci' options (requires PCI and USB support).
-#
-#  ENABLED:
-#  The Bochs gui creates mouse "events" unless the 'enabled' option is
-#  set to 0. The hardware emulation itself is not disabled by this.
-#  Unless you have a particular reason for enabling the mouse by default,
-#  it is recommended that you leave it off. You can also toggle the mouse
-#  usage at runtime (RFB, SDL, Win32, wxWidgets and X11 - see below).
-#
-#  TOGGLE:
-#  The default method to toggle the mouse capture at runtime is to press the
-#  CTRL key and the middle mouse button ('ctrl+mbutton'). This option allows
-#  to change the method to 'ctrl+f10' (like DOSBox), 'ctrl+alt' (like QEMU)
-#  or 'f12' (replaces win32 'legacyF12' option).
-#
-# Examples:
-#   mouse: enabled=1
-#   mouse: type=imps2, enabled=1
-#   mouse: type=serial, enabled=1
-#   mouse: enabled=0, toggle=ctrl+f10
-#=======================================================================
-mouse: enabled=0
-
-#=======================================================================
-# private_colormap: Request that the GUI create and use it's own
-#                   non-shared colormap.  This colormap will be used
-#                   when in the bochs window.  If not enabled, a
-#                   shared colormap scheme may be used.  Not implemented
-#                   on all GUI's.
-#
-# Examples:
-#   private_colormap: enabled=1
-#   private_colormap: enabled=0
-#=======================================================================
-private_colormap: enabled=0
-
-#=======================================================================
-# fullscreen: ONLY IMPLEMENTED ON AMIGA
-#             Request that Bochs occupy the entire screen instead of a
-#             window.
-#
-# Examples:
-#   fullscreen: enabled=0
-#   fullscreen: enabled=1
-#=======================================================================
-#fullscreen: enabled=0
-#screenmode: name="sample"
+#es1370: enabled=1, wavemode=1
 
 #=======================================================================
 # ne2k: NE2000 compatible ethernet adapter
 #
 # Format:
-# ne2k: enabled=1, ioaddr=IOADDR, irq=IRQ, mac=MACADDR, ethmod=MODULE,
-#       ethdev=DEVICE, script=SCRIPT, bootrom=BOOTROM
+# ne2k: card=CARD, enabled=1, type=TYPE, ioaddr=IOADDR, irq=IRQ, mac=MACADDR,
+#       ethmod=MODULE, ethdev=DEVICE, script=SCRIPT, bootrom=BOOTROM
+#
+# CARD: This is the zero-based card number to configure with this ne2k config
+# line. Up to 4 devices are supported now (0...3). If not specified, the
+# following parameters apply to card #0.
+#
+# TYPE: This is the card type to emulate ("isa" or "pci"). If not specified,
+# card #0 defaults to "pci" if assigned to a pci slot. For the additional cards
+# the type parameter should be set up.
 #
 # IOADDR, IRQ: You probably won't need to change ioaddr and irq, unless there
 # are IRQ conflicts. These arguments are ignored when assign the ne2k to a
-# PCI slot.
+# PCI slot or set the type to 'pci'.
 #
 # MAC: The MAC address MUST NOT match the address of any machine on the net.
 # Also, the first byte must be an even number (bit 0 set means a multicast
@@ -857,6 +1053,8 @@ private_colormap: enabled=0
 # Windows machines, you must run niclist to get the name of the ethdev.
 # Niclist source code is in misc/niclist.c and it is included in Windows
 # binary releases.
+# The 'socket' module uses this parameter to specify the UDP port for
+# receiving packets and (optional) the host to connect.
 #
 # SCRIPT: The script value is optional, and is the name of a script that
 # is executed after bochs initialize the network interface. You can use
@@ -864,6 +1062,10 @@ private_colormap: enabled=0
 # This is mainly useful for the tun/tap devices that only exist during
 # Bochs execution. The network interface name is supplied to the script
 # as first parameter.
+# The 'slirp' module uses this parameter to specify a config file for
+# setting up an alternative IP configuration or additional features.
+# The 'vnet' module also uses this parameter to specify a config file similar
+# to slirp, but with only a few settings.
 #
 # BOOTROM: The bootrom value is optional, and is the name of the ROM image
 # to load. Note that this feature is only implemented for the PCI version of
@@ -873,11 +1075,14 @@ private_colormap: enabled=0
 # you can use the following 'ethmod's to simulate a virtual network.
 #   null: All packets are discarded, but logged to a few files.
 #   vde:  Virtual Distributed Ethernet
-#   vnet: ARP, ICMP-echo(ping), DHCP and read/write TFTP are simulated.
+#   vnet: ARP, ICMP-echo(ping), DHCP, DNS, FTP and TFTP are simulated.
 #         The virtual host uses 192.168.10.1.
-#         DHCP assigns 192.168.10.2 to the guest.
-#         TFTP uses the 'ethdev' value for the root directory and doesn't
-#         overwrite files.
+#         DHCP assigns 192.168.10.15 to the guest.
+#         FTP/TFTP using the 'ethdev' value for the root directory.
+#         TFTP doesn't overwrite files, DNS for server and client only.
+# socket: Connect up to 6 Bochs instances with external program 'bxhub'
+#         (simulating an ethernet hub). It provides the same services as the
+#         'vnet' module and assigns IP addresses like 'slirp' (10.0.2.x).
 #
 #=======================================================================
 # ne2k: ioaddr=0x300, irq=9, mac=fe:fd:00:00:00:01, ethmod=fbsd, ethdev=en0 #macosx
@@ -889,111 +1094,62 @@ private_colormap: enabled=0
 # ne2k: ioaddr=0x300, irq=9, mac=b0:c4:20:00:00:01, ethmod=null, ethdev=eth0
 # ne2k: ioaddr=0x300, irq=9, mac=b0:c4:20:00:00:01, ethmod=vde, ethdev="/tmp/vde.ctl"
 # ne2k: ioaddr=0x300, irq=9, mac=b0:c4:20:00:00:01, ethmod=vnet, ethdev="c:/temp"
-# ne2k: mac=b0:c4:20:00:00:01, ethmod=slirp, script=/usr/local/bin/slirp, bootrom=ne2k_pci.rom
+# ne2k: mac=b0:c4:20:00:00:01, ethmod=socket, ethdev=40000 # use localhost
+# ne2k: mac=b0:c4:20:00:00:01, ethmod=socket, ethdev=mymachine:40000
+# ne2k: mac=b0:c4:20:00:00:01, ethmod=slirp, script=slirp.conf, bootrom=ne2k_pci.rom
 
 #=======================================================================
-# pnic: Bochs/Etherboot pseudo-NIC
+# pcipnic: Bochs/Etherboot pseudo-NIC
 #
 # Format:
-# pnic: enabled=1, mac=MACADDR, ethmod=MODULE, ethdev=DEVICE, script=SCRIPT,
-#       bootrom=BOOTROM
+# pcipnic: enabled=1, mac=MACADDR, ethmod=MODULE, ethdev=DEVICE, script=SCRIPT,
+#          bootrom=BOOTROM
 #
 # The pseudo-NIC accepts the same syntax (for mac, ethmod, ethdev, script,
 # bootrom) and supports the same networking modules as the NE2000 adapter.
-# In addition to this, it must be loaded with 'plugin_ctrl' and assigned
-# to a PCI slot.
 #=======================================================================
-#pnic: enabled=1, mac=b0:c4:20:00:00:00, ethmod=vnet
+#pcipnic: enabled=1, mac=b0:c4:20:00:00:00, ethmod=vnet
 
 #=======================================================================
 # e1000: Intel(R) 82540EM Gigabit Ethernet adapter
 #
 # Format:
-# e1000: enabled=1, mac=MACADDR, ethmod=MODULE, ethdev=DEVICE, script=SCRIPT
-#        bootrom=BOOTROM
+# e1000: card=CARD, enabled=1, mac=MACADDR, ethmod=MODULE, ethdev=DEVICE,
+#        script=SCRIPT, bootrom=BOOTROM
 #
-# The E1000 accepts the same syntax (for mac, ethmod, ethdev, script, bootrom)
-# and supports the same networking modules as the NE2000 adapter. In addition
-# to this, it must be loaded with 'plugin_ctrl' and assigned to a PCI slot.
+# The E1000 accepts the same syntax (for card, mac, ethmod, ethdev, script,
+# bootrom) and supports the same networking modules as the NE2000 adapter.
+# It also supports up to 4 devices selected with the card parameter.
 #=======================================================================
-#e1000: enabled=1, mac=52:54:00:12:34:56, ethmod=slirp, script=/usr/local/bin/slirp
+#e1000: enabled=1, mac=52:54:00:12:34:56, ethmod=slirp, script=slirp.conf
 e1000: enabled=1, mac=52:54:00:12:34:56, ethmod=tuntap, ethdev=/dev/net/tun:tap0
 
 #=======================================================================
-# KEYBOARD_MAPPING:
-# This enables a remap of a physical localized keyboard to a
-# virtualized us keyboard, as the PC architecture expects.
-# If enabled, the keymap file must be specified.
-#
-# Examples:
-#   keyboard_mapping: enabled=1, map=gui/keymaps/x11-pc-de.map
-#=======================================================================
-keyboard_mapping: enabled=0, map=
-
-#=======================================================================
-# KEYBOARD_TYPE:
-# Type of keyboard return by a "identify keyboard" command to the
-# keyboard controler. It must be one of "xt", "at" or "mf".
-# Defaults to "mf". It should be ok for almost everybody. A known
-# exception is french macs, that do have a "at"-like keyboard.
-#
-# Examples:
-#   keyboard_type: mf
-#=======================================================================
-#keyboard_type: mf
-
-#=======================================================================
-# USER_SHORTCUT:
-# This defines the keyboard shortcut to be sent when you press the "user"
-# button in the headerbar. The shortcut string is a combination of maximum
-# 3 key names (listed below) separated with a '-' character.
-# Valid key names:
-# "alt", "bksl", "bksp", "ctrl", "del", "down", "end", "enter", "esc",
-# "f1", ... "f12", "home", "ins", "left", "menu", "minus", "pgdwn", "pgup",
-# "plus", "right", "shift", "space", "tab", "up", "win", "print" and "power".
-#
-# Example:
-#   user_shortcut: keys=ctrl-alt-del
-#=======================================================================
-#user_shortcut: keys=ctrl-alt-del
-
-#=======================================================================
-# PCI:
-# This option controls the presence of a PCI chipset in Bochs. Currently it only
-# supports the i440FX chipset. You can also specify the devices connected to
-# PCI slots. Up to 5 slots are available. These devices are currently supported:
-# cirrus, e1000, es1370, ne2k, pcivga, pcidev, pcipnic, usb_ohci and usb_xhci.
-#
-# Example:
-#   pci: enabled=1, chipset=i440fx, slot1=pcivga, slot2=ne2k
-#=======================================================================
-pci: enabled=1, chipset=i440fx, slot1=e1000
-
-#=======================================================================
 # USB_UHCI:
 # This option controls the presence of the USB root hub which is a part
 # of the i440FX PCI chipset. With the portX parameter you can connect devices
-# to the hub (currently supported: 'mouse', 'tablet', 'keypad', 'disk', 'cdrom'
-# 'hub' and 'printer'). NOTE: UHCI must be loaded with 'plugin_ctrl'.
-#
-# The optionsX parameter can be used to assign specific options to the device
-# connected to the corresponding USB port. Currently this feature is only used
-# to set the speed reported by device and by the 'disk' device to specify
-# an alternative redolog file of some image modes.
+# to the hub (currently supported: 'mouse', 'tablet', 'keypad', 'keyboard',
+# 'disk', 'cdrom', 'floppy', 'hub' and 'printer').
 #
 # If you connect the mouse or tablet to one of the ports, Bochs forwards the
 # mouse movement data to the USB device instead of the selected mouse type.
 # When connecting the keypad to one of the ports, Bochs forwards the input of
-# the numeric keypad to the USB device instead of the PS/2 keyboard.
+# the numeric keypad to the USB device instead of the PS/2 keyboard. If the
+# keyboard is selected, all key events are sent to the USB device.
 #
-# To connect a 'flat' mode image as an USB hardisk you can use the 'disk' device
+# To connect a 'flat' mode image as a USB hardisk you can use the 'disk' device
 # with the path to the image separated with a colon. To use other disk image modes
 # similar to ATA disks the syntax 'disk:mode:filename' must be used (see below).
 #
-# To emulate an USB cdrom you can use the 'cdrom' device name and the path to
+# To emulate a USB cdrom you can use the 'cdrom' device name and the path to
 # an ISO image or raw device name also separated with a colon. An option to
 # insert/eject media is available in the runtime configuration.
 #
+# To emulate a USB floppy you can use the 'floppy' device with the path to the
+# image separated with a colon. To use the VVFAT image mode similar to the
+# legacy floppy the syntax 'floppy:vvfat:directory' must be used (see below).
+# An option to insert/eject media is available in the runtime configuration.
+#
 # The device name 'hub' connects an external hub with max. 8 ports (default: 4)
 # to the root hub. To specify the number of ports you have to add the value
 # separated with a colon. Connecting devices to the external hub ports is only
@@ -1001,45 +1157,77 @@ pci: enabled=1, chipset=i440fx, slot1=e1
 #
 # The device 'printer' emulates the HP Deskjet 920C printer. The PCL data is
 # sent to a file specified in bochsrc.txt. The current code appends the PCL
-# code to the file if the file already existed. It would probably be nice to
-# overwrite the file instead, asking user first.
+# code to the file if the file already existed. The output file can be
+# changed at runtime.
+#
+# The optionsX parameter can be used to assign specific options to the device
+# connected to the corresponding USB port. Currently this feature is used to
+# set the speed reported by device ('low', 'full', 'high' or 'super'). The
+# available speed choices depend on both HC and device. The option 'debug' turns
+# on debug output for the device at connection time.
+# For the USB 'disk' device the optionsX parameter can be used to specify an
+# alternative redolog file (journal) of some image modes. For 'vvfat' mode USB
+# disks the optionsX parameter can be used to specify the disk size (range
+# 128M ... 128G). If the size is not specified, it defaults to 504M.
+# For the USB 'floppy' device the optionsX parameter can be used to specify an
+# alternative device ID to be reported. Currently only the model "teac" is
+# supported (can fix hw detection in some guest OS). The USB floppy also
+# accepts the parameter "write_protected" with valid values 0 and 1 to select
+# the access mode (default is 0).
 #=======================================================================
 #usb_uhci: enabled=1
 #usb_uhci: enabled=1, port1=mouse, port2=disk:usbstick.img
 #usb_uhci: enabled=1, port1=hub:7, port2=disk:growing:usbdisk.img
-#usb_uhci: enabled=1, port2=disk:undoable:usbdisk.img, options1=journal:redo.log
+#usb_uhci: enabled=1, port2=disk:undoable:usbdisk.img, options2=journal:redo.log
+#usb_uhci: enabled=1, port2=disk:usbdisk2.img, options2=sect_size:1024
+#usb_uhci: enabled=1, port2=disk:vvfat:vvfat, options2="debug,speed:full"
 #usb_uhci: enabled=1, port1=printer:printdata.bin, port2=cdrom:image.iso
+#usb_uhci: enabled=1, port2=floppy:vvfat:diskette, options2="model:teac"
 
 #=======================================================================
 # USB_OHCI:
 # This option controls the presence of the USB OHCI host controller with a
-# 2-port hub. The portX option accepts the same device types with the same
-# syntax as the UHCI controller (see above). The OHCI HC must be assigned to
-# a PCI slot and loaded with 'plugin_ctrl'.
+# 2-port hub. The portX parameter accepts the same device types with the same
+# syntax as the UHCI controller (see above). The optionsX parameter is also
+# available on OHCI.
 #=======================================================================
 #usb_ohci: enabled=1
 #usb_ohci: enabled=1, port1=printer:usbprinter.bin
 
 #=======================================================================
+# USB_EHCI:
+# This option controls the presence of the USB EHCI host controller with a
+# 6-port hub. The portX parameter accepts the same device types with the
+# same syntax as the UHCI controller (see above). The optionsX parameter is
+# also available on EHCI.
+#=======================================================================
+#usb_ehci: enabled=1
+
+#=======================================================================
 # USB_XHCI:
-# This option controls the presence of the experimental USB xHCI host controller
-# with a 4-port hub. The portX option accepts the same device types with the
-# same syntax as the UHCI controller (see above). The xHCI HC must be assigned
-# to a PCI slot and loaded with 'plugin_ctrl'.
+# This option controls the presence of the USB xHCI host controller with a
+# 4-port hub. The portX parameter accepts the same device types with the
+# same syntax as the UHCI controller (see above). The optionsX parameter is
+# also available on xHCI. NOTE: port 1 and 2 are USB3 and only support
+# super-speed devices, but port 3 and 4 are USB2 and support speed settings
+# low, full and high.
 #=======================================================================
 #usb_xhci: enabled=1
 
 #=======================================================================
-# CMOSIMAGE:
-# This defines image file that can be loaded into the CMOS RAM at startup.
-# The rtc_init parameter controls whether initialize the RTC with values stored
-# in the image. By default the time0 argument given to the clock option is used.
-# With 'rtc_init=image' the image is the source for the initial time.
-#
-# Example:
-#   cmosimage: file=cmos.img, rtc_init=image
+# PCIDEV:
+# PCI host device mapping
+# WARNING: This Bochs feature is not maintained yet and may fail.
 #=======================================================================
-#cmosimage: file=cmos.img, rtc_init=time0
+#pcidev: vendor=0x1234, device=0x5678
+
+#=======================================================================
+# GDBSTUB:
+# Enable GDB stub. See user documentation for details.
+# Default value is enabled=0.
+# WARNING: This Bochs feature is not maintained yet and may fail.
+#=======================================================================
+#gdbstub: enabled=0, port=1234, text_base=0, data_base=0, bss_base=0
 
 #=======================================================================
 # MAGIC_BREAK:
@@ -1050,25 +1238,9 @@ pci: enabled=1, chipset=i440fx, slot1=e1
 # Example:
 #   magic_break: enabled=1
 #=======================================================================
-#magic_break: enabled=1
 magic_break: enabled=1
 
 #=======================================================================
-# PORT_E9_HACK:
-# The 0xE9 port doesn't exists in normal ISA architecture. However, we
-# define a convention here, to display on the console of the system running
-# Bochs anything that is written to it. The idea is to provide debug output
-# very early when writing BIOS or OS code for example, without having to
-# bother with setting up a serial port or etc. Reading from port 0xE9 will
-# will return 0xe9 to let you know if the feature is available.
-# Leave this 0 unless you have a reason to use it.
-#
-# Example:
-#   port_e9_hack: enabled=1
-#=======================================================================
-port_e9_hack: enabled=1
-
-#=======================================================================
 # DEBUG_SYMBOLS:
 # This loads symbols from the specified file for use in Bochs' internal
 # debugger. Symbols are loaded into global context. This is equivalent to
@@ -1080,32 +1252,34 @@ port_e9_hack: enabled=1
 #=======================================================================
 #debug_symbols: file="kernel.sym"
 
-#=======================================================================
-# other stuff
-#=======================================================================
-#load32bitOSImage: os=nullkernel, path=../kernel.img, iolog=../vga_io.log
-#load32bitOSImage: os=linux, path=../linux.img, iolog=../vga_io.log, initrd=../initrd.img
 #print_timestamps: enabled=1
 
-#-------------------------
-# PCI host device mapping
-#-------------------------
-#pcidev: vendor=0x1234, device=0x5678
-
 #=======================================================================
-# GDBSTUB:
-# Enable GDB stub. See user documentation for details.
-# Default value is enabled=0.
+# PORT_E9_HACK:
+# The 0xE9 port doesn't exists in normal ISA architecture. However, we
+# define a convention here, to display on the console of the system running
+# Bochs anything that is written to it. The idea is to provide debug output
+# very early when writing BIOS or OS code for example, without having to
+# bother with setting up a serial port or etc. Reading from port 0xE9 will
+# will return 0xe9 to let you know if the feature is available.
+# Leave this 0 unless you have a reason to use it.
+#
+# Example:
+#   port_e9_hack: enabled=1
 #=======================================================================
-#gdbstub: enabled=0, port=1234, text_base=0, data_base=0, bss_base=0
+port_e9_hack: enabled=1
 
 #=======================================================================
-# USER_PLUGIN:
-# Load user-defined plugin. This option is available only if Bochs is
-# compiled with plugin support. Maximum 8 different plugins are supported.
-# See the example in the Bochs sources how to write a plugin device.
+# fullscreen: ONLY IMPLEMENTED ON AMIGA
+#             Request that Bochs occupy the entire screen instead of a
+#             window.
+#
+# Examples:
+#   fullscreen: enabled=0
+#   fullscreen: enabled=1
 #=======================================================================
-#user_plugin: name=testdev
+#fullscreen: enabled=0
+#screenmode: name="sample"
 
 #=======================================================================
 # for Macintosh, use the style of pathnames in the following
diff -pruN 1.0.0+git-20190125.36a4c85-5.1/debian/changelog 1.21.1+git-20220113.fbbdc3926-0ubuntu1/debian/changelog
--- 1.0.0+git-20190125.36a4c85-5.1/debian/changelog	2021-02-07 17:25:50.000000000 +0000
+++ 1.21.1+git-20220113.fbbdc3926-0ubuntu1/debian/changelog	2022-01-13 13:53:40.000000000 +0000
@@ -1,9 +1,105 @@
-ipxe (1.0.0+git-20190125.36a4c85-5.1) unstable; urgency=medium
+ipxe (1.21.1+git-20220113.fbbdc3926-0ubuntu1) jammy; urgency=medium
 
-  * Non-maintainer upload.
-  * Apply upstream patch to fix FTBFS with gcc 10. (Closes: #966942)
+  * Bump code to 1.21.1+git-20220113.fbbdc3926
+  * d/grub-ipxe.install, d/control, d/rules: Build ipxe-arm64.efi
+    (LP: #1890230)
+
+ -- Christian Ehrhardt <christian.ehrhardt@canonical.com>  Thu, 13 Jan 2022 14:53:40 +0100
+
+ipxe (1.21.1+git-20210429.323af9ee-0ubuntu1) impish; urgency=medium
+
+  * Bump code to 1.21.1+git-20210429.323af9ee
+    - Drop d/p/handle-dhcp-nack.patch: Handle DHCP NAK and send a
+      re-discover. (LP 1707999)
+      [replaced by 1192edf "Handle DHCPNAK by returning to discovery state"]
+    - Drop d/p/lp-1882671-efi-Raise-TPL-during-driver-entry-point.patch
+      [upstream in 1.21.0]
+    - Drop d/p/build-Be-explicit-about-fcommon-compiler-directive.patch
+      [upstream in 1.21.0]
+    - update d/p/0005-strip-802.1Q-VLAN-0-priority-tags.patch to match 1.21
+    - d/rules: don't clean explicitly in between builds
+
+ -- Christian Ehrhardt <christian.ehrhardt@canonical.com>  Thu, 29 Apr 2021 16:12:33 +0200
+
+ipxe (1.0.0+git-20190125.36a4c85-5ubuntu4) hirsute; urgency=medium
+
+  * d/u/geniso: fix rounding to unbreak iso creation
+
+ -- Christian Ehrhardt <christian.ehrhardt@canonical.com>  Tue, 30 Mar 2021 10:09:06 +0200
+
+ipxe (1.0.0+git-20190125.36a4c85-5ubuntu3) groovy; urgency=medium
+
+  * d/p/build-Be-explicit-about-fcommon-compiler-directive.patch: fix
+    FTBFS with gcc-10
+  * d/util/geniso: fix FTBFS due to rounding issues
+
+ -- Christian Ehrhardt <christian.ehrhardt@canonical.com>  Thu, 01 Oct 2020 10:14:14 +0200
+
+ipxe (1.0.0+git-20190125.36a4c85-5ubuntu2) groovy; urgency=medium
+
+  * d/p/lp-1882671-efi-Raise-TPL-during-driver-entry-point.patch: fix the
+    formerly avoided efi TPL issues (LP: #1882671)
+
+ -- Christian Ehrhardt <christian.ehrhardt@canonical.com>  Thu, 16 Jul 2020 14:36:54 +0200
+
+ipxe (1.0.0+git-20190125.36a4c85-5ubuntu1) groovy; urgency=medium
+
+  * Merge with Debian unstable (LP: #1884758). Remaining changes:
+    - Split grub integration from ipxe->grub-ipxe.
+      - d/control: add package and adapt dependencies
+      - d/[grub-]ipxe.install: move some files to grub-ipxe
+      - rename d/ipxe.post* to d/grub-ipxe-post*
+      [updated to match 1.0.0+git-20190125.36a4c85-5]
+    - d/util/check-rom-sizes, d/rules: check sizes of generated roms to avoid
+      accidentally breaking KVM live migration on updates/fixes.
+      [updated for new and dropped rom file names]
+    - debian/copyright: update copyright information to satisfy lintian
+      dep5 checks (LP: 1747071)
+    - Build ROMs for QEMU with CONFIG=qemu (LP: 1789319)
+      [updated to match 1.0.0+git-20190125.36a4c85-5 and be more verbose]
+    - debian/patches/handle-dhcp-nack.patch: Handle DHCP NAK and send a
+      re-discover. (LP 1707999)
+    - d/p/0005-strip-802.1Q-VLAN-0-priority-tags.patch: Strip 802.1Q VLAN 0
+      priority tags; Fixes PXE when VLAN tag is 0. (LP: 1805920)
+    - d/tree/ipxe/etc/grub.d/20_ipxe: Make grub-ipxe work under UEFI
+      (LP: 1811496)
+      - Use ipxe.efi under UEFI
+      - Save default entry when iPXE is selected
+    - d/tree/ipxe/etc/grub.d/20_ipxe: Identify ipxe grub menu entry in
+      an easier way (LP: 1858374)
+  * Dropped changes
+    - new upstream release 20190109.133f4c4 [superseded by new upstream]
+    - new upstream release 20180124.fbe8c52d [superseded by new upstream]
+    - Revert to the former git snapshot 20150424.a25a16d
+      [superseded by new upstream]
+      - This brings back debian/patches/0002-Don-t-use-libiberty.patch as needed
+        on the older source.
+      - Adapt d/p/0001-rom-change-banner-timeout.diff.patch to former state to
+        match old source.
+      - drop d/p/util-elf2efi-GNU_SOURCE.patch as it was not needed on old
+        source
+    - Fix FTBFS with newer perl versions [upstream]
+    - d/p/0004-fix_no-pie_option.patch: correct -no-pie option
+      to build without pie
+      [ still carried before ]
+    - Install ne.rom as pxe-ne2k_isa.rom
+      - d/ipxe-qemu.install: Install ne.rom as pxe-ne2k_isa.rom.
+      - d/ipxe-qemu.links: compat link for ne.rom
+      [ no more needed, was an old xen hvmloader bug ]
+    - d/ipxe-qemu.links: Add compat links from /usr/share/qemu
+      to /usr/lib/ipxe/qemu.
+      [ no more needed, transition from trusty ]
+    - add new rom for vmxnet3 (LP 1737211) [in Debian now]
+    - Add e1000e firmware for qemu. (closes 884240) [in Debian now]
+    - d/control: ipxe-qemu breaks qemu-system-x86 <2.11 [no more needed]
+    - d/p/enable-https.patch: Enable HTTPS support.
+      [resolved per rom type in d/rules now]
+  * Added changes
+    - d/rules: only enable https on non EFI roms. This lets EFI handle https
+      itself and avoids breakage in TPL manipulations (LP: #1882671)
+    - d/util/check-rom-sizes: fix if size does exactly match
 
- -- Chris Hofstaedtler <zeha@debian.org>  Sun, 07 Feb 2021 17:25:50 +0000
+ -- Christian Ehrhardt <christian.ehrhardt@canonical.com>  Tue, 23 Jun 2020 16:23:52 +0200
 
 ipxe (1.0.0+git-20190125.36a4c85-5) unstable; urgency=medium
 
@@ -39,6 +135,179 @@ ipxe (1.0.0+git-20190125.36a4c85-1) unst
 
  -- Bastian Blank <waldi@debian.org>  Sat, 09 Feb 2019 17:41:37 +0100
 
+ipxe (1.0.0+git-20190109.133f4c4-0ubuntu3) focal; urgency=medium
+
+  [Alkis Georgopoulos]
+  * d/tree/ipxe/etc/grub.d/20_ipxe: Make grub-ipxe work under UEFI
+    (LP: #1811496)
+    - Use ipxe.efi under UEFI
+    - Save default entry when iPXE is selected
+  [Sharon Dagan]
+  - d/tree/ipxe/etc/grub.d/20_ipxe: Identify ipxe grub menu entry in
+    an easier way (LP: #1858374)
+
+ -- Rafael David Tinoco <rafaeldtinoco@ubuntu.com>  Mon, 06 Jan 2020 18:59:25 +0000
+
+ipxe (1.0.0+git-20190109.133f4c4-0ubuntu2) disco; urgency=medium
+
+  * Add e1000e firmware for qemu. (closes: #884240)
+    - d/ipxe-qemu.install: install new rom
+    - d/util/check-rom-sizes: check new rom
+
+ -- Christian Ehrhardt <christian.ehrhardt@canonical.com>  Tue, 19 Feb 2019 17:17:04 +0100
+
+ipxe (1.0.0+git-20190109.133f4c4-0ubuntu1) disco; urgency=medium
+
+  * Merge new upstream release 1.0.0+git-20190109.133f4c4
+    Remaining Changes:
+    - d/p/enable-https.patch: Enable HTTPS support.
+    - Split grub integration from ipxe->grub-ipxe.
+      - d/control: add package and adapt dependencies
+      - d/[grub-]ipxe.install: move some files to grub-ipxe
+      - rename d/ipxe.post* to d/grub-ipxe-post*
+    - Install ne.rom as pxe-ne2k_isa.rom
+      - d/ipxe-qemu.install: Install ne.rom as pxe-ne2k_isa.rom.
+      - d/ipxe-qemu.links: compat link for ne.rom
+    - d/ipxe-qemu.links: Add compat links from /usr/share/qemu
+      to /usr/lib/ipxe/qemu.
+    - d/util/check-rom-sizes, d/rules: check sizes of generated roms to avoid
+      accidentially breaking KVM live migration on updates/fixes.
+    - handling of efi rom size changes in Bionic (LP 1713490)
+      - d/util/check-rom-sizes: bump efi rom sizes
+      - d/control: break older qemu versions to ensure the new sized roms
+        are only associated with new qemu versions.
+    - debian/patches/handle-dhcp-nack.patch: Handle DHCP NAK and send a
+      re-discover. (LP 1707999)
+    - updated debian/patches/util-elf2efi-GNU_SOURCE.patch to match latest
+      upstream.
+    - add new rom for vmxnet3 (LP 1737211)
+      - d/ipxe-qemu.install: install new rom
+        are only associated with new qemu versions.
+    - Build ROMs for QEMU with CONFIG=qemu (LP: 1789319)
+    - d/p/0005-strip-802.1Q-VLAN-0-priority-tags.patch: Strip 802.1Q VLAN 0
+      priority tags; Fixes PXE when VLAN tag is 0. (LP: 1805920)
+    - debian/copyright: update copyright information to satisfy lintian
+      dep5 checks (LP: 1747071)
+  * Dropped changes (upstream):
+    - debian/patches/fix-elf2efi-plt-relocation.diff: Cherry-pick fix from
+      ipxe devel mailing list to handle R_X86_64_PLT32 relocations.
+
+ -- Christian Ehrhardt <christian.ehrhardt@canonical.com>  Wed, 09 Jan 2019 11:09:29 +0100
+
+ipxe (1.0.0+git-20180124.fbe8c52d-0ubuntu5) disco; urgency=medium
+
+  * d/p/0005-strip-802.1Q-VLAN-0-priority-tags.patch: Strip 802.1Q VLAN 0
+    priority tags; Fixes PXE when VLAN tag is 0. (LP: #1805920)
+
+ -- Andres Rodriguez <andreserl@ubuntu.com>  Mon, 10 Dec 2018 16:26:42 -0500
+
+ipxe (1.0.0+git-20180124.fbe8c52d-0ubuntu4) cosmic; urgency=medium
+
+  * Build ROMs for QEMU with CONFIG=qemu (LP: #1789319)
+
+ -- Julian Andres Klode <juliank@ubuntu.com>  Mon, 10 Sep 2018 14:56:17 +0200
+
+ipxe (1.0.0+git-20180124.fbe8c52d-0ubuntu3) cosmic; urgency=medium
+
+  * debian/patches/fix-elf2efi-plt-relocation.diff: Cherry-pick fix from
+    ipxe devel mailing list to handle R_X86_64_PLT32 relocations.
+
+ -- Julian Andres Klode <juliank@ubuntu.com>  Mon, 10 Sep 2018 14:27:35 +0200
+
+ipxe (1.0.0+git-20180124.fbe8c52d-0ubuntu2) bionic; urgency=medium
+
+  * debian/copyright: update copyright information to satisfy lintian
+    dep5 checks (LP: #1747071)
+  * d/p/enable-https.patch: adding proper dep3 header
+
+ -- Christian Ehrhardt <christian.ehrhardt@canonical.com>  Mon, 05 Feb 2018 15:09:28 +0100
+
+ipxe (1.0.0+git-20180124.fbe8c52d-0ubuntu1) bionic; urgency=medium
+
+  * Merge new upstream release 20180124.fbe8c52d with last "new"
+    Ubuntu packaging 1.0.0+git-20161027.b991c67-1ubuntu1 and the
+    fixes since 1.0.0+git-20161027.b991c67+really20150424.a25a16d-1ubuntu1
+    Remaining Changes:
+    - d/p/enable-https.patch: Enable HTTPS support.
+    - Split grub integration from ipxe->grub-ipxe.
+      - d/control: add package and adapt dependencies
+      - d/[grub-]ipxe.install: move some files to grub-ipxe
+      - rename d/ipxe.post* to d/grub-ipxe-post*
+    - Install ne.rom as pxe-ne2k_isa.rom
+      - d/ipxe-qemu.install: Install ne.rom as pxe-ne2k_isa.rom.
+      - d/ipxe-qemu.links: compat link for ne.rom
+    - d/ipxe-qemu.links: Add compat links from /usr/share/qemu
+      to /usr/lib/ipxe/qemu.
+    - d/util/check-rom-sizes, d/rules: check sizes of generated roms to avoid
+      accidentially breaking KVM live migration on updates/fixes.
+    - debian/patches/handle-dhcp-nack.patch: Handle DHCP NAK and send a
+      re-discover. (LP 1707999)
+  * Dropped changes (upstream):
+    - d/p/0004-fix_no-pie_option.patch: correct -no-pie option
+      to build without pie
+  * Added Changes:
+    - updated debian/patches/util-elf2efi-GNU_SOURCE.patch to match latest
+      upstream.
+    - add new rom for vmxnet3 (LP: #1737211)
+      - d/ipxe-qemu.install: install new rom
+      - d/util/check-rom-sizes: check new rom as well
+    - handling of efi rom size changes (LP: #1713490)
+      - d/util/check-rom-sizes: bump efi rom sizes
+      - d/control: break older qemu versions to ensure the new sized roms
+        are only associated with new qemu versions.
+    - d/util/check-rom-sizes: update description
+
+ -- Christian Ehrhardt <christian.ehrhardt@canonical.com>  Wed, 24 Jan 2018 15:00:36 +0100
+
+ipxe (1.0.0+git-20161027.b991c67+really20150424.a25a16d-1ubuntu2) artful; urgency=medium
+
+  * debian/patches/handle-dhcp-nack.patch: Handle DHCP NAK and send a
+    re-discover. (LP: #1707999)
+
+ -- Andres Rodriguez <andreserl@ubuntu.com>  Thu, 12 Oct 2017 16:25:52 -0400
+
+ipxe (1.0.0+git-20161027.b991c67+really20150424.a25a16d-1ubuntu1) artful; urgency=medium
+
+  * Revert to the former git snapshot 20150424.a25a16d to fix changed
+    rom sizes that break cross release migrations (LP: #1713490).
+    This makes it effectively identical to 1.0.0+git-20150424.a25a16d-1ubuntu2
+    in regard to the upstream source, but keeps the changes to debian/*.
+    On next merge we need to either ensure that rom sizes don't change, or
+    that we can encapsulate that in qemu so that on forward migration it is
+    taken care off.
+    - This brings back debian/patches/0002-Don-t-use-libiberty.patch as needed
+      on the older source.
+    - Adapt d/p/0001-rom-change-banner-timeout.diff.patch to former state to
+      match old source.
+    - drop d/p/util-elf2efi-GNU_SOURCE.patch as it was not needed on old
+      source
+  * Fix FTBFS with newer perl versions (were dropped due to the revert above
+    but is needed to build in artful)
+    - d/p/0006-build-Fix-.ids.o-creation-for-drivers-not-in-the-all.patch
+    - d/p/0007-build-Remove-nested-my-declaration.patch
+  * d/util/check-rom-sizes, d/rules: check sizes of generated roms to avoid
+    accidentially breaking KVM live migration on updates/fixes.
+
+ -- Christian Ehrhardt <christian.ehrhardt@canonical.com>  Tue, 29 Aug 2017 10:37:57 +0200
+
+ipxe (1.0.0+git-20161027.b991c67-1ubuntu1) artful; urgency=medium
+
+  * Merge from Debian stable. Remaining changes:
+    - d/p/enable-https.patch: Enable HTTPS support.
+    - Split grub integration from ipxe->grub-ipxe.
+      - d/control: add package and adapt dependencies
+      - d/[grub-]ipxe.install: move some files to grub-ipxe
+      - rename d/ipxe.post* to d/grub-ipxe-post*
+    - Install ne.rom as pxe-ne2k_isa.rom
+      - d/ipxe-qemu.install: Install ne.rom as pxe-ne2k_isa.rom.
+      - d/ipxe-qemu.links: compat link for ne.rom
+    - d/ipxe-qemu.links: Add compat links from /usr/share/qemu
+      to /usr/lib/ipxe/qemu.
+    - d/p/0004-fix_no-pie_option.patch: correct -no-pie option
+      to build without pie
+
+ -- Christian Ehrhardt <christian.ehrhardt@canonical.com>  Thu, 17 Aug 2017 08:40:41 +0200
+
 ipxe (1.0.0+git-20161027.b991c67-1) unstable; urgency=medium
 
   * New snapshot. (closes: #799216)
@@ -46,6 +315,24 @@ ipxe (1.0.0+git-20161027.b991c67-1) unst
 
  -- Bastian Blank <waldi@debian.org>  Sun, 13 Nov 2016 13:35:11 +0100
 
+ipxe (1.0.0+git-20150424.a25a16d-1ubuntu2) yakkety; urgency=medium
+
+  * debian/patches/0004-fix_no-pie_option.patch: correct -no-pie
+    option to build without pie
+
+ -- Steve Beattie <sbeattie@ubuntu.com>  Thu, 28 Apr 2016 23:55:40 -0700
+
+ipxe (1.0.0+git-20150424.a25a16d-1ubuntu1) xenial; urgency=medium
+
+  * Merge from Debian unstable. Remaining changes:
+    - d/p/enable-https.patch: Enable HTTPS support.
+    - d/control,grub-ipxe*: Split grub integration from ipxe->grub-ipxe.
+    - d/ipxe-qemu.links: Add compat links from /usr/share/qemu to
+      /usr/lib/ipxe/qemu.
+    - d/ipxe-qemu.install: Install ne.rom as pxe-ne2k_isa.rom.
+
+ -- Serge Hallyn <serge.hallyn@ubuntu.com>  Mon, 08 Feb 2016 20:35:02 -0800
+
 ipxe (1.0.0+git-20150424.a25a16d-1) unstable; urgency=medium
 
   * New snapshot.
@@ -60,6 +347,35 @@ ipxe (1.0.0+git-20150424.a25a16d-1) unst
 
  -- Bastian Blank <waldi@debian.org>  Wed, 29 Apr 2015 21:00:55 +0200
 
+ipxe (1.0.0+git-20141004.86285d1-1ubuntu3) vivid; urgency=medium
+
+  * ipxe.install: remove one more line which was supposed to be split out
+    into grub-ipxe.install.
+
+ -- Serge Hallyn <serge.hallyn@ubuntu.com>  Mon, 09 Feb 2015 11:01:16 -0600
+
+ipxe (1.0.0+git-20141004.86285d1-1ubuntu2) vivid; urgency=medium
+
+  * ipxe.install: remove /boot/ipxe.efi and ipxe.lkrn which are split out
+    into grub-ipxe.install.  (LP: #1418751)
+
+ -- Serge Hallyn <serge.hallyn@ubuntu.com>  Mon, 09 Feb 2015 10:51:22 -0600
+
+ipxe (1.0.0+git-20141004.86285d1-1ubuntu1) vivid; urgency=medium
+
+  * Merge from Debian unstable. (LP: #1409057)  Remaining changes:
+    - d/p/enable-https.patch: Enable HTTPS support.
+    - d/control,grub-ipxe*: Split grub integration from ipxe->grub-ipxe.
+    - d/ipxe-qemu.links: Add compat links from /usr/share/qemu to
+      /usr/lib/ipxe/qemu.
+    - d/ipxe-qemu.install: Install ne.rom as pxe-ne2k_isa.rom.
+  * Dropped changes, alternative fix in Debian:
+    - d/control: Add libiberty-dev to BD's to fix FTBFS.
+    - drop isolinux from build-deps and patch to augment ISOLINUX_BIN
+    - Drop transitional kvm-ipxe package since we are past 14.04
+
+ -- Serge Hallyn <serge.hallyn@ubuntu.com>  Mon, 12 Jan 2015 10:32:26 -0600
+
 ipxe (1.0.0+git-20141004.86285d1-1) unstable; urgency=medium
 
   * New snapshot.
@@ -74,12 +390,50 @@ ipxe (1.0.0+git-20131111.c3d1e78-2.1) un
 
  -- Juli?n Moreno Pati?o <julian@debian.org>  Wed, 10 Sep 2014 11:06:28 -0500
 
+ipxe (1.0.0+git-20131111.c3d1e78-2ubuntu2) utopic; urgency=medium
+
+  * Fix FTBFS in utopic due to movement of isolinux.bin:
+    - add isolinux to build-deps
+    - add /usr/lib/ISOLINUX/isolinux.bin to ISOLINUX_BIN in
+      src/arch/i386/Makefile
+
+ -- Serge Hallyn <serge.hallyn@ubuntu.com>  Tue, 12 Aug 2014 12:56:06 -0500
+
+ipxe (1.0.0+git-20131111.c3d1e78-2ubuntu1) trusty; urgency=low
+
+  * Merge from Debian unstable.  Remaining changes:
+    - d/p/enable-https.patch: Enable HTTPS support.
+    - d/control,grub-ipxe*: Split grub integration from ipxe->grub-ipxe.
+    - d/control: Transition kvm-ipxe->ipxe-qemu for LTS->LTS upgrade.
+    - d/ipxe-qemu.links: Add compat links from /usr/share/qemu to
+      /usr/lib/ipxe/qemu.
+    - d/ipxe-qemu.install: Install ne.rom as pxe-ne2k_isa.rom.
+  * Dropped changes, alternative fix in Debian:
+    - d/control: Add libiberty-dev to BD's to fix FTBFS.
+
+ -- James Page <james.page@ubuntu.com>  Mon, 06 Jan 2014 09:55:25 +0000
+
 ipxe (1.0.0+git-20131111.c3d1e78-2) unstable; urgency=medium
 
   * Don't use libiberty. (closes: #730910)
 
  -- Bastian Blank <waldi@debian.org>  Sun, 22 Dec 2013 20:05:03 +0100
 
+ipxe (1.0.0+git-20131111.c3d1e78-1ubuntu1) trusty; urgency=low
+
+  * Merge from Debian unstable, remaining changes:
+    - d/p/enable-https.patch: Enable HTTPS support.
+    - d/control,grub-ipxe*: Split grub integration from ipxe->grub-ipxe.
+    - d/control: Transition kvm-ipxe->ipxe-qemu for LTS->LTS upgrade.
+    - d/ipxe-qemu.links: Add compat links from /usr/share/qemu to
+      /usr/lib/ipxe/qemu.
+    - d/ipxe-qemu.install: Install ne.rom as pxe-ne2k_isa.rom.
+  * All other changes dropped in preference to upstream Debian
+    packaging.
+  * d/control: Add libiberty-dev to BD's to fix FTBFS.
+
+ -- James Page <james.page@ubuntu.com>  Tue, 26 Nov 2013 17:50:47 +0000
+
 ipxe (1.0.0+git-20131111.c3d1e78-1) unstable; urgency=low
 
   * New snapshot.
@@ -98,6 +452,21 @@ ipxe (1.0.0+git-20131111.c3d1e78-1) unst
 
  -- Bastian Blank <waldi@debian.org>  Thu, 21 Nov 2013 18:26:32 +0100
 
+ipxe (1.0.0+git-20130710.936134e-0ubuntu1) saucy; urgency=low
+
+  * New upstream snapshot:
+    - d/p/fix-bp-bug.patch: Dropped; included in snapshot.
+    - d/p/baseroms-target.diff: Dropped; no longer required.
+    - Refreshed all other patches.
+  * d/rules: Use date for snapshot prefix instead of increment.
+  * d/p/qemu-target-fix-names.diff: Consolidated into qemu-target.diff.
+  * d/p/*: Tidied redundant patches.
+  * d/control,rules: Move roms for use with qemu-kvm to ipxe-qemu, update
+    kvm-ipxe to be transitional.
+  * d/control: Drop Depends from grub-ipxe to ipxe as its not required.
+
+ -- James Page <james.page@ubuntu.com>  Wed, 10 Jul 2013 12:23:26 +0100
+
 ipxe (1.0.0+git-20120202.f6840ba-3) unstable; urgency=low
 
   * Fix to break qemu-system instead of qemu. (closes: #658982)
@@ -126,6 +495,116 @@ ipxe (1.0.0+git-20120202.f6840ba-1) unst
 
  -- Bastian Blank <waldi@debian.org>  Thu, 02 Feb 2012 12:40:26 +0100
 
+ipxe (1.0.0+git-4.d6b0b76-0ubuntu3) saucy; urgency=low
+
+  * debian/patches/fix-bp-bug.patch: fixes FTBFS (LP: #1194914)
+
+ -- Yolanda Robla <yolanda.robla@canonical.com>  Thu, 27 Jun 2013 11:22:43 +0200
+
+ipxe (1.0.0+git-4.d6b0b76-0ubuntu2) raring; urgency=low
+
+  * d/control: Add ipxe-qemu virtual package for use with qemu.
+
+ -- Serge Hallyn <serge.hallyn@ubuntu.com>  Tue, 20 Nov 2012 16:08:21 -0600
+
+ipxe (1.0.0+git-4.d6b0b76-0ubuntu1) raring; urgency=low
+
+  * New upstream snapshot:
+    - d/p/iscsi*.patch: Dropped - included in snapshot.
+    - Refreshed all other patches.
+  * d/p/enable-https.patch: Enable HTTPS support (LP: #1025239).
+
+ -- James Page <james.page@ubuntu.com>  Wed, 14 Nov 2012 15:47:31 +0000
+
+ipxe (1.0.0+git-3.55f6c88-0ubuntu5) quantal; urgency=low
+
+  * Fix input/output errors when using ipxe to boot from iSCSI storage
+    (LP: #1045923).
+    - d/p/iscsi-{report-reponse,send-padding-inline}.patch: Cherry picked
+      patches from upstream VCS which resolve two issues with iSCSI protocol
+      handling.
+
+ -- James Page <james.page@ubuntu.com>  Thu, 06 Sep 2012 21:46:54 +0100
+
+ipxe (1.0.0+git-3.55f6c88-0ubuntu4) quantal; urgency=low
+
+  * debian/ipxe.install: add ipxe.dsk and ipxe.usb (LP: #1014005)
+
+ -- Serge Hallyn <serge.hallyn@ubuntu.com>  Tue, 21 Aug 2012 14:48:44 -0500
+
+ipxe (1.0.0+git-3.55f6c88-0ubuntu3) quantal; urgency=low
+
+  [ Serge Hallyn ]
+  * debian/patches/rom-set-banner-timeout-0.diff: set rom banner timeout
+    to 0.  (LP: #921230)
+  
+  [ Stefan Bader ]
+  * Modify the ROM names in of the allqemu target to use 8086100e instead
+    of e1000_82540 and ne instead of ne2k_isa (LP: #948323)
+
+ -- Serge Hallyn <serge.hallyn@ubuntu.com>  Mon, 28 May 2012 11:57:48 -0500
+
+ipxe (1.0.0+git-3.55f6c88-0ubuntu2) quantal; urgency=low
+
+  * debian/grub.d/25_ipxe: removed the space after "Found iPXE image"
+    to match other grub-update script fragments (LP: #990378).
+  * debian/control: fixed some Lintian warnings.
+    - TODO: lots of missing Copyright information.
+
+ -- Martin-Éric Racine <q-funk@ubuntu.com>  Sat, 28 Apr 2012 11:41:28 +0300
+
+ipxe (1.0.0+git-3.55f6c88-0ubuntu1) precise; urgency=low
+
+  [ Marc Cluet ]
+  * New upstream snapshot.
+  * Added rules for automatic git branch refresh.
+  * Changed rom target from allbaseroms to allroms.
+    - recommended behaviour by upstream, building all full roms is neither
+      recommended nor a desired user experience
+  * Added new target allqemu for qemu package.
+    - created new build target to build full rom drivers just for qemu
+      package purposes
+  * Cleaned lintian errors from debian package
+    - Removed brace extension in ipxe.install
+    - Updated standards to 3.9.2
+    - Fixed copyright file not machine readable
+
+  [ James Page ]
+  * Updated get-orig-source target to generate git snapshots inline
+    with upstream version numbering being used by this package. 
+
+ -- Marc Cluet <marc.cluet@ubuntu.com>  Fri, 10 Feb 2012 16:21:23 +0000
+
+ipxe (1.0.0+git-2.149b50-1ubuntu4) precise; urgency=low
+
+  * Add missing Breaks/Replaces for kvm-ipxe split in
+    1.0.0+git-2.149b50-1ubuntu3 (LP: #905099).
+
+ -- Robie Basak <robie.basak@ubuntu.com>  Fri, 16 Dec 2011 10:43:54 +0000
+
+ipxe (1.0.0+git-2.149b50-1ubuntu3) precise; urgency=low
+
+  * add new binary package, kvm-ipxe. The roms needed by kvm-ipxe are now only
+    provided by it, so
+    - make ipxe depend on kvm-ipxe.
+    - ipxe.links: reverse the links
+
+ -- Serge Hallyn <serge.hallyn@ubuntu.com>  Fri, 25 Nov 2011 12:58:48 -0600
+
+ipxe (1.0.0+git-2.149b50-1ubuntu2) precise; urgency=low
+
+  * Provide a new binary package, grub-ipxe - for ipxe usage via grub.
+    - LP: #814038, Closes #626238
+
+ -- Ben Howard <ben.howard@canonical.com>  Thu, 25 Aug 2011 11:03:52 -0600
+
+ipxe (1.0.0+git-2.149b50-1ubuntu1) oneiric; urgency=low
+
+  * Link Roms into /usr/share/qemu for consumption by
+    qemu-kvm.
+
+ -- Serge Hallyn <serge.hallyn@ubuntu.com>  Thu, 18 Aug 2011 13:34:38 -0500
+
 ipxe (1.0.0+git-2.149b50-1) unstable; urgency=low
 
   * New snapshot.
@@ -146,3 +625,4 @@ ipxe (1.0.0+git-1.293e34-1) unstable; ur
     - Remove linda infiniband driver.
 
  -- Bastian Blank <waldi@debian.org>  Sun, 03 Apr 2011 11:32:56 +0200
+
diff -pruN 1.0.0+git-20190125.36a4c85-5.1/debian/control 1.21.1+git-20220113.fbbdc3926-0ubuntu1/debian/control
--- 1.0.0+git-20190125.36a4c85-5.1/debian/control	2020-02-25 20:45:06.000000000 +0000
+++ 1.21.1+git-20220113.fbbdc3926-0ubuntu1/debian/control	2022-01-13 13:53:40.000000000 +0000
@@ -1,13 +1,15 @@
 Source: ipxe
 Section: admin
 Priority: optional
-Maintainer: Bastian Blank <waldi@debian.org>
+Maintainer: Ubuntu Developers <ubuntu-devel-discuss@lists.ubuntu.com>
+XSBC-Original-Maintainer: Bastian Blank <waldi@debian.org>
 Build-Depends:
  debhelper-compat (= 12),
  dpkg-source-gitarchive,
  dh-exec,
  xorriso, isolinux, syslinux-common, syslinux-utils, dosfstools, mtools,
  binutils-dev, liblzma-dev, zlib1g-dev,
+ gcc-aarch64-linux-gnu,
 Standards-Version: 3.9.6
 Homepage: http://ipxe.org/
 Vcs-Git: https://salsa.debian.org/waldi/ipxe.git
@@ -16,7 +18,7 @@ Vcs-Browser: https://salsa.debian.org/wa
 Package: ipxe
 Architecture: all
 Multi-Arch: foreign
-Depends: ${misc:Depends}
+Depends: ipxe-qemu, grub-ipxe, ${misc:Depends}
 Description: PXE boot firmware
  iPXE is network boot firmware.  It supports a variety of network cards,
  including some wireless cards, and variety of network protocols (traditional
@@ -44,3 +46,15 @@ Description: PXE boot firmware - ROM ima
  .
  This package provides boot code for the qemu emulated network cards in
  as boot ROMs.
+
+Package: grub-ipxe
+Architecture: all
+Suggests: grub-pc (>= 1.96)
+Depends: ${misc:Depends}
+Description: Network booting from GRUB using iPXE
+ iPXE is network boot firmware.  It supports a variety of network cards,
+ including some wireless cards, and variety of network protocols (traditional
+ DHCP, BOOTP and TFTP and also HTTP, iSCSI, SAN via FCoE and Infiniband). It
+ supports scripting.
+ .
+ This package adds a menu entry to grub2 for network booting using iPXE.
diff -pruN 1.0.0+git-20190125.36a4c85-5.1/debian/copyright 1.21.1+git-20220113.fbbdc3926-0ubuntu1/debian/copyright
--- 1.0.0+git-20190125.36a4c85-5.1/debian/copyright	2020-02-25 20:45:06.000000000 +0000
+++ 1.21.1+git-20220113.fbbdc3926-0ubuntu1/debian/copyright	2021-05-10 07:31:55.000000000 +0000
@@ -3,85 +3,513 @@ Upstream-Name: ipxe
 Source: git://git.ipxe.org/ipxe.git
 
 Files: *
-License: GPL-2+
+Copyright: *No copyright*
+License: GPL-2+ or UBDL
 
-Files:
- src/arch/i386/prefix/dskprefix.S
- src/core/pcmcia.c
- src/core/string.c
- src/core/stringextra.c
- src/drivers/infiniband/*_PRM.h
- src/drivers/infiniband/qib_*_regs.h
- src/drivers/net/cs89x0.*
- src/drivers/net/e1000/*
- src/drivers/net/e1000e/*
- src/drivers/net/hfa384x.h
- src/drivers/net/igb/*
- src/drivers/net/igbvf/*
- src/drivers/net/myri10ge*
+Files: src/drivers/net/hfa384x.h
  src/drivers/net/p80211hdr.h
- src/drivers/net/phantom/nxhal_nic_interface.h
- src/drivers/net/rtl818x/*
- src/drivers/net/skge.*
- src/drivers/net/sky2.*
- src/drivers/net/tg3.*
- src/drivers/net/vxge/*
  src/drivers/net/wlan_compat.h
- src/include/i82365.h
- src/include/ipxe/list.h
- src/include/ipxe/pci.h
- src/include/ipxe/pci_ids.h
- src/include/mii.h
- src/include/stddef.h
- src/include/string.h
+Copyright: 1999, AbsoluteValue Systems, Inc.
+License: GPL-2
+
+Files: src/arch/x86/prefix/dskprefix.S
+Copyright: 1991-1992, Linus Torvalds
+License: GPL-2
+
+Files: src/core/stringextra.c
+Copyright: 1991-1992, Linus Torvalds
+  2004, Tobias Lorenz
+License: GPL-2
+
+Files: src/drivers/infiniband/MT25218_PRM.h
+ src/drivers/infiniband/MT25408_PRM.h
+Copyright: 2004, Mellanox Technologies Ltd.
+License: GPL-2
+
+Files: src/drivers/infiniband/qib_7220_regs.h
+ src/drivers/infiniband/qib_7322_regs.h
+Copyright: 2007-2009, QLogic Corporation.
+License: GPL-2
+
+Files: src/drivers/infiniband/linda_fw.c
+Copyright: 2007-2008, QLogic Corporation.
+License: GPL-2
+
+Files: src/arch/x86/core/basemem_packet.c
+ src/core/cachedhcp.c
+ src/arch/x86/core/rdtsc_timer.c
+ src/arch/x86/core/runtime.c
+ src/arch/x86/drivers/net/undi.c
+ src/arch/x86/drivers/net/undiload.c
+ src/arch/x86/drivers/net/undinet.c
+ src/arch/x86/drivers/net/undionly.c
+ src/arch/x86/drivers/net/undipreload.c
+ src/arch/x86/drivers/net/undirom.c
+ src/arch/x86/interface/pcbios/basemem.c
+ src/arch/x86/interface/pcbios/bios_console.c
+ src/arch/x86/interface/pcbios/e820mangler.S
+ src/arch/x86/interface/pcbios/fakee820.c
+ src/arch/x86/interface/pcbios/hidemem.c
+ src/arch/x86/interface/pcbios/memmap.c
+ src/arch/x86/interface/pcbios/pnpbios.c
+ src/arch/x86/hci/commands/pxe_cmd.c
+ src/arch/x86/image/bootsector.c
+ src/arch/x86/image/bzimage.c
+ src/arch/x86/image/elfboot.c
+ src/arch/x86/image/initrd.c
+ src/arch/x86/image/multiboot.c
+ src/arch/x86/image/pxe_image.c
+ src/arch/x86/image/sdi.c
+ src/arch/x86/interface/pcbios/bios_reboot.c
+ src/arch/x86/interface/pcbios/bios_smbios.c
+ src/arch/x86/interface/pcbios/bios_timer.c
+ src/arch/x86/interface/pcbios/int13.c
+ src/arch/x86/interface/pcbios/memtop_umalloc.c
+ src/arch/x86/interface/pcbios/pcibios.c
+ src/arch/x86/interface/pcbios/rtc_entropy.c
+ src/arch/x86/interface/pcbios/rtc_time.c
+ src/arch/x86/interface/pcbios/vesafb.c
+ src/arch/x86/interface/pxe/pxe_call.c
+ src/arch/x86/interface/pxe/pxe_entry.S
+ src/arch/x86/interface/pxe/pxe_file.c
+ src/arch/x86/interface/pxe/pxe_loader.c
+ src/arch/x86/interface/pxe/pxe_preboot.c
+ src/arch/x86/interface/pxe/pxe_tftp.c
+ src/arch/x86/interface/pxe/pxe_udp.c
+ src/arch/x86/interface/pxe/pxe_undi.c
+ src/arch/x86/interface/vmware/guestinfo.c
+ src/arch/x86/interface/vmware/guestrpc.c
+ src/arch/x86/interface/vmware/vmconsole.c
+ src/arch/x86/interface/vmware/vmware.c
+ src/arch/x86/prefix/exeprefix.S
+ src/arch/x86/prefix/isaromprefix.S
+ src/arch/x86/prefix/libprefix.S
+ src/arch/x86/prefix/mromprefix.S
+ src/arch/x86/prefix/pciromprefix.S
+ src/arch/x86/prefix/unlzma.S
+ src/arch/x86/transitions/liba20.S
+ src/arch/x86/transitions/librm_test.c
+ src/arch/x86/core/cpuid.c
+ src/arch/x86/core/cpuid_settings.c
+ src/arch/x86/core/debugcon.c
+ src/arch/x86/core/pcidirect.c
+ src/arch/x86/core/pic8259.c
+ src/arch/x86/core/pit8254.c
+ src/arch/x86/core/vram_settings.c
+ src/arch/x86/core/x86_bigint.c
+ src/arch/x86/core/x86_io.c
+ src/arch/x86/core/x86_string.c
+ src/arch/x86/core/x86_tcpip.c
+ src/arch/x86/drivers/hyperv/hyperv.c
+ src/arch/x86/drivers/xen/hvm.c
+ src/arch/x86/hci/commands/cpuid_cmd.c
+ src/arch/x86/include/bits/string.h
+ src/arch/x86/interface/efi/efix86_nap.c
+ src/interface/efi/efi_entropy.c
+ src/interface/efi/efiprefix.c
+ src/interface/efi/efidrvprefix.c
+ src/core/acpi.c
+ src/core/ansicol.c
+ src/core/ansicoldef.c
+ src/core/ansiesc.c
+ src/core/assert.c
+ src/core/base16.c
+ src/core/base64.c
+ src/core/basename.c
+ src/core/bitmap.c
+ src/core/blockdev.c
+ src/core/cpio.c
+ src/core/ctype.c
+ src/core/cwuri.c
+ src/core/debug.c
+ src/core/debug_md5.c
+ src/core/device.c
+ src/core/downloader.c
+ src/core/edd.c
+ src/core/exec.c
+ src/core/fbcon.c
+ src/core/getkey.c
+ src/core/getopt.c
+ src/core/image.c
+ src/core/init.c
+ src/core/interface.c
+ src/core/iobuf.c
+ src/core/isqrt.c
+ src/core/job.c
+ src/core/linebuf.c
+ src/core/lineconsole.c
+ src/core/list.c
+ src/core/log.c
+ src/core/malloc.c
+ src/core/memmap_settings.c
+ src/core/menu.c
+ src/core/monojob.c
+ src/core/null_reboot.c
+ src/core/null_sanboot.c
+ src/core/null_time.c
+ src/core/nvo.c
+ src/core/open.c
+ src/core/params.c
+ src/core/parseopt.c
+ src/core/pending.c
+ src/core/pinger.c
+ src/core/pixbuf.c
+ src/core/posix_io.c
+ src/core/process.c
+ src/core/profile.c
+ src/core/refcnt.c
+ src/core/resolv.c
+ src/core/settings.c
+ src/core/string.c
+ src/core/time.c
+ src/core/timer.c
+ src/core/uri.c
+ src/core/uuid.c
+ src/core/version.c
+ src/core/vsprintf.c
+ src/core/wchar.c
+ src/core/xfer.c
+ src/core/xferbuf.c
+ src/crypto/asn1.c
+ src/crypto/bigint.c
+ src/crypto/cbc.c
+ src/crypto/certstore.c
+ src/crypto/chap.c
+ src/crypto/cms.c
+ src/crypto/crypto_null.c
+ src/crypto/deflate.c
+ src/crypto/drbg.c
+ src/crypto/entropy.c
+ src/crypto/hash_df.c
+ src/crypto/hmac.c
+ src/crypto/hmac_drbg.c
+ src/crypto/md5.c
+ src/crypto/null_entropy.c
+ src/crypto/ocsp.c
+ src/crypto/privkey.c
+ src/crypto/random_nz.c
+ src/crypto/rbg.c
+ src/crypto/rootcert.c
+ src/crypto/rsa.c
+ src/crypto/sha1.c
+ src/crypto/sha224.c
+ src/crypto/sha256.c
+ src/crypto/sha384.c
+ src/crypto/sha512.c
+ src/crypto/sha512_224.c
+ src/crypto/sha512_256.c
+ src/crypto/x509.c
+ src/drivers/bitbash/bitbash.c
+ src/drivers/bitbash/i2c_bit.c
+ src/drivers/bitbash/spi_bit.c
+ src/drivers/block/ata.c
+ src/drivers/block/scsi.c
+ src/drivers/bus/cdc.c
+ src/drivers/bus/pci.c
+ src/drivers/bus/pci_settings.c
+ src/drivers/bus/pcibackup.c
+ src/drivers/bus/pcivpd.c
+ src/drivers/bus/usb.c
+ src/drivers/infiniband/mlx_bitops.h
+ src/drivers/infiniband/qib7322.c
+ src/drivers/infiniband/qib7322.h
+ src/drivers/infiniband/qib_genbits.pl
+ src/drivers/net/dm96xx.c
+ src/drivers/net/ecm.c
+ src/drivers/net/efi/nii.c
+ src/drivers/net/efi/snp.c
+ src/drivers/net/efi/snpnet.c
+ src/drivers/net/efi/snponly.c
+ src/drivers/net/intel.c
+ src/drivers/net/intelx.c
+ src/drivers/net/ipoib.c
+ src/drivers/net/mii.c
+ src/drivers/net/myson.c
+ src/drivers/net/natsemi.c
+ src/drivers/net/ncm.c
+ src/drivers/net/netfront.c
+ src/drivers/net/netvsc.c
+ src/drivers/net/phantom/nx_bitops.h
+ src/drivers/net/realtek.c
+ src/drivers/net/skeleton.c
+ src/drivers/net/smsc75xx.c
+ src/drivers/net/vmxnet3.c
+ src/drivers/net/vmxnet3.h
+ src/drivers/nvs/nvs.c
+ src/drivers/nvs/nvsvpd.c
+ src/drivers/nvs/spi.c
+ src/drivers/nvs/threewire.c
+ src/drivers/usb/ehci.c
+ src/drivers/usb/usbhub.c
+ src/drivers/usb/usbnet.c
+ src/drivers/usb/xhci.c
+ src/hci/commands/autoboot_cmd.c
+ src/hci/commands/config_cmd.c
+ src/hci/commands/console_cmd.c
+ src/hci/commands/dhcp_cmd.c
+ src/hci/commands/fcmgmt_cmd.c
+ src/hci/commands/ifmgmt_cmd.c
+ src/hci/commands/image_cmd.c
+ src/hci/commands/image_trust_cmd.c
+ src/hci/commands/ipstat_cmd.c
+ src/hci/commands/login_cmd.c
+ src/hci/commands/lotest_cmd.c
+ src/hci/commands/menu_cmd.c
+ src/hci/commands/neighbour_cmd.c
+ src/hci/commands/nvo_cmd.c
+ src/hci/commands/param_cmd.c
+ src/hci/commands/pci_cmd.c
+ src/hci/commands/ping_cmd.c
+ src/hci/commands/profstat_cmd.c
+ src/hci/commands/reboot_cmd.c
+ src/hci/commands/route_cmd.c
+ src/hci/commands/sanboot_cmd.c
+ src/hci/commands/sync_cmd.c
+ src/hci/commands/vlan_cmd.c
+ src/hci/editstring.c
+ src/hci/jumpscroll.c
+ src/hci/mucurses/widgets/editbox.c
+ src/hci/readline.c
+ src/hci/shell.c
+ src/hci/tui/login_ui.c
+ src/hci/tui/menu_ui.c
+ src/hci/tui/settings_ui.c
+ src/image/efi_image.c
+ src/image/elf.c
+ src/image/png.c
+ src/image/pnm.c
+ src/image/script.c
+ src/image/segment.c
+ src/include/errno.h
+ src/include/hci/ifmgmt_cmd.h
+ src/include/ipxe/bitops.h
+ src/include/ipxe/fip.h
+ src/interface/bofm/bofm.c
+ src/interface/efi/efi_autoboot.c
+ src/interface/efi/efi_bofm.c
+ src/interface/efi/efi_console.c
+ src/interface/efi/efi_debug.c
+ src/interface/efi/efi_driver.c
+ src/interface/efi/efi_file.c
+ src/interface/efi/efi_guid.c
+ src/interface/efi/efi_hii.c
+ src/interface/efi/efi_init.c
+ src/interface/efi/efi_pci.c
+ src/interface/efi/efi_reboot.c
+ src/interface/efi/efi_smbios.c
+ src/interface/efi/efi_snp.c
+ src/interface/efi/efi_snp_hii.c
+ src/interface/efi/efi_strings.c
+ src/interface/efi/efi_time.c
+ src/interface/efi/efi_timer.c
+ src/interface/efi/efi_uaccess.c
+ src/interface/efi/efi_umalloc.c
+ src/interface/efi/efi_utils.c
+ src/interface/efi/efi_wrap.c
+ src/interface/hyperv/vmbus.c
+ src/interface/linux/linux_entropy.c
+ src/interface/linux/linux_pci.c
+ src/interface/linux/linux_smbios.c
+ src/interface/linux/linux_time.c
+ src/interface/smbios/smbios.c
+ src/interface/smbios/smbios_settings.c
+ src/interface/xen/xenbus.c
+ src/interface/xen/xenstore.c
+ src/net/aoe.c
+ src/net/arp.c
+ src/net/dhcpopts.c
+ src/net/dhcppkt.c
+ src/net/eth_slow.c
+ src/net/ethernet.c
+ src/net/fakedhcp.c
+ src/net/fc.c
+ src/net/fcels.c
+ src/net/fcns.c
+ src/net/fcoe.c
+ src/net/fcp.c
+ src/net/fragment.c
+ src/net/icmp.c
+ src/net/icmpv4.c
+ src/net/icmpv6.c
+ src/net/infiniband.c
+ src/net/infiniband/ib_cm.c
+ src/net/infiniband/ib_mcast.c
+ src/net/infiniband/ib_mi.c
+ src/net/infiniband/ib_packet.c
+ src/net/infiniband/ib_pathrec.c
+ src/net/infiniband/ib_sma.c
+ src/net/infiniband/ib_smc.c
+ src/net/iobpad.c
+ src/net/ipv6.c
+ src/net/ndp.c
+ src/net/neighbour.c
+ src/net/netdev_settings.c
+ src/net/netdevice.c
+ src/net/nullnet.c
+ src/net/pccrc.c
+ src/net/ping.c
+ src/net/rarp.c
+ src/net/retry.c
+ src/net/rndis.c
+ src/net/socket.c
+ src/net/tcp/ftp.c
+ src/net/tcp/http.c
+ src/net/tcp/httpcore.c
+ src/net/tcp/https.c
+ src/net/tcp/iscsi.c
+ src/net/tcp/syslogs.c
+ src/net/tls.c
+ src/net/udp/dhcp.c
+ src/net/udp/dhcpv6.c
+ src/net/udp/slam.c
+ src/net/udp/syslog.c
+ src/net/udp/tftp.c
+ src/net/validator.c
+ src/net/vlan.c
+ src/tests/base16_test.c
+ src/tests/base64_test.c
+ src/tests/bigint_test.c
+ src/tests/bofm_test.c
+ src/tests/byteswap_test.c
+ src/tests/cms_test.c
+ src/tests/crc32_test.c
+ src/tests/deflate_test.c
+ src/tests/digest_test.c
+ src/tests/dns_test.c
+ src/tests/entropy_sample.c
+ src/tests/hash_df_test.c
+ src/tests/hmac_drbg_test.c
+ src/tests/ipv4_test.c
+ src/tests/ipv6_test.c
+ src/tests/list_test.c
+ src/tests/math_test.c
+ src/tests/md5_test.c
+ src/tests/memcpy_test.c
+ src/tests/memset_test.c
+ src/tests/ocsp_test.c
+ src/tests/pccrc_test.c
+ src/tests/pixbuf_test.c
+ src/tests/png_test.c
+ src/tests/pnm_test.c
+ src/tests/profile_test.c
+ src/tests/rsa_test.c
+ src/tests/setjmp_test.c
+ src/tests/settings_test.c
+ src/tests/sha1_test.c
+ src/tests/sha256_test.c
+ src/tests/sha512_test.c
+ src/tests/string_test.c
+ src/tests/tcpip_test.c
+ src/tests/test.c
+ src/tests/tests.c
+ src/tests/time_test.c
+ src/tests/uri_test.c
+ src/tests/vsprintf_test.c
+ src/tests/x509_test.c
+ src/usr/autoboot.c
+ src/usr/dhcpmgmt.c
+ src/usr/fcmgmt.c
+ src/usr/ifmgmt.c
+ src/usr/imgmgmt.c
+ src/usr/imgtrust.c
+ src/usr/ipstat.c
+ src/usr/lotest.c
+ src/usr/neighmgmt.c
+ src/usr/pingmgmt.c
+ src/usr/profstat.c
+ src/usr/prompt.c
+ src/usr/pxemenu.c
+ src/usr/route.c
+ src/usr/route_ipv4.c
+ src/usr/route_ipv6.c
+ src/usr/sync.c
+ src/util/Option/ROM.pm
+ src/util/disrom.pl
+ src/util/efifatbin.c
+ src/util/efirom.c
+ src/util/einfo.c
+ src/util/elf2efi.c
+ src/util/fixrom.pl
+ src/util/fnrec.pl
+ src/util/genkeymap.pl
+ src/util/licence.pl
+ src/util/mergerom.pl
+Copyright: 2004-2015, Michael Brown <mbrown@fensystems.co.uk>
+License: GPL-2+
+
+Files: src/drivers/net/cs89x0.*
+Copyright: Copyright, 1988-2008, Russell Nelson, Crynwr Software
 License: GPL-2
 
 Files:
- src/crypto/axtls/aes.c
- src/crypto/axtls/bigint.h
- src/crypto/axtls/crypto.h
-License: LGPL-2+
+ src/drivers/net/igbvf/*
+Copyright: 1999, - 2008, Intel Corporation
+License: GPL-2
+
+Files: src/drivers/net/igbvf/igbvf_main.c
+Copyright: 2009, Intel Corporation
+  2010, Eric Keller <ekeller@princeton.edu>
+  2010, Red Hat Inc
+License: GPL-2
 
 Files:
- src/crypto/axtls/bigint.c
- src/crypto/axtls/bigint_impl.h
- src/crypto/axtls/rsa.c
- src/crypto/axtls/sha1.c
-License: LGPL-2.1+
+ src/drivers/net/myri10ge*
+Copyright: 2005-2010, Myricom, Inc
+License: GPL-2
 
 Files:
- src/drivers/net/ath5k/*
-Copyright:
- 2004-2009 Reyk Floeter <reyk@openbsd.org>
- 2006-2009 Nick Kossifidis <mickflemm@gmail.com>
- 2007-2008 Jiri Slaby <jirislaby@gmail.com>
- 2007-2008 Luis Rodriguez <mcgrof@winlab.rutgers.edu>
- 2007-2008 Matthew W. S. Bell  <mentor@madwifi.org>
- 2007-2008 Michael Taylor <mike.taylor@apprion.com>
- 2007-2008 Pavel Roskin <proski@gnu.org>
- 2008-2009 Felix Fietkau <nbd@openwrt.org>
- 2009 Nick Kossifidis <mickflemm@gmail.com>
-License:
- Permission to use, copy, modify, and distribute this software for any
- purpose with or without fee is hereby granted, provided that the above
- copyright notice and this permission notice appear in all copies.
- . 
- THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
- WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
- MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
- ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
- WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
- ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
- OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ src/drivers/net/rtl818x/rtl8180_grf5101.c
+ src/drivers/net/rtl818x/rtl8180_max2820.c
+ src/drivers/net/rtl818x/rtl8180_sa2400.c
+ src/drivers/net/rtl818x/rtl8185_rtl8225.c
+ src/drivers/net/rtl818x/rtl818x.c
+ src/drivers/net/rtl818x/rtl818x.h
+Copyright: 2004-2007, Andrea Merello <andreamrl@tiscali.it>
+  2005-2007, Andrea Merello <andreamrl@tiscali.it>, et al
+License: GPL-2
+
+Files: src/drivers/net/skge.c
+ src/drivers/net/sky2.c
+Copyright: 2004-2005, Stephen Hemminger <shemminger@osdl.org>
+License: GPL-2
+
+Files: src/drivers/net/tg3/*
+Copyright: 2001-2003, Jeff Garzik (jgarzik@pobox.com)
+  2001-2004, David S. Miller (davem@redhat.com)
+  2004, Sun Microsystems Inc
+  2000-2011, Broadcom Corporation
+License: GPL-2
+
+Files: src/drivers/net/vxge/*
+Copyright: 2002-2010, Neterion Inc
+License: GPL-2
+
+Files: src/include/i82365.h
+Copyright: 1999, David A. Hinds.
+License: GPL-2
+
+Files: src/include/mii.h
+Copyright: 1996, 1999, 2001, David S. Miller (davem@redhat.com)
+License: GPL-2
 
 Files:
  src/drivers/bus/mca.c
  src/drivers/net/3c509.c
  src/drivers/net/3c529.c
+Copyright: *No copyright*
+License: BSD-2-clause
+
+Files:
  src/drivers/net/ns8390.h
- src/include/ipxe/ib_cmrc.h
- src/include/ipxe/ib_srp.h
- src/include/ipxe/srp.h
+Copyright: Martin Renters
+License: BSD-2-clause
+
+Files: src/drivers/net/thunderxcfg.h
+Copyright: 2015, Cavium Inc
+License: BSD-2-clause
+
+Files: src/drivers/block/srp.c
+Copyright: 2009 Fen Systems Ltd (<mbrown@fensystems.co.uk>)
 License: BSD-2-clause
 
 Files: src/drivers/net/3c509.h
@@ -99,12 +527,7 @@ Copyright:
  1994 Herb Peyerl <hpeyerl@novatel.ca>
  1995 Serge Babkin
  2000 Shusuke Nisiyama <shu@athena.qe.eng.hokudai.ac.jp>
-License:
- This software may be used, modified, copied, distributed, and sold, in
- both source and binary form provided that the above copyright and these
- terms are retained. Under no circumstances are the authors responsible for
- the proper functioning of this software, nor do the authors assume any
- responsibility for damages incurred with its use.
+License: BSD-2-clause
 
 Files: src/drivers/net/3c595.h
 Copyright:
@@ -116,39 +539,7 @@ Copyright:
  1999 LightSys Technology Services, Inc.
  1999 Steve Smith
  2009 Thomas Miletich
-License:
- This program may be re-distributed in source or binary form, modified,
- sold, or copied for any purpose, provided that the above copyright message
- and this text are included with all source copies or derivative works, and
- provided that the above copyright message and this text are included in the
- documentation of any binary-only distributions.  This program is distributed
- WITHOUT ANY WARRANTY, without even the warranty of FITNESS FOR A PARTICULAR
- PURPOSE or MERCHANTABILITY.  Please read the associated documentation
-
-Files: src/include/ipxe/ibft.h
-Copyright:
- 2007 Fen Systems Ltd
- 2004,2007 IBM Corporation
-License:
- Permission is hereby granted, free of charge, to any person
- obtaining a copy of this software and associated documentation
- files (the "Software"), to deal in the Software without
- restriction, including without limitation the rights to use, copy,
- modify, merge, publish, distribute, sublicense, and/or sell copies
- of the Software, and to permit persons to whom the Software is
- furnished to do so, subject to the following conditions:
- .                       
- The above copyright notice and this permission notice shall be
- included in all copies or substantial portions of the Software.
- .
- THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
- EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
- MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
- NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
- BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
- ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
- CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
- SOFTWARE.
+License: BSD-2-clause
 
 Files:
  src/net/infiniband/ib_cmrc.c
@@ -156,10 +547,20 @@ Files:
 Copyright: 2009 Fen Systems Ltd <mbrown@fensystems.co.uk>
 License: BSD-2-clause
 
+Files: src/drivers/net/ath/*
+Copyright:
+ 2008-2011 Atheros Communications Inc.
+ 2009 Nick Kossifidis <mickflemm@gmail.com>
+ 2004-2009 Reyk Floeter <reyk@openbsd.org>
+ 2006-2009 Nick Kossifidis <mickflemm@gmail.com>
+ 2007-2008 Michael Taylor <mike.taylor@apprion.com>
+ 2010 Bruno Randolf <br1@einfach.org>
+License: ISC
+
 Files:
- src/drivers/net/ath5k/ath5k.c
- src/drivers/net/ath5k/ath5k_rfkill.c
- src/drivers/net/ath5k/base.h
+ src/drivers/net/ath/ath5k/ath5k.c
+ src/drivers/net/ath/ath5k/ath5k_rfkill.c
+ src/drivers/net/ath/ath5k/base.h
 Copyright:
  2002-2007 Sam Leffler, Errno Consulting
  2004-2005 Atheros Communications, Inc.
@@ -167,17 +568,104 @@ Copyright:
  2007 Jiri Slaby <jirislaby@gmail.com>
  2007 Luis R. Rodriguez <mcgrof@winlab.rutgers.edu>
  2009 Tobias Doerffel <tobias.doerffel@gmail.com>
+ 2002-2007 Sam Leffler, Errno Consulting
 License: BSD-3-clause
 
+Files:
+ src/drivers/net/ath/ath5k/ath5k_reset.c
+ src/drivers/net/ath/ath5k/ath5k_dma.c
+ src/drivers/net/ath/ath5k/ath5k_caps.c
+ src/drivers/net/ath/ath5k/ath5k_gpio.c
+ src/drivers/net/ath/ath5k/ath5k_qcu.c
+ src/drivers/net/ath/ath5k/ath5k_rfkill.c
+ src/drivers/net/ath/ath5k/ath5k_attach.c
+ src/drivers/net/ath/ath5k/ath5k_phy.c
+ src/drivers/net/ath/ath5k/ath5k_desc.c
+ src/drivers/net/ath/ath5k/ath5k.h
+ src/drivers/net/ath/ath5k/ath5k_initvals.c
+ src/drivers/net/ath/ath5k/ath5k_eeprom.c
+ src/drivers/net/ath/ath5k/ath5k_pcu.c
+Copyright:
+ 2008-2011 Atheros Communications Inc.
+ 2004-2008 Reyk Floeter <reyk@openbsd.org>
+ 2006-2009 Nick Kossifidis <mickflemm@gmail.com>
+ 2007-2008 Luis Rodriguez <mcgrof@winlab.rutgers.edu>
+ 2007-2008 Pavel Roskin <proski@gnu.org>
+ 2007-2008 Jiri Slaby <jirislaby@gmail.com>
+ 2007-2008 Matthew W. S. Bell  <mentor@madwifi.org>
+ 2008-2009 Felix Fietkau <nbd@openwrt.org>
+ 2009 Tobias Doerffel <tobias.doerffel@gmail.com>
+License: Expat
+
+Files:
+ src/drivers/net/ath/ath9k/ar9002_initvals.h
+ src/drivers/net/ath/ath9k/ar9002_phy.h
+ src/drivers/net/ath/ath9k/ar9003_eeprom.h
+ src/drivers/net/ath/ath9k/common.h
+ src/drivers/net/ath/ath9k/phy.h
+ src/drivers/net/ath/ath9k/ar5008_initvals.h
+ src/drivers/net/ath/ath9k/ani.h
+ src/drivers/net/ath/ath9k/ath9k_ar9002_hw.c
+ src/drivers/net/ath/ath9k/hw.h
+ src/drivers/net/ath/ath9k/eeprom.h
+ src/drivers/net/ath/ath9k/reg.h
+ src/drivers/net/ath/ath9k/ar9001_initvals.h
+ src/drivers/net/ath/ath9k/hw-ops.h
+ src/drivers/net/ath/ath9k/ath9k.h
+ src/drivers/net/ath/ath9k/calib.h
+ src/drivers/net/ath/ath9k/ath9k_init.c
+ src/drivers/net/ath/ath9k/mac.h
+ src/drivers/net/ath/ath.h
+ src/drivers/net/ath/regd.h
+ src/drivers/net/ath/reg.h
+Copyright:
+ 2008-2011 Atheros Communications Inc.
+License: BSD-2-clause
+
+Files:
+ src/include/ipxe/ib_cmrc.h
+ src/include/ipxe/ib_srp.h
+ src/include/ipxe/srp.h
+Copyright: *No copyright*
+License: BSD-2-clause
+
 Files: src/include/ipxe/efi/*
-Copyright: 
+Copyright:
  2006-2010 Intel Corporation
  2008-2009 Apple
 License: BSD-3-clause
 
-Files: src/include/ipxe/efi/efi_*
+Files: src/include/ipxe/efi/efi_download.h
+Copyright:
+ 2010 VMware, Inc
 License: GPL-2+
 
+Files:
+ src/include/ipxe/ibft.h
+ src/drivers/block/ibft.c
+Copyright:
+ 2007 Fen Systems Ltd
+ 2004,2007 IBM Corporation
+License: BSD-2-clause
+
+Files:
+ src/include/ipxe/list.h
+ src/include/ipxe/pci.h
+Copyright: *No copyright*
+License: GPL-2 or UBDL
+
+Files: src/include/xen/*
+Copyright:
+ 2003-2007 Keir Fraser <keir@xensource.com>
+ 2005 XenSource Ltd.
+ 2005 Rusty Russell IBM Corporation
+ 2005 Bin Ren
+ 2005 Nguyen Anh Quynh <aquynh@gmail.com>
+ 2006 Christian Limpach
+ 2011 Citrix Systems
+License: Expat
+
+
 Files: debian/*
 Copyright: 2011 Bastian Blank <waldi@debian.org>
 License: GPL-2+
@@ -215,34 +703,6 @@ License: GPL-2+
  On Debian systems, the complete text of the GNU General
  Public License version 2 can be found in "/usr/share/common-licenses/GPL-2".
 
-License: LGPL-2+
- This package is free software; you can redistribute it and/or
- modify it under the terms of the GNU Lesser General Public
- License as published by the Free Software Foundation; either
- version 2 of the License, or (at your option) any later version.
- .
- This package is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- Lesser General Public License for more details.
- .
- You should have received a copy of the GNU General Public License
- along with this program. If not, see <http://www.gnu.org/licenses/>.
-
-License: LGPL-2.1+
- This package is free software; you can redistribute it and/or
- modify it under the terms of the GNU Lesser General Public
- License as published by the Free Software Foundation; either
- version 2.1 of the License, or (at your option) any later version.
- .
- This package is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- Lesser General Public License for more details.
- .
- You should have received a copy of the GNU General Public License
- along with this program. If not, see <http://www.gnu.org/licenses/>.
-
 License: BSD-2-clause
  Redistribution and use in source and binary forms, with or without
  modification, are permitted provided that the following conditions are met:
@@ -287,3 +747,90 @@ License: BSD-3-clause
  ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
  SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+License: UBDL
+ The GNU General Public License provides a legal guarantee that
+ software covered by it remains free (in the sense of freedom, not
+ price).  It achieves this guarantee by imposing obligations on anyone
+ who chooses to distribute the software.
+ .
+ Some of these obligations may be seen as unnecessarily burdensome.  In
+ particular, when the source code for the software is already publicly
+ and freely available, there is minimal value in imposing upon each
+ distributor the obligation to provide the complete source code (or an
+ equivalent written offer to provide the complete source code).
+ .
+ This Licence allows for the distribution of unmodified binaries built
+ from publicly available source code, without imposing the obligations
+ of the GNU General Public License upon anyone who chooses to
+ distribute only the unmodified binaries built from that source code.
+ .
+ The extra permissions granted by this Licence apply only to unmodified
+ binaries built from source code which has already been made available
+ to the public in accordance with the terms of the GNU General Public
+ Licence.  Nothing in this Licence allows for the creation of
+ closed-source modified versions of the Program.  Any modified versions
+ of the Program are subject to the usual terms and conditions of the
+ GNU General Public License.
+ .
+ TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
+ .
+ This Licence applies to any Program or other work which contains a
+ notice placed by the copyright holder saying it may be distributed
+ under the terms of this Unmodified Binary Distribution Licence.  All
+ terms used in the text of this Licence are to be interpreted as they
+ are used in version 2 of the GNU General Public License as published
+ by the Free Software Foundation.
+ .
+ If you have made this Program available to the public in both source
+ code and executable form in accordance with the terms of the GNU
+ General Public License as published by the Free Software Foundation;
+ either version 2 of the License, or (at your option) any later
+ version, then you are hereby granted an additional permission to use,
+ copy, and distribute the unmodified executable form of this Program
+ (the "Unmodified Binary") without restriction, including the right to
+ permit persons to whom the Unmodified Binary is furnished to do
+ likewise, subject to the following conditions:
+ .
+ - when started running, the Program must display an announcement which
+   includes the details of your existing publication of the Program
+   made in accordance with the terms of the GNU General Public License.
+   For example, the Program could display the URL of the publicly
+   available source code from which the Unmodified Binary was built.
+ .
+ - when exercising your right to grant permissions under this Licence,
+   you do not need to refer directly to the text of this Licence, but
+   you may not grant permissions beyond those granted to you by this
+   Licence.
+
+License: Expat
+ Permission is hereby granted, free of charge, to any person obtaining a copy
+ of this software and associated documentation files (the "Software"), to
+ deal in the Software without restriction, including without limitation the
+ rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
+ sell copies of the Software, and to permit persons to whom the Software is
+ furnished to do so, subject to the following conditions:
+ .
+ The above copyright notice and this permission notice shall be included in
+ all copies or substantial portions of the Software.
+ .
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
+ IN THE SOFTWARE.
+
+License: ISC
+ Permission to use, copy, modify, and/or distribute this software for any
+ purpose with or without fee is hereby granted, provided that the above
+ copyright notice and this permission notice appear in all copies.
+ .
+ THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH
+ REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
+ AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT,
+ INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
+ LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
+ OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+ PERFORMANCE OF THIS SOFTWARE.
diff -pruN 1.0.0+git-20190125.36a4c85-5.1/debian/grub-ipxe.install 1.21.1+git-20220113.fbbdc3926-0ubuntu1/debian/grub-ipxe.install
--- 1.0.0+git-20190125.36a4c85-5.1/debian/grub-ipxe.install	1970-01-01 00:00:00.000000000 +0000
+++ 1.21.1+git-20220113.fbbdc3926-0ubuntu1/debian/grub-ipxe.install	2022-01-13 13:53:40.000000000 +0000
@@ -0,0 +1,4 @@
+debian/tree/ipxe/* .
+src/bin-i386-pcbios/ipxe.lkrn boot
+src/bin-x86_64-efi/ipxe.efi boot
+src/bin-arm64-efi/ipxe-arm64.efi boot
diff -pruN 1.0.0+git-20190125.36a4c85-5.1/debian/grub-ipxe.postinst 1.21.1+git-20220113.fbbdc3926-0ubuntu1/debian/grub-ipxe.postinst
--- 1.0.0+git-20190125.36a4c85-5.1/debian/grub-ipxe.postinst	1970-01-01 00:00:00.000000000 +0000
+++ 1.21.1+git-20220113.fbbdc3926-0ubuntu1/debian/grub-ipxe.postinst	2021-05-10 07:36:04.000000000 +0000
@@ -0,0 +1,13 @@
+#!/bin/sh
+
+set -e
+
+case "$1" in
+    configure)
+        command -v update-grub > /dev/null && update-grub || :
+    ;;
+esac
+
+#DEBHELPER#
+
+exit 0
diff -pruN 1.0.0+git-20190125.36a4c85-5.1/debian/grub-ipxe.postrm 1.21.1+git-20220113.fbbdc3926-0ubuntu1/debian/grub-ipxe.postrm
--- 1.0.0+git-20190125.36a4c85-5.1/debian/grub-ipxe.postrm	1970-01-01 00:00:00.000000000 +0000
+++ 1.21.1+git-20220113.fbbdc3926-0ubuntu1/debian/grub-ipxe.postrm	2021-05-10 07:36:04.000000000 +0000
@@ -0,0 +1,13 @@
+#!/bin/sh
+
+set -e
+
+case "$1" in
+    remove)
+        command -v update-grub > /dev/null && update-grub || :
+    ;;      
+esac
+
+#DEBHELPER#
+
+exit 0
diff -pruN 1.0.0+git-20190125.36a4c85-5.1/debian/ipxe.install 1.21.1+git-20220113.fbbdc3926-0ubuntu1/debian/ipxe.install
--- 1.0.0+git-20190125.36a4c85-5.1/debian/ipxe.install	2020-02-25 20:45:06.000000000 +0000
+++ 1.21.1+git-20220113.fbbdc3926-0ubuntu1/debian/ipxe.install	2022-01-13 13:53:40.000000000 +0000
@@ -1,8 +1,5 @@
-debian/tree/ipxe/* .
 src/bin-combined/ipxe.iso usr/lib/ipxe
-src/bin-i386-pcbios/ipxe.lkrn boot
 src/bin-i386-pcbios/ipxe.pxe usr/lib/ipxe
 src/bin-i386-pcbios/undionly.kkpxe usr/lib/ipxe
 src/bin-i386-pcbios/undionly.kpxe usr/lib/ipxe
-src/bin-x86_64-efi/ipxe.efi boot
 src/bin-x86_64-efi/snponly.efi usr/lib/ipxe
diff -pruN 1.0.0+git-20190125.36a4c85-5.1/debian/ipxe.postinst 1.21.1+git-20220113.fbbdc3926-0ubuntu1/debian/ipxe.postinst
--- 1.0.0+git-20190125.36a4c85-5.1/debian/ipxe.postinst	2020-02-25 20:45:06.000000000 +0000
+++ 1.21.1+git-20220113.fbbdc3926-0ubuntu1/debian/ipxe.postinst	1970-01-01 00:00:00.000000000 +0000
@@ -1,13 +0,0 @@
-#!/bin/bash
-
-set -e
-
-case "$1" in
-    configure)
-        command -v update-grub > /dev/null && update-grub || :
-    ;;
-esac
-
-#DEBHELPER#
-
-exit 0
diff -pruN 1.0.0+git-20190125.36a4c85-5.1/debian/ipxe.postrm 1.21.1+git-20220113.fbbdc3926-0ubuntu1/debian/ipxe.postrm
--- 1.0.0+git-20190125.36a4c85-5.1/debian/ipxe.postrm	2020-02-25 20:45:06.000000000 +0000
+++ 1.21.1+git-20220113.fbbdc3926-0ubuntu1/debian/ipxe.postrm	1970-01-01 00:00:00.000000000 +0000
@@ -1,13 +0,0 @@
-#!/bin/bash
-
-set -e
-
-case "$1" in
-    remove)
-        command -v update-grub > /dev/null && update-grub || :
-    ;;      
-esac
-    
-#DEBHELPER#
-        
-exit 0
diff -pruN 1.0.0+git-20190125.36a4c85-5.1/debian/patches/0005-strip-802.1Q-VLAN-0-priority-tags.patch 1.21.1+git-20220113.fbbdc3926-0ubuntu1/debian/patches/0005-strip-802.1Q-VLAN-0-priority-tags.patch
--- 1.0.0+git-20190125.36a4c85-5.1/debian/patches/0005-strip-802.1Q-VLAN-0-priority-tags.patch	1970-01-01 00:00:00.000000000 +0000
+++ 1.21.1+git-20220113.fbbdc3926-0ubuntu1/debian/patches/0005-strip-802.1Q-VLAN-0-priority-tags.patch	2021-05-10 07:36:04.000000000 +0000
@@ -0,0 +1,143 @@
+From: Ladi Prosek <lprosek@redhat.com>
+Subject: Strip 802.1Q VLAN 0 priority tags
+ iPXE was unable to receive priority tagged packets specified in
+ the 802.1Q standard and supported by all major networking stacks.
+
+ This commit adds a new function net_pull_tags which is called by
+ all consumers of incoming packets after stripping their link-layer
+ headers.
+
+ Update 2021:
+ Upstream made the vlan_find function that is used here static in
+  https://github.com/ipxe/ipxe/commit/fe680c8228563369804948010954128aacb7db74
+ We have to un-do this part of the change to be able to further use it from
+ where it is needed for this functionality.
+
+Origin: vendor, https://git.centos.org/blob/rpms!ipxe.git/c7/SOURCES!0009-Strip-802.1Q-VLAN-0-priority-tags.patch
+Bug-Ubuntu: https://bugs.launchpad.net/bugs/1805920
+Last-Update: 2021-05-03
+
+--- a/src/arch/x86/interface/pxe/pxe_undi.c
++++ b/src/arch/x86/interface/pxe/pxe_undi.c
+@@ -976,6 +976,12 @@ static PXENV_EXIT_t pxenv_undi_isr ( str
+ 		}
+ 		ll_hlen = ( len - iob_len ( iobuf ) );
+ 
++		/* Strip link-layer-independent headers */
++		if ( ( rc = net_pull_tags ( iobuf, pxe_netdev, &net_proto ) ) != 0 ) {
++			/* Assume unknown net_proto */
++			net_proto = 0;
++		}
++
+ 		/* Determine network-layer protocol */
+ 		switch ( net_proto ) {
+ 		case htons ( ETH_P_IP ):
+--- a/src/include/ipxe/netdevice.h
++++ b/src/include/ipxe/netdevice.h
+@@ -738,6 +738,8 @@ extern int net_tx ( struct io_buffer *io
+ extern int net_rx ( struct io_buffer *iobuf, struct net_device *netdev,
+ 		    uint16_t net_proto, const void *ll_dest,
+ 		    const void *ll_source, unsigned int flags );
++extern int net_pull_tags ( struct io_buffer *iobuf, struct net_device *netdev,
++			   uint16_t *net_proto );
+ extern void net_poll ( void );
+ extern struct net_device_configurator *
+ find_netdev_configurator ( const char *name );
+--- a/src/interface/efi/efi_snp.c
++++ b/src/interface/efi/efi_snp.c
+@@ -816,6 +816,13 @@ efi_snp_receive ( EFI_SIMPLE_NETWORK_PRO
+ 		goto out_bad_ll_header;
+ 	}
+ 
++	/* Strip link-layer-independent headers */
++	if ( ( rc = net_pull_tags ( iobuf, snpdev->netdev, &iob_net_proto ) ) ) {
++		DBGC ( snpdev, "SNPDEV %p could not parse tags: %s\n",
++			snpdev, strerror ( rc ) );
++		goto out_bad_ll_header;
++	}
++
+ 	/* Return link-layer header parameters to caller, if required */
+ 	if ( ll_header_len )
+ 		*ll_header_len = ll_protocol->ll_header_len;
+--- a/src/net/netdevice.c
++++ b/src/net/netdevice.c
+@@ -1099,6 +1099,44 @@ int net_rx ( struct io_buffer *iobuf, st
+ }
+ 
+ /**
++ * Strip extra link-layer-independent tags from a received packet
++ *
++ * @v iobuf        I/O buffer
++ * @v netdev        Network device
++ * @v net_proto        Network-layer protocol, in network-byte order
++ * @ret rc        Return status code
++ *
++ * This function should be called after stripping link-layer headers but
++ * before inspecting the network-layer protocol.
++ */
++int net_pull_tags ( struct io_buffer *iobuf, struct net_device *netdev,
++            uint16_t *net_proto ) {
++    struct vlan_header *vlanhdr;
++    uint16_t tag;
++
++    /* Strip 802.1Q VLAN 0 priority tags if present */
++    while ( *net_proto == htons ( ETH_P_8021Q ) ) {
++        if ( iob_len ( iobuf ) < sizeof ( *vlanhdr ) ) {
++            DBG ( "VLAN header too short at %zd bytes (min %zd bytes)\n",
++                  iob_len ( iobuf ), sizeof ( *vlanhdr ) );
++            return -EINVAL;
++        }
++        vlanhdr = ( struct vlan_header * ) iobuf->data;
++        tag = VLAN_TAG ( ntohs ( vlanhdr->tci ) );
++
++        if ( tag == 0 && ! vlan_find ( netdev, tag ) ) {
++            /* VLAN 0, strip and continue */
++            *net_proto = vlanhdr->net_proto;
++            iob_pull ( iobuf, sizeof ( *vlanhdr ) );
++        } else {
++            /* Real VLAN tag, leave it alone */
++            break;
++        }
++    }
++    return 0;
++}
++
++/**
+  * Poll the network stack
+  *
+  * This polls all interfaces for received packets, and processes
+@@ -1148,6 +1186,12 @@ void net_poll ( void ) {
+ 				free_iob ( iobuf );
+ 				continue;
+ 			}
++
++			/* Remove link-layer-independent headers */
++			if ( ( rc = net_pull_tags ( iobuf, netdev, &net_proto ) ) ) {
++				free_iob ( iobuf );
++				continue;
++			}
+ 
+ 			/* Hand packet to network layer */
+ 			if ( ( rc = net_rx ( iob_disown ( iobuf ), netdev,
+--- a/src/include/ipxe/vlan.h
++++ b/src/include/ipxe/vlan.h
+@@ -61,6 +61,8 @@ struct vlan_header {
+  */
+ #define VLAN_PRIORITY_IS_VALID( priority ) ( (priority) <= 7 )
+ 
++extern struct net_device * vlan_find ( struct net_device *trunk,
++                                      unsigned int tag );
+ extern unsigned int vlan_tag ( struct net_device *netdev );
+ extern int vlan_can_be_trunk ( struct net_device *trunk );
+ extern int vlan_create ( struct net_device *trunk, unsigned int tag,
+--- a/src/net/vlan.c
++++ b/src/net/vlan.c
+@@ -199,7 +199,7 @@ static void vlan_sync ( struct net_devic
+  * @v tag		VLAN tag
+  * @ret netdev		VLAN device, if any
+  */
+-static struct net_device * vlan_find ( struct net_device *trunk,
++struct net_device * vlan_find ( struct net_device *trunk,
+ 				       unsigned int tag ) {
+ 	struct net_device *netdev;
+ 	struct vlan_device *vlan;
diff -pruN 1.0.0+git-20190125.36a4c85-5.1/debian/patches/f982a712979619dbae2c6e0d741757e2ce94be11-fcommon.patch 1.21.1+git-20220113.fbbdc3926-0ubuntu1/debian/patches/f982a712979619dbae2c6e0d741757e2ce94be11-fcommon.patch
--- 1.0.0+git-20190125.36a4c85-5.1/debian/patches/f982a712979619dbae2c6e0d741757e2ce94be11-fcommon.patch	2021-02-07 17:25:18.000000000 +0000
+++ 1.21.1+git-20220113.fbbdc3926-0ubuntu1/debian/patches/f982a712979619dbae2c6e0d741757e2ce94be11-fcommon.patch	1970-01-01 00:00:00.000000000 +0000
@@ -1,27 +0,0 @@
-From f982a712979619dbae2c6e0d741757e2ce94be11 Mon Sep 17 00:00:00 2001
-From: Bruce Rogers <brogers@suse.com>
-Date: Wed, 6 May 2020 15:03:02 -0600
-Subject: [PATCH] [build] Be explicit about -fcommon compiler directive
-
-gcc10 switched default behavior from -fcommon to -fno-common.  Since
-"__shared" relies on the legacy behavior, explicitly specify it.
-
-Signed-off-by: Bruce Rogers <brogers@suse.com>
-Modified-by: Michael Brown <mcb30@ipxe.org>
-Signed-off-by: Michael Brown <mcb30@ipxe.org>
----
- src/Makefile.housekeeping | 1 +
- 1 file changed, 1 insertion(+)
-
-diff --git a/src/Makefile.housekeeping b/src/Makefile.housekeeping
-index 66d6dd449..b6c61c112 100644
---- a/src/Makefile.housekeeping
-+++ b/src/Makefile.housekeeping
-@@ -418,6 +418,7 @@ CFLAGS		+= -Os
- CFLAGS		+= -g
- ifeq ($(CCTYPE),gcc)
- CFLAGS		+= -ffreestanding
-+CFLAGS		+= -fcommon
- CFLAGS		+= -Wall -W -Wformat-nonliteral
- HOST_CFLAGS	+= -Wall -W -Wformat-nonliteral
- endif
diff -pruN 1.0.0+git-20190125.36a4c85-5.1/debian/patches/series 1.21.1+git-20220113.fbbdc3926-0ubuntu1/debian/patches/series
--- 1.0.0+git-20190125.36a4c85-5.1/debian/patches/series	2021-02-07 17:25:39.000000000 +0000
+++ 1.21.1+git-20220113.fbbdc3926-0ubuntu1/debian/patches/series	2021-05-10 07:36:04.000000000 +0000
@@ -1,2 +1,2 @@
 debian-changes
-f982a712979619dbae2c6e0d741757e2ce94be11-fcommon.patch
+0005-strip-802.1Q-VLAN-0-priority-tags.patch
diff -pruN 1.0.0+git-20190125.36a4c85-5.1/debian/rules 1.21.1+git-20220113.fbbdc3926-0ubuntu1/debian/rules
--- 1.0.0+git-20190125.36a4c85-5.1/debian/rules	2020-02-25 20:45:06.000000000 +0000
+++ 1.21.1+git-20220113.fbbdc3926-0ubuntu1/debian/rules	2022-01-13 13:53:40.000000000 +0000
@@ -16,12 +16,42 @@ VERSION := $(shell dpkg-parsechangelog |
 override_dh_auto_configure:
 	cp debian/config/* src/config/local
 
-src/bin-i386-pcbios/% src/bin-x86_64-efi/%:
-	dh_auto_build --sourcedirectory=src -- V=1 NO_WERROR=1 VERSION="$(VERSION)" $(subst src/,,$@)
+# qemu EFI roms shall be built with CONFIG=qemu
+# This will make it select src/config/qemu/* as config base
+# and set -DCONFIG=qemu -DLOCAL_CONFIG=qemu
+src/bin-i386-pcbios/%.rom src/bin-x86_64-efi/%.efirom: export CONFIG=qemu
+# qemu EFI roms are built without HTTPS, EFI does that on its own (and better)
+src/bin-x86_64-efi/%.efirom: export NOHTTPS=true
+
+# Note: d/rules Makefile logic can't differentiate src/bin-arm64-efi/ipxe.efi
+# from src/bin-x86_64-efi/ipxe.efi which makes these steps more complex and
+# ugly than they should be.
+src/bin-i386-pcbios/% src/bin-x86_64-efi/% src/bin-arm64-efi/%.efi:
+	# clean and reconfigure if either NOHTTPS or CONFIG=qemu switches
+	if [ "config:$(CONFIG)nohttps:$(NOHTTPS)" != "$(shell cat debian/last-used-config 2>/dev/null)" ]; then \
+	    if [ "$(NOHTTPS)" = "true" ]; then \
+	        cp -v debian/config/* src/config/local; \
+	    else \
+	        echo "#define DOWNLOAD_PROTO_HTTPS" >> src/config/local/general.h; \
+	    fi; \
+	   echo -n "config:$(CONFIG)" > debian/last-used-config; \
+	   echo -n "nohttps:$(NOHTTPS)" >> debian/last-used-config; \
+	fi; \
+	if [ "$@" = "src/bin-arm64-efi/ipxe-arm64.efi" ]; then \
+		export CROSS=aarch64-linux-gnu-; \
+		export CC=aarch64-linux-gnu-gcc; \
+		dh_auto_build --sourcedirectory=src -- V=1 NO_WERROR=1 VERSION="$(VERSION)" bin-arm64-efi/ipxe.efi; \
+		mv src/bin-arm64-efi/ipxe.efi src/bin-arm64-efi/ipxe-arm64.efi; \
+	else \
+		dh_auto_build --sourcedirectory=src -- V=1 NO_WERROR=1 VERSION="$(VERSION)" $(subst src/,,$@); \
+	fi; \
 
 src/bin-combined/%.efirom: src/bin-i386-pcbios/%.rom src/bin-x86_64-efi/%.efirom
 	@[ -d $(dir $@) ] || mkdir $(dir $@)
 	src/util/catrom.pl $^ > $@
+	# efi roms are >256k since Bionic due to https + natural growth
+	# stay at 256k-512k after disabling https in efi via padding
+	src/util/padimg.pl --blksize=524288 --byte=0xff --verbose $@
 
 src/bin-combined/%.iso: src/bin-i386-pcbios/%.lkrn src/bin-x86_64-efi/%.efi
 	@[ -d $(dir $@) ] || mkdir $(dir $@)
@@ -29,10 +59,15 @@ src/bin-combined/%.iso: src/bin-i386-pcb
 
 override_dh_auto_build: $(shell grep -hoE 'src/bin(-[^/]*)?/\S+' debian/*.install)
 
+override_dh_install:
+	dh_install
+	debian/util/check-rom-sizes
+
 override_dh_auto_clean:
 	$(MAKE) -C src veryclean
+	rm -f debian/last-used-config
 	rm -fr src/bin*
-	rm -f src/config/local/*
+	rm -fr src/config/local/*
 
 .NOTPARALLEL:
 .SECONDARY:
diff -pruN 1.0.0+git-20190125.36a4c85-5.1/debian/tree/ipxe/etc/grub.d/20_ipxe 1.21.1+git-20220113.fbbdc3926-0ubuntu1/debian/tree/ipxe/etc/grub.d/20_ipxe
--- 1.0.0+git-20190125.36a4c85-5.1/debian/tree/ipxe/etc/grub.d/20_ipxe	2020-02-25 20:45:06.000000000 +0000
+++ 1.21.1+git-20220113.fbbdc3926-0ubuntu1/debian/tree/ipxe/etc/grub.d/20_ipxe	2021-05-10 07:36:04.000000000 +0000
@@ -15,11 +15,24 @@ IPXE=/boot/ipxe.lkrn
 
 if test -e "$IPXE" ; then
   IPXEPATH=$( make_system_path_relative_to_its_root "$IPXE" )
+  # Remove the .lkrn extension
+  IPXEPATH=${IPXEPATH%.lkrn}
   echo "Found iPXE image: $IPXE" >&2
   cat << EOF
-menuentry "Network boot (iPXE)" --users "" --class network {
+menuentry "Network boot (iPXE)" --users "" --class network --id ipxe {
 ${prepare_boot_cache}
-	linux16 $IPXEPATH
+EOF
+  save_default_entry | grub_add_tab
+  cat << EOF
+	if [ "\$grub_platform" = "efi" ]; then
+		chainloader $IPXEPATH.efi
+	else
+		linux16 $IPXEPATH.lkrn
+		# If the user provided an iPXE script, load it
+		if [ -f $IPXEPATH.ipxe ]; then
+			initrd16 $IPXEPATH.ipxe
+		fi
+	fi
 }
 EOF
 fi
diff -pruN 1.0.0+git-20190125.36a4c85-5.1/debian/util/check-rom-sizes 1.21.1+git-20220113.fbbdc3926-0ubuntu1/debian/util/check-rom-sizes
--- 1.0.0+git-20190125.36a4c85-5.1/debian/util/check-rom-sizes	1970-01-01 00:00:00.000000000 +0000
+++ 1.21.1+git-20220113.fbbdc3926-0ubuntu1/debian/util/check-rom-sizes	2021-05-10 07:36:04.000000000 +0000
@@ -0,0 +1,66 @@
+#!/bin/bash
+#
+# Generate a isolinux/bios and efi ISO boot image
+
+set -e
+PATH=/usr/bin:/bin:/usr/sbin:/sbin
+
+dir="./debian/ipxe-qemu/usr/lib/ipxe/qemu/"
+rc=0
+
+declare -A roms
+# these are the current power-of-2 buckets of roms generated by ipxe
+# If any of these roms grows/shrinks out of its bucket a KVM
+# live migration between two systems with those different sizes will fail.
+# This check is intended to break builds on such a change to make it an opt-in
+# change by a developer (to change the sizes below AFTER he has taken care that
+# the qemu/libvirt on the migration paths will take care of it on migration).
+# Due to ipxe (currently) not being part of Ubuntu Cloud Archive all UCA have
+# the ipxe of the latest LTS. Which makes a certain qemu version (which defines
+# the machine type) ambiguous which ipxe roms it has.
+# Therefore such size breaking upgrades are only reasonably doable on LTS
+# releases where qemu can assume all former types are of the former size
+# and can handle all of these as one.
+roms["efi-e1000.rom"]="524288"
+roms["efi-e1000e.rom"]="524288"
+roms["efi-eepro100.rom"]="524288"
+roms["efi-ne2k_pci.rom"]="524288"
+roms["efi-pcnet.rom"]="524288"
+roms["efi-rtl8139.rom"]="524288"
+roms["efi-virtio.rom"]="524288"
+roms["efi-vmxnet3.rom"]="524288"
+roms["pxe-e1000.rom"]="131072"
+roms["pxe-e1000e.rom"]="131072"
+roms["pxe-eepro100.rom"]="131072"
+roms["pxe-ne2k_pci.rom"]="131072"
+roms["pxe-pcnet.rom"]="131072"
+roms["pxe-rtl8139.rom"]="131072"
+roms["pxe-virtio.rom"]="131072"
+roms["pxe-vmxnet3.rom"]="131072"
+
+echo "Generated roms:"
+ls -laF "${dir}"
+
+for rom in "${!roms[@]}"; do
+    size=$(stat --printf="%s" "${dir}/${rom}")
+    shiftsize="${size}"
+    bucket=1
+    while [ "${shiftsize}" -ne "1" ]; do
+        shiftsize=$((shiftsize>>1))
+        bucket=$((bucket<<1))
+    done
+    bucket=$((bucket<<1))
+    # being smaller could be ok, but check -eq to warn/break on unexpected size loss as well
+    if [ "${size}" -eq "${roms[$rom]}" ]; then
+        echo "OK: ${rom} is exactly ${size} bytes as expected"
+    else
+        if [ "${bucket}" -eq "${roms[$rom]}" ]; then
+            echo "OK: ${rom} is ${size} bytes and thereby in bucket ${bucket} which matches ${roms[$rom]}"
+        else
+            echo "ERROR: ${rom} is ${size} bytes and thereby in bucket ${bucket} which does not match ${roms[$rom]}"
+            rc=1
+        fi
+    fi
+done
+
+exit ${rc}
diff -pruN 1.0.0+git-20190125.36a4c85-5.1/debian/util/geniso 1.21.1+git-20220113.fbbdc3926-0ubuntu1/debian/util/geniso
--- 1.0.0+git-20190125.36a4c85-5.1/debian/util/geniso	2020-02-25 20:45:06.000000000 +0000
+++ 1.21.1+git-20220113.fbbdc3926-0ubuntu1/debian/util/geniso	2022-01-13 13:53:40.000000000 +0000
@@ -32,7 +32,7 @@ cp /usr/lib/ISOLINUX/isolinux.bin ${dir}
 cp /usr/lib/syslinux/modules/bios/ldlinux.c32 ${dir}
 
 # generate EFI boot image
-blocks=$((($(stat -c %s "$EFI") / 1024 + 55) / 32 * 32 ))
+blocks=$((($(stat -c %s "$EFI") / 1024 + 55 + 1) / 32 * 32 ))
 mkfs.msdos -C ${dir}/efi.img $blocks >/dev/null
 mmd -i ${dir}/efi.img ::efi
 mmd -i ${dir}/efi.img ::efi/boot
diff -pruN 1.0.0+git-20190125.36a4c85-5.1/.github/workflows/build.yml 1.21.1+git-20220113.fbbdc3926-0ubuntu1/.github/workflows/build.yml
--- 1.0.0+git-20190125.36a4c85-5.1/.github/workflows/build.yml	1970-01-01 00:00:00.000000000 +0000
+++ 1.21.1+git-20220113.fbbdc3926-0ubuntu1/.github/workflows/build.yml	2022-01-13 13:43:08.000000000 +0000
@@ -0,0 +1,71 @@
+name: Build
+
+on: push
+
+jobs:
+
+  x86:
+    name: x86
+    runs-on: ubuntu-20.04
+    steps:
+      - name: Check out code
+        uses: actions/checkout@v2
+        with:
+          fetch-depth: 0
+      - name: Install packages
+        run: |
+          sudo dpkg --add-architecture i386
+          sudo apt update
+          sudo apt install -y -o Acquire::Retries=50 \
+                           mtools syslinux isolinux \
+                           libc6-dev-i386 libc6-dbg:i386 valgrind
+      - name: Build (BIOS)
+        run: |
+          make -j 4 -C src
+      - name: Build (Everything)
+        run: |
+          make -j 4 -C src everything
+      - name: Test
+        run: |
+          valgrind ./src/bin-i386-linux/tests.linux
+          valgrind ./src/bin-x86_64-linux/tests.linux
+
+  arm32:
+    name: ARM32
+    runs-on: ubuntu-20.04
+    steps:
+      - name: Check out code
+        uses: actions/checkout@v2
+        with:
+          fetch-depth: 0
+      - name: Install packages
+        run: |
+          sudo apt update
+          sudo apt install -y -o Acquire::Retries=50 \
+                           mtools syslinux isolinux gcc-arm-none-eabi
+      - name: Build
+        run: |
+          make -j 4 -C src CROSS=arm-none-eabi- \
+               bin-arm32-efi/intel.efi \
+               bin-arm32-efi/intel.usb \
+               bin-arm32-efi/intel.iso
+
+  arm64:
+    name: ARM64
+    runs-on: ubuntu-20.04
+    steps:
+      - name: Check out code
+        uses: actions/checkout@v2
+        with:
+          fetch-depth: 0
+      - name: Install packages
+        run: |
+          sudo apt update
+          sudo apt install -y -o Acquire::Retries=50 \
+                           mtools syslinux isolinux gcc-aarch64-linux-gnu
+      - name: Build
+        run: |
+          make -j 4 -C src CROSS=aarch64-linux-gnu- \
+               bin-arm64-efi/ipxe.efi \
+               bin-arm64-efi/ipxe.usb \
+               bin-arm64-efi/ipxe.iso
diff -pruN 1.0.0+git-20190125.36a4c85-5.1/.github/workflows/coverity.yml 1.21.1+git-20220113.fbbdc3926-0ubuntu1/.github/workflows/coverity.yml
--- 1.0.0+git-20190125.36a4c85-5.1/.github/workflows/coverity.yml	1970-01-01 00:00:00.000000000 +0000
+++ 1.21.1+git-20220113.fbbdc3926-0ubuntu1/.github/workflows/coverity.yml	2022-01-13 13:43:08.000000000 +0000
@@ -0,0 +1,37 @@
+name: Coverity Scan
+
+on:
+  push:
+    branches:
+      - coverity_scan
+
+jobs:
+  submit:
+    name: Submit
+    runs-on: ubuntu-20.04
+    steps:
+      - name: Check out code
+        uses: actions/checkout@v2
+      - name: Download Coverity Scan
+        run: |
+          curl --form token=${{ secrets.COVERITY_SCAN_TOKEN }} \
+               --form project=${{ github.repository }} \
+               --output coverity.tar.gz \
+               https://scan.coverity.com/download/cxx/linux64
+          mkdir -p /opt/coverity
+          sudo tar xvzf coverity.tar.gz --strip 1 --directory /opt/coverity
+      - name: Build via Coverity Scan
+        run: |
+          make -C src bin/deps
+          /opt/coverity/bin/cov-build --dir cov-int make -C src bin/blib.a
+      - name: Create submission
+        run : |
+          tar cvzf cov-int.tar.gz cov-int
+      - name: Submit to Coverity Scan
+        run: |
+          curl --form token=${{ secrets.COVERITY_SCAN_TOKEN }} \
+               --form email=${{ secrets.COVERITY_SCAN_EMAIL }} \
+               --form file=@cov-int.tar.gz \
+               --form version=${{ github.sha }} \
+               --form description=${{ github.ref }} \
+               https://scan.coverity.com/builds?project=${{ github.repository }}
diff -pruN 1.0.0+git-20190125.36a4c85-5.1/src/arch/arm/include/ipxe/arm_io.h 1.21.1+git-20220113.fbbdc3926-0ubuntu1/src/arch/arm/include/ipxe/arm_io.h
--- 1.0.0+git-20190125.36a4c85-5.1/src/arch/arm/include/ipxe/arm_io.h	2019-02-09 16:03:59.000000000 +0000
+++ 1.21.1+git-20220113.fbbdc3926-0ubuntu1/src/arch/arm/include/ipxe/arm_io.h	2022-01-13 13:43:08.000000000 +0000
@@ -43,43 +43,84 @@ IOAPI_INLINE ( arm, bus_to_phys ) ( unsi
  *
  */
 
-#define ARM_READX( _api_func, _type, _insn_suffix, _reg_prefix )	      \
+#define ARM_READX( _suffix, _type, _insn_suffix, _reg_prefix )		      \
 static inline __always_inline _type					      \
-IOAPI_INLINE ( arm, _api_func ) ( volatile _type *io_addr ) {		      \
+IOAPI_INLINE ( arm, read ## _suffix ) ( volatile _type *io_addr ) {	      \
 	_type data;							      \
 	__asm__ __volatile__ ( "ldr" _insn_suffix " %" _reg_prefix "0, %1"    \
 			       : "=r" ( data ) : "Qo" ( *io_addr ) );	      \
 	return data;							      \
 }
 #ifdef __aarch64__
-ARM_READX ( readb, uint8_t, "b", "w" );
-ARM_READX ( readw, uint16_t, "h", "w" );
-ARM_READX ( readl, uint32_t, "", "w" );
-ARM_READX ( readq, uint64_t, "", "" );
+ARM_READX ( b, uint8_t, "b", "w" );
+ARM_READX ( w, uint16_t, "h", "w" );
+ARM_READX ( l, uint32_t, "", "w" );
+ARM_READX ( q, uint64_t, "", "" );
 #else
-ARM_READX ( readb, uint8_t, "b", "" );
-ARM_READX ( readw, uint16_t, "h", "" );
-ARM_READX ( readl, uint32_t, "", "" );
+ARM_READX ( b, uint8_t, "b", "" );
+ARM_READX ( w, uint16_t, "h", "" );
+ARM_READX ( l, uint32_t, "", "" );
 #endif
 
-#define ARM_WRITEX( _api_func, _type, _insn_suffix, _reg_prefix )			\
+#define ARM_WRITEX( _suffix, _type, _insn_suffix, _reg_prefix )		      \
 static inline __always_inline void					      \
-IOAPI_INLINE ( arm, _api_func ) ( _type data, volatile _type *io_addr ) {     \
+IOAPI_INLINE ( arm, write ## _suffix ) ( _type data,			      \
+					 volatile _type *io_addr ) {	      \
 	__asm__ __volatile__ ( "str" _insn_suffix " %" _reg_prefix "0, %1"    \
 			       : : "r" ( data ), "Qo" ( *io_addr ) );	      \
 }
 #ifdef __aarch64__
-ARM_WRITEX ( writeb, uint8_t, "b", "w" );
-ARM_WRITEX ( writew, uint16_t, "h", "w" );
-ARM_WRITEX ( writel, uint32_t, "", "w" );
-ARM_WRITEX ( writeq, uint64_t, "", "" );
+ARM_WRITEX ( b, uint8_t, "b", "w" );
+ARM_WRITEX ( w, uint16_t, "h", "w" );
+ARM_WRITEX ( l, uint32_t, "", "w" );
+ARM_WRITEX ( q, uint64_t, "", "" );
 #else
-ARM_WRITEX ( writeb, uint8_t, "b", "" );
-ARM_WRITEX ( writew, uint16_t, "h", "" );
-ARM_WRITEX ( writel, uint32_t, "", "" );
+ARM_WRITEX ( b, uint8_t, "b", "" );
+ARM_WRITEX ( w, uint16_t, "h", "" );
+ARM_WRITEX ( l, uint32_t, "", "" );
 #endif
 
 /*
+ * Dummy PIO reads and writes up to 32 bits
+ *
+ * There is no common standard for I/O-space access for ARM, and
+ * non-MMIO peripherals are vanishingly rare.  Provide dummy
+ * implementations that will allow code to link and should cause
+ * drivers to simply fail to detect hardware at runtime.
+ *
+ */
+
+#define ARM_INX( _suffix, _type )					      \
+static inline __always_inline _type					      \
+IOAPI_INLINE ( arm, in ## _suffix ) ( volatile _type *io_addr __unused) {     \
+	return ~( (_type) 0 );						      \
+}									      \
+static inline __always_inline void					      \
+IOAPI_INLINE ( arm, ins ## _suffix ) ( volatile _type *io_addr __unused,      \
+				       _type *data, unsigned int count ) {    \
+	memset ( data, 0xff, count * sizeof ( *data ) );		      \
+}
+ARM_INX ( b, uint8_t );
+ARM_INX ( w, uint16_t );
+ARM_INX ( l, uint32_t );
+
+#define ARM_OUTX( _suffix, _type )					      \
+static inline __always_inline void					      \
+IOAPI_INLINE ( arm, out ## _suffix ) ( _type data __unused,		      \
+				       volatile _type *io_addr __unused ) {   \
+	/* Do nothing */						      \
+}									      \
+static inline __always_inline void					      \
+IOAPI_INLINE ( arm, outs ## _suffix ) ( volatile _type *io_addr __unused,     \
+					const _type *data __unused,	      \
+					unsigned int count __unused ) {	      \
+	/* Do nothing */						      \
+}
+ARM_OUTX ( b, uint8_t );
+ARM_OUTX ( w, uint16_t );
+ARM_OUTX ( l, uint32_t );
+
+/*
  * Slow down I/O
  *
  */
diff -pruN 1.0.0+git-20190125.36a4c85-5.1/src/arch/i386/core/linux/linuxprefix.S 1.21.1+git-20220113.fbbdc3926-0ubuntu1/src/arch/i386/core/linux/linuxprefix.S
--- 1.0.0+git-20190125.36a4c85-5.1/src/arch/i386/core/linux/linuxprefix.S	2019-02-09 16:03:59.000000000 +0000
+++ 1.21.1+git-20220113.fbbdc3926-0ubuntu1/src/arch/i386/core/linux/linuxprefix.S	1970-01-01 00:00:00.000000000 +0000
@@ -1,28 +0,0 @@
-#include <linux/unistd.h>
-
-	.section ".text"
-	.code32
-	.globl _linux_start
-	.type _linux_start, @function
-
-_linux_start:
-	xorl	%ebp, %ebp
-
-	popl	%esi       // save argc
-	movl	%esp, %edi // save argv
-
-	andl	$~15, %esp // 16-byte align the stack
-
-	pushl	%edi // argv -> C arg2
-	pushl	%esi // argc -> C arg1
-
-	call	save_args
-
-	/* Our main doesn't use any arguments */
-	call	main
-
-	movl	%eax, %ebx // rc -> syscall arg1
-	movl	$__NR_exit, %eax
-	int	$0x80
-
-	.size _linux_start, . - _linux_start
diff -pruN 1.0.0+git-20190125.36a4c85-5.1/src/arch/i386/core/linux/linux_syscall.S 1.21.1+git-20220113.fbbdc3926-0ubuntu1/src/arch/i386/core/linux/linux_syscall.S
--- 1.0.0+git-20190125.36a4c85-5.1/src/arch/i386/core/linux/linux_syscall.S	2019-02-09 16:03:59.000000000 +0000
+++ 1.21.1+git-20220113.fbbdc3926-0ubuntu1/src/arch/i386/core/linux/linux_syscall.S	1970-01-01 00:00:00.000000000 +0000
@@ -1,45 +0,0 @@
-
-	.section ".data"
-	.globl linux_errno
-
-linux_errno:	.int 0
-
-	.section ".text"
-	.code32
-	.globl linux_syscall
-	.type  linux_syscall, @function
-
-linux_syscall:
-	/* Save registers */
-	pushl	%ebx
-	pushl	%esi
-	pushl	%edi
-	pushl	%ebp
-
-	movl	20(%esp), %eax  // C arg1 -> syscall number
-	movl	24(%esp), %ebx  // C arg2 -> syscall arg1
-	movl	28(%esp), %ecx  // C arg3 -> syscall arg2
-	movl	32(%esp), %edx  // C arg4 -> syscall arg3
-	movl	36(%esp), %esi  // C arg5 -> syscall arg4
-	movl	40(%esp), %edi  // C arg6 -> syscall arg5
-	movl	44(%esp), %ebp  // C arg7 -> syscall arg6
-
-	int	$0x80
-
-	/* Restore registers */
-	popl	%ebp
-	popl	%edi
-	popl	%esi
-	popl	%ebx
-
-	cmpl	$-4095, %eax
-	jae	1f
-	ret
-
-1:
-	negl	%eax
-	movl	%eax, linux_errno
-	movl	$-1, %eax
-	ret
-
-	.size linux_syscall, . - linux_syscall
diff -pruN 1.0.0+git-20190125.36a4c85-5.1/src/arch/i386/include/bits/compiler.h 1.21.1+git-20220113.fbbdc3926-0ubuntu1/src/arch/i386/include/bits/compiler.h
--- 1.0.0+git-20190125.36a4c85-5.1/src/arch/i386/include/bits/compiler.h	2019-02-09 16:03:59.000000000 +0000
+++ 1.21.1+git-20220113.fbbdc3926-0ubuntu1/src/arch/i386/include/bits/compiler.h	2022-01-13 13:43:08.000000000 +0000
@@ -9,7 +9,7 @@ FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
 #ifndef ASSEMBLY
 
 /** Declare a function with standard calling conventions */
-#define __asmcall __attribute__ (( used, cdecl, regparm(0) ))
+#define __asmcall __attribute__ (( cdecl, regparm(0) ))
 
 /**
  * Declare a function with libgcc implicit linkage
diff -pruN 1.0.0+git-20190125.36a4c85-5.1/src/arch/i386/include/bits/linux_api.h 1.21.1+git-20220113.fbbdc3926-0ubuntu1/src/arch/i386/include/bits/linux_api.h
--- 1.0.0+git-20190125.36a4c85-5.1/src/arch/i386/include/bits/linux_api.h	2019-02-09 16:03:59.000000000 +0000
+++ 1.21.1+git-20220113.fbbdc3926-0ubuntu1/src/arch/i386/include/bits/linux_api.h	1970-01-01 00:00:00.000000000 +0000
@@ -1,6 +0,0 @@
-#ifndef _I386_LINUX_API_H
-#define _I386_LINUX_API_H
-
-#define __SYSCALL_mmap __NR_mmap2
-
-#endif /* _I386_LINUX_API_H */
diff -pruN 1.0.0+git-20190125.36a4c85-5.1/src/arch/i386/Makefile 1.21.1+git-20220113.fbbdc3926-0ubuntu1/src/arch/i386/Makefile
--- 1.0.0+git-20190125.36a4c85-5.1/src/arch/i386/Makefile	2019-02-09 16:03:59.000000000 +0000
+++ 1.21.1+git-20220113.fbbdc3926-0ubuntu1/src/arch/i386/Makefile	2022-01-13 13:43:08.000000000 +0000
@@ -69,22 +69,6 @@ CFLAGS		+= -fshort-wchar
 #
 CFLAGS			+= -Ui386
 
-# Some widespread patched versions of gcc include -fPIE -Wl,-pie by
-# default.  Note that gcc will exit *successfully* if it fails to
-# recognise an option that starts with "no", so we have to test for
-# output on stderr instead of checking the exit status.
-#
-# Current versions of gcc require -no-pie; older versions require
-# -nopie.  We therefore test for both.
-#
-ifeq ($(CCTYPE),gcc)
-PIE_TEST = [ -z "`$(CC) -fno-PIE -no-pie -x c -c /dev/null -o /dev/null 2>&1`" ]
-PIE_FLAGS := $(shell $(PIE_TEST) && $(ECHO) '-fno-PIE -no-pie')
-PIE_TEST2 = [ -z "`$(CC) -fno-PIE -nopie -x c -c /dev/null -o /dev/null 2>&1`" ]
-PIE_FLAGS2 := $(shell $(PIE_TEST2) && $(ECHO) '-fno-PIE -nopie')
-WORKAROUND_CFLAGS += $(PIE_FLAGS) $(PIE_FLAGS2)
-endif
-
 # i386-specific directories containing source files
 #
 SRCDIRS		+= arch/i386/core
diff -pruN 1.0.0+git-20190125.36a4c85-5.1/src/arch/i386/Makefile.linux 1.21.1+git-20220113.fbbdc3926-0ubuntu1/src/arch/i386/Makefile.linux
--- 1.0.0+git-20190125.36a4c85-5.1/src/arch/i386/Makefile.linux	2019-02-09 16:03:59.000000000 +0000
+++ 1.21.1+git-20220113.fbbdc3926-0ubuntu1/src/arch/i386/Makefile.linux	2022-01-13 13:43:08.000000000 +0000
@@ -1,6 +1,14 @@
+# -*- makefile -*- : Force emacs to use Makefile mode
+
+# Linker script
+#
 LDSCRIPT = arch/i386/scripts/linux.lds
 
-SRCDIRS += arch/i386/core/linux
+# Compiler flags for building host API wrapper
+#
+LINUX_CFLAGS	+= -m32
 
+# Include generic Linux Makefile
+#
 MAKEDEPS += arch/x86/Makefile.linux
 include arch/x86/Makefile.linux
diff -pruN 1.0.0+git-20190125.36a4c85-5.1/src/arch/x86/core/cachedhcp.c 1.21.1+git-20220113.fbbdc3926-0ubuntu1/src/arch/x86/core/cachedhcp.c
--- 1.0.0+git-20190125.36a4c85-5.1/src/arch/x86/core/cachedhcp.c	2019-02-09 16:03:59.000000000 +0000
+++ 1.21.1+git-20220113.fbbdc3926-0ubuntu1/src/arch/x86/core/cachedhcp.c	1970-01-01 00:00:00.000000000 +0000
@@ -1,179 +0,0 @@
-/*
- * Copyright (C) 2013 Michael Brown <mbrown@fensystems.co.uk>.
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License as
- * published by the Free Software Foundation; either version 2 of the
- * License, or any later version.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
- * 02110-1301, USA.
- *
- * You can also choose to distribute this program under the terms of
- * the Unmodified Binary Distribution Licence (as given in the file
- * COPYING.UBDL), provided that you have satisfied its requirements.
- */
-
-FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
-
-#include <stdint.h>
-#include <stdlib.h>
-#include <ipxe/dhcppkt.h>
-#include <ipxe/init.h>
-#include <ipxe/netdevice.h>
-#include <realmode.h>
-#include <pxe_api.h>
-
-/** @file
- *
- * Cached DHCP packet
- *
- */
-
-/** Cached DHCPACK physical address
- *
- * This can be set by the prefix.
- */
-uint32_t __bss16 ( cached_dhcpack_phys );
-#define cached_dhcpack_phys __use_data16 ( cached_dhcpack_phys )
-
-/** Colour for debug messages */
-#define colour &cached_dhcpack_phys
-
-/** Cached DHCPACK */
-static struct dhcp_packet *cached_dhcpack;
-
-/**
- * Cached DHCPACK startup function
- *
- */
-static void cachedhcp_init ( void ) {
-	struct dhcp_packet *dhcppkt;
-	struct dhcp_packet *tmp;
-	struct dhcphdr *dhcphdr;
-	size_t max_len;
-	size_t len;
-
-	/* Do nothing if no cached DHCPACK is present */
-	if ( ! cached_dhcpack_phys ) {
-		DBGC ( colour, "CACHEDHCP found no cached DHCPACK\n" );
-		return;
-	}
-
-	/* No reliable way to determine length before parsing packet;
-	 * start by assuming maximum length permitted by PXE.
-	 */
-	max_len = sizeof ( BOOTPLAYER_t );
-
-	/* Allocate and populate DHCP packet */
-	dhcppkt = zalloc ( sizeof ( *dhcppkt ) + max_len );
-	if ( ! dhcppkt ) {
-		DBGC ( colour, "CACHEDHCP could not allocate copy\n" );
-		return;
-	}
-	dhcphdr = ( ( ( void * ) dhcppkt ) + sizeof ( *dhcppkt ) );
-	copy_from_user ( dhcphdr, phys_to_user ( cached_dhcpack_phys ), 0,
-			 max_len );
-	dhcppkt_init ( dhcppkt, dhcphdr, max_len );
-
-	/* Shrink packet to required length.  If reallocation fails,
-	 * just continue to use the original packet and waste the
-	 * unused space.
-	 */
-	len = dhcppkt_len ( dhcppkt );
-	assert ( len <= max_len );
-	tmp = realloc ( dhcppkt, ( sizeof ( *dhcppkt ) + len ) );
-	if ( tmp )
-		dhcppkt = tmp;
-
-	/* Reinitialise packet at new address */
-	dhcphdr = ( ( ( void * ) dhcppkt ) + sizeof ( *dhcppkt ) );
-	dhcppkt_init ( dhcppkt, dhcphdr, len );
-
-	/* Store as cached DHCPACK, and mark original copy as consumed */
-	DBGC ( colour, "CACHEDHCP found cached DHCPACK at %08x+%zx\n",
-	       cached_dhcpack_phys, len );
-	cached_dhcpack = dhcppkt;
-	cached_dhcpack_phys = 0;
-}
-
-/**
- * Cached DHCPACK startup function
- *
- */
-static void cachedhcp_startup ( void ) {
-
-	/* If cached DHCP packet was not claimed by any network device
-	 * during startup, then free it.
-	 */
-	if ( cached_dhcpack ) {
-		DBGC ( colour, "CACHEDHCP freeing unclaimed cached DHCPACK\n" );
-		dhcppkt_put ( cached_dhcpack );
-		cached_dhcpack = NULL;
-	}
-}
-
-/** Cached DHCPACK initialisation function */
-struct init_fn cachedhcp_init_fn __init_fn ( INIT_NORMAL ) = {
-	.initialise = cachedhcp_init,
-};
-
-/** Cached DHCPACK startup function */
-struct startup_fn cachedhcp_startup_fn __startup_fn ( STARTUP_LATE ) = {
-	.name = "cachedhcp",
-	.startup = cachedhcp_startup,
-};
-
-/**
- * Apply cached DHCPACK to network device, if applicable
- *
- * @v netdev		Network device
- * @ret rc		Return status code
- */
-static int cachedhcp_probe ( struct net_device *netdev ) {
-	struct ll_protocol *ll_protocol = netdev->ll_protocol;
-	int rc;
-
-	/* Do nothing unless we have a cached DHCPACK */
-	if ( ! cached_dhcpack )
-		return 0;
-
-	/* Do nothing unless cached DHCPACK's MAC address matches this
-	 * network device.
-	 */
-	if ( memcmp ( netdev->ll_addr, cached_dhcpack->dhcphdr->chaddr,
-		      ll_protocol->ll_addr_len ) != 0 ) {
-		DBGC ( colour, "CACHEDHCP cached DHCPACK does not match %s\n",
-		       netdev->name );
-		return 0;
-	}
-	DBGC ( colour, "CACHEDHCP cached DHCPACK is for %s\n", netdev->name );
-
-	/* Register as DHCP settings for this network device */
-	if ( ( rc = register_settings ( &cached_dhcpack->settings,
-					netdev_settings ( netdev ),
-					DHCP_SETTINGS_NAME ) ) != 0 ) {
-		DBGC ( colour, "CACHEDHCP could not register settings: %s\n",
-		       strerror ( rc ) );
-		return rc;
-	}
-
-	/* Claim cached DHCPACK */
-	dhcppkt_put ( cached_dhcpack );
-	cached_dhcpack = NULL;
-
-	return 0;
-}
-
-/** Cached DHCP packet network device driver */
-struct net_driver cachedhcp_driver __net_driver = {
-	.name = "cachedhcp",
-	.probe = cachedhcp_probe,
-};
diff -pruN 1.0.0+git-20190125.36a4c85-5.1/src/arch/x86/core/linux/linux_api.c 1.21.1+git-20220113.fbbdc3926-0ubuntu1/src/arch/x86/core/linux/linux_api.c
--- 1.0.0+git-20190125.36a4c85-5.1/src/arch/x86/core/linux/linux_api.c	2019-02-09 16:03:59.000000000 +0000
+++ 1.21.1+git-20220113.fbbdc3926-0ubuntu1/src/arch/x86/core/linux/linux_api.c	1970-01-01 00:00:00.000000000 +0000
@@ -1,149 +0,0 @@
-/*
- * Copyright (C) 2010 Piotr Jaroszyński <p.jaroszynski@gmail.com>
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License as
- * published by the Free Software Foundation; either version 2 of the
- * License, or any later version.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- */
-
-FILE_LICENCE ( GPL2_OR_LATER );
-
-/** @file
- *
- * Implementation of most of the linux API.
- */
-
-#include <linux_api.h>
-
-#include <stdarg.h>
-#include <asm/unistd.h>
-#include <string.h>
-
-int linux_open ( const char *pathname, int flags ) {
-	return linux_syscall ( __NR_open, pathname, flags );
-}
-
-int linux_close ( int fd ) {
-	return linux_syscall ( __NR_close, fd );
-}
-
-off_t linux_lseek ( int fd, off_t offset, int whence ) {
-	return linux_syscall ( __NR_lseek, fd, offset, whence );
-}
-
-__kernel_ssize_t linux_read ( int fd, void *buf, __kernel_size_t count ) {
-	return linux_syscall ( __NR_read, fd, buf, count );
-}
-
-__kernel_ssize_t linux_write ( int fd, const void *buf,
-			       __kernel_size_t count ) {
-	return linux_syscall  (  __NR_write, fd, buf, count );
-}
-
-int linux_fcntl ( int fd, int cmd, ... ) {
-	long arg;
-	va_list list;
-
-	va_start ( list, cmd );
-	arg = va_arg ( list, long );
-	va_end ( list );
-
-	return linux_syscall ( __NR_fcntl, fd, cmd, arg );
-}
-
-int linux_ioctl ( int fd, int request, ... ) {
-	void *arg;
-	va_list list;
-
-	va_start ( list, request );
-	arg = va_arg ( list, void * );
-	va_end ( list );
-
-	return linux_syscall ( __NR_ioctl, fd, request, arg );
-}
-
-int linux_poll ( struct pollfd *fds, nfds_t nfds, int timeout ) {
-	return linux_syscall ( __NR_poll, fds, nfds, timeout );
-}
-
-int linux_nanosleep ( const struct timespec *req, struct timespec *rem ) {
-	return linux_syscall ( __NR_nanosleep, req, rem );
-}
-
-int linux_usleep ( useconds_t usec ) {
-	struct timespec ts = {
-		.tv_sec = ( ( long ) ( usec / 1000000 ) ),
-		.tv_nsec = ( ( long ) ( usec % 1000000 ) * 1000UL ),
-	};
-
-	return linux_nanosleep ( &ts, NULL );
-}
-
-int linux_gettimeofday ( struct timeval *tv, struct timezone *tz ) {
-	return linux_syscall ( __NR_gettimeofday, tv, tz );
-}
-
-void * linux_mmap ( void *addr, __kernel_size_t length, int prot, int flags,
-		    int fd, __kernel_off_t offset ) {
-	return ( void * ) linux_syscall ( __SYSCALL_mmap, addr, length, prot,
-					  flags, fd, offset );
-}
-
-void * linux_mremap ( void *old_address, __kernel_size_t old_size,
-		      __kernel_size_t new_size, int flags ) {
-	return ( void * ) linux_syscall ( __NR_mremap, old_address, old_size,
-					  new_size, flags );
-}
-
-int linux_munmap ( void *addr, __kernel_size_t length ) {
-	return linux_syscall ( __NR_munmap, addr, length );
-}
-
-int linux_socket ( int domain, int type_, int protocol ) {
-#ifdef __NR_socket
-	return linux_syscall ( __NR_socket, domain, type_, protocol );
-#else
-#ifndef SOCKOP_socket
-# define SOCKOP_socket 1
-#endif
-	unsigned long sc_args[] = { domain, type_, protocol };
-	return linux_syscall ( __NR_socketcall, SOCKOP_socket, sc_args );
-#endif
-}
-
-int linux_bind ( int fd, const struct sockaddr *addr, socklen_t addrlen ) {
-#ifdef __NR_bind
-	return linux_syscall ( __NR_bind, fd, addr, addrlen );
-#else
-#ifndef SOCKOP_bind
-# define SOCKOP_bind 2
-#endif
-	unsigned long sc_args[] = { fd, (unsigned long)addr, addrlen };
-	return linux_syscall ( __NR_socketcall, SOCKOP_bind, sc_args );
-#endif
-}
-
-ssize_t linux_sendto ( int fd, const void *buf, size_t len, int flags,
-		       const struct sockaddr *daddr, socklen_t addrlen ) {
-#ifdef __NR_sendto
-	return linux_syscall ( __NR_sendto, fd, buf, len, flags,
-			       daddr, addrlen );
-#else
-#ifndef SOCKOP_sendto
-# define SOCKOP_sendto 11
-#endif
-	unsigned long sc_args[] = { fd, (unsigned long)buf, len,
-				    flags, (unsigned long)daddr, addrlen };
-	return linux_syscall ( __NR_socketcall, SOCKOP_sendto, sc_args );
-#endif
-}
diff -pruN 1.0.0+git-20190125.36a4c85-5.1/src/arch/x86/core/linux/linux_strerror.c 1.21.1+git-20220113.fbbdc3926-0ubuntu1/src/arch/x86/core/linux/linux_strerror.c
--- 1.0.0+git-20190125.36a4c85-5.1/src/arch/x86/core/linux/linux_strerror.c	2019-02-09 16:03:59.000000000 +0000
+++ 1.21.1+git-20220113.fbbdc3926-0ubuntu1/src/arch/x86/core/linux/linux_strerror.c	1970-01-01 00:00:00.000000000 +0000
@@ -1,169 +0,0 @@
-/*
- * Copyright (C) 2010 Piotr Jaroszyński <p.jaroszynski@gmail.com>
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License as
- * published by the Free Software Foundation; either version 2 of the
- * License, or any later version.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- */
-
-FILE_LICENCE(GPL2_OR_LATER);
-
-/** @file
- *
- * linux_strerror implementation
- */
-
-#include <linux_api.h>
-#include <stdio.h>
-
-/** Error names from glibc */
-static const char *errors[] = {
-	"Success",
-	"Operation not permitted",
-	"No such file or directory",
-	"No such process",
-	"Interrupted system call",
-	"Input/output error",
-	"No such device or address",
-	"Argument list too long",
-	"Exec format error",
-	"Bad file descriptor",
-	"No child processes",
-	"Resource temporarily unavailable",
-	"Cannot allocate memory",
-	"Permission denied",
-	"Bad address",
-	"Block device required",
-	"Device or resource busy",
-	"File exists",
-	"Invalid cross-device link",
-	"No such device",
-	"Not a directory",
-	"Is a directory",
-	"Invalid argument",
-	"Too many open files in system",
-	"Too many open files",
-	"Inappropriate ioctl for device",
-	"Text file busy",
-	"File too large",
-	"No space left on device",
-	"Illegal seek",
-	"Read-only file system",
-	"Too many links",
-	"Broken pipe",
-	"Numerical argument out of domain",
-	"Numerical result out of range",
-	"Resource deadlock avoided",
-	"File name too long",
-	"No locks available",
-	"Function not implemented",
-	"Directory not empty",
-	"Too many levels of symbolic links",
-	"",
-	"No message of desired type",
-	"Identifier removed",
-	"Channel number out of range",
-	"Level 2 not synchronized",
-	"Level 3 halted",
-	"Level 3 reset",
-	"Link number out of range",
-	"Protocol driver not attached",
-	"No CSI structure available",
-	"Level 2 halted",
-	"Invalid exchange",
-	"Invalid request descriptor",
-	"Exchange full",
-	"No anode",
-	"Invalid request code",
-	"Invalid slot",
-	"",
-	"Bad font file format",
-	"Device not a stream",
-	"No data available",
-	"Timer expired",
-	"Out of streams resources",
-	"Machine is not on the network",
-	"Package not installed",
-	"Object is remote",
-	"Link has been severed",
-	"Advertise error",
-	"Srmount error",
-	"Communication error on send",
-	"Protocol error",
-	"Multihop attempted",
-	"RFS specific error",
-	"Bad message",
-	"Value too large for defined data type",
-	"Name not unique on network",
-	"File descriptor in bad state",
-	"Remote address changed",
-	"Can not access a needed shared library",
-	"Accessing a corrupted shared library",
-	".lib section in a.out corrupted",
-	"Attempting to link in too many shared libraries",
-	"Cannot exec a shared library directly",
-	"Invalid or incomplete multibyte or wide character",
-	"Interrupted system call should be restarted",
-	"Streams pipe error",
-	"Too many users",
-	"Socket operation on non-socket",
-	"Destination address required",
-	"Message too long",
-	"Protocol wrong type for socket",
-	"Protocol not available",
-	"Protocol not supported",
-	"Socket type not supported",
-	"Operation not supported",
-	"Protocol family not supported",
-	"Address family not supported by protocol",
-	"Address already in use",
-	"Cannot assign requested address",
-	"Network is down",
-	"Network is unreachable",
-	"Network dropped connection on reset",
-	"Software caused connection abort",
-	"Connection reset by peer",
-	"No buffer space available",
-	"Transport endpoint is already connected",
-	"Transport endpoint is not connected",
-	"Cannot send after transport endpoint shutdown",
-	"Too many references: cannot splice",
-	"Connection timed out",
-	"Connection refused",
-	"Host is down",
-	"No route to host",
-	"Operation already in progress",
-	"Operation now in progress",
-	"Stale NFS file handle",
-	"Structure needs cleaning",
-	"Not a XENIX named type file",
-	"No XENIX semaphores available",
-	"Is a named type file",
-	"Remote I/O error",
-	"Disk quota exceeded",
-	"No medium found",
-	"Wrong medium type",
-};
-
-const char *linux_strerror(int errnum)
-{
-	static char errbuf[64];
-	static int errors_size = sizeof(errors) / sizeof(*errors);
-	
-	if (errnum >= errors_size || errnum < 0) {
-		snprintf(errbuf, sizeof(errbuf), "Error %#08x", errnum);
-		return errbuf;
-	} else {
-		return errors[errnum];
-	}
-}
diff -pruN 1.0.0+git-20190125.36a4c85-5.1/src/arch/x86/core/pcidirect.c 1.21.1+git-20220113.fbbdc3926-0ubuntu1/src/arch/x86/core/pcidirect.c
--- 1.0.0+git-20190125.36a4c85-5.1/src/arch/x86/core/pcidirect.c	2019-02-09 16:03:59.000000000 +0000
+++ 1.21.1+git-20220113.fbbdc3926-0ubuntu1/src/arch/x86/core/pcidirect.c	2022-01-13 13:43:08.000000000 +0000
@@ -52,3 +52,4 @@ PROVIDE_PCIAPI_INLINE ( direct, pci_read
 PROVIDE_PCIAPI_INLINE ( direct, pci_write_config_byte );
 PROVIDE_PCIAPI_INLINE ( direct, pci_write_config_word );
 PROVIDE_PCIAPI_INLINE ( direct, pci_write_config_dword );
+PROVIDE_PCIAPI_INLINE ( direct, pci_ioremap );
diff -pruN 1.0.0+git-20190125.36a4c85-5.1/src/arch/x86/core/runtime.c 1.21.1+git-20220113.fbbdc3926-0ubuntu1/src/arch/x86/core/runtime.c
--- 1.0.0+git-20190125.36a4c85-5.1/src/arch/x86/core/runtime.c	2019-02-09 16:03:59.000000000 +0000
+++ 1.21.1+git-20220113.fbbdc3926-0ubuntu1/src/arch/x86/core/runtime.c	2022-01-13 13:43:08.000000000 +0000
@@ -38,7 +38,6 @@ FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
 #include <ipxe/init.h>
 #include <ipxe/image.h>
 #include <ipxe/script.h>
-#include <ipxe/umalloc.h>
 #include <realmode.h>
 
 /** Command line physical address
@@ -180,7 +179,6 @@ static int cmdline_init ( void ) {
  */
 static int initrd_init ( void ) {
 	struct image *image;
-	int rc;
 
 	/* Do nothing if no initrd was specified */
 	if ( ! initrd_phys ) {
@@ -194,53 +192,18 @@ static int initrd_init ( void ) {
 	DBGC ( colour, "RUNTIME found initrd at [%x,%x)\n",
 	       initrd_phys, ( initrd_phys + initrd_len ) );
 
-	/* Allocate image */
-	image = alloc_image ( NULL );
+	/* Create initrd image */
+	image = image_memory ( "<INITRD>", phys_to_user ( initrd_phys ),
+			       initrd_len );
 	if ( ! image ) {
-		DBGC ( colour, "RUNTIME could not allocate image for "
-		       "initrd\n" );
-		rc = -ENOMEM;
-		goto err_alloc_image;
-	}
-	if ( ( rc = image_set_name ( image, "<INITRD>" ) ) != 0 ) {
-		DBGC ( colour, "RUNTIME could not set image name: %s\n",
-		       strerror ( rc ) );
-		goto err_set_name;
+		DBGC ( colour, "RUNTIME could not create initrd image\n" );
+		return -ENOMEM;
 	}
 
-	/* Allocate and copy initrd content */
-	image->data = umalloc ( initrd_len );
-	if ( ! image->data ) {
-		DBGC ( colour, "RUNTIME could not allocate %d bytes for "
-		       "initrd\n", initrd_len );
-		rc = -ENOMEM;
-		goto err_umalloc;
-	}
-	image->len = initrd_len;
-	memcpy_user ( image->data, 0, phys_to_user ( initrd_phys ), 0,
-		      initrd_len );
-
 	/* Mark initrd as consumed */
 	initrd_phys = 0;
 
-	/* Register image */
-	if ( ( rc = register_image ( image ) ) != 0 ) {
-		DBGC ( colour, "RUNTIME could not register initrd: %s\n",
-		       strerror ( rc ) );
-		goto err_register_image;
-	}
-
-	/* Drop our reference to the image */
-	image_put ( image );
-
 	return 0;
-
- err_register_image:
- err_umalloc:
- err_set_name:
-	image_put ( image );
- err_alloc_image:
-	return rc;
 }
 
 /**
diff -pruN 1.0.0+git-20190125.36a4c85-5.1/src/arch/x86/core/stack16.S 1.21.1+git-20220113.fbbdc3926-0ubuntu1/src/arch/x86/core/stack16.S
--- 1.0.0+git-20190125.36a4c85-5.1/src/arch/x86/core/stack16.S	2019-02-09 16:03:59.000000000 +0000
+++ 1.21.1+git-20220113.fbbdc3926-0ubuntu1/src/arch/x86/core/stack16.S	2022-01-13 13:43:08.000000000 +0000
@@ -7,7 +7,7 @@ FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL )
  ****************************************************************************
  */
 	.section ".stack16", "aw", @nobits
-	.align 8
+	.balign 8
 	.globl _stack16
 _stack16:
 	.space 4096
diff -pruN 1.0.0+git-20190125.36a4c85-5.1/src/arch/x86/core/stack.S 1.21.1+git-20220113.fbbdc3926-0ubuntu1/src/arch/x86/core/stack.S
--- 1.0.0+git-20190125.36a4c85-5.1/src/arch/x86/core/stack.S	2019-02-09 16:03:59.000000000 +0000
+++ 1.21.1+git-20220113.fbbdc3926-0ubuntu1/src/arch/x86/core/stack.S	2022-01-13 13:43:08.000000000 +0000
@@ -13,7 +13,7 @@ FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL )
  ****************************************************************************
  */
 	.section ".stack", "aw", @nobits
-	.align 8
+	.balign 8
 	.globl _stack
 _stack:
 	.space STACK_SIZE
diff -pruN 1.0.0+git-20190125.36a4c85-5.1/src/arch/x86/core/x86_bigint.c 1.21.1+git-20220113.fbbdc3926-0ubuntu1/src/arch/x86/core/x86_bigint.c
--- 1.0.0+git-20190125.36a4c85-5.1/src/arch/x86/core/x86_bigint.c	2019-02-09 16:03:59.000000000 +0000
+++ 1.21.1+git-20220113.fbbdc3926-0ubuntu1/src/arch/x86/core/x86_bigint.c	2022-01-13 13:43:08.000000000 +0000
@@ -75,17 +75,18 @@ void bigint_multiply_raw ( const uint32_
 			 *
 			 *     a < 2^{n}, b < 2^{n} => ab < 2^{2n}
 			 */
-			__asm__ __volatile__ ( "mull %4\n\t"
-					       "addl %%eax, (%5,%2,4)\n\t"
-					       "adcl %%edx, 4(%5,%2,4)\n\t"
+			__asm__ __volatile__ ( "mull %5\n\t"
+					       "addl %%eax, (%6,%2,4)\n\t"
+					       "adcl %%edx, 4(%6,%2,4)\n\t"
 					       "\n1:\n\t"
-					       "adcl $0, 8(%5,%2,4)\n\t"
+					       "adcl $0, 8(%6,%2,4)\n\t"
 					       "inc %2\n\t"
 						       /* Does not affect CF */
 					       "jc 1b\n\t"
 					       : "=&a" ( discard_a ),
 						 "=&d" ( discard_d ),
-						 "=&r" ( index )
+						 "=&r" ( index ),
+						 "+m" ( *result )
 					       : "0" ( multiplicand_element ),
 						 "g" ( multiplier_element ),
 						 "r" ( result_elements ),
diff -pruN 1.0.0+git-20190125.36a4c85-5.1/src/arch/x86/core/x86_string.c 1.21.1+git-20220113.fbbdc3926-0ubuntu1/src/arch/x86/core/x86_string.c
--- 1.0.0+git-20190125.36a4c85-5.1/src/arch/x86/core/x86_string.c	2019-02-09 16:03:59.000000000 +0000
+++ 1.21.1+git-20220113.fbbdc3926-0ubuntu1/src/arch/x86/core/x86_string.c	2022-01-13 13:43:08.000000000 +0000
@@ -30,6 +30,14 @@
 FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
 
 #include <string.h>
+#include <config/defaults.h>
+
+/* Use generic_memcpy_reverse() if we cannot safely set the direction flag */
+#ifdef UNSAFE_STD
+#define USE_GENERIC_MEMCPY_REVERSE 1
+#else
+#define USE_GENERIC_MEMCPY_REVERSE 0
+#endif
 
 /**
  * Copy memory area
@@ -77,6 +85,12 @@ void * __attribute__ (( noinline )) __me
 	const void *esi = ( src + len - 1 );
 	int discard_ecx;
 
+	/* Use unoptimised version if we are not permitted to modify
+	 * the direction flag.
+	 */
+	if ( USE_GENERIC_MEMCPY_REVERSE )
+		return generic_memcpy_reverse ( dest, src, len );
+
 	/* Assume memmove() is not performance-critical, and perform a
 	 * bytewise copy for simplicity.
 	 */
diff -pruN 1.0.0+git-20190125.36a4c85-5.1/src/arch/x86/drivers/hyperv/hyperv.c 1.21.1+git-20220113.fbbdc3926-0ubuntu1/src/arch/x86/drivers/hyperv/hyperv.c
--- 1.0.0+git-20190125.36a4c85-5.1/src/arch/x86/drivers/hyperv/hyperv.c	2019-02-09 16:03:59.000000000 +0000
+++ 1.21.1+git-20220113.fbbdc3926-0ubuntu1/src/arch/x86/drivers/hyperv/hyperv.c	2022-01-13 13:43:08.000000000 +0000
@@ -83,7 +83,7 @@ hv_alloc_pages ( struct hv_hypervisor *h
 	/* Allocate and zero pages */
 	va_start ( args, hv );
 	for ( i = 0 ; ( ( page = va_arg ( args, void ** ) ) != NULL ); i++ ) {
-		*page = malloc_dma ( PAGE_SIZE, PAGE_SIZE );
+		*page = malloc_phys ( PAGE_SIZE, PAGE_SIZE );
 		if ( ! *page )
 			goto err_alloc;
 		memset ( *page, 0, PAGE_SIZE );
@@ -97,7 +97,7 @@ hv_alloc_pages ( struct hv_hypervisor *h
 	va_start ( args, hv );
 	for ( ; i >= 0 ; i-- ) {
 		page = va_arg ( args, void ** );
-		free_dma ( *page, PAGE_SIZE );
+		free_phys ( *page, PAGE_SIZE );
 	}
 	va_end ( args );
 	return -ENOMEM;
@@ -116,7 +116,7 @@ hv_free_pages ( struct hv_hypervisor *hv
 
 	va_start ( args, hv );
 	while ( ( page = va_arg ( args, void * ) ) != NULL )
-		free_dma ( page, PAGE_SIZE );
+		free_phys ( page, PAGE_SIZE );
 	va_end ( args );
 }
 
@@ -131,8 +131,8 @@ static int hv_alloc_message ( struct hv_
 	/* Allocate buffer.  Must be aligned to at least 8 bytes and
 	 * must not cross a page boundary, so align on its own size.
 	 */
-	hv->message = malloc_dma ( sizeof ( *hv->message ),
-				   sizeof ( *hv->message ) );
+	hv->message = malloc_phys ( sizeof ( *hv->message ),
+				    sizeof ( *hv->message ) );
 	if ( ! hv->message )
 		return -ENOMEM;
 
@@ -147,7 +147,7 @@ static int hv_alloc_message ( struct hv_
 static void hv_free_message ( struct hv_hypervisor *hv ) {
 
 	/* Free buffer */
-	free_dma ( hv->message, sizeof ( *hv->message ) );
+	free_phys ( hv->message, sizeof ( *hv->message ) );
 }
 
 /**
diff -pruN 1.0.0+git-20190125.36a4c85-5.1/src/arch/x86/drivers/net/undinet.c 1.21.1+git-20220113.fbbdc3926-0ubuntu1/src/arch/x86/drivers/net/undinet.c
--- 1.0.0+git-20190125.36a4c85-5.1/src/arch/x86/drivers/net/undinet.c	2019-02-09 16:03:59.000000000 +0000
+++ 1.21.1+git-20220113.fbbdc3926-0ubuntu1/src/arch/x86/drivers/net/undinet.c	2022-01-13 13:43:08.000000000 +0000
@@ -104,6 +104,13 @@ static union u_PXENV_ANY __bss16 ( undin
 SEGOFF16_t __bss16 ( undinet_entry_point );
 #define undinet_entry_point __use_data16 ( undinet_entry_point )
 
+/* Read TSC in real mode only when profiling */
+#if PROFILING
+#define RDTSC_IF_PROFILING "rdtsc\n\t"
+#else
+#define RDTSC_IF_PROFILING ""
+#endif
+
 /** IRQ profiler */
 static struct profiler undinet_irq_profiler __profiler =
 	{ .name = "undinet.irq" };
@@ -288,14 +295,14 @@ static int undinet_call ( struct undi_ni
 	 */
 	profile_start ( &profiler->total );
 	__asm__ __volatile__ ( REAL_CODE ( "pushl %%ebp\n\t" /* gcc bug */
-					   "rdtsc\n\t"
+					   RDTSC_IF_PROFILING
 					   "pushl %%eax\n\t"
 					   "pushw %%es\n\t"
 					   "pushw %%di\n\t"
 					   "pushw %%bx\n\t"
 					   "lcall *undinet_entry_point\n\t"
 					   "movw %%ax, %%bx\n\t"
-					   "rdtsc\n\t"
+					   RDTSC_IF_PROFILING
 					   "addw $6, %%sp\n\t"
 					   "popl %%edx\n\t"
 					   "popl %%ebp\n\t" /* gcc bug */ )
diff -pruN 1.0.0+git-20190125.36a4c85-5.1/src/arch/x86/drivers/xen/hvm.c 1.21.1+git-20220113.fbbdc3926-0ubuntu1/src/arch/x86/drivers/xen/hvm.c
--- 1.0.0+git-20190125.36a4c85-5.1/src/arch/x86/drivers/xen/hvm.c	2019-02-09 16:03:59.000000000 +0000
+++ 1.21.1+git-20220113.fbbdc3926-0ubuntu1/src/arch/x86/drivers/xen/hvm.c	2022-01-13 13:43:08.000000000 +0000
@@ -106,7 +106,7 @@ static int hvm_map_hypercall ( struct hv
 
 	/* Allocate pages */
 	hvm->hypercall_len = ( pages * PAGE_SIZE );
-	hvm->xen.hypercall = malloc_dma ( hvm->hypercall_len, PAGE_SIZE );
+	hvm->xen.hypercall = malloc_phys ( hvm->hypercall_len, PAGE_SIZE );
 	if ( ! hvm->xen.hypercall ) {
 		DBGC ( hvm, "HVM could not allocate %d hypercall page(s)\n",
 		       pages );
@@ -141,7 +141,7 @@ static int hvm_map_hypercall ( struct hv
 static void hvm_unmap_hypercall ( struct hvm_device *hvm ) {
 
 	/* Free pages */
-	free_dma ( hvm->xen.hypercall, hvm->hypercall_len );
+	free_phys ( hvm->xen.hypercall, hvm->hypercall_len );
 }
 
 /**
@@ -175,7 +175,7 @@ static void * hvm_ioremap ( struct hvm_d
 	}
 
 	/* Map this space */
-	mmio = ioremap ( ( hvm->mmio + hvm->mmio_offset ), len );
+	mmio = pci_ioremap ( hvm->pci, ( hvm->mmio + hvm->mmio_offset ), len );
 	if ( ! mmio ) {
 		DBGC ( hvm, "HVM could not map MMIO space [%08lx,%08lx)\n",
 		       ( hvm->mmio + hvm->mmio_offset ),
@@ -371,7 +371,8 @@ static int hvm_map_xenstore ( struct hvm
 	xenstore_phys = ( xenstore_pfn * PAGE_SIZE );
 
 	/* Map XenStore */
-	hvm->xen.store.intf = ioremap ( xenstore_phys, PAGE_SIZE );
+	hvm->xen.store.intf = pci_ioremap ( hvm->pci, xenstore_phys,
+					    PAGE_SIZE );
 	if ( ! hvm->xen.store.intf ) {
 		DBGC ( hvm, "HVM could not map XenStore at [%08lx,%08lx)\n",
 		       xenstore_phys, ( xenstore_phys + PAGE_SIZE ) );
@@ -420,6 +421,7 @@ static int hvm_probe ( struct pci_device
 		rc = -ENOMEM;
 		goto err_alloc;
 	}
+	hvm->pci = pci;
 	hvm->mmio = pci_bar_start ( pci, HVM_MMIO_BAR );
 	hvm->mmio_len = pci_bar_size ( pci, HVM_MMIO_BAR );
 	DBGC2 ( hvm, "HVM has MMIO space [%08lx,%08lx)\n",
diff -pruN 1.0.0+git-20190125.36a4c85-5.1/src/arch/x86/drivers/xen/hvm.h 1.21.1+git-20220113.fbbdc3926-0ubuntu1/src/arch/x86/drivers/xen/hvm.h
--- 1.0.0+git-20190125.36a4c85-5.1/src/arch/x86/drivers/xen/hvm.h	2019-02-09 16:03:59.000000000 +0000
+++ 1.21.1+git-20220113.fbbdc3926-0ubuntu1/src/arch/x86/drivers/xen/hvm.h	2022-01-13 13:43:08.000000000 +0000
@@ -39,6 +39,8 @@ FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
 struct hvm_device {
 	/** Xen hypervisor */
 	struct xen_hypervisor xen;
+	/** PCI device */
+	struct pci_device *pci;
 	/** CPUID base */
 	uint32_t cpuid_base;
 	/** Length of hypercall table */
diff -pruN 1.0.0+git-20190125.36a4c85-5.1/src/arch/x86/image/bzimage.c 1.21.1+git-20220113.fbbdc3926-0ubuntu1/src/arch/x86/image/bzimage.c
--- 1.0.0+git-20190125.36a4c85-5.1/src/arch/x86/image/bzimage.c	2019-02-09 16:03:59.000000000 +0000
+++ 1.21.1+git-20220113.fbbdc3926-0ubuntu1/src/arch/x86/image/bzimage.c	2022-01-13 13:43:08.000000000 +0000
@@ -327,32 +327,6 @@ static void bzimage_set_cmdline ( struct
 }
 
 /**
- * Parse standalone image command line for cpio parameters
- *
- * @v image		bzImage file
- * @v cpio		CPIO header
- * @v cmdline		Command line
- */
-static void bzimage_parse_cpio_cmdline ( struct image *image,
-					 struct cpio_header *cpio,
-					 const char *cmdline ) {
-	char *arg;
-	char *end;
-	unsigned int mode;
-
-	/* Look for "mode=" */
-	if ( ( arg = strstr ( cmdline, "mode=" ) ) ) {
-		arg += 5;
-		mode = strtoul ( arg, &end, 8 /* Octal for file mode */ );
-		if ( *end && ( *end != ' ' ) ) {
-			DBGC ( image, "bzImage %p strange \"mode=\""
-			       "terminator '%c'\n", image, *end );
-		}
-		cpio_set_field ( cpio->c_mode, ( 0100000 | mode ) );
-	}
-}
-
-/**
  * Align initrd length
  *
  * @v len		Length
@@ -374,11 +348,9 @@ static inline size_t bzimage_align ( siz
 static size_t bzimage_load_initrd ( struct image *image,
 				    struct image *initrd,
 				    userptr_t address ) {
-	char *filename = initrd->cmdline;
-	char *cmdline;
+	const char *filename = cpio_name ( initrd );
 	struct cpio_header cpio;
 	size_t offset;
-	size_t name_len;
 	size_t pad_len;
 
 	/* Do not include kernel image itself as an initrd */
@@ -386,25 +358,7 @@ static size_t bzimage_load_initrd ( stru
 		return 0;
 
 	/* Create cpio header for non-prebuilt images */
-	if ( filename && filename[0] ) {
-		cmdline = strchr ( filename, ' ' );
-		name_len = ( ( cmdline ? ( ( size_t ) ( cmdline - filename ) )
-			       : strlen ( filename ) ) + 1 /* NUL */ );
-		memset ( &cpio, '0', sizeof ( cpio ) );
-		memcpy ( cpio.c_magic, CPIO_MAGIC, sizeof ( cpio.c_magic ) );
-		cpio_set_field ( cpio.c_mode, 0100644 );
-		cpio_set_field ( cpio.c_nlink, 1 );
-		cpio_set_field ( cpio.c_filesize, initrd->len );
-		cpio_set_field ( cpio.c_namesize, name_len );
-		if ( cmdline ) {
-			bzimage_parse_cpio_cmdline ( image, &cpio,
-						     ( cmdline + 1 /* ' ' */ ));
-		}
-		offset = ( ( sizeof ( cpio ) + name_len + 0x03 ) & ~0x03 );
-	} else {
-		offset = 0;
-		name_len = 0;
-	}
+	offset = cpio_header ( initrd, &cpio );
 
 	/* Copy in initrd image body (and cpio header if applicable) */
 	if ( address ) {
@@ -413,7 +367,7 @@ static size_t bzimage_load_initrd ( stru
 			memset_user ( address, 0, 0, offset );
 			copy_to_user ( address, 0, &cpio, sizeof ( cpio ) );
 			copy_to_user ( address, sizeof ( cpio ), filename,
-				       ( name_len - 1 /* NUL (or space) */ ) );
+				       cpio_name_len ( initrd ) );
 		}
 		DBGC ( image, "bzImage %p initrd %p [%#08lx,%#08lx,%#08lx)"
 		       "%s%s\n", image, initrd, user_to_phys ( address, 0 ),
diff -pruN 1.0.0+git-20190125.36a4c85-5.1/src/arch/x86/image/com32.c 1.21.1+git-20220113.fbbdc3926-0ubuntu1/src/arch/x86/image/com32.c
--- 1.0.0+git-20190125.36a4c85-5.1/src/arch/x86/image/com32.c	2019-02-09 16:03:59.000000000 +0000
+++ 1.21.1+git-20220113.fbbdc3926-0ubuntu1/src/arch/x86/image/com32.c	2022-01-13 13:43:08.000000000 +0000
@@ -110,7 +110,7 @@ static int com32_exec_loop ( struct imag
 			/* Disable interrupts */
 			"cli\n\t"
 			/* Restore stack pointer */
-			"movl 24(%%esp), %%esp\n\t"
+			"movl 28(%%esp), %%esp\n\t"
 			/* Restore registers */
 			"popal\n\t" )
 			:
diff -pruN 1.0.0+git-20190125.36a4c85-5.1/src/arch/x86/image/initrd.c 1.21.1+git-20220113.fbbdc3926-0ubuntu1/src/arch/x86/image/initrd.c
--- 1.0.0+git-20190125.36a4c85-5.1/src/arch/x86/image/initrd.c	2019-02-09 16:03:59.000000000 +0000
+++ 1.21.1+git-20220113.fbbdc3926-0ubuntu1/src/arch/x86/image/initrd.c	2022-01-13 13:43:08.000000000 +0000
@@ -29,6 +29,7 @@ FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
 #include <ipxe/uaccess.h>
 #include <ipxe/init.h>
 #include <ipxe/memblock.h>
+#include <ipxe/cpio.h>
 
 /** @file
  *
@@ -175,18 +176,18 @@ static int initrd_swap_any ( userptr_t f
 		/* Search for adjacent image */
 		for_each_image ( high ) {
 
-			/* If we have found the adjacent image, swap and exit */
-			if ( high->data == adjacent ) {
-				initrd_swap ( low, high, free, free_len );
-				return 1;
-			}
-
 			/* Stop search if all remaining potential
 			 * adjacent images are already in the correct
 			 * order.
 			 */
 			if ( high == low )
 				break;
+
+			/* If we have found the adjacent image, swap and exit */
+			if ( high->data == adjacent ) {
+				initrd_swap ( low, high, free, free_len );
+				return 1;
+			}
 		}
 	}
 
diff -pruN 1.0.0+git-20190125.36a4c85-5.1/src/arch/x86/include/bits/bigint.h 1.21.1+git-20220113.fbbdc3926-0ubuntu1/src/arch/x86/include/bits/bigint.h
--- 1.0.0+git-20190125.36a4c85-5.1/src/arch/x86/include/bits/bigint.h	2019-02-09 16:03:59.000000000 +0000
+++ 1.21.1+git-20220113.fbbdc3926-0ubuntu1/src/arch/x86/include/bits/bigint.h	2022-01-13 13:43:08.000000000 +0000
@@ -25,19 +25,22 @@ typedef uint32_t bigint_element_t;
 static inline __attribute__ (( always_inline )) void
 bigint_init_raw ( uint32_t *value0, unsigned int size,
 		  const void *data, size_t len ) {
-	long pad_len = ( sizeof ( bigint_t ( size ) ) - len );
+	bigint_t ( size ) __attribute__ (( may_alias )) *value =
+		( ( void * ) value0 );
+	long pad_len = ( sizeof ( *value ) - len );
 	void *discard_D;
 	long discard_c;
 
 	/* Copy raw data in reverse order, padding with zeros */
 	__asm__ __volatile__ ( "\n1:\n\t"
-			       "movb -1(%2,%1), %%al\n\t"
+			       "movb -1(%3,%1), %%al\n\t"
 			       "stosb\n\t"
 			       "loop 1b\n\t"
 			       "xorl %%eax, %%eax\n\t"
-			       "mov %3, %1\n\t"
+			       "mov %4, %1\n\t"
 			       "rep stosb\n\t"
-			       : "=&D" ( discard_D ), "=&c" ( discard_c )
+			       : "=&D" ( discard_D ), "=&c" ( discard_c ),
+				 "+m" ( *value )
 			       : "r" ( data ), "g" ( pad_len ), "0" ( value0 ),
 				 "1" ( len )
 			       : "eax" );
@@ -53,6 +56,8 @@ bigint_init_raw ( uint32_t *value0, unsi
 static inline __attribute__ (( always_inline )) void
 bigint_add_raw ( const uint32_t *addend0, uint32_t *value0,
 		 unsigned int size ) {
+	bigint_t ( size ) __attribute__ (( may_alias )) *value =
+		( ( void * ) value0 );
 	long index;
 	void *discard_S;
 	long discard_c;
@@ -60,11 +65,11 @@ bigint_add_raw ( const uint32_t *addend0
 	__asm__ __volatile__ ( "xor %0, %0\n\t" /* Zero %0 and clear CF */
 			       "\n1:\n\t"
 			       "lodsl\n\t"
-			       "adcl %%eax, (%3,%0,4)\n\t"
+			       "adcl %%eax, (%4,%0,4)\n\t"
 			       "inc %0\n\t" /* Does not affect CF */
 			       "loop 1b\n\t"
 			       : "=&r" ( index ), "=&S" ( discard_S ),
-				 "=&c" ( discard_c )
+				 "=&c" ( discard_c ), "+m" ( *value )
 			       : "r" ( value0 ), "1" ( addend0 ), "2" ( size )
 			       : "eax" );
 }
@@ -79,6 +84,8 @@ bigint_add_raw ( const uint32_t *addend0
 static inline __attribute__ (( always_inline )) void
 bigint_subtract_raw ( const uint32_t *subtrahend0, uint32_t *value0,
 		      unsigned int size ) {
+	bigint_t ( size ) __attribute__ (( may_alias )) *value =
+		( ( void * ) value0 );
 	long index;
 	void *discard_S;
 	long discard_c;
@@ -86,11 +93,11 @@ bigint_subtract_raw ( const uint32_t *su
 	__asm__ __volatile__ ( "xor %0, %0\n\t" /* Zero %0 and clear CF */
 			       "\n1:\n\t"
 			       "lodsl\n\t"
-			       "sbbl %%eax, (%3,%0,4)\n\t"
+			       "sbbl %%eax, (%4,%0,4)\n\t"
 			       "inc %0\n\t" /* Does not affect CF */
 			       "loop 1b\n\t"
 			       : "=&r" ( index ), "=&S" ( discard_S ),
-				 "=&c" ( discard_c )
+				 "=&c" ( discard_c ), "+m" ( *value )
 			       : "r" ( value0 ), "1" ( subtrahend0 ),
 				 "2" ( size )
 			       : "eax" );
@@ -104,15 +111,18 @@ bigint_subtract_raw ( const uint32_t *su
  */
 static inline __attribute__ (( always_inline )) void
 bigint_rol_raw ( uint32_t *value0, unsigned int size ) {
+	bigint_t ( size ) __attribute__ (( may_alias )) *value =
+		( ( void * ) value0 );
 	long index;
 	long discard_c;
 
 	__asm__ __volatile__ ( "xor %0, %0\n\t" /* Zero %0 and clear CF */
 			       "\n1:\n\t"
-			       "rcll $1, (%2,%0,4)\n\t"
+			       "rcll $1, (%3,%0,4)\n\t"
 			       "inc %0\n\t" /* Does not affect CF */
 			       "loop 1b\n\t"
-			       : "=&r" ( index ), "=&c" ( discard_c )
+			       : "=&r" ( index ), "=&c" ( discard_c ),
+				 "+m" ( *value )
 			       : "r" ( value0 ), "1" ( size ) );
 }
 
@@ -124,13 +134,15 @@ bigint_rol_raw ( uint32_t *value0, unsig
  */
 static inline __attribute__ (( always_inline )) void
 bigint_ror_raw ( uint32_t *value0, unsigned int size ) {
+	bigint_t ( size ) __attribute__ (( may_alias )) *value =
+		( ( void * ) value0 );
 	long discard_c;
 
 	__asm__ __volatile__ ( "clc\n\t"
 			       "\n1:\n\t"
-			       "rcrl $1, -4(%1,%0,4)\n\t"
+			       "rcrl $1, -4(%2,%0,4)\n\t"
 			       "loop 1b\n\t"
-			       : "=&c" ( discard_c )
+			       : "=&c" ( discard_c ), "+m" ( *value )
 			       : "r" ( value0 ), "0" ( size ) );
 }
 
@@ -167,28 +179,19 @@ bigint_is_zero_raw ( const uint32_t *val
 static inline __attribute__ (( always_inline, pure )) int
 bigint_is_geq_raw ( const uint32_t *value0, const uint32_t *reference0,
 		    unsigned int size ) {
-	const bigint_t ( size ) __attribute__ (( may_alias )) *value =
-		( ( const void * ) value0 );
-	const bigint_t ( size ) __attribute__ (( may_alias )) *reference =
-		( ( const void * ) reference0 );
-	void *discard_S;
-	void *discard_D;
 	long discard_c;
+	long discard_tmp;
 	int result;
 
-	__asm__ __volatile__ ( "std\n\t"
-			       "\n1:\n\t"
-			       "lodsl\n\t"
-			       "scasl\n\t"
+	__asm__ __volatile__ ( "\n1:\n\t"
+			       "movl -4(%3, %1, 4), %k2\n\t"
+			       "cmpl -4(%4, %1, 4), %k2\n\t"
 			       "loope 1b\n\t"
 			       "setae %b0\n\t"
-			       "cld\n\t"
-			       : "=q" ( result ), "=&S" ( discard_S ),
-				 "=&D" ( discard_D ), "=&c" ( discard_c )
-			       : "0" ( 0 ), "1" ( &value->element[ size - 1 ] ),
-				 "2" ( &reference->element[ size - 1 ] ),
-				 "3" ( size )
-			       : "eax" );
+			       : "=q" ( result ), "=&c" ( discard_c ),
+				 "=&r" ( discard_tmp )
+			       : "r" ( value0 ), "r" ( reference0 ),
+				 "0" ( 0 ), "1" ( size ) );
 	return result;
 }
 
@@ -248,6 +251,8 @@ bigint_max_set_bit_raw ( const uint32_t
 static inline __attribute__ (( always_inline )) void
 bigint_grow_raw ( const uint32_t *source0, unsigned int source_size,
 		  uint32_t *dest0, unsigned int dest_size ) {
+	bigint_t ( dest_size ) __attribute__ (( may_alias )) *dest =
+		( ( void * ) dest0 );
 	long pad_size = ( dest_size - source_size );
 	void *discard_D;
 	void *discard_S;
@@ -255,10 +260,10 @@ bigint_grow_raw ( const uint32_t *source
 
 	__asm__ __volatile__ ( "rep movsl\n\t"
 			       "xorl %%eax, %%eax\n\t"
-			       "mov %3, %2\n\t"
+			       "mov %4, %2\n\t"
 			       "rep stosl\n\t"
 			       : "=&D" ( discard_D ), "=&S" ( discard_S ),
-				 "=&c" ( discard_c )
+				 "=&c" ( discard_c ), "+m" ( *dest )
 			       : "g" ( pad_size ), "0" ( dest0 ),
 				 "1" ( source0 ), "2" ( source_size )
 			       : "eax" );
@@ -275,13 +280,15 @@ bigint_grow_raw ( const uint32_t *source
 static inline __attribute__ (( always_inline )) void
 bigint_shrink_raw ( const uint32_t *source0, unsigned int source_size __unused,
 		    uint32_t *dest0, unsigned int dest_size ) {
+	bigint_t ( dest_size ) __attribute__ (( may_alias )) *dest =
+		( ( void * ) dest0 );
 	void *discard_D;
 	void *discard_S;
 	long discard_c;
 
 	__asm__ __volatile__ ( "rep movsl\n\t"
 			       : "=&D" ( discard_D ), "=&S" ( discard_S ),
-				 "=&c" ( discard_c )
+				 "=&c" ( discard_c ), "+m" ( *dest )
 			       : "0" ( dest0 ), "1" ( source0 ),
 				 "2" ( dest_size )
 			       : "eax" );
@@ -298,15 +305,19 @@ bigint_shrink_raw ( const uint32_t *sour
 static inline __attribute__ (( always_inline )) void
 bigint_done_raw ( const uint32_t *value0, unsigned int size __unused,
 		  void *out, size_t len ) {
+	struct {
+		uint8_t bytes[len];
+	} __attribute__ (( may_alias )) *out_bytes = out;
 	void *discard_D;
 	long discard_c;
 
 	/* Copy raw data in reverse order */
 	__asm__ __volatile__ ( "\n1:\n\t"
-			       "movb -1(%2,%1), %%al\n\t"
+			       "movb -1(%3,%1), %%al\n\t"
 			       "stosb\n\t"
 			       "loop 1b\n\t"
-			       : "=&D" ( discard_D ), "=&c" ( discard_c )
+			       : "=&D" ( discard_D ), "=&c" ( discard_c ),
+				 "+m" ( *out_bytes )
 			       : "r" ( value0 ), "0" ( out ), "1" ( len )
 			       : "eax" );
 }
diff -pruN 1.0.0+git-20190125.36a4c85-5.1/src/arch/x86/include/bits/bitops.h 1.21.1+git-20220113.fbbdc3926-0ubuntu1/src/arch/x86/include/bits/bitops.h
--- 1.0.0+git-20190125.36a4c85-5.1/src/arch/x86/include/bits/bitops.h	2019-02-09 16:03:59.000000000 +0000
+++ 1.21.1+git-20220113.fbbdc3926-0ubuntu1/src/arch/x86/include/bits/bitops.h	2022-01-13 13:43:08.000000000 +0000
@@ -29,7 +29,7 @@ set_bit ( unsigned int bit, volatile voi
 		uint8_t byte[ ( bit / 8 ) + 1 ];
 	} *bytes = bits;
 
-	__asm__ __volatile__ ( "lock bts %1, %0"
+	__asm__ __volatile__ ( "lock btsl %k1, %0"
 			       : "+m" ( *bytes ) : "Ir" ( bit ) );
 }
 
@@ -45,7 +45,7 @@ clear_bit ( unsigned int bit, volatile v
 		uint8_t byte[ ( bit / 8 ) + 1 ];
 	} *bytes = bits;
 
-	__asm__ __volatile__ ( "lock btr %1, %0"
+	__asm__ __volatile__ ( "lock btrl %k1, %0"
 			       : "+m" ( *bytes ) : "Ir" ( bit ) );
 }
 
@@ -63,7 +63,7 @@ test_and_set_bit ( unsigned int bit, vol
 	} *bytes = bits;
 	int old;
 
-	__asm__ __volatile__ ( "lock bts %2, %0\n\t"
+	__asm__ __volatile__ ( "lock btsl %k2, %0\n\t"
 			       "sbb %1, %1\n\t"
 			       : "+m" ( *bytes ), "=r"  ( old )
 			       : "Ir" ( bit ) );
@@ -84,7 +84,7 @@ test_and_clear_bit ( unsigned int bit, v
 	} *bytes = bits;
 	int old;
 
-	__asm__ __volatile__ ( "lock btr %2, %0\n\t"
+	__asm__ __volatile__ ( "lock btrl %k2, %0\n\t"
 			       "sbb %1, %1\n\t"
 			       : "+m" ( *bytes ), "=r"  ( old )
 			       : "Ir" ( bit ) );
diff -pruN 1.0.0+git-20190125.36a4c85-5.1/src/arch/x86/include/bits/linux_api_platform.h 1.21.1+git-20220113.fbbdc3926-0ubuntu1/src/arch/x86/include/bits/linux_api_platform.h
--- 1.0.0+git-20190125.36a4c85-5.1/src/arch/x86/include/bits/linux_api_platform.h	2019-02-09 16:03:59.000000000 +0000
+++ 1.21.1+git-20220113.fbbdc3926-0ubuntu1/src/arch/x86/include/bits/linux_api_platform.h	1970-01-01 00:00:00.000000000 +0000
@@ -1,6 +0,0 @@
-#ifndef _LINUX_API_PLATFORM_H
-#define _LINUX_API_PLATFORM_H
-
-extern int linux_errno;
-
-#endif /* _LINUX_API_PLATFORM_H */
diff -pruN 1.0.0+git-20190125.36a4c85-5.1/src/arch/x86/include/initrd.h 1.21.1+git-20220113.fbbdc3926-0ubuntu1/src/arch/x86/include/initrd.h
--- 1.0.0+git-20190125.36a4c85-5.1/src/arch/x86/include/initrd.h	2019-02-09 16:03:59.000000000 +0000
+++ 1.21.1+git-20220113.fbbdc3926-0ubuntu1/src/arch/x86/include/initrd.h	2022-01-13 13:43:08.000000000 +0000
@@ -11,13 +11,6 @@ FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
 
 #include <ipxe/uaccess.h>
 
-/** Minimum alignment for initrds
- *
- * Some versions of Linux complain about initrds that are not
- * page-aligned.
- */
-#define INITRD_ALIGN 4096
-
 /** Minimum free space required to reshuffle initrds
  *
  * Chosen to avoid absurdly long reshuffling times
diff -pruN 1.0.0+git-20190125.36a4c85-5.1/src/arch/x86/include/ipxe/cpuid.h 1.21.1+git-20220113.fbbdc3926-0ubuntu1/src/arch/x86/include/ipxe/cpuid.h
--- 1.0.0+git-20190125.36a4c85-5.1/src/arch/x86/include/ipxe/cpuid.h	2019-02-09 16:03:59.000000000 +0000
+++ 1.21.1+git-20220113.fbbdc3926-0ubuntu1/src/arch/x86/include/ipxe/cpuid.h	2022-01-13 13:43:08.000000000 +0000
@@ -42,6 +42,12 @@ struct x86_features {
 /** Hypervisor is present */
 #define CPUID_FEATURES_INTEL_ECX_HYPERVISOR 0x80000000UL
 
+/** TSC is present */
+#define CPUID_FEATURES_INTEL_EDX_TSC 0x00000010UL
+
+/** FXSAVE and FXRSTOR are supported */
+#define CPUID_FEATURES_INTEL_EDX_FXSR 0x01000000UL
+
 /** Get largest extended function */
 #define CPUID_AMD_MAX_FN 0x80000000UL
 
diff -pruN 1.0.0+git-20190125.36a4c85-5.1/src/arch/x86/include/ipxe/pcibios.h 1.21.1+git-20220113.fbbdc3926-0ubuntu1/src/arch/x86/include/ipxe/pcibios.h
--- 1.0.0+git-20190125.36a4c85-5.1/src/arch/x86/include/ipxe/pcibios.h	2019-02-09 16:03:59.000000000 +0000
+++ 1.21.1+git-20220113.fbbdc3926-0ubuntu1/src/arch/x86/include/ipxe/pcibios.h	2022-01-13 13:43:08.000000000 +0000
@@ -132,4 +132,17 @@ PCIAPI_INLINE ( pcbios, pci_write_config
 	return pcibios_write ( pci, PCIBIOS_WRITE_CONFIG_DWORD | where, value);
 }
 
+/**
+ * Map PCI bus address as an I/O address
+ *
+ * @v bus_addr		PCI bus address
+ * @v len		Length of region
+ * @ret io_addr		I/O address, or NULL on error
+ */
+static inline __always_inline void *
+PCIAPI_INLINE ( pcbios, pci_ioremap ) ( struct pci_device *pci __unused,
+					unsigned long bus_addr, size_t len ) {
+	return ioremap ( bus_addr, len );
+}
+
 #endif /* _IPXE_PCIBIOS_H */
diff -pruN 1.0.0+git-20190125.36a4c85-5.1/src/arch/x86/include/ipxe/pcidirect.h 1.21.1+git-20220113.fbbdc3926-0ubuntu1/src/arch/x86/include/ipxe/pcidirect.h
--- 1.0.0+git-20190125.36a4c85-5.1/src/arch/x86/include/ipxe/pcidirect.h	2019-02-09 16:03:59.000000000 +0000
+++ 1.21.1+git-20220113.fbbdc3926-0ubuntu1/src/arch/x86/include/ipxe/pcidirect.h	2022-01-13 13:43:08.000000000 +0000
@@ -32,8 +32,8 @@ extern void pcidirect_prepare ( struct p
  */
 static inline __always_inline int
 PCIAPI_INLINE ( direct, pci_num_bus ) ( void ) {
-	/* No way to work this out via Type 1 accesses */
-	return 0x100;
+	/* Scan first bus and rely on bridge detection to find higher buses */
+	return 1;
 }
 
 /**
@@ -138,4 +138,17 @@ PCIAPI_INLINE ( direct, pci_write_config
 	return 0;
 }
 
+/**
+ * Map PCI bus address as an I/O address
+ *
+ * @v bus_addr		PCI bus address
+ * @v len		Length of region
+ * @ret io_addr		I/O address, or NULL on error
+ */
+static inline __always_inline void *
+PCIAPI_INLINE ( direct, pci_ioremap ) ( struct pci_device *pci __unused,
+					unsigned long bus_addr, size_t len ) {
+	return ioremap ( bus_addr, len );
+}
+
 #endif /* _PCIDIRECT_H */
diff -pruN 1.0.0+git-20190125.36a4c85-5.1/src/arch/x86/include/ipxe/rsdp.h 1.21.1+git-20220113.fbbdc3926-0ubuntu1/src/arch/x86/include/ipxe/rsdp.h
--- 1.0.0+git-20190125.36a4c85-5.1/src/arch/x86/include/ipxe/rsdp.h	2019-02-09 16:03:59.000000000 +0000
+++ 1.21.1+git-20220113.fbbdc3926-0ubuntu1/src/arch/x86/include/ipxe/rsdp.h	2022-01-13 13:43:08.000000000 +0000
@@ -15,4 +15,17 @@ FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
 #define ACPI_PREFIX_rsdp __rsdp_
 #endif
 
+/**
+ * Locate ACPI table
+ *
+ * @v signature		Requested table signature
+ * @v index		Requested index of table with this signature
+ * @ret table		Table, or UNULL if not found
+ */
+static inline __attribute__ (( always_inline )) userptr_t
+ACPI_INLINE ( rsdp, acpi_find ) ( uint32_t signature, unsigned int index ) {
+
+	return acpi_find_via_rsdt ( signature, index );
+}
+
 #endif /* _IPXE_RSDP_H */
diff -pruN 1.0.0+git-20190125.36a4c85-5.1/src/arch/x86/interface/pcbios/acpipwr.c 1.21.1+git-20220113.fbbdc3926-0ubuntu1/src/arch/x86/interface/pcbios/acpipwr.c
--- 1.0.0+git-20190125.36a4c85-5.1/src/arch/x86/interface/pcbios/acpipwr.c	2019-02-09 16:03:59.000000000 +0000
+++ 1.21.1+git-20220113.fbbdc3926-0ubuntu1/src/arch/x86/interface/pcbios/acpipwr.c	2022-01-13 13:43:08.000000000 +0000
@@ -43,6 +43,69 @@ FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
 #define S5_SIGNATURE ACPI_SIGNATURE ( '_', 'S', '5', '_' )
 
 /**
+ * Extract \_Sx value from DSDT/SSDT
+ *
+ * @v zsdt		DSDT or SSDT
+ * @v len		Length of DSDT/SSDT
+ * @v offset		Offset of signature within DSDT/SSDT
+ * @v data		Data buffer
+ * @ret rc		Return status code
+ *
+ * In theory, extracting the \_Sx value from the DSDT/SSDT requires a
+ * full ACPI parser plus some heuristics to work around the various
+ * broken encodings encountered in real ACPI implementations.
+ *
+ * In practice, we can get the same result by scanning through the
+ * DSDT/SSDT for the signature (e.g. "_S5_"), extracting the first
+ * four bytes, removing any bytes with bit 3 set, and treating
+ * whatever is left as a little-endian value.  This is one of the
+ * uglier hacks I have ever implemented, but it's still prettier than
+ * the ACPI specification itself.
+ */
+static int acpi_extract_sx ( userptr_t zsdt, size_t len, size_t offset,
+			     void *data ) {
+	unsigned int *sx = data;
+	uint8_t bytes[4];
+	uint8_t *byte;
+
+	/* Skip signature and package header */
+	offset += ( 4 /* signature */ + 3 /* package header */ );
+
+	/* Sanity check */
+	if ( ( offset + sizeof ( bytes ) /* value */ ) > len ) {
+		return -EINVAL;
+	}
+
+	/* Read first four bytes of value */
+	copy_from_user ( bytes, zsdt, offset, sizeof ( bytes ) );
+	DBGC ( colour, "ACPI found \\_Sx containing %02x:%02x:%02x:%02x\n",
+	       bytes[0], bytes[1], bytes[2], bytes[3] );
+
+	/* Extract \Sx value.  There are three potential encodings
+	 * that we might encounter:
+	 *
+	 * - SLP_TYPa, SLP_TYPb, rsvd, rsvd
+	 *
+	 * - <byteprefix>, SLP_TYPa, <byteprefix>, SLP_TYPb, ...
+	 *
+	 * - <dwordprefix>, SLP_TYPa, SLP_TYPb, 0, 0
+	 *
+	 * Since <byteprefix> and <dwordprefix> both have bit 3 set,
+	 * and valid SLP_TYPx must have bit 3 clear (since SLP_TYPx is
+	 * a 3-bit field), we can just skip any bytes with bit 3 set.
+	 */
+	byte = bytes;
+	if ( *byte & 0x08 )
+		byte++;
+	*sx = *(byte++);
+	if ( *byte & 0x08 )
+		byte++;
+	*sx |= ( *byte << 8 );
+
+	return 0;
+}
+
+/**
  * Power off the computer using ACPI
  *
  * @ret rc		Return status code
@@ -56,7 +119,7 @@ int acpi_poweroff ( void ) {
 	unsigned int pm1b_cnt;
 	unsigned int slp_typa;
 	unsigned int slp_typb;
-	int s5;
+	unsigned int s5;
 	int rc;
 
 	/* Locate FADT */
@@ -74,9 +137,8 @@ int acpi_poweroff ( void ) {
 	pm1b_cnt = ( pm1b_cnt_blk + ACPI_PM1_CNT );
 
 	/* Extract \_S5 from DSDT or any SSDT */
-	s5 = acpi_sx ( S5_SIGNATURE );
-	if ( s5 < 0 ) {
-		rc = s5;
+	if ( ( rc = acpi_extract ( S5_SIGNATURE, &s5,
+				   acpi_extract_sx ) ) != 0 ) {
 		DBGC ( colour, "ACPI could not extract \\_S5: %s\n",
 		       strerror ( rc ) );
 		return rc;
diff -pruN 1.0.0+git-20190125.36a4c85-5.1/src/arch/x86/interface/pcbios/bios_cachedhcp.c 1.21.1+git-20220113.fbbdc3926-0ubuntu1/src/arch/x86/interface/pcbios/bios_cachedhcp.c
--- 1.0.0+git-20190125.36a4c85-5.1/src/arch/x86/interface/pcbios/bios_cachedhcp.c	1970-01-01 00:00:00.000000000 +0000
+++ 1.21.1+git-20220113.fbbdc3926-0ubuntu1/src/arch/x86/interface/pcbios/bios_cachedhcp.c	2022-01-13 13:43:08.000000000 +0000
@@ -0,0 +1,77 @@
+/*
+ * Copyright (C) 2013 Michael Brown <mbrown@fensystems.co.uk>.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of the
+ * License, or any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+ * 02110-1301, USA.
+ *
+ * You can also choose to distribute this program under the terms of
+ * the Unmodified Binary Distribution Licence (as given in the file
+ * COPYING.UBDL), provided that you have satisfied its requirements.
+ */
+
+FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
+
+#include <stdint.h>
+#include <ipxe/init.h>
+#include <ipxe/cachedhcp.h>
+#include <realmode.h>
+#include <pxe_api.h>
+
+/** @file
+ *
+ * Cached DHCP packet
+ *
+ */
+
+/** Cached DHCPACK physical address
+ *
+ * This can be set by the prefix.
+ */
+uint32_t __bss16 ( cached_dhcpack_phys );
+#define cached_dhcpack_phys __use_data16 ( cached_dhcpack_phys )
+
+/** Colour for debug messages */
+#define colour &cached_dhcpack_phys
+
+/**
+ * Cached DHCPACK initialisation function
+ *
+ */
+static void cachedhcp_init ( void ) {
+	int rc;
+
+	/* Do nothing if no cached DHCPACK is present */
+	if ( ! cached_dhcpack_phys ) {
+		DBGC ( colour, "CACHEDHCP found no cached DHCPACK\n" );
+		return;
+	}
+
+	/* Record cached DHCPACK */
+	if ( ( rc = cachedhcp_record ( &cached_dhcpack,
+				       phys_to_user ( cached_dhcpack_phys ),
+				       sizeof ( BOOTPLAYER_t ) ) ) != 0 ) {
+		DBGC ( colour, "CACHEDHCP could not record DHCPACK: %s\n",
+		       strerror ( rc ) );
+		return;
+	}
+
+	/* Mark as consumed */
+	cached_dhcpack_phys = 0;
+}
+
+/** Cached DHCPACK initialisation function */
+struct init_fn cachedhcp_init_fn __init_fn ( INIT_NORMAL ) = {
+	.initialise = cachedhcp_init,
+};
diff -pruN 1.0.0+git-20190125.36a4c85-5.1/src/arch/x86/interface/pcbios/bios_console.c 1.21.1+git-20220113.fbbdc3926-0ubuntu1/src/arch/x86/interface/pcbios/bios_console.c
--- 1.0.0+git-20190125.36a4c85-5.1/src/arch/x86/interface/pcbios/bios_console.c	2019-02-09 16:03:59.000000000 +0000
+++ 1.21.1+git-20220113.fbbdc3926-0ubuntu1/src/arch/x86/interface/pcbios/bios_console.c	2022-01-13 13:43:08.000000000 +0000
@@ -443,7 +443,7 @@ struct console_driver bios_console __con
  *
  * @v ix86		Registers as passed to INT 16
  */
-static __asmcall void bios_inject ( struct i386_all_regs *ix86 ) {
+static __asmcall __used void bios_inject ( struct i386_all_regs *ix86 ) {
 	unsigned int discard_a;
 	unsigned int scancode;
 	unsigned int i;
diff -pruN 1.0.0+git-20190125.36a4c85-5.1/src/arch/x86/interface/pcbios/e820mangler.S 1.21.1+git-20220113.fbbdc3926-0ubuntu1/src/arch/x86/interface/pcbios/e820mangler.S
--- 1.0.0+git-20190125.36a4c85-5.1/src/arch/x86/interface/pcbios/e820mangler.S	2019-02-09 16:03:59.000000000 +0000
+++ 1.21.1+git-20220113.fbbdc3926-0ubuntu1/src/arch/x86/interface/pcbios/e820mangler.S	2022-01-13 13:43:08.000000000 +0000
@@ -67,7 +67,7 @@ FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL )
  ****************************************************************************
  */
 	.section ".data16", "aw", @progbits
-	.align 16
+	.balign 16
 	.globl hidemem_base
 	.globl hidemem_umalloc
 	.globl hidemem_textdata
diff -pruN 1.0.0+git-20190125.36a4c85-5.1/src/arch/x86/interface/pcbios/int13.c 1.21.1+git-20220113.fbbdc3926-0ubuntu1/src/arch/x86/interface/pcbios/int13.c
--- 1.0.0+git-20190125.36a4c85-5.1/src/arch/x86/interface/pcbios/int13.c	2019-02-09 16:03:59.000000000 +0000
+++ 1.21.1+git-20220113.fbbdc3926-0ubuntu1/src/arch/x86/interface/pcbios/int13.c	2022-01-13 13:43:08.000000000 +0000
@@ -678,10 +678,10 @@ static int int13_get_disk_type ( struct
  * @ret cx		Extensions API support bitmap
  * @ret status		Status code / API version
  */
-static int int13_extension_check ( struct san_device *sandev __unused,
+static int int13_extension_check ( struct san_device *sandev,
 				   struct i386_all_regs *ix86 ) {
 
-	if ( ix86->regs.bx == 0x55aa ) {
+	if ( ( ix86->regs.bx == 0x55aa ) && ! int13_is_fdd ( sandev ) ) {
 		DBGC2 ( sandev, "INT13 extensions installation check\n" );
 		ix86->regs.bx = 0xaa55;
 		ix86->regs.cx = ( INT13_EXTENSION_LINEAR |
@@ -1064,7 +1064,7 @@ static int int13_cdrom_read_boot_catalog
  * INT 13 handler
  *
  */
-static __asmcall void int13 ( struct i386_all_regs *ix86 ) {
+static __asmcall __used void int13 ( struct i386_all_regs *ix86 ) {
 	int command = ix86->regs.ah;
 	unsigned int bios_drive = ix86->regs.dl;
 	struct san_device *sandev;
diff -pruN 1.0.0+git-20190125.36a4c85-5.1/src/arch/x86/interface/pcbios/memtop_umalloc.c 1.21.1+git-20220113.fbbdc3926-0ubuntu1/src/arch/x86/interface/pcbios/memtop_umalloc.c
--- 1.0.0+git-20190125.36a4c85-5.1/src/arch/x86/interface/pcbios/memtop_umalloc.c	2019-02-09 16:03:59.000000000 +0000
+++ 1.21.1+git-20220113.fbbdc3926-0ubuntu1/src/arch/x86/interface/pcbios/memtop_umalloc.c	2022-01-13 13:43:08.000000000 +0000
@@ -190,14 +190,14 @@ static userptr_t memtop_urealloc ( userp
 	/* Expand/shrink block if possible */
 	if ( ptr == bottom ) {
 		/* Update block */
-		if ( new_size > ( heap_size - extmem.size ) ) {
-			DBG ( "EXTMEM out of space\n" );
-			return UNULL;
-		}
 		new = userptr_add ( ptr, - ( new_size - extmem.size ) );
 		align = ( user_to_phys ( new, 0 ) & ( EM_ALIGN - 1 ) );
 		new_size += align;
 		new = userptr_add ( new, -align );
+		if ( new_size > ( heap_size + extmem.size ) ) {
+			DBG ( "EXTMEM out of space\n" );
+			return UNULL;
+		}
 		DBG ( "EXTMEM expanding [%lx,%lx) to [%lx,%lx)\n",
 		      user_to_phys ( ptr, 0 ),
 		      user_to_phys ( ptr, extmem.size ),
diff -pruN 1.0.0+git-20190125.36a4c85-5.1/src/arch/x86/interface/pcbios/pcibios.c 1.21.1+git-20220113.fbbdc3926-0ubuntu1/src/arch/x86/interface/pcbios/pcibios.c
--- 1.0.0+git-20190125.36a4c85-5.1/src/arch/x86/interface/pcbios/pcibios.c	2019-02-09 16:03:59.000000000 +0000
+++ 1.21.1+git-20220113.fbbdc3926-0ubuntu1/src/arch/x86/interface/pcbios/pcibios.c	2022-01-13 13:43:08.000000000 +0000
@@ -121,3 +121,4 @@ PROVIDE_PCIAPI_INLINE ( pcbios, pci_read
 PROVIDE_PCIAPI_INLINE ( pcbios, pci_write_config_byte );
 PROVIDE_PCIAPI_INLINE ( pcbios, pci_write_config_word );
 PROVIDE_PCIAPI_INLINE ( pcbios, pci_write_config_dword );
+PROVIDE_PCIAPI_INLINE ( pcbios, pci_ioremap );
diff -pruN 1.0.0+git-20190125.36a4c85-5.1/src/arch/x86/interface/pcbios/rsdp.c 1.21.1+git-20220113.fbbdc3926-0ubuntu1/src/arch/x86/interface/pcbios/rsdp.c
--- 1.0.0+git-20190125.36a4c85-5.1/src/arch/x86/interface/pcbios/rsdp.c	2019-02-09 16:03:59.000000000 +0000
+++ 1.21.1+git-20220113.fbbdc3926-0ubuntu1/src/arch/x86/interface/pcbios/rsdp.c	2022-01-13 13:43:08.000000000 +0000
@@ -123,3 +123,4 @@ static userptr_t rsdp_find_rsdt ( void )
 }
 
 PROVIDE_ACPI ( rsdp, acpi_find_rsdt, rsdp_find_rsdt );
+PROVIDE_ACPI_INLINE ( rsdp, acpi_find );
diff -pruN 1.0.0+git-20190125.36a4c85-5.1/src/arch/x86/interface/pcbios/rtc_entropy.c 1.21.1+git-20220113.fbbdc3926-0ubuntu1/src/arch/x86/interface/pcbios/rtc_entropy.c
--- 1.0.0+git-20190125.36a4c85-5.1/src/arch/x86/interface/pcbios/rtc_entropy.c	2019-02-09 16:03:59.000000000 +0000
+++ 1.21.1+git-20220113.fbbdc3926-0ubuntu1/src/arch/x86/interface/pcbios/rtc_entropy.c	2022-01-13 13:43:08.000000000 +0000
@@ -36,6 +36,7 @@ FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
 #include <biosint.h>
 #include <pic8259.h>
 #include <rtc.h>
+#include <ipxe/cpuid.h>
 #include <ipxe/entropy.h>
 
 /** Maximum time to wait for an RTC interrupt, in milliseconds */
@@ -174,8 +175,17 @@ static int rtc_entropy_check ( void ) {
  * @ret rc		Return status code
  */
 static int rtc_entropy_enable ( void ) {
+	struct x86_features features;
 	int rc;
 
+	/* Check that TSC is supported */
+	x86_features ( &features );
+	if ( ! ( features.intel.edx & CPUID_FEATURES_INTEL_EDX_TSC ) ) {
+		DBGC ( &rtc_flag, "RTC has no TSC\n" );
+		rc = -ENOTSUP;
+		goto err_no_tsc;
+	}
+
 	/* Hook ISR and enable RTC interrupts */
 	rtc_hook_isr();
 	enable_irq ( RTC_IRQ );
@@ -191,6 +201,7 @@ static int rtc_entropy_enable ( void ) {
 	rtc_disable_int();
 	disable_irq ( RTC_IRQ );
 	rtc_unhook_isr();
+ err_no_tsc:
 	return rc;
 }
 
diff -pruN 1.0.0+git-20190125.36a4c85-5.1/src/arch/x86/interface/pxe/pxe_entry.S 1.21.1+git-20220113.fbbdc3926-0ubuntu1/src/arch/x86/interface/pxe/pxe_entry.S
--- 1.0.0+git-20190125.36a4c85-5.1/src/arch/x86/interface/pxe/pxe_entry.S	2019-02-09 16:03:59.000000000 +0000
+++ 1.21.1+git-20220113.fbbdc3926-0ubuntu1/src/arch/x86/interface/pxe/pxe_entry.S	2022-01-13 13:43:08.000000000 +0000
@@ -34,7 +34,7 @@ FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL )
  */
 	.section ".text16.data", "aw", @progbits
 	.globl ppxe
-	.align 16
+	.balign 16
 ppxe:
 	.ascii "!PXE"			/* Signature */
 	.byte pxe_length		/* StructLength */
@@ -72,7 +72,7 @@ undiheader:
  */
 	.section ".text16.data", "aw", @progbits
 	.globl pxenv
-	.align 16
+	.balign 16
 pxenv:
 	.ascii "PXENV+"			/* Signature */
 	.word 0x0201			/* Version */
diff -pruN 1.0.0+git-20190125.36a4c85-5.1/src/arch/x86/interface/syslinux/comboot_call.c 1.21.1+git-20220113.fbbdc3926-0ubuntu1/src/arch/x86/interface/syslinux/comboot_call.c
--- 1.0.0+git-20190125.36a4c85-5.1/src/arch/x86/interface/syslinux/comboot_call.c	2019-02-09 16:03:59.000000000 +0000
+++ 1.21.1+git-20220113.fbbdc3926-0ubuntu1/src/arch/x86/interface/syslinux/comboot_call.c	2022-01-13 13:43:08.000000000 +0000
@@ -47,7 +47,7 @@ static char __bss16_array ( syslinux_ver
 #define syslinux_version __use_data16 ( syslinux_version )
 
 /** The "SYSLINUX" copyright string */
-static char __data16_array ( syslinux_copyright, [] ) = " http://ipxe.org";
+static char __data16_array ( syslinux_copyright, [] ) = " https://ipxe.org";
 #define syslinux_copyright __use_data16 ( syslinux_copyright )
 
 static char __data16_array ( syslinux_configuration_file, [] ) = "";
@@ -220,7 +220,7 @@ static int comboot_fetch_kernel ( char *
 /**
  * Terminate program interrupt handler
  */
-static __asmcall void int20 ( struct i386_all_regs *ix86 __unused ) {
+static __asmcall __used void int20 ( struct i386_all_regs *ix86 __unused ) {
 	rmlongjmp ( comboot_return, COMBOOT_EXIT );
 }
 
@@ -228,7 +228,7 @@ static __asmcall void int20 ( struct i38
 /**
  * DOS-compatible API
  */
-static __asmcall void int21 ( struct i386_all_regs *ix86 ) {
+static __asmcall __used void int21 ( struct i386_all_regs *ix86 ) {
 	ix86->flags |= CF;
 
 	switch ( ix86->regs.ah ) {
@@ -311,7 +311,7 @@ __weak int pxe_api_call_weak ( struct i3
 /**
  * SYSLINUX API
  */
-static __asmcall void int22 ( struct i386_all_regs *ix86 ) {
+static __asmcall __used void int22 ( struct i386_all_regs *ix86 ) {
 	ix86->flags |= CF;
 
 	switch ( ix86->regs.ax ) {
diff -pruN 1.0.0+git-20190125.36a4c85-5.1/src/arch/x86/Makefile.linux 1.21.1+git-20220113.fbbdc3926-0ubuntu1/src/arch/x86/Makefile.linux
--- 1.0.0+git-20190125.36a4c85-5.1/src/arch/x86/Makefile.linux	2019-02-09 16:03:59.000000000 +0000
+++ 1.21.1+git-20220113.fbbdc3926-0ubuntu1/src/arch/x86/Makefile.linux	2022-01-13 13:43:08.000000000 +0000
@@ -1,13 +1,10 @@
-MEDIA = linux
-
-# enable valgrind
-CFLAGS += -UNVALGRIND
+# -*- makefile -*- : Force emacs to use Makefile mode
 
+# Include x86 Linux headers
+#
 INCDIRS += arch/x86/include/linux
-SRCDIRS += interface/linux
-SRCDIRS += drivers/linux
-SRCDIRS += arch/x86/core/linux
 
-$(BIN)/%.linux : $(BIN)/%.linux.tmp
-	$(QM)$(ECHO) "  [FINISH] $@"
-	$(Q)$(CP) $< $@
+# Include generic Linux Makefile
+#
+MAKEDEPS	+= Makefile.linux
+include Makefile.linux
diff -pruN 1.0.0+git-20190125.36a4c85-5.1/src/arch/x86/Makefile.pcbios 1.21.1+git-20220113.fbbdc3926-0ubuntu1/src/arch/x86/Makefile.pcbios
--- 1.0.0+git-20190125.36a4c85-5.1/src/arch/x86/Makefile.pcbios	2019-02-09 16:03:59.000000000 +0000
+++ 1.21.1+git-20220113.fbbdc3926-0ubuntu1/src/arch/x86/Makefile.pcbios	2022-01-13 13:43:08.000000000 +0000
@@ -4,18 +4,15 @@
 #
 SRCDIRS		+= arch/x86/drivers/net
 
-# The i386 linker script
+# The linker scripts
 #
 LDSCRIPT	= arch/x86/scripts/pcbios.lds
+LDSCRIPT_PREFIX	= arch/x86/scripts/prefixonly.lds
 
 # Stop ld from complaining about our customised linker script
 #
 LDFLAGS		+= -N --no-check-sections
 
-# Prefix always starts at address zero
-#
-LDFLAGS		+= --section-start=.prefix=0
-
 # Media types.
 #
 MEDIA		+= rom
@@ -57,46 +54,11 @@ LIST_NAME_mrom := ROMS
 LIST_NAME_pcirom := ROMS
 LIST_NAME_isarom := ROMS
 
-# Locations of isolinux files
-#
-SYSLINUX_DIR_LIST	:= \
-	/usr/lib/syslinux \
-	/usr/lib/syslinux/bios \
-	/usr/lib/syslinux/modules/bios \
-	/usr/share/syslinux \
-	/usr/share/syslinux/bios \
-	/usr/share/syslinux/modules/bios \
-	/usr/local/share/syslinux \
-	/usr/local/share/syslinux/bios \
-	/usr/local/share/syslinux/modules/bios \
-	/usr/lib/ISOLINUX
-ISOLINUX_BIN_LIST	:= \
-	$(ISOLINUX_BIN) \
-	$(patsubst %,%/isolinux.bin,$(SYSLINUX_DIR_LIST))
-LDLINUX_C32_LIST	:= \
-	$(LDLINUX_C32) \
-	$(patsubst %,%/ldlinux.c32,$(SYSLINUX_DIR_LIST))
-ISOLINUX_BIN	= $(firstword $(wildcard $(ISOLINUX_BIN_LIST)))
-LDLINUX_C32	= $(firstword $(wildcard $(LDLINUX_C32_LIST)))
-
-# rule to make a non-emulation ISO boot image
+# ISO or FAT filesystem images
 NON_AUTO_MEDIA	+= iso
-%iso:	%lkrn util/geniso
-	$(QM)$(ECHO) "  [GENISO] $@"
-	$(Q)ISOLINUX_BIN=$(ISOLINUX_BIN) LDLINUX_C32=$(LDLINUX_C32) \
-	    VERSION="$(VERSION)" bash util/geniso -o $@ $<
-
-# rule to make a floppy emulation ISO boot image
-NON_AUTO_MEDIA	+= liso
-%liso:	%lkrn util/geniso
-	$(QM)$(ECHO) "  [GENISO] $@"
-	$(Q)VERSION="$(VERSION)" bash util/geniso -l -o $@ $<
-
-# rule to make a syslinux floppy image (mountable, bootable)
-NON_AUTO_MEDIA	+= sdsk
-%sdsk:	%lkrn util/gensdsk
-	$(QM)$(ECHO) "  [GENSDSK] $@"
-	$(Q)bash util/gensdsk $@ $<
+$(BIN)/%.iso $(BIN)/%.sdsk: $(BIN)/%.lkrn util/genfsimg
+	$(QM)$(ECHO) "  [GENFSIMG] $@"
+	$(Q)util/genfsimg -o $@ $<
 
 # rule to write disk images to /dev/fd0
 NON_AUTO_MEDIA	+= fd0
@@ -108,12 +70,12 @@ NON_AUTO_MEDIA	+= fd0
 # Special target for building Master Boot Record binary
 $(BIN)/mbr.tmp : $(BIN)/mbr.o
 	$(QM)$(ECHO) "  [LD] $@"
-	$(Q)$(LD) $(LDFLAGS) -o $@ -e mbr $<
+	$(Q)$(LD) $(LDFLAGS) -T $(LDSCRIPT_PREFIX) -o $@ -e mbr $<
 
 # rule to make a USB disk image
 $(BIN)/usbdisk.tmp : $(BIN)/usbdisk.o
 	$(QM)$(ECHO) "  [LD] $@"
-	$(Q)$(LD) $(LDFLAGS) -o $@ -e mbr $<
+	$(Q)$(LD) $(LDFLAGS) -T $(LDSCRIPT_PREFIX) -o $@ -e mbr $<
 
 NON_AUTO_MEDIA	+= usb
 %usb: $(BIN)/usbdisk.bin %hd
diff -pruN 1.0.0+git-20190125.36a4c85-5.1/src/arch/x86/prefix/exeprefix.S 1.21.1+git-20220113.fbbdc3926-0ubuntu1/src/arch/x86/prefix/exeprefix.S
--- 1.0.0+git-20190125.36a4c85-5.1/src/arch/x86/prefix/exeprefix.S	2019-02-09 16:03:59.000000000 +0000
+++ 1.21.1+git-20220113.fbbdc3926-0ubuntu1/src/arch/x86/prefix/exeprefix.S	2022-01-13 13:43:08.000000000 +0000
@@ -110,7 +110,7 @@ overlay:
 	/* Overlay number */
 	.word	0
 
-	.align 16, 0
+	.balign 16, 0
 
 	.globl	_exe_start
 _exe_start:
diff -pruN 1.0.0+git-20190125.36a4c85-5.1/src/arch/x86/prefix/mromprefix.S 1.21.1+git-20220113.fbbdc3926-0ubuntu1/src/arch/x86/prefix/mromprefix.S
--- 1.0.0+git-20190125.36a4c85-5.1/src/arch/x86/prefix/mromprefix.S	2019-02-09 16:03:59.000000000 +0000
+++ 1.21.1+git-20220113.fbbdc3926-0ubuntu1/src/arch/x86/prefix/mromprefix.S	2022-01-13 13:43:08.000000000 +0000
@@ -492,7 +492,7 @@ mromheader:
 	.word	0
 	.size	mromheader, . - mromheader
 
-	.align	4
+	.balign	4
 mpciheader:
 	.ascii	"PCIR"			/* Signature */
 	.word	pci_vendor_id		/* Vendor identification */
diff -pruN 1.0.0+git-20190125.36a4c85-5.1/src/arch/x86/prefix/rawprefix.S 1.21.1+git-20220113.fbbdc3926-0ubuntu1/src/arch/x86/prefix/rawprefix.S
--- 1.0.0+git-20190125.36a4c85-5.1/src/arch/x86/prefix/rawprefix.S	1970-01-01 00:00:00.000000000 +0000
+++ 1.21.1+git-20220113.fbbdc3926-0ubuntu1/src/arch/x86/prefix/rawprefix.S	2022-01-13 13:43:08.000000000 +0000
@@ -0,0 +1,53 @@
+/*
+ * Raw binary prefix
+ *
+ * Assumes that entire image is already loaded as a contiguous block
+ * on a paragraph boundary and entered in real mode.
+ *
+ */
+
+FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL )
+
+	.text
+	.arch i386
+	.org 0
+	.code16
+
+#include <librm.h>
+
+	.section ".prefix", "ax", @progbits
+	.globl	_raw_start
+_raw_start:
+
+	/* Adjust %cs so that %cs:0000 is the start of the image */
+	movw	%cs, %ax
+	call	1f
+1:	popw	%bx
+	subw	$1b, %bx
+	shrw	$4, %bx
+	addw	%bx, %ax
+	pushw	%ax
+	pushw	$2f
+	lret
+2:
+	/* Install iPXE */
+	call	install
+
+	/* Set up real-mode stack */
+	movw	%bx, %ss
+	movw	$_estack16, %sp
+
+	/* Jump to .text16 segment */
+	pushw	%ax
+	pushw	$1f
+	lret
+	.section ".text16", "awx", @progbits
+1:
+	/* Run iPXE */
+	virtcall main
+
+	/* Uninstall iPXE */
+	call	uninstall
+
+	/* Boot next device */
+	int $0x18
diff -pruN 1.0.0+git-20190125.36a4c85-5.1/src/arch/x86/prefix/romprefix.S 1.21.1+git-20220113.fbbdc3926-0ubuntu1/src/arch/x86/prefix/romprefix.S
--- 1.0.0+git-20190125.36a4c85-5.1/src/arch/x86/prefix/romprefix.S	2019-02-09 16:03:59.000000000 +0000
+++ 1.21.1+git-20220113.fbbdc3926-0ubuntu1/src/arch/x86/prefix/romprefix.S	2022-01-13 13:43:08.000000000 +0000
@@ -88,7 +88,7 @@ checksum:
 	.previous
 
 .ifeqs	BUSTYPE, "PCIR"
-	.align	4
+	.balign	4
 pciheader:
 	.ascii	"PCIR"			/* Signature */
 	.word	pci_vendor_id		/* Vendor identification */ 
@@ -136,7 +136,7 @@ pci_devlist_end:
 	 * BIOSes will scan on 16-byte boundaries rather than using
 	 * the offset stored at 0x1a
 	 */
-	.align	16
+	.balign	16
 pnpheader:
 	.ascii	"$PnP"			/* Signature */
 	.byte	0x01			/* Structure revision */
@@ -161,7 +161,7 @@ pnpheader:
 
 /* Manufacturer string */
 mfgstr:
-	.asciz	"http://ipxe.org"
+	.asciz	"https://ipxe.org"
 	.size mfgstr, . - mfgstr
 
 /* Product string
@@ -184,7 +184,7 @@ prodstr_pci_id:
 
 	.globl	undiheader	
 	.weak	undiloader
-	.align	4
+	.balign	4
 undiheader:
 	.ascii	"UNDI"			/* Signature */
 	.byte	undiheader_len		/* Length of structure */
@@ -199,7 +199,7 @@ undiheader:
 	.equ undiheader_len, . - undiheader
 	.size undiheader, . - undiheader
 
-	.align	4
+	.balign	4
 ipxeheader:
 	.ascii	"iPXE"			/* Signature */
 	.byte	ipxeheader_len		/* Length of structure */
@@ -607,7 +607,7 @@ get_pmm_decompress_to:
  * strings PRODUCT_NAME and PRODUCT_SHORT_NAME in config/branding.h.
  *
  * While nothing in the GPL prevents you from removing all references
- * to iPXE or http://ipxe.org, we prefer you not to do so.
+ * to iPXE or https://ipxe.org, we prefer you not to do so.
  *
  * If you have an OEM-mandated branding requirement that cannot be
  * satisfied simply by defining PRODUCT_NAME and PRODUCT_SHORT_NAME,
diff -pruN 1.0.0+git-20190125.36a4c85-5.1/src/arch/x86/prefix/unlzma.S 1.21.1+git-20220113.fbbdc3926-0ubuntu1/src/arch/x86/prefix/unlzma.S
--- 1.0.0+git-20190125.36a4c85-5.1/src/arch/x86/prefix/unlzma.S	2019-02-09 16:03:59.000000000 +0000
+++ 1.21.1+git-20220113.fbbdc3926-0ubuntu1/src/arch/x86/prefix/unlzma.S	2022-01-13 13:43:08.000000000 +0000
@@ -44,7 +44,7 @@ FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
  */
 
 	.text
-	.arch i586
+	.arch i486
 	.section ".prefix.lib", "ax", @progbits
 
 #ifdef CODE16
@@ -231,7 +231,7 @@ rep_len_dec:	.space	sizeof__lzma_len_dec
 literal:	.rept	( ( 1 << LZMA_LC ) * 0x300 )
 		.word	0
 		.endr
-	.align	4
+	.balign	4
 	.equ	sizeof__lzma_dec, . - lzma_dec
 	.previous
 
diff -pruN 1.0.0+git-20190125.36a4c85-5.1/src/arch/x86/prefix/usbdisk.S 1.21.1+git-20220113.fbbdc3926-0ubuntu1/src/arch/x86/prefix/usbdisk.S
--- 1.0.0+git-20190125.36a4c85-5.1/src/arch/x86/prefix/usbdisk.S	2019-02-09 16:03:59.000000000 +0000
+++ 1.21.1+git-20220113.fbbdc3926-0ubuntu1/src/arch/x86/prefix/usbdisk.S	2022-01-13 13:43:08.000000000 +0000
@@ -1,5 +1,7 @@
 FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL )
 
+#include <config/console.h>
+
 	.text
 	.arch i386
 	.section ".prefix", "awx", @progbits
@@ -9,26 +11,68 @@ FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL )
 #include "mbr.S"
 
 /* Partition table: 64 heads, 32 sectors/track (ZIP-drive compatible) */
+#define HEADS 64
+#define SECTORS 32
+#define CYLADDR(cyl) ((((cyl) * HEADS + (((cyl) == 0) & 1)) * SECTORS) * 512)
+
+#ifdef CONSOLE_INT13
+#define LOGPART 1
+#define LOGSTART 0
+#define LOGCOUNT 1
+#define BOOTSTART 1
+#define BOOTCOUNT 2
+#else /* CONSOLE_INT13 */
+#define LOGPART 0
+#define BOOTSTART 0
+#define BOOTCOUNT 2
+#endif /* CONSOLE_INT13 */
+
+	/* Construct a C/H/S address */
+	.macro	chs cylinder, head, sector
+	.byte	\head
+	.byte	(((\cylinder & 0x300) >> 2) | \sector)
+	.byte	(\cylinder & 0x0ff)
+	.endm
+
+	/* Construct a linear address */
+	.macro	linear cylinders, heads, sectors
+	.long	((((\cylinders * HEADS) + \heads) * SECTORS) + \sectors - 1)
+	.endm
+
+	/* Construct a partition table entry */
+	.macro	partition bootflag, type, start, count
+	.byte	\bootflag
+	chs	\start, ((\start == 0) & 1), 1
+	.byte	\type
+	chs	(\start + \count - 1), (HEADS - 1), SECTORS
+	linear	\start, ((\start == 0) & 1), 1
+	linear	\count, 0, (1 - (((\start == 0) & 1) * SECTORS))
+	.endm
+
+	/* Partition table */
 	.org 446
 	.space 16
 	.space 16
+
 	/* Partition 3: log partition (for CONSOLE_INT13) */
-	.byte 0x00, 0x01, 0x01, 0x00
-	.byte 0xe0, 0x3f, 0x20, 0x00
-	.long 0x00000020
-	.long 0x000007e0
+	.if LOGPART
+	partition 0x00, 0xe0, LOGSTART, LOGCOUNT
+	.else
+	.space 16
+	.endif
+
 	/* Partition 4: boot partition */
-	.byte 0x80, 0x00, 0x01, 0x01
-	.byte 0xeb, 0x3f, 0x20, 0x02
-	.long 0x00000800
-	.long 0x00001000
+	partition 0x80, 0xeb, BOOTSTART, BOOTCOUNT
 
+	/* Disk signature */
 	.org 510
 	.byte 0x55, 0xaa
 
 /* Skip to start of log partition */
-	.org 32 * 512
+	.if LOGPART
+	.org CYLADDR(LOGSTART)
 	.ascii "iPXE LOG\n\n"
+	.endif
 
 /* Skip to start of boot partition */
-	.org 2048 * 512
+	.org CYLADDR(BOOTSTART)
diff -pruN 1.0.0+git-20190125.36a4c85-5.1/src/arch/x86/scripts/pcbios.lds 1.21.1+git-20220113.fbbdc3926-0ubuntu1/src/arch/x86/scripts/pcbios.lds
--- 1.0.0+git-20190125.36a4c85-5.1/src/arch/x86/scripts/pcbios.lds	2019-02-09 16:03:59.000000000 +0000
+++ 1.21.1+git-20220113.fbbdc3926-0ubuntu1/src/arch/x86/scripts/pcbios.lds	2022-01-13 13:43:08.000000000 +0000
@@ -58,11 +58,12 @@ SECTIONS {
 	*(SORT(.pci_devlist.*))
 	*(.prefix.*)
 	_mprefix = .;
-    } .bss.prefix (NOLOAD) : AT ( _end_lma ) {
+    } .bss.prefix (NOLOAD) : AT ( _bss_prefix_lma ) {
 	_eprefix = .;
     }
     _prefix_filesz	= ABSOLUTE ( _mprefix ) - ABSOLUTE ( _prefix );
     _prefix_memsz	= ABSOLUTE ( _eprefix ) - ABSOLUTE ( _prefix );
+    _prefix_padsz	= ABSOLUTE ( _eprefix ) - ABSOLUTE ( _mprefix );
 
     /*
      * The 16-bit (real-mode) code section
@@ -82,7 +83,7 @@ SECTIONS {
 	*(.text16)
 	*(.text16.*)
 	_mtext16 = .;
-    } .bss.text16 (NOLOAD) : AT ( _end_lma ) {
+    } .bss.text16 (NOLOAD) : AT ( _bss_text16_lma ) {
 	_etext16 = .;
     }
     _text16_early_filesz = ABSOLUTE ( _etext16_early ) - ABSOLUTE ( _text16 );
@@ -90,6 +91,7 @@ SECTIONS {
     _text16_late_filesz	= ABSOLUTE ( _mtext16 ) - ABSOLUTE ( _text16_late );
     _text16_late_memsz	= ABSOLUTE ( _etext16 ) - ABSOLUTE ( _text16_late );
     _text16_memsz	= ABSOLUTE ( _etext16 ) - ABSOLUTE ( _text16 );
+    _text16_padsz	= ABSOLUTE ( _etext16 ) - ABSOLUTE ( _mtext16 );
 
     /*
      * The 16-bit (real-mode) data section
@@ -104,7 +106,7 @@ SECTIONS {
 	*(.data16)
 	*(.data16.*)
 	_mdata16 = .;
-    } .bss.data16 (NOLOAD) : AT ( _end_lma ) {
+    } .bss.data16 (NOLOAD) : AT ( _bss_data16_lma ) {
 	*(.bss16)
 	*(.bss16.*)
 	*(.stack16)
@@ -114,6 +116,7 @@ SECTIONS {
     }
     _data16_filesz	= ABSOLUTE ( _mdata16 ) - ABSOLUTE ( _data16 );
     _data16_memsz	= ABSOLUTE ( _edata16 ) - ABSOLUTE ( _data16 );
+    _data16_padsz	= ABSOLUTE ( _edata16 ) - ABSOLUTE ( _mdata16 );
 
     /*
      * The 32-bit sections
@@ -135,7 +138,7 @@ SECTIONS {
 	KEEP(*(.provided))
 	KEEP(*(.provided.*))
 	_mtextdata = .;
-    } .bss.textdata (NOLOAD) : AT ( _end_lma ) {
+    } .bss.textdata (NOLOAD) : AT ( _bss_textdata_lma ) {
 	*(.bss)
 	*(.bss.*)
 	*(COMMON)
@@ -157,6 +160,7 @@ SECTIONS {
     }
     _textdata_filesz	= ABSOLUTE ( _mtextdata ) - ABSOLUTE ( _textdata );
     _textdata_memsz	= ABSOLUTE ( _etextdata ) - ABSOLUTE ( _textdata );
+    _textdata_padsz	= ABSOLUTE ( _etextdata ) - ABSOLUTE ( _mtextdata );
 
     /*
      * Payload prefix
@@ -169,11 +173,12 @@ SECTIONS {
 	KEEP(*(.pprefix))
 	KEEP(*(.pprefix.*))
 	_mpprefix = .;
-    } .bss.pprefix (NOLOAD) : AT ( _end_lma ) {
+    } .bss.pprefix (NOLOAD) : AT ( _bss_pprefix_lma ) {
 	_epprefix = .;
     }
     _pprefix_filesz	= ABSOLUTE ( _mpprefix ) - ABSOLUTE ( _pprefix );
     _pprefix_memsz	= ABSOLUTE ( _epprefix ) - ABSOLUTE ( _pprefix );
+    _pprefix_padsz	= ABSOLUTE ( _epprefix ) - ABSOLUTE ( _mpprefix );
 
     /*
      * Compressor information block
@@ -185,11 +190,12 @@ SECTIONS {
 	KEEP(*(.zinfo))
 	KEEP(*(.zinfo.*))
 	_mzinfo = .;
-    } .bss.zinfo (NOLOAD) : AT ( _end_lma ) {
+    } .bss.zinfo (NOLOAD) : AT ( _bss_zinfo_lma ) {
 	_ezinfo = .;
     }
     _zinfo_filesz	= ABSOLUTE ( _mzinfo ) - ABSOLUTE ( _zinfo );
     _zinfo_memsz	= ABSOLUTE ( _ezinfo ) - ABSOLUTE ( _zinfo );
+    _zinfo_padsz	= ABSOLUTE ( _ezinfo ) - ABSOLUTE ( _mzinfo );
 
     /*
      * Weak symbols that need zero values if not otherwise defined
@@ -235,36 +241,65 @@ SECTIONS {
 
     .			= ALIGN ( _max_align );
     _prefix_lma		= .;
-    .			+= _prefix_filesz;
+    .			+= ABSOLUTE ( _prefix_filesz );
 
     .			= ALIGN ( _max_align );
     _text16_early_lma	= .;
-    .			+= _text16_early_filesz;
+    .			+= ABSOLUTE ( _text16_early_filesz );
 
     .			= ALIGN ( _max_align );
     .			= ALIGN ( _payload_align );
     _pprefix_lma	= .;
-    .			+= _pprefix_filesz;
+    .			+= ABSOLUTE ( _pprefix_filesz );
 
     .			= ALIGN ( _max_align );
     _payload_lma	= .;
     _pprefix_skip	= ABSOLUTE ( _payload_lma ) - ABSOLUTE ( _pprefix_lma );
     _text16_late_lma	= .;
-    .			+= _text16_late_filesz;
+    .			+= ABSOLUTE ( _text16_late_filesz );
 
     .			= ALIGN ( _max_align );
     _data16_lma		= .;
-    .			+= _data16_filesz;
+    .			+= ABSOLUTE ( _data16_filesz );
 
     .			= ALIGN ( _max_align );
     _textdata_lma	= .;
-    .			+= _textdata_filesz;
+    .			+= ABSOLUTE ( _textdata_filesz );
 
-    _filesz		= .; /* Do not include zinfo block in file size */
+    _filesz		= .; /* Do not include .bss.* or .zinfo in file size */
+
+    /*
+     * Dummy load addresses for .bss.* and .zinfo sections
+     *
+     */
+
+    .			= ALIGN ( _max_align );
+    _bss_prefix_lma	= .;
+    .			+= ABSOLUTE ( _prefix_padsz );
+
+    .			= ALIGN ( _max_align );
+    _bss_text16_lma	= .;
+    .			+= ABSOLUTE ( _text16_padsz );
+
+    .			= ALIGN ( _max_align );
+    _bss_data16_lma	= .;
+    .			+= ABSOLUTE ( _data16_padsz );
+
+    .			= ALIGN ( _max_align );
+    _bss_textdata_lma	= .;
+    .			+= ABSOLUTE ( _textdata_padsz );
+
+    .			= ALIGN ( _max_align );
+    _bss_pprefix_lma	= .;
+    .			+= ABSOLUTE ( _pprefix_padsz );
+
+    .			= ALIGN ( _max_align );
+    _bss_zinfo_lma	= .;
+    .			+= ABSOLUTE ( _zinfo_padsz );
 
     .			= ALIGN ( _max_align );
     _zinfo_lma		= .;
-    .			+= _zinfo_filesz;
+    .			+= ABSOLUTE ( _zinfo_filesz );
 
     .			= ALIGN ( _max_align );
     _end_lma		= .;
diff -pruN 1.0.0+git-20190125.36a4c85-5.1/src/arch/x86/scripts/prefixonly.lds 1.21.1+git-20220113.fbbdc3926-0ubuntu1/src/arch/x86/scripts/prefixonly.lds
--- 1.0.0+git-20190125.36a4c85-5.1/src/arch/x86/scripts/prefixonly.lds	1970-01-01 00:00:00.000000000 +0000
+++ 1.21.1+git-20220113.fbbdc3926-0ubuntu1/src/arch/x86/scripts/prefixonly.lds	2022-01-13 13:43:08.000000000 +0000
@@ -0,0 +1,29 @@
+/* -*- ld-script -*- */
+
+/*
+ * Linker script for prefix-only binaries (e.g. USB disk MBR)
+ *
+ */
+
+SECTIONS {
+
+    .prefix 0x0 : AT ( 0x0 ) {
+	*(.prefix)
+    }
+
+    /DISCARD/ : {
+	*(.comment)
+	*(.comment.*)
+	*(.note)
+	*(.note.*)
+	*(.eh_frame)
+	*(.eh_frame.*)
+	*(.rel)
+	*(.rel.*)
+	*(.einfo)
+	*(.einfo.*)
+	*(.discard)
+	*(.discard.*)
+    }
+
+}
diff -pruN 1.0.0+git-20190125.36a4c85-5.1/src/arch/x86/transitions/liba20.S 1.21.1+git-20220113.fbbdc3926-0ubuntu1/src/arch/x86/transitions/liba20.S
--- 1.0.0+git-20190125.36a4c85-5.1/src/arch/x86/transitions/liba20.S	2019-02-09 16:03:59.000000000 +0000
+++ 1.21.1+git-20220113.fbbdc3926-0ubuntu1/src/arch/x86/transitions/liba20.S	2022-01-13 13:43:08.000000000 +0000
@@ -285,7 +285,7 @@ enable_a20:
 	ret
 
 	.section ".text16.early.data", "aw", @progbits
-	.align	2
+	.balign	2
 enable_a20_method:
 	.word	0
 	.size	enable_a20_method, . - enable_a20_method
diff -pruN 1.0.0+git-20190125.36a4c85-5.1/src/arch/x86/transitions/librm_mgmt.c 1.21.1+git-20220113.fbbdc3926-0ubuntu1/src/arch/x86/transitions/librm_mgmt.c
--- 1.0.0+git-20190125.36a4c85-5.1/src/arch/x86/transitions/librm_mgmt.c	2019-02-09 16:03:59.000000000 +0000
+++ 1.21.1+git-20220113.fbbdc3926-0ubuntu1/src/arch/x86/transitions/librm_mgmt.c	2022-01-13 13:43:08.000000000 +0000
@@ -14,6 +14,7 @@ FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
 #include <realmode.h>
 #include <pic8259.h>
 #include <ipxe/shell.h>
+#include <ipxe/cpuid.h>
 
 /*
  * This file provides functions for managing librm.
@@ -118,7 +119,7 @@ void set_interrupt_vector ( unsigned int
  * Initialise interrupt descriptor table
  *
  */
-void init_idt ( void ) {
+__asmcall void init_idt ( void ) {
 	struct interrupt_vector *vec;
 	unsigned int intr;
 
@@ -386,6 +387,21 @@ static void iounmap_pages ( volatile con
 	       io_addr, first, i );
 }
 
+/**
+ * Check for FXSAVE/FXRSTOR instruction support
+ *
+ */
+__asmcall void check_fxsr ( struct i386_all_regs *regs ) {
+	struct x86_features features;
+
+	/* Check for FXSR bit */
+	x86_features ( &features );
+	if ( ! ( features.intel.edx & CPUID_FEATURES_INTEL_EDX_FXSR ) )
+		regs->flags |= CF;
+	DBGC ( &features, "FXSAVE/FXRSTOR is%s supported\n",
+	       ( ( regs->flags & CF ) ? " not" : "" ) );
+}
+
 PROVIDE_UACCESS_INLINE ( librm, phys_to_user );
 PROVIDE_UACCESS_INLINE ( librm, user_to_phys );
 PROVIDE_UACCESS_INLINE ( librm, virt_to_user );
diff -pruN 1.0.0+git-20190125.36a4c85-5.1/src/arch/x86/transitions/librm.S 1.21.1+git-20220113.fbbdc3926-0ubuntu1/src/arch/x86/transitions/librm.S
--- 1.0.0+git-20190125.36a4c85-5.1/src/arch/x86/transitions/librm.S	2019-02-09 16:03:59.000000000 +0000
+++ 1.21.1+git-20220113.fbbdc3926-0ubuntu1/src/arch/x86/transitions/librm.S	2022-01-13 13:43:08.000000000 +0000
@@ -99,7 +99,7 @@ FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL )
  ****************************************************************************
  */
 	.section ".data16.gdt", "aw", @progbits
-	.align 16
+	.balign 16
 gdt:
 gdtr:		/* The first GDT entry is unused, the GDTR can fit here. */
 gdt_limit:		.word gdt_length - 1
@@ -210,9 +210,7 @@ VC_TMP_CR3:		.space	4
 VC_TMP_CR4:		.space	4
 VC_TMP_EMER:		.space	8
 .endif
-#ifdef TIVOLI_VMM_WORKAROUND
 VC_TMP_FXSAVE:		.space	512
-#endif
 VC_TMP_END:
 	.previous
 
@@ -224,7 +222,7 @@ RC_TMP_END:
 
 	/* Shared temporary static buffer */
 	.section ".bss16.rm_tmpbuf", "aw", @nobits
-	.align 16
+	.balign 16
 rm_tmpbuf:
 	.space	VC_TMP_END
 	.size	rm_tmpbuf, . - rm_tmpbuf
@@ -350,6 +348,13 @@ init_librm_rmode:
 	/* Initialise IDT */
 	virtcall init_idt
 
+#ifdef TIVOLI_VMM_WORKAROUND
+	/* Check for FXSAVE/FXRSTOR */
+	clc
+	virtcall check_fxsr
+	setnc	fxsr_supported
+#endif
+
 	/* Restore registers */
 	popl	%edi
 	popl	%ebx
@@ -366,6 +371,10 @@ set_seg_base:
 	roll	$16, %eax
 	ret
 
+	.section ".data16.fxsr_supported", "awx", @progbits
+fxsr_supported:		/* FXSAVE/FXRSTOR instructions supported */
+	.byte	0
+
 /****************************************************************************
  * real_to_prot (real-mode near call, 32-bit virtual return address)
  *
@@ -1007,10 +1016,11 @@ virt_call:
 	cli
 	movw	%cs:rm_ds, %ds
 
-#ifdef TIVOLI_VMM_WORKAROUND
 	/* Preserve FPU, MMX and SSE state in temporary static buffer */
+	testb	$0xff, fxsr_supported
+	jz	1f
 	fxsave	( rm_tmpbuf + VC_TMP_FXSAVE )
-#endif
+1:
 	/* Preserve GDT and IDT in temporary static buffer */
 	sidt	( rm_tmpbuf + VC_TMP_IDT )
 	sgdt	( rm_tmpbuf + VC_TMP_GDT )
@@ -1077,10 +1087,11 @@ vc_rmode:
 	wrmsr
 .endif
 
-#ifdef TIVOLI_VMM_WORKAROUND
 	/* Restore FPU, MMX and SSE state from temporary static buffer */
+	testb	$0xff, fxsr_supported
+	jz	1f
 	fxrstor	( rm_tmpbuf + VC_TMP_FXSAVE )
-#endif
+1:
 	/* Restore registers and flags and return */
 	popl	%eax /* skip %cs and %ss */
 	popw	%ds
@@ -1470,7 +1481,7 @@ interrupt_wrapper:
  ****************************************************************************
  */
 	.section ".pages", "aw", @nobits
-	.align	SIZEOF_PT
+	.balign	SIZEOF_PT
 
 	/* Page map level 4 entries (PML4Es)
 	 *
diff -pruN 1.0.0+git-20190125.36a4c85-5.1/src/arch/x86/transitions/librm_test.c 1.21.1+git-20220113.fbbdc3926-0ubuntu1/src/arch/x86/transitions/librm_test.c
--- 1.0.0+git-20190125.36a4c85-5.1/src/arch/x86/transitions/librm_test.c	2019-02-09 16:03:59.000000000 +0000
+++ 1.21.1+git-20220113.fbbdc3926-0ubuntu1/src/arch/x86/transitions/librm_test.c	2022-01-13 13:43:08.000000000 +0000
@@ -58,7 +58,8 @@ static struct profiler virt_call_profile
 /**
  * Dummy function for profiling tests
  */
-static __asmcall void librm_test_call ( struct i386_all_regs *ix86 __unused ) {
+static __asmcall __used void
+librm_test_call ( struct i386_all_regs *ix86 __unused ) {
 	/* Do nothing */
 }
 
diff -pruN 1.0.0+git-20190125.36a4c85-5.1/src/arch/x86_64/core/linux/linuxprefix.S 1.21.1+git-20220113.fbbdc3926-0ubuntu1/src/arch/x86_64/core/linux/linuxprefix.S
--- 1.0.0+git-20190125.36a4c85-5.1/src/arch/x86_64/core/linux/linuxprefix.S	2019-02-09 16:03:59.000000000 +0000
+++ 1.21.1+git-20220113.fbbdc3926-0ubuntu1/src/arch/x86_64/core/linux/linuxprefix.S	1970-01-01 00:00:00.000000000 +0000
@@ -1,25 +0,0 @@
-#include <linux/unistd.h>
-
-	.section ".text"
-	.code64
-	.globl _linux_start
-	.type _linux_start, @function
-
-_linux_start:
-	xorq	%rbp, %rbp
-
-	popq	%rdi       // argc -> C arg1
-	movq	%rsp, %rsi // argv -> C arg2
-
-	andq	$~15, %rsp // 16-byte align the stack
-
-	call	save_args
-
-	/* Our main doesn't use any arguments */
-	call	main
-
-	movq	%rax, %rdi // rc -> syscall arg1
-	movq	$__NR_exit, %rax
-	syscall
-
-	.size _linux_start, . - _linux_start
diff -pruN 1.0.0+git-20190125.36a4c85-5.1/src/arch/x86_64/core/linux/linux_syscall.S 1.21.1+git-20220113.fbbdc3926-0ubuntu1/src/arch/x86_64/core/linux/linux_syscall.S
--- 1.0.0+git-20190125.36a4c85-5.1/src/arch/x86_64/core/linux/linux_syscall.S	2019-02-09 16:03:59.000000000 +0000
+++ 1.21.1+git-20220113.fbbdc3926-0ubuntu1/src/arch/x86_64/core/linux/linux_syscall.S	1970-01-01 00:00:00.000000000 +0000
@@ -1,33 +0,0 @@
-
-	.section ".data"
-	.globl linux_errno
-
-linux_errno:	.int 0
-
-	.section ".text"
-	.code64
-	.globl linux_syscall
-	.type  linux_syscall, @function
-
-linux_syscall:
-	movq	%rdi, %rax    // C arg1 -> syscall number
-	movq	%rsi, %rdi    // C arg2 -> syscall arg1
-	movq	%rdx, %rsi    // C arg3 -> syscall arg2
-	movq	%rcx, %rdx    // C arg4 -> syscall arg3
-	movq	%r8, %r10     // C arg5 -> syscall arg4
-	movq	%r9, %r8      // C arg6 -> syscall arg5
-	movq	8(%rsp), %r9  // C arg7 -> syscall arg6
-
-	syscall
-
-	cmpq	$-4095, %rax
-	jae	1f
-	ret
-
-1:
-	negq	%rax
-	movl	%eax, linux_errno
-	movq	$-1, %rax
-	ret
-
-	.size linux_syscall, . - linux_syscall
diff -pruN 1.0.0+git-20190125.36a4c85-5.1/src/arch/x86_64/include/bits/compiler.h 1.21.1+git-20220113.fbbdc3926-0ubuntu1/src/arch/x86_64/include/bits/compiler.h
--- 1.0.0+git-20190125.36a4c85-5.1/src/arch/x86_64/include/bits/compiler.h	2019-02-09 16:03:59.000000000 +0000
+++ 1.21.1+git-20220113.fbbdc3926-0ubuntu1/src/arch/x86_64/include/bits/compiler.h	2022-01-13 13:43:08.000000000 +0000
@@ -9,7 +9,7 @@ FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
 #ifndef ASSEMBLY
 
 /** Declare a function with standard calling conventions */
-#define __asmcall __attribute__ (( used, regparm(0) ))
+#define __asmcall __attribute__ (( regparm(0) ))
 
 /** Declare a function with libgcc implicit linkage */
 #define __libgcc
diff -pruN 1.0.0+git-20190125.36a4c85-5.1/src/arch/x86_64/include/bits/linux_api.h 1.21.1+git-20220113.fbbdc3926-0ubuntu1/src/arch/x86_64/include/bits/linux_api.h
--- 1.0.0+git-20190125.36a4c85-5.1/src/arch/x86_64/include/bits/linux_api.h	2019-02-09 16:03:59.000000000 +0000
+++ 1.21.1+git-20220113.fbbdc3926-0ubuntu1/src/arch/x86_64/include/bits/linux_api.h	1970-01-01 00:00:00.000000000 +0000
@@ -1,6 +0,0 @@
-#ifndef _X86_64_LINUX_API_H
-#define _X86_64_LINUX_API_H
-
-#define __SYSCALL_mmap __NR_mmap
-
-#endif /* _X86_64_LINUX_API_H */
diff -pruN 1.0.0+git-20190125.36a4c85-5.1/src/arch/x86_64/Makefile.linux 1.21.1+git-20220113.fbbdc3926-0ubuntu1/src/arch/x86_64/Makefile.linux
--- 1.0.0+git-20190125.36a4c85-5.1/src/arch/x86_64/Makefile.linux	2019-02-09 16:03:59.000000000 +0000
+++ 1.21.1+git-20220113.fbbdc3926-0ubuntu1/src/arch/x86_64/Makefile.linux	2022-01-13 13:43:08.000000000 +0000
@@ -1,6 +1,10 @@
-LDSCRIPT = arch/x86_64/scripts/linux.lds
+# -*- makefile -*- : Force emacs to use Makefile mode
 
-SRCDIRS += arch/x86_64/core/linux
+# Linker script
+#
+LDSCRIPT = arch/x86_64/scripts/linux.lds
 
+# Include generic Linux Makefile
+#
 MAKEDEPS += arch/x86/Makefile.linux
 include arch/x86/Makefile.linux
diff -pruN 1.0.0+git-20190125.36a4c85-5.1/src/config/branding.h 1.21.1+git-20220113.fbbdc3926-0ubuntu1/src/config/branding.h
--- 1.0.0+git-20190125.36a4c85-5.1/src/config/branding.h	2019-02-09 16:03:59.000000000 +0000
+++ 1.21.1+git-20220113.fbbdc3926-0ubuntu1/src/config/branding.h	2022-01-13 13:43:08.000000000 +0000
@@ -26,7 +26,7 @@ FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
  */
 #define PRODUCT_NAME ""
 #define PRODUCT_SHORT_NAME "iPXE"
-#define PRODUCT_URI "http://ipxe.org"
+#define PRODUCT_URI "https://ipxe.org"
 
 /*
  * Tag line
@@ -44,15 +44,15 @@ FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
  * (e.g. "Permission denied") and a 32-bit error number.  This number
  * is incorporated into an error URI such as
  *
- *   "No such file or directory (http://ipxe.org/2d0c613b)"
+ *   "No such file or directory (https://ipxe.org/2d0c613b)"
  *
  * or
  *
- *   "Operation not supported (http://ipxe.org/3c092003)"
+ *   "Operation not supported (https://ipxe.org/3c092003)"
  *
  * Users may browse to the URI within the error message, which is
  * provided by a database running on the iPXE web site
- * (http://ipxe.org).  This database provides details for all possible
+ * (https://ipxe.org).  This database provides details for all possible
  * errors generated by iPXE, including:
  *
  * - the detailed error message (e.g. "Not an OCSP signing
@@ -74,13 +74,13 @@ FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
  *
  * If you have a customer support team and would like your customers
  * to contact your support team for all problems, instead of using the
- * existing support infrastructure provided by http://ipxe.org, then
+ * existing support infrastructure provided by https://ipxe.org, then
  * you may define a custom URI to be included within error messages.
  *
  * Note that the custom URI is a printf() format string which must
  * include a format specifier for the 32-bit error number.
  */
-#define PRODUCT_ERROR_URI "http://ipxe.org/%08x"
+#define PRODUCT_ERROR_URI "https://ipxe.org/%08x"
 
 /*
  * Command help messages
@@ -88,7 +88,7 @@ FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
  * iPXE command help messages include a URI constructed from the
  * command name, such as
  *
- *   "See http://ipxe.org/cmd/vcreate for further information"
+ *   "See https://ipxe.org/cmd/vcreate for further information"
  *
  * The iPXE web site includes documentation for the commands provided
  * by the iPXE shell, including:
@@ -113,7 +113,7 @@ FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
  *
  * If you want to provide your own documentation for all of the
  * commands provided by the iPXE shell, rather than using the existing
- * support infrastructure provided by http://ipxe.org, then you may
+ * support infrastructure provided by https://ipxe.org, then you may
  * define a custom URI to be included within command help messages.
  *
  * Note that the custom URI is a printf() format string which must
@@ -124,7 +124,7 @@ FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
  *   iPXE project and prohibit the alteration or removal of any
  *   references to "iPXE". ]
  */
-#define PRODUCT_COMMAND_URI "http://ipxe.org/cmd/%s"
+#define PRODUCT_COMMAND_URI "https://ipxe.org/cmd/%s"
 
 /*
  * Setting help messages
@@ -132,7 +132,7 @@ FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
  * iPXE setting help messages include a URI constructed from the
  * setting name, such as
  *
- *   "http://ipxe.org/cfg/initiator-iqn"
+ *   "https://ipxe.org/cfg/initiator-iqn"
  *
  * The iPXE web site includes documentation for the settings used by
  * iPXE, including:
@@ -156,7 +156,7 @@ FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
  *
  * If you want to provide your own documentation for all of the
  * settings used by iPXE, rather than using the existing support
- * infrastructure provided by http://ipxe.org, then you may define a
+ * infrastructure provided by https://ipxe.org, then you may define a
  * custom URI to be included within setting help messages.
  *
  * Note that the custom URI is a printf() format string which must
@@ -167,7 +167,7 @@ FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
  *   iPXE project and prohibit the alteration or removal of any
  *   references to "iPXE". ]
  */
-#define PRODUCT_SETTING_URI "http://ipxe.org/cfg/%s"
+#define PRODUCT_SETTING_URI "https://ipxe.org/cfg/%s"
 
 #include <config/local/branding.h>
 
diff -pruN 1.0.0+git-20190125.36a4c85-5.1/src/config/cloud/aws.ipxe 1.21.1+git-20220113.fbbdc3926-0ubuntu1/src/config/cloud/aws.ipxe
--- 1.0.0+git-20190125.36a4c85-5.1/src/config/cloud/aws.ipxe	2019-02-09 16:03:59.000000000 +0000
+++ 1.21.1+git-20220113.fbbdc3926-0ubuntu1/src/config/cloud/aws.ipxe	2022-01-13 13:43:08.000000000 +0000
@@ -3,6 +3,22 @@
 echo Amazon EC2 - iPXE boot via user-data
 echo CPU: ${cpuvendor} ${cpumodel}
 ifstat ||
-dhcp ||
+
+set attempt:int8 1
+:dhcp_retry
+echo DHCP attempt ${attempt}
+dhcp --timeout 5000 && goto dhcp_ok ||
+ifstat ||
+inc attempt
+iseq ${attempt} 10 || goto dhcp_retry
+
+:dhcp_fail
+echo DHCP failed - rebooting
+reboot ||
+exit
+
+:dhcp_ok
 route ||
-chain -ar http://169.254.169.254/latest/user-data
+chain -ar http://169.254.169.254/latest/user-data ||
+ifstat ||
+exit
diff -pruN 1.0.0+git-20190125.36a4c85-5.1/src/config/cloud/console.h 1.21.1+git-20220113.fbbdc3926-0ubuntu1/src/config/cloud/console.h
--- 1.0.0+git-20190125.36a4c85-5.1/src/config/cloud/console.h	2019-02-09 16:03:59.000000000 +0000
+++ 1.21.1+git-20220113.fbbdc3926-0ubuntu1/src/config/cloud/console.h	2022-01-13 13:43:08.000000000 +0000
@@ -18,8 +18,13 @@
  * Note that the serial port output from an AWS EC2 virtual machine is
  * generally available (as the "System Log") only after the instance
  * has been stopped.
+ *
+ * Enable only for non-EFI builds, on the assumption that the standard
+ * EFI firmware is likely to already be logging to the serial port.
  */
+#ifndef PLATFORM_efi
 #define CONSOLE_SERIAL
+#endif
 
 /* Log to partition on local disk
  *
diff -pruN 1.0.0+git-20190125.36a4c85-5.1/src/config/cloud/gce.ipxe 1.21.1+git-20220113.fbbdc3926-0ubuntu1/src/config/cloud/gce.ipxe
--- 1.0.0+git-20190125.36a4c85-5.1/src/config/cloud/gce.ipxe	2019-02-09 16:03:59.000000000 +0000
+++ 1.21.1+git-20220113.fbbdc3926-0ubuntu1/src/config/cloud/gce.ipxe	2022-01-13 13:43:08.000000000 +0000
@@ -5,4 +5,5 @@ echo CPU: ${cpuvendor} ${cpumodel}
 ifstat ||
 dhcp ||
 route ||
-chain -ar http://metadata.google.internal/computeMetadata/v1/instance/attributes/ipxeboot
+chain -ar http://metadata.google.internal/computeMetadata/v1/instance/attributes/ipxeboot ||
+ifstat ||
diff -pruN 1.0.0+git-20190125.36a4c85-5.1/src/config/cloud/general.h 1.21.1+git-20220113.fbbdc3926-0ubuntu1/src/config/cloud/general.h
--- 1.0.0+git-20190125.36a4c85-5.1/src/config/cloud/general.h	2019-02-09 16:03:59.000000000 +0000
+++ 1.21.1+git-20220113.fbbdc3926-0ubuntu1/src/config/cloud/general.h	2022-01-13 13:43:08.000000000 +0000
@@ -1,4 +1,13 @@
+/* Enable IPv6 and HTTPS */
+#define NET_PROTO_IPV6
+#define DOWNLOAD_PROTO_HTTPS
+
 /* Allow retrieval of metadata (such as an iPXE boot script) from
  * Google Compute Engine metadata server.
  */
 #define HTTP_HACK_GCE
+
+/* Allow scripts to handle errors by powering down the VM to avoid
+ * incurring unnecessary costs.
+ */
+#define POWEROFF_CMD
diff -pruN 1.0.0+git-20190125.36a4c85-5.1/src/config/cloud/ioapi.h 1.21.1+git-20220113.fbbdc3926-0ubuntu1/src/config/cloud/ioapi.h
--- 1.0.0+git-20190125.36a4c85-5.1/src/config/cloud/ioapi.h	1970-01-01 00:00:00.000000000 +0000
+++ 1.21.1+git-20220113.fbbdc3926-0ubuntu1/src/config/cloud/ioapi.h	2022-01-13 13:43:08.000000000 +0000
@@ -0,0 +1,7 @@
+/* Work around missing PCI BIOS calls in the cut-down SeaBIOS found in
+ * some AWS EC2 instances.
+ */
+#ifdef PLATFORM_pcbios
+#undef PCIAPI_PCBIOS
+#define PCIAPI_DIRECT
+#endif
diff -pruN 1.0.0+git-20190125.36a4c85-5.1/src/config/cloud/settings.h 1.21.1+git-20220113.fbbdc3926-0ubuntu1/src/config/cloud/settings.h
--- 1.0.0+git-20190125.36a4c85-5.1/src/config/cloud/settings.h	2019-02-09 16:03:59.000000000 +0000
+++ 1.21.1+git-20220113.fbbdc3926-0ubuntu1/src/config/cloud/settings.h	2022-01-13 13:43:08.000000000 +0000
@@ -1,4 +1,6 @@
 /* It can often be useful to know the CPU on which a cloud instance is
  * running (e.g. to isolate problems with Azure AMD instances).
  */
+#if defined ( __i386__ ) || defined ( __x86_64__ )
 #define CPUID_SETTINGS
+#endif
diff -pruN 1.0.0+git-20190125.36a4c85-5.1/src/config/config_archive.c 1.21.1+git-20220113.fbbdc3926-0ubuntu1/src/config/config_archive.c
--- 1.0.0+git-20190125.36a4c85-5.1/src/config/config_archive.c	1970-01-01 00:00:00.000000000 +0000
+++ 1.21.1+git-20220113.fbbdc3926-0ubuntu1/src/config/config_archive.c	2022-01-13 13:43:08.000000000 +0000
@@ -0,0 +1,36 @@
+/*
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of the
+ * License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+ * 02110-1301, USA.
+ *
+ * You can also choose to distribute this program under the terms of
+ * the Unmodified Binary Distribution Licence (as given in the file
+ * COPYING.UBDL), provided that you have satisfied its requirements.
+ */
+
+FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
+
+#include <config/general.h>
+
+/** @file
+ *
+ * Archive image configuration
+ *
+ */
+
+PROVIDE_REQUIRING_SYMBOL();
+
+#ifdef IMAGE_ARCHIVE_CMD
+REQUIRE_OBJECT ( image_archive_cmd );
+#endif
diff -pruN 1.0.0+git-20190125.36a4c85-5.1/src/config/config.c 1.21.1+git-20220113.fbbdc3926-0ubuntu1/src/config/config.c
--- 1.0.0+git-20190125.36a4c85-5.1/src/config/config.c	2019-02-09 16:03:59.000000000 +0000
+++ 1.21.1+git-20220113.fbbdc3926-0ubuntu1/src/config/config.c	2022-01-13 13:43:08.000000000 +0000
@@ -182,6 +182,12 @@ REQUIRE_OBJECT ( efi_image );
 #ifdef IMAGE_SDI
 REQUIRE_OBJECT ( sdi );
 #endif
+#ifdef IMAGE_ZLIB
+REQUIRE_OBJECT ( zlib );
+#endif
+#ifdef IMAGE_GZIP
+REQUIRE_OBJECT ( gzip );
+#endif
 
 /*
  * Drag in all requested commands
@@ -281,6 +287,9 @@ REQUIRE_OBJECT ( ntp_cmd );
 #ifdef CERT_CMD
 REQUIRE_OBJECT ( cert_cmd );
 #endif
+#ifdef IMAGE_MEM_CMD
+REQUIRE_OBJECT ( image_mem_cmd );
+#endif
 
 /*
  * Drag in miscellaneous objects
diff -pruN 1.0.0+git-20190125.36a4c85-5.1/src/config/config_crypto.c 1.21.1+git-20220113.fbbdc3926-0ubuntu1/src/config/config_crypto.c
--- 1.0.0+git-20190125.36a4c85-5.1/src/config/config_crypto.c	2019-02-09 16:03:59.000000000 +0000
+++ 1.21.1+git-20220113.fbbdc3926-0ubuntu1/src/config/config_crypto.c	2022-01-13 13:43:08.000000000 +0000
@@ -33,6 +33,56 @@ FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
 
 PROVIDE_REQUIRING_SYMBOL();
 
+/* RSA */
+#if defined ( CRYPTO_PUBKEY_RSA )
+REQUIRE_OBJECT ( oid_rsa );
+#endif
+
+/* MD4 */
+#if defined ( CRYPTO_DIGEST_MD4 )
+REQUIRE_OBJECT ( oid_md4 );
+#endif
+
+/* MD5 */
+#if defined ( CRYPTO_DIGEST_MD5 )
+REQUIRE_OBJECT ( oid_md5 );
+#endif
+
+/* SHA-1 */
+#if defined ( CRYPTO_DIGEST_SHA1 )
+REQUIRE_OBJECT ( oid_sha1 );
+#endif
+
+/* SHA-224 */
+#if defined ( CRYPTO_DIGEST_SHA224 )
+REQUIRE_OBJECT ( oid_sha224 );
+#endif
+
+/* SHA-256 */
+#if defined ( CRYPTO_DIGEST_SHA256 )
+REQUIRE_OBJECT ( oid_sha256 );
+#endif
+
+/* SHA-384 */
+#if defined ( CRYPTO_DIGEST_SHA384 )
+REQUIRE_OBJECT ( oid_sha384 );
+#endif
+
+/* SHA-512 */
+#if defined ( CRYPTO_DIGEST_SHA512 )
+REQUIRE_OBJECT ( oid_sha512 );
+#endif
+
+/* SHA-512/224 */
+#if defined ( CRYPTO_DIGEST_SHA512_224 )
+REQUIRE_OBJECT ( oid_sha512_224 );
+#endif
+
+/* SHA-512/256 */
+#if defined ( CRYPTO_DIGEST_SHA512_256 )
+REQUIRE_OBJECT ( oid_sha512_256 );
+#endif
+
 /* RSA and MD5 */
 #if defined ( CRYPTO_PUBKEY_RSA ) && defined ( CRYPTO_DIGEST_MD5 )
 REQUIRE_OBJECT ( rsa_md5 );
diff -pruN 1.0.0+git-20190125.36a4c85-5.1/src/config/config_ethernet.c 1.21.1+git-20220113.fbbdc3926-0ubuntu1/src/config/config_ethernet.c
--- 1.0.0+git-20190125.36a4c85-5.1/src/config/config_ethernet.c	2019-02-09 16:03:59.000000000 +0000
+++ 1.21.1+git-20220113.fbbdc3926-0ubuntu1/src/config/config_ethernet.c	2022-01-13 13:43:08.000000000 +0000
@@ -46,3 +46,6 @@ REQUIRE_OBJECT ( stp );
 #ifdef NET_PROTO_LACP
 REQUIRE_OBJECT ( eth_slow );
 #endif
+#ifdef NET_PROTO_EAPOL
+REQUIRE_OBJECT ( eapol );
+#endif
diff -pruN 1.0.0+git-20190125.36a4c85-5.1/src/config/config_fdt.c 1.21.1+git-20220113.fbbdc3926-0ubuntu1/src/config/config_fdt.c
--- 1.0.0+git-20190125.36a4c85-5.1/src/config/config_fdt.c	1970-01-01 00:00:00.000000000 +0000
+++ 1.21.1+git-20220113.fbbdc3926-0ubuntu1/src/config/config_fdt.c	2022-01-13 13:43:08.000000000 +0000
@@ -0,0 +1,41 @@
+/*
+ * Copyright (C) 2019 Michael Brown <mbrown@fensystems.co.uk>.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of the
+ * License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+ * 02110-1301, USA.
+ *
+ * You can also choose to distribute this program under the terms of
+ * the Unmodified Binary Distribution Licence (as given in the file
+ * COPYING.UBDL), provided that you have satisfied its requirements.
+ */
+
+FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
+
+#include <config/fdt.h>
+
+/** @file
+ *
+ * Flattened Device Tree configuration options
+ *
+ */
+
+PROVIDE_REQUIRING_SYMBOL();
+
+/*
+ * Drag in devicetree sources
+ */
+#ifdef FDT_EFI
+REQUIRE_OBJECT ( efi_fdt );
+#endif
diff -pruN 1.0.0+git-20190125.36a4c85-5.1/src/config/config_usb.c 1.21.1+git-20220113.fbbdc3926-0ubuntu1/src/config/config_usb.c
--- 1.0.0+git-20190125.36a4c85-5.1/src/config/config_usb.c	2019-02-09 16:03:59.000000000 +0000
+++ 1.21.1+git-20220113.fbbdc3926-0ubuntu1/src/config/config_usb.c	2022-01-13 13:43:08.000000000 +0000
@@ -53,6 +53,9 @@ REQUIRE_OBJECT ( usbio );
 #ifdef USB_KEYBOARD
 REQUIRE_OBJECT ( usbkbd );
 #endif
+#ifdef USB_BLOCK
+REQUIRE_OBJECT ( usbblk );
+#endif
 
 /*
  * Drag in USB external interfaces
diff -pruN 1.0.0+git-20190125.36a4c85-5.1/src/config/crypto.h 1.21.1+git-20220113.fbbdc3926-0ubuntu1/src/config/crypto.h
--- 1.0.0+git-20190125.36a4c85-5.1/src/config/crypto.h	2019-02-09 16:03:59.000000000 +0000
+++ 1.21.1+git-20220113.fbbdc3926-0ubuntu1/src/config/crypto.h	2022-01-13 13:43:08.000000000 +0000
@@ -9,31 +9,28 @@
 
 FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
 
+/** Minimum TLS version */
+#define TLS_VERSION_MIN TLS_VERSION_TLS_1_1
+
 /** RSA public-key algorithm */
 #define CRYPTO_PUBKEY_RSA
 
 /** AES-CBC block cipher */
 #define CRYPTO_CIPHER_AES_CBC
 
-/** MD5 digest algorithm
- *
- * Note that use of MD5 is implicit when using TLSv1.1 or earlier.
- */
-#define CRYPTO_DIGEST_MD5
+/** MD4 digest algorithm */
+//#define CRYPTO_DIGEST_MD4
 
-/** SHA-1 digest algorithm
- *
- * Note that use of SHA-1 is implicit when using TLSv1.1 or earlier.
- */
+/** MD5 digest algorithm */
+//#define CRYPTO_DIGEST_MD5
+
+/** SHA-1 digest algorithm */
 #define CRYPTO_DIGEST_SHA1
 
 /** SHA-224 digest algorithm */
 #define CRYPTO_DIGEST_SHA224
 
-/** SHA-256 digest algorithm
- *
- * Note that use of SHA-256 is implicit when using TLSv1.2.
- */
+/** SHA-256 digest algorithm */
 #define CRYPTO_DIGEST_SHA256
 
 /** SHA-384 digest algorithm */
@@ -42,6 +39,12 @@ FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
 /** SHA-512 digest algorithm */
 #define CRYPTO_DIGEST_SHA512
 
+/** SHA-512/224 digest algorithm */
+//#define CRYPTO_DIGEST_SHA512_224
+
+/** SHA-512/256 digest algorithm */
+//#define CRYPTO_DIGEST_SHA512_256
+
 /** Margin of error (in seconds) allowed in signed timestamps
  *
  * We default to allowing a reasonable margin of error: 12 hours to
diff -pruN 1.0.0+git-20190125.36a4c85-5.1/src/config/defaults/efi.h 1.21.1+git-20220113.fbbdc3926-0ubuntu1/src/config/defaults/efi.h
--- 1.0.0+git-20190125.36a4c85-5.1/src/config/defaults/efi.h	2019-02-09 16:03:59.000000000 +0000
+++ 1.21.1+git-20220113.fbbdc3926-0ubuntu1/src/config/defaults/efi.h	2022-01-13 13:43:08.000000000 +0000
@@ -12,6 +12,7 @@ FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
 #define UACCESS_EFI
 #define IOMAP_VIRT
 #define PCIAPI_EFI
+#define DMAAPI_OP
 #define CONSOLE_EFI
 #define TIMER_EFI
 #define UMALLOC_EFI
@@ -22,6 +23,9 @@ FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
 #define TIME_EFI
 #define REBOOT_EFI
 #define ACPI_EFI
+#define FDT_EFI
+
+#define	NET_PROTO_IPV6		/* IPv6 protocol */
 
 #define DOWNLOAD_PROTO_FILE	/* Local filesystem access */
 
@@ -38,6 +42,7 @@ FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
 #define	USB_HCD_EHCI		/* EHCI USB host controller */
 #define	USB_HCD_UHCI		/* UHCI USB host controller */
 #define	USB_EFI			/* Provide EFI_USB_IO_PROTOCOL interface */
+#define USB_BLOCK		/* USB block devices */
 
 #define	REBOOT_CMD		/* Reboot command */
 
@@ -45,6 +50,7 @@ FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
 #define IOAPI_X86
 #define NAP_EFIX86
 #define	CPUID_CMD		/* x86 CPU feature detection command */
+#define	UNSAFE_STD		/* Avoid setting direction flag */
 #endif
 
 #if defined ( __arm__ ) || defined ( __aarch64__ )
diff -pruN 1.0.0+git-20190125.36a4c85-5.1/src/config/defaults/linux.h 1.21.1+git-20220113.fbbdc3926-0ubuntu1/src/config/defaults/linux.h
--- 1.0.0+git-20190125.36a4c85-5.1/src/config/defaults/linux.h	2019-02-09 16:03:59.000000000 +0000
+++ 1.21.1+git-20220113.fbbdc3926-0ubuntu1/src/config/defaults/linux.h	2022-01-13 13:43:08.000000000 +0000
@@ -20,6 +20,8 @@ FILE_LICENCE ( GPL2_OR_LATER );
 #define TIME_LINUX
 #define REBOOT_NULL
 #define PCIAPI_LINUX
+#define DMAAPI_FLAT
+#define ACPI_LINUX
 
 #define DRIVERS_LINUX
 
diff -pruN 1.0.0+git-20190125.36a4c85-5.1/src/config/defaults/pcbios.h 1.21.1+git-20220113.fbbdc3926-0ubuntu1/src/config/defaults/pcbios.h
--- 1.0.0+git-20190125.36a4c85-5.1/src/config/defaults/pcbios.h	2019-02-09 16:03:59.000000000 +0000
+++ 1.21.1+git-20220113.fbbdc3926-0ubuntu1/src/config/defaults/pcbios.h	2022-01-13 13:43:08.000000000 +0000
@@ -12,6 +12,7 @@ FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
 #define UACCESS_LIBRM
 #define IOAPI_X86
 #define PCIAPI_PCBIOS
+#define DMAAPI_FLAT
 #define TIMER_PCBIOS
 #define CONSOLE_PCBIOS
 #define NAP_PCBIOS
@@ -48,6 +49,7 @@ FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
 #define	USB_HCD_EHCI		/* EHCI USB host controller */
 #define	USB_HCD_UHCI		/* UHCI USB host controller */
 #define	USB_KEYBOARD		/* USB keyboards */
+#define USB_BLOCK		/* USB block devices */
 
 #define	REBOOT_CMD		/* Reboot command */
 #define	CPUID_CMD		/* x86 CPU feature detection command */
diff -pruN 1.0.0+git-20190125.36a4c85-5.1/src/config/dhcp.h 1.21.1+git-20220113.fbbdc3926-0ubuntu1/src/config/dhcp.h
--- 1.0.0+git-20190125.36a4c85-5.1/src/config/dhcp.h	2019-02-09 16:03:59.000000000 +0000
+++ 1.21.1+git-20220113.fbbdc3926-0ubuntu1/src/config/dhcp.h	2022-01-13 13:43:08.000000000 +0000
@@ -28,7 +28,7 @@ FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
  * Maximum number of discovery deferrals due to blocked links
  * (e.g. from non-forwarding STP ports)
  */
-#define DHCP_DISC_MAX_DEFERRALS		60
+#define DHCP_DISC_MAX_DEFERRALS		180
 
 /*
  * ProxyDHCP offers are given precedence by continue to wait for them
diff -pruN 1.0.0+git-20190125.36a4c85-5.1/src/config/fdt.h 1.21.1+git-20220113.fbbdc3926-0ubuntu1/src/config/fdt.h
--- 1.0.0+git-20190125.36a4c85-5.1/src/config/fdt.h	1970-01-01 00:00:00.000000000 +0000
+++ 1.21.1+git-20220113.fbbdc3926-0ubuntu1/src/config/fdt.h	2022-01-13 13:43:08.000000000 +0000
@@ -0,0 +1,16 @@
+#ifndef CONFIG_FDT_H
+#define CONFIG_FDT_H
+
+/** @file
+ *
+ * Flattened Device Tree configuration
+ *
+ */
+
+FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
+
+#include <config/defaults.h>
+
+#include <config/local/fdt.h>
+
+#endif /* CONFIG_FDT_H */
diff -pruN 1.0.0+git-20190125.36a4c85-5.1/src/config/general.h 1.21.1+git-20220113.fbbdc3926-0ubuntu1/src/config/general.h
--- 1.0.0+git-20190125.36a4c85-5.1/src/config/general.h	2019-02-09 16:03:59.000000000 +0000
+++ 1.21.1+git-20220113.fbbdc3926-0ubuntu1/src/config/general.h	2022-01-13 13:43:08.000000000 +0000
@@ -35,10 +35,11 @@ FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
  */
 
 #define	NET_PROTO_IPV4		/* IPv4 protocol */
-#undef	NET_PROTO_IPV6		/* IPv6 protocol */
+//#define NET_PROTO_IPV6	/* IPv6 protocol */
 #undef	NET_PROTO_FCOE		/* Fibre Channel over Ethernet protocol */
 #define	NET_PROTO_STP		/* Spanning Tree protocol */
 #define	NET_PROTO_LACP		/* Link Aggregation control protocol */
+#define	NET_PROTO_EAPOL		/* EAP over LAN protocol */
 
 /*
  * PXE support
@@ -116,6 +117,8 @@ FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
 #define	IMAGE_PNG		/* PNG image support */
 #define	IMAGE_DER		/* DER image support */
 #define	IMAGE_PEM		/* PEM image support */
+//#define	IMAGE_ZLIB		/* ZLIB image support */
+//#define	IMAGE_GZIP		/* GZIP image support */
 
 /*
  * Command-line commands to include
@@ -154,6 +157,8 @@ FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
 //#define PROFSTAT_CMD		/* Profiling commands */
 //#define NTP_CMD		/* NTP commands */
 //#define CERT_CMD		/* Certificate management commands */
+//#define IMAGE_MEM_CMD		/* Read memory command */
+#define IMAGE_ARCHIVE_CMD	/* Archive image management commands */
 
 /*
  * ROM-specific options
diff -pruN 1.0.0+git-20190125.36a4c85-5.1/src/config/ioapi.h 1.21.1+git-20220113.fbbdc3926-0ubuntu1/src/config/ioapi.h
--- 1.0.0+git-20190125.36a4c85-5.1/src/config/ioapi.h	2019-02-09 16:03:59.000000000 +0000
+++ 1.21.1+git-20220113.fbbdc3926-0ubuntu1/src/config/ioapi.h	2022-01-13 13:43:08.000000000 +0000
@@ -14,6 +14,9 @@ FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
 //#undef	PCIAPI_PCBIOS		/* Access via PCI BIOS */
 //#define	PCIAPI_DIRECT		/* Direct access via Type 1 accesses */
 
+#include <config/named.h>
+#include NAMED_CONFIG(ioapi.h)
 #include <config/local/ioapi.h>
+#include LOCAL_NAMED_CONFIG(ioapi.h)
 
 #endif /* CONFIG_IOAPI_H */
diff -pruN 1.0.0+git-20190125.36a4c85-5.1/src/config/rpi/usb.h 1.21.1+git-20220113.fbbdc3926-0ubuntu1/src/config/rpi/usb.h
--- 1.0.0+git-20190125.36a4c85-5.1/src/config/rpi/usb.h	1970-01-01 00:00:00.000000000 +0000
+++ 1.21.1+git-20220113.fbbdc3926-0ubuntu1/src/config/rpi/usb.h	2022-01-13 13:43:08.000000000 +0000
@@ -0,0 +1,13 @@
+/*
+ * Use EFI_USB_IO_PROTOCOL
+ *
+ * The Raspberry Pi uses an embedded DesignWare USB controller for
+ * which we do not have a native driver.  Use via the
+ * EFI_USB_IO_PROTOCOL driver instead.
+ *
+ */
+#undef USB_HCD_XHCI
+#undef USB_HCD_EHCI
+#undef USB_HCD_UHCI
+#define USB_HCD_USBIO
+#undef USB_EFI
diff -pruN 1.0.0+git-20190125.36a4c85-5.1/src/config/usb.h 1.21.1+git-20220113.fbbdc3926-0ubuntu1/src/config/usb.h
--- 1.0.0+git-20190125.36a4c85-5.1/src/config/usb.h	2019-02-09 16:03:59.000000000 +0000
+++ 1.21.1+git-20220113.fbbdc3926-0ubuntu1/src/config/usb.h	2022-01-13 13:43:08.000000000 +0000
@@ -25,6 +25,7 @@ FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
  *
  */
 //#undef	USB_KEYBOARD	/* USB keyboards */
+//#undef	USB_BLOCK	/* USB block devices */
 
 /*
  * USB external interfaces
diff -pruN 1.0.0+git-20190125.36a4c85-5.1/src/core/acpi.c 1.21.1+git-20220113.fbbdc3926-0ubuntu1/src/core/acpi.c
--- 1.0.0+git-20190125.36a4c85-5.1/src/core/acpi.c	2019-02-09 16:03:59.000000000 +0000
+++ 1.21.1+git-20220113.fbbdc3926-0ubuntu1/src/core/acpi.c	2022-01-13 13:43:08.000000000 +0000
@@ -35,6 +35,9 @@ FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
  *
  */
 
+/** Colour for debug messages */
+#define colour FADT_SIGNATURE
+
 /******************************************************************************
  *
  * Utility functions
@@ -80,13 +83,13 @@ void acpi_fix_checksum ( struct acpi_hea
 }
 
 /**
- * Locate ACPI table
+ * Locate ACPI table via RSDT
  *
  * @v signature		Requested table signature
  * @v index		Requested index of table with this signature
  * @ret table		Table, or UNULL if not found
  */
-userptr_t acpi_find ( uint32_t signature, unsigned int index ) {
+userptr_t acpi_find_via_rsdt ( uint32_t signature, unsigned int index ) {
 	struct acpi_header acpi;
 	struct acpi_rsdt *rsdtab;
 	typeof ( rsdtab->entry[0] ) entry;
@@ -106,17 +109,17 @@ userptr_t acpi_find ( uint32_t signature
 	/* Read RSDT header */
 	copy_from_user ( &acpi, rsdt, 0, sizeof ( acpi ) );
 	if ( acpi.signature != cpu_to_le32 ( RSDT_SIGNATURE ) ) {
-		DBGC ( rsdt, "RSDT %#08lx has invalid signature:\n",
+		DBGC ( colour, "RSDT %#08lx has invalid signature:\n",
 		       user_to_phys ( rsdt, 0 ) );
-		DBGC_HDA ( rsdt, user_to_phys ( rsdt, 0 ), &acpi,
+		DBGC_HDA ( colour, user_to_phys ( rsdt, 0 ), &acpi,
 			   sizeof ( acpi ) );
 		return UNULL;
 	}
 	len = le32_to_cpu ( acpi.length );
 	if ( len < sizeof ( rsdtab->acpi ) ) {
-		DBGC ( rsdt, "RSDT %#08lx has invalid length:\n",
+		DBGC ( colour, "RSDT %#08lx has invalid length:\n",
 		       user_to_phys ( rsdt, 0 ) );
-		DBGC_HDA ( rsdt, user_to_phys ( rsdt, 0 ), &acpi,
+		DBGC_HDA ( colour, user_to_phys ( rsdt, 0 ), &acpi,
 			   sizeof ( acpi ) );
 		return UNULL;
 	}
@@ -147,52 +150,41 @@ userptr_t acpi_find ( uint32_t signature
 
 		/* Check table integrity */
 		if ( acpi_checksum ( table ) != 0 ) {
-			DBGC ( rsdt, "RSDT %#08lx found %s with bad checksum "
-			       "at %08lx\n", user_to_phys ( rsdt, 0 ),
+			DBGC ( colour, "RSDT %#08lx found %s with bad "
+			       "checksum at %08lx\n", user_to_phys ( rsdt, 0 ),
 			       acpi_name ( signature ),
 			       user_to_phys ( table, 0 ) );
 			break;
 		}
 
-		DBGC ( rsdt, "RSDT %#08lx found %s at %08lx\n",
+		DBGC ( colour, "RSDT %#08lx found %s at %08lx\n",
 		       user_to_phys ( rsdt, 0 ), acpi_name ( signature ),
 		       user_to_phys ( table, 0 ) );
 		return table;
 	}
 
-	DBGC ( rsdt, "RSDT %#08lx could not find %s\n",
+	DBGC ( colour, "RSDT %#08lx could not find %s\n",
 	       user_to_phys ( rsdt, 0 ), acpi_name ( signature ) );
 	return UNULL;
 }
 
 /**
- * Extract \_Sx value from DSDT/SSDT
+ * Extract value from DSDT/SSDT
  *
  * @v zsdt		DSDT or SSDT
  * @v signature		Signature (e.g. "_S5_")
- * @ret sx		\_Sx value, or negative error
- *
- * In theory, extracting the \_Sx value from the DSDT/SSDT requires a
- * full ACPI parser plus some heuristics to work around the various
- * broken encodings encountered in real ACPI implementations.
- *
- * In practice, we can get the same result by scanning through the
- * DSDT/SSDT for the signature (e.g. "_S5_"), extracting the first
- * four bytes, removing any bytes with bit 3 set, and treating
- * whatever is left as a little-endian value.  This is one of the
- * uglier hacks I have ever implemented, but it's still prettier than
- * the ACPI specification itself.
- */
-static int acpi_sx_zsdt ( userptr_t zsdt, uint32_t signature ) {
+ * @v data		Data buffer
+ * @v extract		Extraction method
+ * @ret rc		Return status code
+ */
+static int acpi_zsdt ( userptr_t zsdt, uint32_t signature, void *data,
+		       int ( * extract ) ( userptr_t zsdt, size_t len,
+					   size_t offset, void *data ) ) {
 	struct acpi_header acpi;
-	union {
-		uint32_t dword;
-		uint8_t byte[4];
-	} buf;
+	uint32_t buf;
 	size_t offset;
 	size_t len;
-	unsigned int sx;
-	uint8_t *byte;
+	int rc;
 
 	/* Read table header */
 	copy_from_user ( &acpi, zsdt, 0, sizeof ( acpi ) );
@@ -200,83 +192,51 @@ static int acpi_sx_zsdt ( userptr_t zsdt
 
 	/* Locate signature */
 	for ( offset = sizeof ( acpi ) ;
-	      ( ( offset + sizeof ( buf ) /* signature */ + 3 /* pkg header */
-		  + sizeof ( buf ) /* value */ ) < len ) ;
+	      ( ( offset + sizeof ( buf ) /* signature */ ) < len ) ;
 	      offset++ ) {
 
 		/* Check signature */
 		copy_from_user ( &buf, zsdt, offset, sizeof ( buf ) );
-		if ( buf.dword != cpu_to_le32 ( signature ) )
+		if ( buf != cpu_to_le32 ( signature ) )
 			continue;
 		DBGC ( zsdt, "DSDT/SSDT %#08lx found %s at offset %#zx\n",
 		       user_to_phys ( zsdt, 0 ), acpi_name ( signature ),
 		       offset );
-		offset += sizeof ( buf );
 
-		/* Read first four bytes of value */
-		copy_from_user ( &buf, zsdt, ( offset + 3 /* pkg header */ ),
-				 sizeof ( buf ) );
-		DBGC ( zsdt, "DSDT/SSDT %#08lx found %s containing "
-		       "%02x:%02x:%02x:%02x\n", user_to_phys ( zsdt, 0 ),
-		       acpi_name ( signature ), buf.byte[0], buf.byte[1],
-		       buf.byte[2], buf.byte[3] );
-
-		/* Extract \Sx value.  There are three potential
-		 * encodings that we might encounter:
-		 *
-		 * - SLP_TYPa, SLP_TYPb, rsvd, rsvd
-		 *
-		 * - <byteprefix>, SLP_TYPa, <byteprefix>, SLP_TYPb, ...
-		 *
-		 * - <dwordprefix>, SLP_TYPa, SLP_TYPb, 0, 0
-		 *
-		 * Since <byteprefix> and <dwordprefix> both have bit
-		 * 3 set, and valid SLP_TYPx must have bit 3 clear
-		 * (since SLP_TYPx is a 3-bit field), we can just skip
-		 * any bytes with bit 3 set.
-		 */
-		byte = &buf.byte[0];
-		if ( *byte & 0x08 )
-			byte++;
-		sx = *(byte++);
-		if ( *byte & 0x08 )
-			byte++;
-		sx |= ( *byte << 8 );
-		return sx;
+		/* Attempt to extract data */
+		if ( ( rc = extract ( zsdt, len, offset, data ) ) == 0 )
+			return 0;
 	}
 
 	return -ENOENT;
 }
 
 /**
- * Extract \_Sx value from DSDT/SSDT
+ * Extract value from DSDT/SSDT
  *
  * @v signature		Signature (e.g. "_S5_")
- * @ret sx		\_Sx value, or negative error
- */
-int acpi_sx ( uint32_t signature ) {
+ * @v data		Data buffer
+ * @v extract		Extraction method
+ * @ret rc		Return status code
+ */
+int acpi_extract ( uint32_t signature, void *data,
+		   int ( * extract ) ( userptr_t zsdt, size_t len,
+				       size_t offset, void *data ) ) {
 	struct acpi_fadt fadtab;
-	userptr_t rsdt;
 	userptr_t fadt;
 	userptr_t dsdt;
 	userptr_t ssdt;
 	unsigned int i;
-	int sx;
-
-	/* Locate RSDT */
-	rsdt = acpi_find_rsdt();
-	if ( ! rsdt ) {
-		DBG ( "RSDT not found\n" );
-		return -ENOENT;
-	}
+	int rc;
 
 	/* Try DSDT first */
 	fadt = acpi_find ( FADT_SIGNATURE, 0 );
 	if ( fadt ) {
 		copy_from_user ( &fadtab, fadt, 0, sizeof ( fadtab ) );
 		dsdt = phys_to_user ( fadtab.dsdt );
-		if ( ( sx = acpi_sx_zsdt ( dsdt, signature ) ) >= 0 )
-			return sx;
+		if ( ( rc = acpi_zsdt ( dsdt, signature, data,
+					extract ) ) == 0 )
+			return 0;
 	}
 
 	/* Try all SSDTs */
@@ -284,12 +244,13 @@ int acpi_sx ( uint32_t signature ) {
 		ssdt = acpi_find ( SSDT_SIGNATURE, i );
 		if ( ! ssdt )
 			break;
-		if ( ( sx = acpi_sx_zsdt ( ssdt, signature ) ) >= 0 )
-			return sx;
+		if ( ( rc = acpi_zsdt ( ssdt, signature, data,
+					extract ) ) == 0 )
+			return 0;
 	}
 
-	DBGC ( rsdt, "RSDT %#08lx could not find \\_Sx \"%s\"\n",
-	       user_to_phys ( rsdt, 0 ), acpi_name ( signature ) );
+	DBGC ( colour, "ACPI could not find \"%s\"\n",
+	       acpi_name ( signature ) );
 	return -ENOENT;
 }
 
diff -pruN 1.0.0+git-20190125.36a4c85-5.1/src/core/acpimac.c 1.21.1+git-20220113.fbbdc3926-0ubuntu1/src/core/acpimac.c
--- 1.0.0+git-20190125.36a4c85-5.1/src/core/acpimac.c	1970-01-01 00:00:00.000000000 +0000
+++ 1.21.1+git-20220113.fbbdc3926-0ubuntu1/src/core/acpimac.c	2022-01-13 13:43:08.000000000 +0000
@@ -0,0 +1,154 @@
+/*
+ * Copyright (C) 2021 Michael Brown <mbrown@fensystems.co.uk>.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of the
+ * License, or any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+ * 02110-1301, USA.
+ *
+ * You can also choose to distribute this program under the terms of
+ * the Unmodified Binary Distribution Licence (as given in the file
+ * COPYING.UBDL), provided that you have satisfied its requirements.
+ */
+
+FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
+
+#include <string.h>
+#include <errno.h>
+#include <ipxe/acpi.h>
+#include <ipxe/base16.h>
+#include <ipxe/ethernet.h>
+#include <ipxe/if_ether.h>
+#include <ipxe/acpimac.h>
+
+/** @file
+ *
+ * ACPI MAC address
+ *
+ */
+
+/** Colour for debug messages */
+#define colour FADT_SIGNATURE
+
+/** AMAC signature */
+#define AMAC_SIGNATURE ACPI_SIGNATURE ( 'A', 'M', 'A', 'C' )
+
+/** MACA signature */
+#define MACA_SIGNATURE ACPI_SIGNATURE ( 'M', 'A', 'C', 'A' )
+
+/** Maximum number of bytes to skip after AMAC/MACA signature
+ *
+ * This is entirely empirical.
+ */
+#define AUXMAC_MAX_SKIP 8
+
+/**
+ * Extract MAC address from DSDT/SSDT
+ *
+ * @v zsdt		DSDT or SSDT
+ * @v len		Length of DSDT/SSDT
+ * @v offset		Offset of signature within DSDT/SSDT
+ * @v data		Data buffer
+ * @ret rc		Return status code
+ *
+ * Some vendors provide a "system MAC address" within the DSDT/SSDT,
+ * to be used to override the MAC address for a USB docking station.
+ *
+ * A full implementation would require an ACPI bytecode interpreter,
+ * since at least one OEM allows the MAC address to be constructed by
+ * executable ACPI bytecode (rather than a fixed data structure).
+ *
+ * We instead attempt to extract a plausible-looking "_AUXMAC_#.....#"
+ * string that appears shortly after an "AMAC" or "MACA" signature.
+ * This should work for most implementations encountered in practice.
+ */
+static int acpi_extract_mac ( userptr_t zsdt, size_t len, size_t offset,
+			      void *data ) {
+	static const char prefix[9] = "_AUXMAC_#";
+	uint8_t *hw_addr = data;
+	size_t skip = 0;
+	char auxmac[ sizeof ( prefix ) /* "_AUXMAC_#" */ +
+		     ( ETH_ALEN * 2 ) /* MAC */ + 1 /* "#" */ + 1 /* NUL */ ];
+	char *mac = &auxmac[ sizeof ( prefix ) ];
+	int decoded_len;
+	int rc;
+
+	/* Skip signature and at least one tag byte */
+	offset += ( 4 /* signature */ + 1 /* tag byte */ );
+
+	/* Scan for "_AUXMAC_#.....#" close to signature */
+	for ( skip = 0 ;
+	      ( ( skip < AUXMAC_MAX_SKIP ) &&
+		( offset + skip + sizeof ( auxmac ) ) < len ) ;
+	      skip++ ) {
+
+		/* Read value */
+		copy_from_user ( auxmac, zsdt, ( offset + skip ),
+				 sizeof ( auxmac ) );
+
+		/* Check for expected format */
+		if ( memcmp ( auxmac, prefix, sizeof ( prefix ) ) != 0 )
+			continue;
+		if ( auxmac[ sizeof ( auxmac ) - 2 ] != '#' )
+			continue;
+		if ( auxmac[ sizeof ( auxmac ) - 1 ] != '\0' )
+			continue;
+		DBGC ( colour, "ACPI found MAC string \"%s\"\n", auxmac );
+
+		/* Terminate MAC address string */
+		mac = &auxmac[ sizeof ( prefix ) ];
+		mac[ ETH_ALEN * 2 ] = '\0';
+
+		/* Decode MAC address */
+		decoded_len = base16_decode ( mac, hw_addr, ETH_ALEN );
+		if ( decoded_len < 0 ) {
+			rc = decoded_len;
+			DBGC ( colour, "ACPI could not decode MAC \"%s\": %s\n",
+			       mac, strerror ( rc ) );
+			return rc;
+		}
+
+		/* Check MAC address validity */
+		if ( ! is_valid_ether_addr ( hw_addr ) ) {
+			DBGC ( colour, "ACPI has invalid MAC %s\n",
+			       eth_ntoa ( hw_addr ) );
+			return -EINVAL;
+		}
+
+		return 0;
+	}
+
+	return -ENOENT;
+}
+
+/**
+ * Extract MAC address from DSDT/SSDT
+ *
+ * @v hw_addr		MAC address to fill in
+ * @ret rc		Return status code
+ */
+int acpi_mac ( uint8_t *hw_addr ) {
+	int rc;
+
+	/* Look for an "AMAC" address */
+	if ( ( rc = acpi_extract ( AMAC_SIGNATURE, hw_addr,
+				   acpi_extract_mac ) ) == 0 )
+		return 0;
+
+	/* Look for a "MACA" address */
+	if ( ( rc = acpi_extract ( MACA_SIGNATURE, hw_addr,
+				   acpi_extract_mac ) ) == 0 )
+		return 0;
+
+	return -ENOENT;
+}
diff -pruN 1.0.0+git-20190125.36a4c85-5.1/src/core/archive.c 1.21.1+git-20220113.fbbdc3926-0ubuntu1/src/core/archive.c
--- 1.0.0+git-20190125.36a4c85-5.1/src/core/archive.c	1970-01-01 00:00:00.000000000 +0000
+++ 1.21.1+git-20220113.fbbdc3926-0ubuntu1/src/core/archive.c	2022-01-13 13:43:08.000000000 +0000
@@ -0,0 +1,138 @@
+/*
+ * Copyright (C) 2021 Michael Brown <mbrown@fensystems.co.uk>.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of the
+ * License, or any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+ * 02110-1301, USA.
+ *
+ * You can also choose to distribute this program under the terms of
+ * the Unmodified Binary Distribution Licence (as given in the file
+ * COPYING.UBDL), provided that you have satisfied its requirements.
+ */
+
+FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
+
+#include <string.h>
+#include <errno.h>
+#include <ipxe/image.h>
+
+/** @file
+ *
+ * Archive images
+ *
+ */
+
+/**
+ * Extract archive image
+ *
+ * @v image		Image
+ * @v name		Extracted image name
+ * @v extracted		Extracted image to fill in
+ * @ret rc		Return status code
+ */
+int image_extract ( struct image *image, const char *name,
+		    struct image **extracted ) {
+	char *dot;
+	int rc;
+
+	/* Check that this image can be used to extract an archive image */
+	if ( ! ( image->type && image->type->extract ) ) {
+		rc = -ENOTSUP;
+		goto err_unsupported;
+	}
+
+	/* Allocate new image */
+	*extracted = alloc_image ( image->uri );
+	if ( ! *extracted ) {
+		rc = -ENOMEM;
+		goto err_alloc;
+	}
+
+	/* Set image name */
+	if ( ( rc = image_set_name ( *extracted,
+				     ( name ? name : image->name ) ) ) != 0 ) {
+		goto err_set_name;
+	}
+
+	/* Strip any archive or compression suffix from implicit name */
+	if ( ( ! name ) && ( (*extracted)->name ) &&
+	     ( ( dot = strrchr ( (*extracted)->name, '.' ) ) != NULL ) ) {
+		*dot = '\0';
+	}
+
+	/* Try extracting archive image */
+	if ( ( rc = image->type->extract ( image, *extracted ) ) != 0 ) {
+		DBGC ( image, "IMAGE %s could not extract image: %s\n",
+		       image->name, strerror ( rc ) );
+		goto err_extract;
+	}
+
+	/* Register image */
+	if ( ( rc = register_image ( *extracted ) ) != 0 )
+		goto err_register;
+
+	/* Propagate trust flag */
+	if ( image->flags & IMAGE_TRUSTED )
+		image_trust ( *extracted );
+
+	/* Drop local reference to image */
+	image_put ( *extracted );
+
+	return 0;
+
+	unregister_image ( *extracted );
+ err_register:
+ err_extract:
+ err_set_name:
+	image_put ( *extracted );
+ err_alloc:
+ err_unsupported:
+	return rc;
+}
+
+/**
+ * Extract and execute image
+ *
+ * @v image		Image
+ * @ret rc		Return status code
+ */
+int image_extract_exec ( struct image *image ) {
+	struct image *extracted;
+	int rc;
+
+	/* Extract image */
+	if ( ( rc = image_extract ( image, NULL, &extracted ) ) != 0 )
+		goto err_extract;
+
+	/* Set image command line */
+	if ( ( rc = image_set_cmdline ( extracted, image->cmdline ) ) != 0 )
+		goto err_set_cmdline;
+
+	/* Set auto-unregister flag */
+	extracted->flags |= IMAGE_AUTO_UNREGISTER;
+
+	/* Tail-recurse into extracted image */
+	return image_exec ( extracted );
+
+ err_set_cmdline:
+	unregister_image ( extracted );
+ err_extract:
+	return rc;
+}
+
+/* Drag in objects via image_extract() */
+REQUIRING_SYMBOL ( image_extract );
+
+/* Drag in archive image formats */
+REQUIRE_OBJECT ( config_archive );
diff -pruN 1.0.0+git-20190125.36a4c85-5.1/src/core/base64.c 1.21.1+git-20220113.fbbdc3926-0ubuntu1/src/core/base64.c
--- 1.0.0+git-20190125.36a4c85-5.1/src/core/base64.c	2019-02-09 16:03:59.000000000 +0000
+++ 1.21.1+git-20220113.fbbdc3926-0ubuntu1/src/core/base64.c	2022-01-13 13:43:08.000000000 +0000
@@ -36,7 +36,7 @@ FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
  *
  */
 
-static const char base64[64] =
+static const char base64[ 64 + 1 /* NUL */ ] =
 	"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
 
 /**
diff -pruN 1.0.0+git-20190125.36a4c85-5.1/src/core/blocktrans.c 1.21.1+git-20220113.fbbdc3926-0ubuntu1/src/core/blocktrans.c
--- 1.0.0+git-20190125.36a4c85-5.1/src/core/blocktrans.c	2019-02-09 16:03:59.000000000 +0000
+++ 1.21.1+git-20220113.fbbdc3926-0ubuntu1/src/core/blocktrans.c	2022-01-13 13:43:08.000000000 +0000
@@ -242,9 +242,7 @@ int block_translate ( struct interface *
 	}
 
 	/* Attach to interfaces, mortalise self, and return */
-	assert ( block->dest != &null_intf );
-	intf_plug_plug ( &blktrans->xfer, block->dest );
-	intf_plug_plug ( &blktrans->block, block );
+	intf_insert ( block, &blktrans->block, &blktrans->xfer );
 	ref_put ( &blktrans->refcnt );
 
 	DBGC2 ( blktrans, "BLKTRANS %p created", blktrans );
diff -pruN 1.0.0+git-20190125.36a4c85-5.1/src/core/cachedhcp.c 1.21.1+git-20220113.fbbdc3926-0ubuntu1/src/core/cachedhcp.c
--- 1.0.0+git-20190125.36a4c85-5.1/src/core/cachedhcp.c	1970-01-01 00:00:00.000000000 +0000
+++ 1.21.1+git-20220113.fbbdc3926-0ubuntu1/src/core/cachedhcp.c	2022-01-13 13:43:08.000000000 +0000
@@ -0,0 +1,243 @@
+/*
+ * Copyright (C) 2013 Michael Brown <mbrown@fensystems.co.uk>.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of the
+ * License, or any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+ * 02110-1301, USA.
+ *
+ * You can also choose to distribute this program under the terms of
+ * the Unmodified Binary Distribution Licence (as given in the file
+ * COPYING.UBDL), provided that you have satisfied its requirements.
+ */
+
+FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
+
+#include <stdint.h>
+#include <stdlib.h>
+#include <errno.h>
+#include <ipxe/dhcppkt.h>
+#include <ipxe/init.h>
+#include <ipxe/netdevice.h>
+#include <ipxe/cachedhcp.h>
+
+/** @file
+ *
+ * Cached DHCP packet
+ *
+ */
+
+/** A cached DHCP packet */
+struct cached_dhcp_packet {
+	/** Settings block name */
+	const char *name;
+	/** DHCP packet (if any) */
+	struct dhcp_packet *dhcppkt;
+};
+
+/** Cached DHCPACK */
+struct cached_dhcp_packet cached_dhcpack = {
+	.name = DHCP_SETTINGS_NAME,
+};
+
+/** Cached ProxyDHCPOFFER */
+struct cached_dhcp_packet cached_proxydhcp = {
+	.name = PROXYDHCP_SETTINGS_NAME,
+};
+
+/** Cached PXEBSACK */
+struct cached_dhcp_packet cached_pxebs = {
+	.name = PXEBS_SETTINGS_NAME,
+};
+
+/** List of cached DHCP packets */
+static struct cached_dhcp_packet *cached_packets[] = {
+	&cached_dhcpack,
+	&cached_proxydhcp,
+	&cached_pxebs,
+};
+
+/** Colour for debug messages */
+#define colour &cached_dhcpack
+
+/**
+ * Free cached DHCP packet
+ *
+ * @v cache		Cached DHCP packet
+ */
+static void cachedhcp_free ( struct cached_dhcp_packet *cache ) {
+
+	dhcppkt_put ( cache->dhcppkt );
+	cache->dhcppkt = NULL;
+}
+
+/**
+ * Apply cached DHCP packet settings
+ *
+ * @v cache		Cached DHCP packet
+ * @v netdev		Network device, or NULL
+ * @ret rc		Return status code
+ */
+static int cachedhcp_apply ( struct cached_dhcp_packet *cache,
+			     struct net_device *netdev ) {
+	struct settings *settings;
+	int rc;
+
+	/* Do nothing if cache is empty */
+	if ( ! cache->dhcppkt )
+		return 0;
+
+	/* Do nothing unless cached packet's MAC address matches this
+	 * network device, if specified.
+	 */
+	if ( netdev ) {
+		if ( memcmp ( netdev->ll_addr, cache->dhcppkt->dhcphdr->chaddr,
+			      netdev->ll_protocol->ll_addr_len ) != 0 ) {
+			DBGC ( colour, "CACHEDHCP %s does not match %s\n",
+			       cache->name, netdev->name );
+			return 0;
+		}
+		DBGC ( colour, "CACHEDHCP %s is for %s\n",
+		       cache->name, netdev->name );
+	}
+
+	/* Select appropriate parent settings block */
+	settings = ( netdev ? netdev_settings ( netdev ) : NULL );
+
+	/* Register settings */
+	if ( ( rc = register_settings ( &cache->dhcppkt->settings, settings,
+					cache->name ) ) != 0 ) {
+		DBGC ( colour, "CACHEDHCP %s could not register settings: %s\n",
+		       cache->name, strerror ( rc ) );
+		return rc;
+	}
+
+	/* Free cached DHCP packet */
+	cachedhcp_free ( cache );
+
+	return 0;
+}
+
+/**
+ * Record cached DHCP packet
+ *
+ * @v cache		Cached DHCP packet
+ * @v data		DHCPACK packet buffer
+ * @v max_len		Maximum possible length
+ * @ret rc		Return status code
+ */
+int cachedhcp_record ( struct cached_dhcp_packet *cache, userptr_t data,
+		       size_t max_len ) {
+	struct dhcp_packet *dhcppkt;
+	struct dhcp_packet *tmp;
+	struct dhcphdr *dhcphdr;
+	unsigned int i;
+	size_t len;
+
+	/* Free any existing cached packet */
+	cachedhcp_free ( cache );
+
+	/* Allocate and populate DHCP packet */
+	dhcppkt = zalloc ( sizeof ( *dhcppkt ) + max_len );
+	if ( ! dhcppkt ) {
+		DBGC ( colour, "CACHEDHCP %s could not allocate copy\n",
+		       cache->name );
+		return -ENOMEM;
+	}
+	dhcphdr = ( ( ( void * ) dhcppkt ) + sizeof ( *dhcppkt ) );
+	copy_from_user ( dhcphdr, data, 0, max_len );
+	dhcppkt_init ( dhcppkt, dhcphdr, max_len );
+
+	/* Shrink packet to required length.  If reallocation fails,
+	 * just continue to use the original packet and waste the
+	 * unused space.
+	 */
+	len = dhcppkt_len ( dhcppkt );
+	assert ( len <= max_len );
+	tmp = realloc ( dhcppkt, ( sizeof ( *dhcppkt ) + len ) );
+	if ( tmp )
+		dhcppkt = tmp;
+
+	/* Reinitialise packet at new address */
+	dhcphdr = ( ( ( void * ) dhcppkt ) + sizeof ( *dhcppkt ) );
+	dhcppkt_init ( dhcppkt, dhcphdr, len );
+
+	/* Discard duplicate packets, since some PXE stacks (including
+	 * iPXE itself) will report the DHCPACK packet as the PXEBSACK
+	 * if no separate PXEBSACK exists.
+	 */
+	for ( i = 0 ; i < ( sizeof ( cached_packets ) /
+			    sizeof ( cached_packets[0] ) ) ; i++ ) {
+		tmp = cached_packets[i]->dhcppkt;
+		if ( tmp && ( dhcppkt_len ( tmp ) == len ) &&
+		     ( memcmp ( tmp->dhcphdr, dhcppkt->dhcphdr, len ) == 0 ) ) {
+			DBGC ( colour, "CACHEDHCP %s duplicates %s\n",
+			       cache->name, cached_packets[i]->name );
+			dhcppkt_put ( dhcppkt );
+			return -EEXIST;
+		}
+	}
+
+	/* Store as cached packet */
+	DBGC ( colour, "CACHEDHCP %s at %#08lx+%#zx/%#zx\n", cache->name,
+	       user_to_phys ( data, 0 ), len, max_len );
+	cache->dhcppkt = dhcppkt;
+
+	return 0;
+}
+
+/**
+ * Cached DHCPACK startup function
+ *
+ */
+static void cachedhcp_startup ( void ) {
+
+	/* Apply cached ProxyDHCPOFFER, if any */
+	cachedhcp_apply ( &cached_proxydhcp, NULL );
+
+	/* Apply cached PXEBSACK, if any */
+	cachedhcp_apply ( &cached_pxebs, NULL );
+
+	/* Free any remaining cached packets */
+	if ( cached_dhcpack.dhcppkt ) {
+		DBGC ( colour, "CACHEDHCP %s unclaimed\n",
+		       cached_dhcpack.name );
+	}
+	cachedhcp_free ( &cached_dhcpack );
+	cachedhcp_free ( &cached_proxydhcp );
+	cachedhcp_free ( &cached_pxebs );
+}
+
+/** Cached DHCPACK startup function */
+struct startup_fn cachedhcp_startup_fn __startup_fn ( STARTUP_LATE ) = {
+	.name = "cachedhcp",
+	.startup = cachedhcp_startup,
+};
+
+/**
+ * Apply cached DHCPACK to network device, if applicable
+ *
+ * @v netdev		Network device
+ * @ret rc		Return status code
+ */
+static int cachedhcp_probe ( struct net_device *netdev ) {
+
+	/* Apply cached DHCPACK to network device, if applicable */
+	return cachedhcp_apply ( &cached_dhcpack, netdev );
+}
+
+/** Cached DHCP packet network device driver */
+struct net_driver cachedhcp_driver __net_driver = {
+	.name = "cachedhcp",
+	.probe = cachedhcp_probe,
+};
diff -pruN 1.0.0+git-20190125.36a4c85-5.1/src/core/console.c 1.21.1+git-20220113.fbbdc3926-0ubuntu1/src/core/console.c
--- 1.0.0+git-20190125.36a4c85-5.1/src/core/console.c	2019-02-09 16:03:59.000000000 +0000
+++ 1.21.1+git-20220113.fbbdc3926-0ubuntu1/src/core/console.c	2022-01-13 13:43:08.000000000 +0000
@@ -20,11 +20,12 @@ unsigned int console_height = CONSOLE_DE
  * Write a single character to each console device
  *
  * @v character		Character to be written
+ * @ret character	Character written
  *
  * The character is written out to all enabled console devices, using
  * each device's console_driver::putchar() method.
  */
-void putchar ( int character ) {
+int putchar ( int character ) {
 	struct console_driver *console;
 
 	/* Automatic LF -> CR,LF translation */
@@ -37,6 +38,8 @@ void putchar ( int character ) {
 		     console->putchar )
 			console->putchar ( character );
 	}
+
+	return character;
 }
 
 /**
diff -pruN 1.0.0+git-20190125.36a4c85-5.1/src/core/cpio.c 1.21.1+git-20220113.fbbdc3926-0ubuntu1/src/core/cpio.c
--- 1.0.0+git-20190125.36a4c85-5.1/src/core/cpio.c	2019-02-09 16:03:59.000000000 +0000
+++ 1.21.1+git-20220113.fbbdc3926-0ubuntu1/src/core/cpio.c	2022-01-13 13:43:08.000000000 +0000
@@ -30,6 +30,7 @@ FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
  */
 
 #include <stdio.h>
+#include <stdlib.h>
 #include <string.h>
 #include <ipxe/cpio.h>
 
@@ -45,3 +46,87 @@ void cpio_set_field ( char *field, unsig
 	snprintf ( buf, sizeof ( buf ), "%08lx", value );
 	memcpy ( field, buf, 8 );
 }
+
+/**
+ * Get CPIO image filename
+ *
+ * @v image		Image
+ * @ret len		CPIO filename length (0 for no filename)
+ */
+size_t cpio_name_len ( struct image *image ) {
+	const char *name = cpio_name ( image );
+	char *sep;
+	size_t len;
+
+	/* Check for existence of CPIO filename */
+	if ( ! name )
+		return 0;
+
+	/* Locate separator (if any) */
+	sep = strchr ( name, ' ' );
+	len = ( sep ? ( ( size_t ) ( sep - name ) ) : strlen ( name ) );
+
+	return len;
+}
+
+/**
+ * Parse CPIO image parameters
+ *
+ * @v image		Image
+ * @v cpio		CPIO header to fill in
+ */
+static void cpio_parse_cmdline ( struct image *image,
+				 struct cpio_header *cpio ) {
+	const char *cmdline;
+	char *arg;
+	char *end;
+	unsigned int mode;
+
+	/* Skip image filename */
+	cmdline = ( cpio_name ( image ) + cpio_name_len ( image ) );
+
+	/* Look for "mode=" */
+	if ( ( arg = strstr ( cmdline, "mode=" ) ) ) {
+		arg += 5;
+		mode = strtoul ( arg, &end, 8 /* Octal for file mode */ );
+		if ( *end && ( *end != ' ' ) ) {
+			DBGC ( image, "CPIO %p strange \"mode=\" "
+			       "terminator '%c'\n", image, *end );
+		}
+		cpio_set_field ( cpio->c_mode, ( 0100000 | mode ) );
+	}
+}
+
+/**
+ * Construct CPIO header for image, if applicable
+ *
+ * @v image		Image
+ * @v cpio		CPIO header to fill in
+ * @ret len		Length of magic CPIO header (including filename)
+ */
+size_t cpio_header ( struct image *image, struct cpio_header *cpio ) {
+	size_t name_len;
+	size_t len;
+
+	/* Get filename length */
+	name_len = cpio_name_len ( image );
+
+	/* Images with no filename are assumed to already be CPIO archives */
+	if ( ! name_len )
+		return 0;
+
+	/* Construct CPIO header */
+	memset ( cpio, '0', sizeof ( *cpio ) );
+	memcpy ( cpio->c_magic, CPIO_MAGIC, sizeof ( cpio->c_magic ) );
+	cpio_set_field ( cpio->c_mode, 0100644 );
+	cpio_set_field ( cpio->c_nlink, 1 );
+	cpio_set_field ( cpio->c_filesize, image->len );
+	cpio_set_field ( cpio->c_namesize, ( name_len + 1 /* NUL */ ) );
+	cpio_parse_cmdline ( image, cpio );
+
+	/* Calculate total length */
+	len = ( ( sizeof ( *cpio ) + name_len + 1 /* NUL */ + CPIO_ALIGN - 1 )
+		& ~( CPIO_ALIGN - 1 ) );
+
+	return len;
+}
diff -pruN 1.0.0+git-20190125.36a4c85-5.1/src/core/dma.c 1.21.1+git-20220113.fbbdc3926-0ubuntu1/src/core/dma.c
--- 1.0.0+git-20190125.36a4c85-5.1/src/core/dma.c	1970-01-01 00:00:00.000000000 +0000
+++ 1.21.1+git-20220113.fbbdc3926-0ubuntu1/src/core/dma.c	2022-01-13 13:43:08.000000000 +0000
@@ -0,0 +1,179 @@
+/*
+ * Copyright (C) 2020 Michael Brown <mbrown@fensystems.co.uk>.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of the
+ * License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+ * 02110-1301, USA.
+ *
+ * You can also choose to distribute this program under the terms of
+ * the Unmodified Binary Distribution Licence (as given in the file
+ * COPYING.UBDL), provided that you have satisfied its requirements.
+ */
+
+FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
+
+#include <assert.h>
+#include <errno.h>
+#include <ipxe/dma.h>
+
+/** @file
+ *
+ * DMA mappings
+ *
+ */
+
+/******************************************************************************
+ *
+ * Flat address space DMA API
+ *
+ ******************************************************************************
+ */
+
+PROVIDE_DMAAPI_INLINE ( flat, dma_map );
+PROVIDE_DMAAPI_INLINE ( flat, dma_unmap );
+PROVIDE_DMAAPI_INLINE ( flat, dma_alloc );
+PROVIDE_DMAAPI_INLINE ( flat, dma_free );
+PROVIDE_DMAAPI_INLINE ( flat, dma_umalloc );
+PROVIDE_DMAAPI_INLINE ( flat, dma_ufree );
+PROVIDE_DMAAPI_INLINE ( flat, dma_set_mask );
+PROVIDE_DMAAPI_INLINE ( flat, dma_phys );
+
+/******************************************************************************
+ *
+ * Operations-based DMA API
+ *
+ ******************************************************************************
+ */
+
+/**
+ * Map buffer for DMA
+ *
+ * @v dma		DMA device
+ * @v map		DMA mapping to fill in
+ * @v addr		Buffer address
+ * @v len		Length of buffer
+ * @v flags		Mapping flags
+ * @ret rc		Return status code
+ */
+static int dma_op_map ( struct dma_device *dma, struct dma_mapping *map,
+			physaddr_t addr, size_t len, int flags ) {
+	struct dma_operations *op = dma->op;
+
+	if ( ! op )
+		return -ENODEV;
+	return op->map ( dma, map, addr, len, flags );
+}
+
+/**
+ * Unmap buffer
+ *
+ * @v map		DMA mapping
+ */
+static void dma_op_unmap ( struct dma_mapping *map ) {
+	struct dma_device *dma = map->dma;
+
+	assert ( dma != NULL );
+	assert ( dma->op != NULL );
+	dma->op->unmap ( dma, map );
+}
+
+/**
+ * Allocate and map DMA-coherent buffer
+ *
+ * @v dma		DMA device
+ * @v map		DMA mapping to fill in
+ * @v len		Length of buffer
+ * @v align		Physical alignment
+ * @ret addr		Buffer address, or NULL on error
+ */
+static void * dma_op_alloc ( struct dma_device *dma, struct dma_mapping *map,
+			     size_t len, size_t align ) {
+	struct dma_operations *op = dma->op;
+
+	if ( ! op )
+		return NULL;
+	return op->alloc ( dma, map, len, align );
+}
+
+/**
+ * Unmap and free DMA-coherent buffer
+ *
+ * @v map		DMA mapping
+ * @v addr		Buffer address
+ * @v len		Length of buffer
+ */
+static void dma_op_free ( struct dma_mapping *map, void *addr, size_t len ) {
+	struct dma_device *dma = map->dma;
+
+	assert ( dma != NULL );
+	assert ( dma->op != NULL );
+	dma->op->free ( dma, map, addr, len );
+}
+
+/**
+ * Allocate and map DMA-coherent buffer from external (user) memory
+ *
+ * @v dma		DMA device
+ * @v map		DMA mapping to fill in
+ * @v len		Length of buffer
+ * @v align		Physical alignment
+ * @ret addr		Buffer address, or NULL on error
+ */
+static userptr_t dma_op_umalloc ( struct dma_device *dma,
+				  struct dma_mapping *map,
+				  size_t len, size_t align ) {
+	struct dma_operations *op = dma->op;
+
+	if ( ! op )
+		return UNULL;
+	return op->umalloc ( dma, map, len, align );
+}
+
+/**
+ * Unmap and free DMA-coherent buffer from external (user) memory
+ *
+ * @v map		DMA mapping
+ * @v addr		Buffer address
+ * @v len		Length of buffer
+ */
+static void dma_op_ufree ( struct dma_mapping *map, userptr_t addr,
+			   size_t len ) {
+	struct dma_device *dma = map->dma;
+
+	assert ( dma != NULL );
+	assert ( dma->op != NULL );
+	dma->op->ufree ( dma, map, addr, len );
+}
+
+/**
+ * Set addressable space mask
+ *
+ * @v dma		DMA device
+ * @v mask		Addressable space mask
+ */
+static void dma_op_set_mask ( struct dma_device *dma, physaddr_t mask ) {
+	struct dma_operations *op = dma->op;
+
+	if ( op )
+		op->set_mask ( dma, mask );
+}
+
+PROVIDE_DMAAPI ( op, dma_map, dma_op_map );
+PROVIDE_DMAAPI ( op, dma_unmap, dma_op_unmap );
+PROVIDE_DMAAPI ( op, dma_alloc, dma_op_alloc );
+PROVIDE_DMAAPI ( op, dma_free, dma_op_free );
+PROVIDE_DMAAPI ( op, dma_umalloc, dma_op_umalloc );
+PROVIDE_DMAAPI ( op, dma_ufree, dma_op_ufree );
+PROVIDE_DMAAPI ( op, dma_set_mask, dma_op_set_mask );
+PROVIDE_DMAAPI_INLINE ( op, dma_phys );
diff -pruN 1.0.0+git-20190125.36a4c85-5.1/src/core/fdt.c 1.21.1+git-20220113.fbbdc3926-0ubuntu1/src/core/fdt.c
--- 1.0.0+git-20190125.36a4c85-5.1/src/core/fdt.c	1970-01-01 00:00:00.000000000 +0000
+++ 1.21.1+git-20220113.fbbdc3926-0ubuntu1/src/core/fdt.c	2022-01-13 13:43:08.000000000 +0000
@@ -0,0 +1,486 @@
+/*
+ * Copyright (C) 2019 Michael Brown <mbrown@fensystems.co.uk>.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of the
+ * License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+ * 02110-1301, USA.
+ *
+ * You can also choose to distribute this program under the terms of
+ * the Unmodified Binary Distribution Licence (as given in the file
+ * COPYING.UBDL), provided that you have satisfied its requirements.
+ */
+
+FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
+
+#include <string.h>
+#include <errno.h>
+#include <assert.h>
+#include <byteswap.h>
+#include <ipxe/netdevice.h>
+#include <ipxe/fdt.h>
+
+/** @file
+ *
+ * Flattened Device Tree
+ *
+ */
+
+/** The system flattened device tree (if present) */
+static struct fdt fdt;
+
+/** A position within a device tree */
+struct fdt_cursor {
+	/** Offset within structure block */
+	unsigned int offset;
+	/** Tree depth */
+	int depth;
+};
+
+/** A lexical descriptor */
+struct fdt_descriptor {
+	/** Node or property name (if applicable) */
+	const char *name;
+	/** Property data (if applicable) */
+	const void *data;
+	/** Length of property data (if applicable) */
+	size_t len;
+};
+
+/**
+ * Check if device tree exists
+ *
+ * @v has_fdt		Device tree exists
+ */
+static inline __attribute__ (( always_inline )) int fdt_exists ( void ) {
+
+	return ( fdt.hdr != NULL );
+}
+
+/**
+ * Traverse device tree
+ *
+ * @v pos		Position within device tree
+ * @v desc		Lexical descriptor to fill in
+ * @ret rc		Return status code
+ */
+static int fdt_traverse ( struct fdt_cursor *pos,
+			  struct fdt_descriptor *desc ) {
+	const fdt_token_t *token;
+	const void *data;
+	const struct fdt_prop *prop;
+	unsigned int name_off;
+	size_t remaining;
+	size_t len;
+
+	/* Sanity checks */
+	assert ( pos->offset < fdt.len );
+	assert ( ( pos->offset & ( FDT_STRUCTURE_ALIGN - 1 ) ) == 0 );
+
+	/* Clear descriptor */
+	memset ( desc, 0, sizeof ( *desc ) );
+
+	/* Locate token and calculate remaining space */
+	token = ( fdt.raw + fdt.structure + pos->offset );
+	remaining = ( fdt.len - pos->offset );
+	if ( remaining < sizeof ( *token ) ) {
+		DBGC ( &fdt, "FDT truncated tree at +%#04x\n", pos->offset );
+		return -EINVAL;
+	}
+	remaining -= sizeof ( *token );
+	data = ( ( ( const void * ) token ) + sizeof ( *token ) );
+	len = 0;
+
+	/* Handle token */
+	switch ( *token ) {
+
+	case cpu_to_be32 ( FDT_BEGIN_NODE ):
+
+		/* Start of node */
+		desc->name = data;
+		len = ( strnlen ( desc->name, remaining ) + 1 /* NUL */ );
+		if ( remaining < len ) {
+			DBGC ( &fdt, "FDT unterminated node name at +%#04x\n",
+			       pos->offset );
+			return -EINVAL;
+		}
+		pos->depth++;
+		break;
+
+	case cpu_to_be32 ( FDT_END_NODE ):
+
+		/* End of node */
+		if ( pos->depth < 0 ) {
+			DBGC ( &fdt, "FDT spurious node end at +%#04x\n",
+			       pos->offset );
+			return -EINVAL;
+		}
+		pos->depth--;
+		if ( pos->depth < 0 ) {
+			/* End of (sub)tree */
+			return -ENOENT;
+		}
+		break;
+
+	case cpu_to_be32 ( FDT_PROP ):
+
+		/* Property */
+		prop = data;
+		if ( remaining < sizeof ( *prop ) ) {
+			DBGC ( &fdt, "FDT truncated property at +%#04x\n",
+			       pos->offset );
+			return -EINVAL;
+		}
+		desc->data = ( ( ( const void * ) prop ) + sizeof ( *prop ) );
+		desc->len = be32_to_cpu ( prop->len );
+		len = ( sizeof ( *prop ) + desc->len );
+		if ( remaining < len ) {
+			DBGC ( &fdt, "FDT overlength property at +%#04x\n",
+			       pos->offset );
+			return -EINVAL;
+		}
+		name_off = be32_to_cpu ( prop->name_off );
+		if ( name_off > fdt.strings_len ) {
+			DBGC ( &fdt, "FDT property name outside strings "
+			       "block at +%#04x\n", pos->offset );
+			return -EINVAL;
+		}
+		desc->name = ( fdt.raw + fdt.strings + name_off );
+		break;
+
+	case cpu_to_be32 ( FDT_NOP ):
+
+		/* Do nothing */
+		break;
+
+	default:
+
+		/* Unrecognised or unexpected token */
+		DBGC ( &fdt, "FDT unexpected token %#08x at +%#04x\n",
+		       be32_to_cpu ( *token ), pos->offset );
+		return -EINVAL;
+	}
+
+	/* Update cursor */
+	len = ( ( len + FDT_STRUCTURE_ALIGN - 1 ) &
+		~( FDT_STRUCTURE_ALIGN - 1 ) );
+	pos->offset += ( sizeof ( *token ) + len );
+
+	/* Sanity checks */
+	assert ( pos->offset <= fdt.len );
+
+	return 0;
+}
+
+/**
+ * Find child node
+ *
+ * @v offset		Starting node offset
+ * @v name		Node name
+ * @v child		Child node offset to fill in
+ * @ret rc		Return status code
+ */
+static int fdt_child ( unsigned int offset, const char *name,
+		       unsigned int *child ) {
+	struct fdt_cursor pos;
+	struct fdt_descriptor desc;
+	unsigned int orig_offset;
+	int rc;
+
+	/* Record original offset (for debugging) */
+	orig_offset = offset;
+
+	/* Initialise cursor */
+	pos.offset = offset;
+	pos.depth = -1;
+
+	/* Find child node */
+	while ( 1 ) {
+
+		/* Record current offset */
+		*child = pos.offset;
+
+		/* Traverse tree */
+		if ( ( rc = fdt_traverse ( &pos, &desc ) ) != 0 ) {
+			DBGC ( &fdt, "FDT +%#04x has no child node \"%s\": "
+			       "%s\n", orig_offset, name, strerror ( rc ) );
+			return rc;
+		}
+
+		/* Check for matching immediate child node */
+		if ( ( pos.depth == 1 ) && desc.name && ( ! desc.data ) ) {
+			DBGC2 ( &fdt, "FDT +%#04x has child node \"%s\"\n",
+				orig_offset, desc.name );
+			if ( strcmp ( name, desc.name ) == 0 ) {
+				DBGC2 ( &fdt, "FDT +%#04x found child node "
+					"\"%s\" at +%#04x\n", orig_offset,
+					desc.name, *child );
+				return 0;
+			}
+		}
+	}
+}
+
+/**
+ * Find node by path
+ *
+ * @v path		Node path
+ * @v offset		Offset to fill in
+ * @ret rc		Return status code
+ */
+int fdt_path ( const char *path, unsigned int *offset ) {
+	char *tmp = ( ( char * ) path );
+	char *del;
+	int rc;
+
+	/* Initialise offset */
+	*offset = 0;
+
+	/* Traverse tree one path segment at a time */
+	while ( *tmp ) {
+
+		/* Skip any leading '/' */
+		while ( *tmp == '/' )
+			tmp++;
+
+		/* Find next '/' delimiter and convert to NUL */
+		del = strchr ( tmp, '/' );
+		if ( del )
+			*del = '\0';
+
+		/* Find child and restore delimiter */
+		rc = fdt_child ( *offset, tmp, offset );
+		if ( del )
+			*del = '/';
+		if ( rc != 0 )
+			return rc;
+
+		/* Move to next path component, if any */
+		while ( *tmp && ( *tmp != '/' ) )
+			tmp++;
+	}
+
+	DBGC2 ( &fdt, "FDT found path \"%s\" at +%#04x\n", path, *offset );
+	return 0;
+}
+
+/**
+ * Find node by alias
+ *
+ * @v name		Alias name
+ * @v offset		Offset to fill in
+ * @ret rc		Return status code
+ */
+int fdt_alias ( const char *name, unsigned int *offset ) {
+	const char *alias;
+	int rc;
+
+	/* Locate "/aliases" node */
+	if ( ( rc = fdt_child ( 0, "aliases", offset ) ) != 0 )
+		return rc;
+
+	/* Locate alias property */
+	if ( ( alias = fdt_string ( *offset, name ) ) == NULL )
+		return -ENOENT;
+	DBGC ( &fdt, "FDT alias \"%s\" is \"%s\"\n", name, alias );
+
+	/* Locate aliased node */
+	if ( ( rc = fdt_path ( alias, offset ) ) != 0 )
+		return rc;
+
+	return 0;
+}
+
+/**
+ * Find property
+ *
+ * @v offset		Starting node offset
+ * @v name		Property name
+ * @v desc		Lexical descriptor to fill in
+ * @ret rc		Return status code
+ */
+static int fdt_property ( unsigned int offset, const char *name,
+			  struct fdt_descriptor *desc ) {
+	struct fdt_cursor pos;
+	int rc;
+
+	/* Initialise cursor */
+	pos.offset = offset;
+	pos.depth = -1;
+
+	/* Find property */
+	while ( 1 ) {
+
+		/* Traverse tree */
+		if ( ( rc = fdt_traverse ( &pos, desc ) ) != 0 ) {
+			DBGC ( &fdt, "FDT +%#04x has no property \"%s\": %s\n",
+			       offset, name, strerror ( rc ) );
+			return rc;
+		}
+
+		/* Check for matching immediate child property */
+		if ( ( pos.depth == 0 ) && desc->data ) {
+			DBGC2 ( &fdt, "FDT +%#04x has property \"%s\" len "
+				"%#zx\n", offset, desc->name, desc->len );
+			if ( strcmp ( name, desc->name ) == 0 ) {
+				DBGC2 ( &fdt, "FDT +%#04x found property "
+					"\"%s\"\n", offset, desc->name );
+				DBGC2_HDA ( &fdt, 0, desc->data, desc->len );
+				return 0;
+			}
+		}
+	}
+}
+
+/**
+ * Find string property
+ *
+ * @v offset		Starting node offset
+ * @v name		Property name
+ * @ret string		String property, or NULL on error
+ */
+const char * fdt_string ( unsigned int offset, const char *name ) {
+	struct fdt_descriptor desc;
+	int rc;
+
+	/* Find property */
+	if ( ( rc = fdt_property ( offset, name, &desc ) ) != 0 )
+		return NULL;
+
+	/* Check NUL termination */
+	if ( strnlen ( desc.data, desc.len ) == desc.len ) {
+		DBGC ( &fdt, "FDT unterminated string property \"%s\"\n",
+		       name );
+		return NULL;
+	}
+
+	return desc.data;
+}
+
+/**
+ * Get MAC address from property
+ *
+ * @v offset		Starting node offset
+ * @v netdev		Network device
+ * @ret rc		Return status code
+ */
+int fdt_mac ( unsigned int offset, struct net_device *netdev ) {
+	struct fdt_descriptor desc;
+	size_t len;
+	int rc;
+
+	/* Find applicable MAC address property */
+	if ( ( ( rc = fdt_property ( offset, "mac-address", &desc ) ) != 0 ) &&
+	     ( ( rc = fdt_property ( offset, "local-mac-address",
+				     &desc ) ) != 0 ) ) {
+		return rc;
+	}
+
+	/* Check length */
+	len = netdev->ll_protocol->hw_addr_len;
+	if ( len != desc.len ) {
+		DBGC ( &fdt, "FDT malformed MAC address \"%s\":\n",
+		       desc.name );
+		DBGC_HDA ( &fdt, 0, desc.data, desc.len );
+		return -ERANGE;
+	}
+
+	/* Fill in MAC address */
+	memcpy ( netdev->hw_addr, desc.data, len );
+
+	return 0;
+}
+
+/**
+ * Register device tree
+ *
+ * @v fdt		Device tree header
+ * @ret rc		Return status code
+ */
+int register_fdt ( const struct fdt_header *hdr ) {
+	const uint8_t *end;
+
+	/* Record device tree location */
+	fdt.hdr = hdr;
+	fdt.len = be32_to_cpu ( hdr->totalsize );
+	DBGC ( &fdt, "FDT version %d at %p+%#04zx\n",
+	       be32_to_cpu ( hdr->version ), fdt.hdr, fdt.len );
+
+	/* Check signature */
+	if ( hdr->magic != cpu_to_be32 ( FDT_MAGIC ) ) {
+		DBGC ( &fdt, "FDT has invalid magic value %#08x\n",
+		       be32_to_cpu ( hdr->magic ) );
+		goto err;
+	}
+
+	/* Check version */
+	if ( hdr->last_comp_version != cpu_to_be32 ( FDT_VERSION ) ) {
+		DBGC ( &fdt, "FDT unsupported version %d\n",
+		       be32_to_cpu ( hdr->last_comp_version ) );
+		goto err;
+	}
+
+	/* Record structure block location */
+	fdt.structure = be32_to_cpu ( hdr->off_dt_struct );
+	fdt.structure_len = be32_to_cpu ( hdr->size_dt_struct );
+	DBGC ( &fdt, "FDT structure block at +[%#04x,%#04zx)\n",
+	       fdt.structure, ( fdt.structure + fdt.structure_len ) );
+	if ( ( fdt.structure > fdt.len ) ||
+	     ( fdt.structure_len > ( fdt.len - fdt.structure ) ) ) {
+		DBGC ( &fdt, "FDT structure block exceeds table\n" );
+		goto err;
+	}
+	if ( ( fdt.structure | fdt.structure_len ) &
+	     ( FDT_STRUCTURE_ALIGN - 1 ) ) {
+		DBGC ( &fdt, "FDT structure block is misaligned\n" );
+		goto err;
+	}
+
+	/* Record strings block location */
+	fdt.strings = be32_to_cpu ( hdr->off_dt_strings );
+	fdt.strings_len = be32_to_cpu ( hdr->size_dt_strings );
+	DBGC ( &fdt, "FDT strings block at +[%#04x,%#04zx)\n",
+	       fdt.strings, ( fdt.strings + fdt.strings_len ) );
+	if ( ( fdt.strings > fdt.len ) ||
+	     ( fdt.strings_len > ( fdt.len - fdt.strings ) ) ) {
+		DBGC ( &fdt, "FDT strings block exceeds table\n" );
+		goto err;
+	}
+
+	/* Shrink strings block to ensure NUL termination safety */
+	end = ( fdt.raw + fdt.strings + fdt.strings_len );
+	for ( ; fdt.strings_len ; fdt.strings_len-- ) {
+		if ( *(--end) == '\0' )
+			break;
+	}
+	if ( fdt.strings_len != be32_to_cpu ( hdr->size_dt_strings ) ) {
+		DBGC ( &fdt, "FDT strings block shrunk to +[%#04x,%#04zx)\n",
+		       fdt.strings, ( fdt.strings + fdt.strings_len ) );
+	}
+
+	/* Print model name (for debugging) */
+	DBGC ( &fdt, "FDT model is \"%s\"\n", fdt_string ( 0, "model" ) );
+
+	return 0;
+
+ err:
+	DBGC_HDA ( &fdt, 0, hdr, sizeof ( *hdr ) );
+	fdt.hdr = NULL;
+	return -EINVAL;
+}
+
+/* Drag in objects via register_fdt */
+REQUIRING_SYMBOL ( register_fdt );
+
+/* Drag in device tree configuration */
+REQUIRE_OBJECT ( config_fdt );
diff -pruN 1.0.0+git-20190125.36a4c85-5.1/src/core/image.c 1.21.1+git-20220113.fbbdc3926-0ubuntu1/src/core/image.c
--- 1.0.0+git-20190125.36a4c85-5.1/src/core/image.c	2019-02-09 16:03:59.000000000 +0000
+++ 1.21.1+git-20220113.fbbdc3926-0ubuntu1/src/core/image.c	2022-01-13 13:43:08.000000000 +0000
@@ -176,6 +176,47 @@ int image_set_cmdline ( struct image *im
 }
 
 /**
+ * Set image length
+ *
+ * @v image		Image
+ * @v len		Length of image data
+ * @ret rc		Return status code
+ */
+int image_set_len ( struct image *image, size_t len ) {
+	userptr_t new;
+
+	/* (Re)allocate image data */
+	new = urealloc ( image->data, len );
+	if ( ! new )
+		return -ENOMEM;
+	image->data = new;
+	image->len = len;
+
+	return 0;
+}
+
+/**
+ * Set image data
+ *
+ * @v image		Image
+ * @v data		Image data
+ * @v len		Length of image data
+ * @ret rc		Return status code
+ */
+int image_set_data ( struct image *image, userptr_t data, size_t len ) {
+	int rc;
+
+	/* Set image length */
+	if ( ( rc = image_set_len ( image, len ) ) != 0 )
+		return rc;
+
+	/* Copy in new image data */
+	memcpy_user ( image->data, 0, data, 0, len );
+
+	return 0;
+}
+
+/**
  * Determine image type
  *
  * @v image		Executable image
@@ -481,3 +522,47 @@ int image_set_trust ( int require_truste
 
 	return 0;
 }
+
+/**
+ * Create registered image from block of memory
+ *
+ * @v name		Name
+ * @v data		Image data
+ * @v len		Length
+ * @ret image		Image, or NULL on error
+ */
+struct image * image_memory ( const char *name, userptr_t data, size_t len ) {
+	struct image *image;
+	int rc;
+
+	/* Allocate image */
+	image = alloc_image ( NULL );
+	if ( ! image ) {
+		rc = -ENOMEM;
+		goto err_alloc_image;
+	}
+
+	/* Set name */
+	if ( ( rc = image_set_name ( image, name ) ) != 0 )
+		goto err_set_name;
+
+	/* Set data */
+	if ( ( rc = image_set_data ( image, data, len ) ) != 0 )
+		goto err_set_data;
+
+	/* Register image */
+	if ( ( rc = register_image ( image ) ) != 0 )
+		goto err_register;
+
+	/* Drop local reference to image */
+	image_put ( image );
+
+	return image;
+
+ err_register:
+ err_set_data:
+ err_set_name:
+	image_put ( image );
+ err_alloc_image:
+	return NULL;
+}
diff -pruN 1.0.0+git-20190125.36a4c85-5.1/src/core/interface.c 1.21.1+git-20220113.fbbdc3926-0ubuntu1/src/core/interface.c
--- 1.0.0+git-20190125.36a4c85-5.1/src/core/interface.c	2019-02-09 16:03:59.000000000 +0000
+++ 1.21.1+git-20220113.fbbdc3926-0ubuntu1/src/core/interface.c	2022-01-13 13:43:08.000000000 +0000
@@ -81,9 +81,14 @@ struct interface null_intf = INTF_INIT (
  * interface is updated to point to the new destination interface.
  */
 void intf_plug ( struct interface *intf, struct interface *dest ) {
+
+	if ( intf == &null_intf )
+		return;
+
 	DBGC ( INTF_COL ( intf ),
 	       "INTF " INTF_INTF_FMT " replug to " INTF_FMT "\n",
 	       INTF_INTF_DBG ( intf, intf->dest ), INTF_DBG ( dest ) );
+
 	intf_get ( dest );
 	intf_put ( intf->dest );
 	intf->dest = dest;
@@ -386,6 +391,23 @@ void intfs_restart ( int rc, ... ) {
 }
 
 /**
+ * Insert a filter interface
+ *
+ * @v intf		Object interface
+ * @v upper		Upper end of filter
+ * @v lower		Lower end of filter
+ */
+void intf_insert ( struct interface *intf, struct interface *upper,
+		   struct interface *lower ) {
+	struct interface *dest = intf->dest;
+
+	intf_get ( dest );
+	intf_plug_plug ( intf, upper );
+	intf_plug_plug ( lower, dest );
+	intf_put ( dest );
+}
+
+/**
  * Poke an object interface
  *
  * @v intf		Object interface
diff -pruN 1.0.0+git-20190125.36a4c85-5.1/src/core/iobuf.c 1.21.1+git-20220113.fbbdc3926-0ubuntu1/src/core/iobuf.c
--- 1.0.0+git-20190125.36a4c85-5.1/src/core/iobuf.c	2019-02-09 16:03:59.000000000 +0000
+++ 1.21.1+git-20220113.fbbdc3926-0ubuntu1/src/core/iobuf.c	2022-01-13 13:43:08.000000000 +0000
@@ -88,8 +88,8 @@ struct io_buffer * alloc_iob_raw ( size_
 		len += ( ( - len - offset ) & ( __alignof__ ( *iobuf ) - 1 ) );
 
 		/* Allocate memory for buffer plus descriptor */
-		data = malloc_dma_offset ( len + sizeof ( *iobuf ), align,
-					   offset );
+		data = malloc_phys_offset ( len + sizeof ( *iobuf ), align,
+					    offset );
 		if ( ! data )
 			return NULL;
 		iobuf = ( data + len );
@@ -97,19 +97,20 @@ struct io_buffer * alloc_iob_raw ( size_
 	} else {
 
 		/* Allocate memory for buffer */
-		data = malloc_dma_offset ( len, align, offset );
+		data = malloc_phys_offset ( len, align, offset );
 		if ( ! data )
 			return NULL;
 
 		/* Allocate memory for descriptor */
 		iobuf = malloc ( sizeof ( *iobuf ) );
 		if ( ! iobuf ) {
-			free_dma ( data, len );
+			free_phys ( data, len );
 			return NULL;
 		}
 	}
 
 	/* Populate descriptor */
+	memset ( &iobuf->map, 0, sizeof ( iobuf->map ) );
 	iobuf->head = iobuf->data = iobuf->tail = data;
 	iobuf->end = ( data + len );
 
@@ -153,23 +154,67 @@ void free_iob ( struct io_buffer *iobuf
 	assert ( iobuf->head <= iobuf->data );
 	assert ( iobuf->data <= iobuf->tail );
 	assert ( iobuf->tail <= iobuf->end );
+	assert ( ! dma_mapped ( &iobuf->map ) );
 
 	/* Free buffer */
 	len = ( iobuf->end - iobuf->head );
 	if ( iobuf->end == iobuf ) {
 
 		/* Descriptor is inline */
-		free_dma ( iobuf->head, ( len + sizeof ( *iobuf ) ) );
+		free_phys ( iobuf->head, ( len + sizeof ( *iobuf ) ) );
 
 	} else {
 
 		/* Descriptor is detached */
-		free_dma ( iobuf->head, len );
+		free_phys ( iobuf->head, len );
 		free ( iobuf );
 	}
 }
 
 /**
+ * Allocate and map I/O buffer for receive DMA
+ *
+ * @v len		Length of I/O buffer
+ * @v dma		DMA device
+ * @ret iobuf		I/O buffer, or NULL on error
+ */
+struct io_buffer * alloc_rx_iob ( size_t len, struct dma_device *dma ) {
+	struct io_buffer *iobuf;
+	int rc;
+
+	/* Allocate I/O buffer */
+	iobuf = alloc_iob ( len );
+	if ( ! iobuf )
+		goto err_alloc;
+
+	/* Map I/O buffer */
+	if ( ( rc = iob_map_rx ( iobuf, dma ) ) != 0 )
+		goto err_map;
+
+	return iobuf;
+
+	iob_unmap ( iobuf );
+ err_map:
+	free_iob ( iobuf );
+ err_alloc:
+	return NULL;
+}
+
+/**
+ * Unmap and free I/O buffer for receive DMA
+ *
+ * @v iobuf	I/O buffer
+ */
+void free_rx_iob ( struct io_buffer *iobuf ) {
+
+	/* Unmap I/O buffer */
+	iob_unmap ( iobuf );
+
+	/* Free I/O buffer */
+	free_iob ( iobuf );
+}
+
+/**
  * Ensure I/O buffer has sufficient headroom
  *
  * @v iobuf	I/O buffer
diff -pruN 1.0.0+git-20190125.36a4c85-5.1/src/core/malloc.c 1.21.1+git-20220113.fbbdc3926-0ubuntu1/src/core/malloc.c
--- 1.0.0+git-20190125.36a4c85-5.1/src/core/malloc.c	2019-02-09 16:03:59.000000000 +0000
+++ 1.21.1+git-20220113.fbbdc3926-0ubuntu1/src/core/malloc.c	2022-01-13 13:43:08.000000000 +0000
@@ -596,8 +596,8 @@ void * malloc ( size_t size ) {
  *
  * @v ptr		Memory allocated by malloc(), or NULL
  *
- * Memory allocated with malloc_dma() cannot be freed with free(); it
- * must be freed with free_dma() instead.
+ * Memory allocated with malloc_phys() cannot be freed with free(); it
+ * must be freed with free_phys() instead.
  *
  * If @c ptr is NULL, no action is taken.
  */
diff -pruN 1.0.0+git-20190125.36a4c85-5.1/src/core/null_acpi.c 1.21.1+git-20220113.fbbdc3926-0ubuntu1/src/core/null_acpi.c
--- 1.0.0+git-20190125.36a4c85-5.1/src/core/null_acpi.c	2019-02-09 16:03:59.000000000 +0000
+++ 1.21.1+git-20220113.fbbdc3926-0ubuntu1/src/core/null_acpi.c	2022-01-13 13:43:08.000000000 +0000
@@ -1,3 +1,3 @@
 #include <ipxe/acpi.h>
 
-PROVIDE_ACPI_INLINE ( null, acpi_find_rsdt );
+PROVIDE_ACPI_INLINE ( null, acpi_find );
diff -pruN 1.0.0+git-20190125.36a4c85-5.1/src/core/open.c 1.21.1+git-20220113.fbbdc3926-0ubuntu1/src/core/open.c
--- 1.0.0+git-20190125.36a4c85-5.1/src/core/open.c	2019-02-09 16:03:59.000000000 +0000
+++ 1.21.1+git-20220113.fbbdc3926-0ubuntu1/src/core/open.c	2022-01-13 13:43:08.000000000 +0000
@@ -25,6 +25,7 @@ FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
 
 #include <stdarg.h>
 #include <string.h>
+#include <strings.h>
 #include <errno.h>
 #include <ipxe/xfer.h>
 #include <ipxe/uri.h>
@@ -47,7 +48,7 @@ struct uri_opener * xfer_uri_opener ( co
 	struct uri_opener *opener;
 
 	for_each_table_entry ( opener, URI_OPENERS ) {
-		if ( strcmp ( scheme, opener->scheme ) == 0 )
+		if ( strcasecmp ( scheme, opener->scheme ) == 0 )
 			return opener;
 	}
 	return NULL;
@@ -147,10 +148,8 @@ int xfer_open_socket ( struct interface
 	       socket_family_name ( peer->sa_family ) );
 
 	for_each_table_entry ( opener, SOCKET_OPENERS ) {
-		if ( ( opener->semantics == semantics ) &&
-		     ( opener->family == peer->sa_family ) ) {
+		if ( opener->semantics == semantics )
 			return opener->open ( intf, peer, local );
-		}
 	}
 
 	DBGC ( INTF_COL ( intf ), "INTF " INTF_FMT " attempted to open "
diff -pruN 1.0.0+git-20190125.36a4c85-5.1/src/core/parseopt.c 1.21.1+git-20220113.fbbdc3926-0ubuntu1/src/core/parseopt.c
--- 1.0.0+git-20190125.36a4c85-5.1/src/core/parseopt.c	2019-02-09 16:03:59.000000000 +0000
+++ 1.21.1+git-20220113.fbbdc3926-0ubuntu1/src/core/parseopt.c	2022-01-13 13:43:08.000000000 +0000
@@ -93,7 +93,7 @@ int parse_integer ( char *text, unsigned
 
 	/* Parse integer */
 	*value = strtoul ( text, &endp, 0 );
-	if ( *endp ) {
+	if ( *endp || ( ! *text ) ) {
 		printf ( "\"%s\": invalid integer value\n", text );
 		return -EINVAL_INTEGER;
 	}
diff -pruN 1.0.0+git-20190125.36a4c85-5.1/src/core/settings.c 1.21.1+git-20220113.fbbdc3926-0ubuntu1/src/core/settings.c
--- 1.0.0+git-20190125.36a4c85-5.1/src/core/settings.c	2019-02-09 16:03:59.000000000 +0000
+++ 1.21.1+git-20220113.fbbdc3926-0ubuntu1/src/core/settings.c	2022-01-13 13:43:08.000000000 +0000
@@ -370,12 +370,14 @@ const char * settings_name ( struct sett
 static struct settings *
 parse_settings_name ( const char *name, get_child_settings_t get_child ) {
 	struct settings *settings = &settings_root;
-	char name_copy[ strlen ( name ) + 1 ];
+	char *name_copy;
 	char *subname;
 	char *remainder;
 
 	/* Create modifiable copy of name */
-	memcpy ( name_copy, name, sizeof ( name_copy ) );
+	name_copy = strdup ( name );
+	if ( ! name_copy )
+		return NULL;
 	remainder = name_copy;
 
 	/* Parse each name component in turn */
@@ -389,6 +391,9 @@ parse_settings_name ( const char *name,
 			break;
 	}
 
+	/* Free modifiable copy of name */
+	free ( name_copy );
+
 	return settings;
 }
 
@@ -2194,7 +2199,7 @@ const struct setting_type setting_type_b
 };
 
 /**
- * Format UUID setting value
+ * Format UUID/GUID setting value
  *
  * @v type		Setting type
  * @v raw		Raw setting value
@@ -2203,17 +2208,24 @@ const struct setting_type setting_type_b
  * @v len		Length of buffer
  * @ret len		Length of formatted value, or negative error
  */
-static int format_uuid_setting ( const struct setting_type *type __unused,
+static int format_uuid_setting ( const struct setting_type *type,
 				 const void *raw, size_t raw_len, char *buf,
 				 size_t len ) {
-	const union uuid *uuid = raw;
+	union uuid uuid;
 
 	/* Range check */
-	if ( raw_len != sizeof ( *uuid ) )
+	if ( raw_len != sizeof ( uuid ) )
 		return -ERANGE;
 
+	/* Copy value */
+	memcpy ( &uuid, raw, sizeof ( uuid ) );
+
+	/* Mangle GUID byte ordering */
+	if ( type == &setting_type_guid )
+		uuid_mangle ( &uuid );
+
 	/* Format value */
-	return snprintf ( buf, len, "%s", uuid_ntoa ( uuid ) );
+	return snprintf ( buf, len, "%s", uuid_ntoa ( &uuid ) );
 }
 
 /** UUID setting type */
@@ -2222,6 +2234,12 @@ const struct setting_type setting_type_u
 	.format = format_uuid_setting,
 };
 
+/** GUID setting type */
+const struct setting_type setting_type_guid __setting_type = {
+	.name = "guid",
+	.format = format_uuid_setting,
+};
+
 /**
  * Format PCI bus:dev.fn setting value
  *
diff -pruN 1.0.0+git-20190125.36a4c85-5.1/src/core/string.c 1.21.1+git-20220113.fbbdc3926-0ubuntu1/src/core/string.c
--- 1.0.0+git-20190125.36a4c85-5.1/src/core/string.c	2019-02-09 16:03:59.000000000 +0000
+++ 1.21.1+git-20220113.fbbdc3926-0ubuntu1/src/core/string.c	2022-01-13 13:43:08.000000000 +0000
@@ -27,6 +27,7 @@ FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
 #include <stdint.h>
 #include <stdlib.h>
 #include <string.h>
+#include <strings.h>
 #include <ctype.h>
 
 /** @file
@@ -52,7 +53,7 @@ void * generic_memset ( void *dest, int
 }
 
 /**
- * Copy memory region
+ * Copy memory region (forwards)
  *
  * @v dest		Destination region
  * @v src		Source region
@@ -69,25 +70,40 @@ void * generic_memcpy ( void *dest, cons
 }
 
 /**
- * Copy (possibly overlapping) memory region
+ * Copy memory region (backwards)
  *
  * @v dest		Destination region
  * @v src		Source region
  * @v len		Length
  * @ret dest		Destination region
  */
-void * generic_memmove ( void *dest, const void *src, size_t len ) {
+void * generic_memcpy_reverse ( void *dest, const void *src, size_t len ) {
 	const uint8_t *src_bytes = ( src + len );
 	uint8_t *dest_bytes = ( dest + len );
 
-	if ( dest < src )
-		return generic_memcpy ( dest, src, len );
 	while ( len-- )
 		*(--dest_bytes) = *(--src_bytes);
 	return dest;
 }
 
 /**
+ * Copy (possibly overlapping) memory region
+ *
+ * @v dest		Destination region
+ * @v src		Source region
+ * @v len		Length
+ * @ret dest		Destination region
+ */
+void * generic_memmove ( void *dest, const void *src, size_t len ) {
+
+	if ( dest < src ) {
+		return generic_memcpy ( dest, src, len );
+	} else {
+		return generic_memcpy_reverse ( dest, src, len );
+	}
+}
+
+/**
  * Compare memory regions
  *
  * @v first		First region
@@ -101,7 +117,7 @@ int memcmp ( const void *first, const vo
 	int diff;
 
 	while ( len-- ) {
-		diff = ( *(second_bytes++) - *(first_bytes++) );
+		diff = ( *(first_bytes++) - *(second_bytes++) );
 		if ( diff )
 			return diff;
 	}
@@ -190,11 +206,24 @@ int strncmp ( const char *first, const c
  * @ret diff		Difference
  */
 int strcasecmp ( const char *first, const char *second ) {
+
+	return strncasecmp ( first, second, ~( ( size_t ) 0 ) );
+}
+
+/**
+ * Compare case-insensitive strings
+ *
+ * @v first		First string
+ * @v second		Second string
+ * @v max		Maximum length to compare
+ * @ret diff		Difference
+ */
+int strncasecmp ( const char *first, const char *second, size_t max ) {
 	const uint8_t *first_bytes = ( ( const uint8_t * ) first );
 	const uint8_t *second_bytes = ( ( const uint8_t * ) second );
 	int diff;
 
-	for ( ; ; first_bytes++, second_bytes++ ) {
+	for ( ; max-- ; first_bytes++, second_bytes++ ) {
 		diff = ( toupper ( *first_bytes ) -
 			 toupper ( *second_bytes ) );
 		if ( diff )
@@ -202,6 +231,7 @@ int strcasecmp ( const char *first, cons
 		if ( ! *first_bytes )
 			return 0;
 	}
+	return 0;
 }
 
 /**
diff -pruN 1.0.0+git-20190125.36a4c85-5.1/src/core/uri.c 1.21.1+git-20220113.fbbdc3926-0ubuntu1/src/core/uri.c
--- 1.0.0+git-20190125.36a4c85-5.1/src/core/uri.c	2019-02-09 16:03:59.000000000 +0000
+++ 1.21.1+git-20220113.fbbdc3926-0ubuntu1/src/core/uri.c	2022-01-13 13:43:08.000000000 +0000
@@ -79,12 +79,10 @@ size_t uri_decode ( const char *encoded,
 /**
  * Decode URI field in-place
  *
- * @v uri		URI
- * @v field		URI field index
+ * @v encoded		Encoded field, or NULL
  */
-static void uri_decode_inplace ( struct uri *uri, unsigned int field ) {
-	const char *encoded = uri_field ( uri, field );
-	char *decoded = ( ( char * ) encoded );
+static void uri_decode_inplace ( char *encoded ) {
+	char *decoded = encoded;
 	size_t len;
 
 	/* Do nothing if field is not present */
@@ -150,7 +148,7 @@ static int uri_character_escaped ( char
 	 * parser but for any other URI parsers (e.g. HTTP query
 	 * string parsers, which care about '=' and '&').
 	 */
-	static const char *escaped[URI_FIELDS] = {
+	static const char *escaped[URI_EPATH] = {
 		/* Scheme or default: escape everything */
 		[URI_SCHEME]	= "/#:@?=&",
 		/* Opaque part: escape characters which would affect
@@ -172,20 +170,21 @@ static int uri_character_escaped ( char
 		 * appears within paths.
 		 */
 		[URI_PATH]	= "#:@?",
-		/* Query: escape everything except '/', which
-		 * sometimes appears within queries.
-		 */
-		[URI_QUERY]	= "#:@?",
-		/* Fragment: escape everything */
-		[URI_FRAGMENT]	= "/#:@?",
 	};
 
-	return ( /* Always escape non-printing characters and whitespace */
-		 ( ! isprint ( c ) ) || ( c == ' ' ) ||
-		 /* Always escape '%' */
-		 ( c == '%' ) ||
-		 /* Escape field-specific characters */
-		 strchr ( escaped[field], c ) );
+	/* Always escape non-printing characters and whitespace */
+	if ( ( ! isprint ( c ) ) || ( c == ' ' ) )
+		return 1;
+
+	/* Escape nothing else in already-escaped fields */
+	if ( field >= URI_EPATH )
+		return 0;
+
+	/* Escape '%' and any field-specific characters */
+	if ( ( c == '%' ) || strchr ( escaped[field], c ) )
+		return 1;
+
+	return 0;
 }
 
 /**
@@ -262,10 +261,12 @@ static void uri_dump ( const struct uri
 		DBGC ( uri, " port \"%s\"", uri->port );
 	if ( uri->path )
 		DBGC ( uri, " path \"%s\"", uri->path );
-	if ( uri->query )
-		DBGC ( uri, " query \"%s\"", uri->query );
-	if ( uri->fragment )
-		DBGC ( uri, " fragment \"%s\"", uri->fragment );
+	if ( uri->epath )
+		DBGC ( uri, " epath \"%s\"", uri->epath );
+	if ( uri->equery )
+		DBGC ( uri, " equery \"%s\"", uri->equery );
+	if ( uri->efragment )
+		DBGC ( uri, " efragment \"%s\"", uri->efragment );
 	if ( uri->params )
 		DBGC ( uri, " params \"%s\"", uri->params->name );
 }
@@ -298,17 +299,19 @@ struct uri * parse_uri ( const char *uri
 	char *raw;
 	char *tmp;
 	char *path;
+	char *epath;
 	char *authority;
 	size_t raw_len;
 	unsigned int field;
 
-	/* Allocate space for URI struct and a copy of the string */
+	/* Allocate space for URI struct and two copies of the string */
 	raw_len = ( strlen ( uri_string ) + 1 /* NUL */ );
-	uri = zalloc ( sizeof ( *uri ) + raw_len );
+	uri = zalloc ( sizeof ( *uri ) + ( 2 * raw_len ) );
 	if ( ! uri )
 		return NULL;
 	ref_init ( &uri->refcnt, uri_free );
 	raw = ( ( ( void * ) uri ) + sizeof ( *uri ) );
+	path = ( raw + raw_len );
 
 	/* Copy in the raw string */
 	memcpy ( raw, uri_string, raw_len );
@@ -328,7 +331,7 @@ struct uri * parse_uri ( const char *uri
 	/* Chop off the fragment, if it exists */
 	if ( ( tmp = strchr ( raw, '#' ) ) ) {
 		*(tmp++) = '\0';
-		uri->fragment = tmp;
+		uri->efragment = tmp;
 	}
 
 	/* Identify absolute/relative URI */
@@ -338,47 +341,47 @@ struct uri * parse_uri ( const char *uri
 		*(tmp++) = '\0';
 		if ( *tmp == '/' ) {
 			/* Absolute URI with hierarchical part */
-			path = tmp;
+			epath = tmp;
 		} else {
 			/* Absolute URI with opaque part */
 			uri->opaque = tmp;
-			path = NULL;
+			epath = NULL;
 		}
 	} else {
 		/* Relative URI */
-		path = raw;
+		epath = raw;
 	}
 
 	/* If we don't have a path (i.e. we have an absolute URI with
 	 * an opaque portion, we're already finished processing
 	 */
-	if ( ! path )
+	if ( ! epath )
 		goto done;
 
 	/* Chop off the query, if it exists */
-	if ( ( tmp = strchr ( path, '?' ) ) ) {
+	if ( ( tmp = strchr ( epath, '?' ) ) ) {
 		*(tmp++) = '\0';
-		uri->query = tmp;
+		uri->equery = tmp;
 	}
 
 	/* If we have no path remaining, then we're already finished
 	 * processing.
 	 */
-	if ( ! path[0] )
+	if ( ! epath[0] )
 		goto done;
 
 	/* Identify net/absolute/relative path */
-	if ( uri->scheme && ( strncmp ( path, "//", 2 ) == 0 ) ) {
+	if ( uri->scheme && ( strncmp ( epath, "//", 2 ) == 0 ) ) {
 		/* Net path.  If this is terminated by the first '/'
 		 * of an absolute path, then we have no space for a
 		 * terminator after the authority field, so shuffle
 		 * the authority down by one byte, overwriting one of
 		 * the two slashes.
 		 */
-		authority = ( path + 2 );
+		authority = ( epath + 2 );
 		if ( ( tmp = strchr ( authority, '/' ) ) ) {
 			/* Shuffle down */
-			uri->path = tmp;
+			uri->epath = tmp;
 			memmove ( ( authority - 1 ), authority,
 				  ( tmp - authority ) );
 			authority--;
@@ -386,10 +389,16 @@ struct uri * parse_uri ( const char *uri
 		}
 	} else {
 		/* Absolute/relative path */
-		uri->path = path;
+		uri->epath = epath;
 		authority = NULL;
 	}
 
+	/* Create copy of path for decoding */
+	if ( uri->epath ) {
+		strcpy ( path, uri->epath );
+		uri->path = path;
+	}
+
 	/* If we don't have an authority (i.e. we have a non-net
 	 * path), we're already finished processing
 	 */
@@ -413,16 +422,16 @@ struct uri * parse_uri ( const char *uri
 	}
 
 	/* Split host into host[:port] */
-	if ( ( uri->host[ strlen ( uri->host ) - 1 ] != ']' ) &&
-	     ( tmp = strrchr ( uri->host, ':' ) ) ) {
+	if ( ( tmp = strrchr ( uri->host, ':' ) ) &&
+	     ( uri->host[ strlen ( uri->host ) - 1 ] != ']' ) ) {
 		*(tmp++) = '\0';
 		uri->port = tmp;
 	}
 
  done:
 	/* Decode fields in-place */
-	for ( field = 0 ; field < URI_FIELDS ; field++ )
-		uri_decode_inplace ( uri, field );
+	for ( field = 0 ; field < URI_EPATH ; field++ )
+		uri_decode_inplace ( ( char * ) uri_field ( uri, field ) );
 
 	DBGC ( uri, "URI parsed \"%s\" to", uri_string );
 	uri_dump ( uri );
@@ -458,8 +467,8 @@ size_t format_uri ( const struct uri *ur
 	static const char prefixes[URI_FIELDS] = {
 		[URI_PASSWORD] = ':',
 		[URI_PORT] = ':',
-		[URI_QUERY] = '?',
-		[URI_FRAGMENT] = '#',
+		[URI_EQUERY] = '?',
+		[URI_EFRAGMENT] = '#',
 	};
 	char prefix;
 	size_t used = 0;
@@ -480,6 +489,10 @@ size_t format_uri ( const struct uri *ur
 		if ( ! uri_field ( uri, field ) )
 			continue;
 
+		/* Skip path field if encoded path is present */
+		if ( ( field == URI_PATH ) && uri->epath )
+			continue;
+
 		/* Prefix this field, if applicable */
 		prefix = prefixes[field];
 		if ( ( field == URI_HOST ) && ( uri->user != NULL ) )
@@ -676,6 +689,7 @@ char * resolve_path ( const char *base_p
 struct uri * resolve_uri ( const struct uri *base_uri,
 			   struct uri *relative_uri ) {
 	struct uri tmp_uri;
+	char *tmp_epath = NULL;
 	char *tmp_path = NULL;
 	struct uri *new_uri;
 
@@ -685,20 +699,27 @@ struct uri * resolve_uri ( const struct
 
 	/* Mangle URI */
 	memcpy ( &tmp_uri, base_uri, sizeof ( tmp_uri ) );
-	if ( relative_uri->path ) {
-		tmp_path = resolve_path ( ( base_uri->path ?
-					    base_uri->path : "/" ),
-					  relative_uri->path );
+	if ( relative_uri->epath ) {
+		tmp_epath = resolve_path ( ( base_uri->epath ?
+					     base_uri->epath : "/" ),
+					   relative_uri->epath );
+		if ( ! tmp_epath )
+			goto err_epath;
+		tmp_path = strdup ( tmp_epath );
+		if ( ! tmp_path )
+			goto err_path;
+		uri_decode_inplace ( tmp_path );
+		tmp_uri.epath = tmp_epath;
 		tmp_uri.path = tmp_path;
-		tmp_uri.query = relative_uri->query;
-		tmp_uri.fragment = relative_uri->fragment;
+		tmp_uri.equery = relative_uri->equery;
+		tmp_uri.efragment = relative_uri->efragment;
 		tmp_uri.params = relative_uri->params;
-	} else if ( relative_uri->query ) {
-		tmp_uri.query = relative_uri->query;
-		tmp_uri.fragment = relative_uri->fragment;
+	} else if ( relative_uri->equery ) {
+		tmp_uri.equery = relative_uri->equery;
+		tmp_uri.efragment = relative_uri->efragment;
 		tmp_uri.params = relative_uri->params;
-	} else if ( relative_uri->fragment ) {
-		tmp_uri.fragment = relative_uri->fragment;
+	} else if ( relative_uri->efragment ) {
+		tmp_uri.efragment = relative_uri->efragment;
 		tmp_uri.params = relative_uri->params;
 	} else if ( relative_uri->params ) {
 		tmp_uri.params = relative_uri->params;
@@ -707,7 +728,14 @@ struct uri * resolve_uri ( const struct
 	/* Create demangled URI */
 	new_uri = uri_dup ( &tmp_uri );
 	free ( tmp_path );
+	free ( tmp_epath );
 	return new_uri;
+
+	free ( tmp_path );
+ err_path:
+	free ( tmp_epath );
+ err_epath:
+	return NULL;
 }
 
 /**
@@ -746,6 +774,7 @@ static struct uri * tftp_uri ( struct so
 	if ( asprintf ( &path, "/%s", filename ) < 0 )
 		goto err_path;
 	tmp.path = path;
+	tmp.epath = path;
 
 	/* Demangle URI */
 	uri = uri_dup ( &tmp );
diff -pruN 1.0.0+git-20190125.36a4c85-5.1/src/crypto/bigint.c 1.21.1+git-20220113.fbbdc3926-0ubuntu1/src/crypto/bigint.c
--- 1.0.0+git-20190125.36a4c85-5.1/src/crypto/bigint.c	2019-02-09 16:03:59.000000000 +0000
+++ 1.21.1+git-20220113.fbbdc3926-0ubuntu1/src/crypto/bigint.c	2022-01-13 13:43:08.000000000 +0000
@@ -26,6 +26,7 @@ FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
 #include <stdint.h>
 #include <string.h>
 #include <assert.h>
+#include <ipxe/profile.h>
 #include <ipxe/bigint.h>
 
 /** @file
@@ -33,6 +34,22 @@ FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
  * Big integer support
  */
 
+/** Modular multiplication overall profiler */
+static struct profiler bigint_mod_multiply_profiler __profiler =
+	{ .name = "bigint_mod_multiply" };
+
+/** Modular multiplication multiply step profiler */
+static struct profiler bigint_mod_multiply_multiply_profiler __profiler =
+	{ .name = "bigint_mod_multiply.multiply" };
+
+/** Modular multiplication rescale step profiler */
+static struct profiler bigint_mod_multiply_rescale_profiler __profiler =
+	{ .name = "bigint_mod_multiply.rescale" };
+
+/** Modular multiplication subtract step profiler */
+static struct profiler bigint_mod_multiply_subtract_profiler __profiler =
+	{ .name = "bigint_mod_multiply.subtract" };
+
 /**
  * Perform modular multiplication of big integers
  *
@@ -63,31 +80,43 @@ void bigint_mod_multiply_raw ( const big
 	int rotation;
 	int i;
 
+	/* Start profiling */
+	profile_start ( &bigint_mod_multiply_profiler );
+
 	/* Sanity check */
 	assert ( sizeof ( *temp ) == bigint_mod_multiply_tmp_len ( modulus ) );
 
 	/* Perform multiplication */
+	profile_start ( &bigint_mod_multiply_multiply_profiler );
 	bigint_multiply ( multiplicand, multiplier, &temp->result );
+	profile_stop ( &bigint_mod_multiply_multiply_profiler );
 
 	/* Rescale modulus to match result */
+	profile_start ( &bigint_mod_multiply_rescale_profiler );
 	bigint_grow ( modulus, &temp->modulus );
 	rotation = ( bigint_max_set_bit ( &temp->result ) -
 		     bigint_max_set_bit ( &temp->modulus ) );
 	for ( i = 0 ; i < rotation ; i++ )
 		bigint_rol ( &temp->modulus );
+	profile_stop ( &bigint_mod_multiply_rescale_profiler );
 
 	/* Subtract multiples of modulus */
+	profile_start ( &bigint_mod_multiply_subtract_profiler );
 	for ( i = 0 ; i <= rotation ; i++ ) {
 		if ( bigint_is_geq ( &temp->result, &temp->modulus ) )
 			bigint_subtract ( &temp->modulus, &temp->result );
 		bigint_ror ( &temp->modulus );
 	}
+	profile_stop ( &bigint_mod_multiply_subtract_profiler );
 
 	/* Resize result */
 	bigint_shrink ( &temp->result, result );
 
 	/* Sanity check */
 	assert ( bigint_is_geq ( modulus, result ) );
+
+	/* Stop profiling */
+	profile_stop ( &bigint_mod_multiply_profiler );
 }
 
 /**
diff -pruN 1.0.0+git-20190125.36a4c85-5.1/src/crypto/certstore.c 1.21.1+git-20220113.fbbdc3926-0ubuntu1/src/crypto/certstore.c
--- 1.0.0+git-20190125.36a4c85-5.1/src/crypto/certstore.c	2019-02-09 16:03:59.000000000 +0000
+++ 1.21.1+git-20220113.fbbdc3926-0ubuntu1/src/crypto/certstore.c	2022-01-13 13:43:08.000000000 +0000
@@ -116,13 +116,13 @@ struct x509_certificate * certstore_find
  * @v key		Private key
  * @ret cert		X.509 certificate, or NULL if not found
  */
-struct x509_certificate * certstore_find_key ( struct asn1_cursor *key ) {
+struct x509_certificate * certstore_find_key ( struct private_key *key ) {
 	struct x509_certificate *cert;
 
 	/* Search for certificate within store */
 	list_for_each_entry ( cert, &certstore.links, store.list ) {
 		if ( pubkey_match ( cert->signature_algorithm->pubkey,
-				    key->data, key->len,
+				    key->builder.data, key->builder.len,
 				    cert->subject.public_key.raw.data,
 				    cert->subject.public_key.raw.len ) == 0 )
 			return certstore_found ( cert );
diff -pruN 1.0.0+git-20190125.36a4c85-5.1/src/crypto/cms.c 1.21.1+git-20220113.fbbdc3926-0ubuntu1/src/crypto/cms.c
--- 1.0.0+git-20190125.36a4c85-5.1/src/crypto/cms.c	2019-02-09 16:03:59.000000000 +0000
+++ 1.21.1+git-20220113.fbbdc3926-0ubuntu1/src/crypto/cms.c	2022-01-13 13:43:08.000000000 +0000
@@ -76,7 +76,7 @@ static uint8_t oid_signeddata[] = { ASN1
 
 /** "pkcs7-signedData" object identifier cursor */
 static struct asn1_cursor oid_signeddata_cursor =
-	ASN1_OID_CURSOR ( oid_signeddata );
+	ASN1_CURSOR ( oid_signeddata );
 
 /**
  * Parse CMS signature content type
diff -pruN 1.0.0+git-20190125.36a4c85-5.1/src/crypto/deflate.c 1.21.1+git-20220113.fbbdc3926-0ubuntu1/src/crypto/deflate.c
--- 1.0.0+git-20190125.36a4c85-5.1/src/crypto/deflate.c	2019-02-09 16:03:59.000000000 +0000
+++ 1.21.1+git-20220113.fbbdc3926-0ubuntu1/src/crypto/deflate.c	2022-01-13 13:43:08.000000000 +0000
@@ -56,7 +56,7 @@ static uint8_t deflate_reverse[256];
  * does not fit the pattern (it represents a length of 258; following
  * the pattern from the earlier codes would give a length of 259), and
  * has no extra bits.  Codes 286-287 are invalid, but can occur.  We
- * treat any code greater than 284 as meaning "length 285, no extra
+ * treat any code greater than 284 as meaning "length 258, no extra
  * bits".
  */
 static uint8_t deflate_litlen_base[28];
diff -pruN 1.0.0+git-20190125.36a4c85-5.1/src/crypto/md4.c 1.21.1+git-20220113.fbbdc3926-0ubuntu1/src/crypto/md4.c
--- 1.0.0+git-20190125.36a4c85-5.1/src/crypto/md4.c	2019-02-09 16:03:59.000000000 +0000
+++ 1.21.1+git-20220113.fbbdc3926-0ubuntu1/src/crypto/md4.c	2022-01-13 13:43:08.000000000 +0000
@@ -35,7 +35,6 @@ FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
 #include <assert.h>
 #include <ipxe/rotate.h>
 #include <ipxe/crypto.h>
-#include <ipxe/asn1.h>
 #include <ipxe/md4.h>
 
 /** MD4 variables */
@@ -268,13 +267,3 @@ struct digest_algorithm md4_algorithm =
 	.update		= md4_update,
 	.final		= md4_final,
 };
-
-/** "md4" object identifier */
-static uint8_t oid_md4[] = { ASN1_OID_MD4 };
-
-/** "md4" OID-identified algorithm */
-struct asn1_algorithm oid_md4_algorithm __asn1_algorithm = {
-	.name = "md4",
-	.digest = &md4_algorithm,
-	.oid = ASN1_OID_CURSOR ( oid_md4 ),
-};
diff -pruN 1.0.0+git-20190125.36a4c85-5.1/src/crypto/md5.c 1.21.1+git-20220113.fbbdc3926-0ubuntu1/src/crypto/md5.c
--- 1.0.0+git-20190125.36a4c85-5.1/src/crypto/md5.c	2019-02-09 16:03:59.000000000 +0000
+++ 1.21.1+git-20220113.fbbdc3926-0ubuntu1/src/crypto/md5.c	2022-01-13 13:43:08.000000000 +0000
@@ -35,7 +35,6 @@ FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
 #include <assert.h>
 #include <ipxe/rotate.h>
 #include <ipxe/crypto.h>
-#include <ipxe/asn1.h>
 #include <ipxe/md5.h>
 
 /** MD5 variables */
@@ -293,13 +292,3 @@ struct digest_algorithm md5_algorithm =
 	.update		= md5_update,
 	.final		= md5_final,
 };
-
-/** "md5" object identifier */
-static uint8_t oid_md5[] = { ASN1_OID_MD5 };
-
-/** "md5" OID-identified algorithm */
-struct asn1_algorithm oid_md5_algorithm __asn1_algorithm = {
-	.name = "md5",
-	.digest = &md5_algorithm,
-	.oid = ASN1_OID_CURSOR ( oid_md5 ),
-};
diff -pruN 1.0.0+git-20190125.36a4c85-5.1/src/crypto/mishmash/oid_md4.c 1.21.1+git-20220113.fbbdc3926-0ubuntu1/src/crypto/mishmash/oid_md4.c
--- 1.0.0+git-20190125.36a4c85-5.1/src/crypto/mishmash/oid_md4.c	1970-01-01 00:00:00.000000000 +0000
+++ 1.21.1+git-20220113.fbbdc3926-0ubuntu1/src/crypto/mishmash/oid_md4.c	2022-01-13 13:43:08.000000000 +0000
@@ -0,0 +1,37 @@
+/*
+ * Copyright (C) 2020 Michael Brown <mbrown@fensystems.co.uk>.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of the
+ * License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+ * 02110-1301, USA.
+ *
+ * You can also choose to distribute this program under the terms of
+ * the Unmodified Binary Distribution Licence (as given in the file
+ * COPYING.UBDL), provided that you have satisfied its requirements.
+ */
+
+FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
+
+#include <ipxe/md4.h>
+#include <ipxe/asn1.h>
+
+/** "md4" object identifier */
+static uint8_t oid_md4[] = { ASN1_OID_MD4 };
+
+/** "md4" OID-identified algorithm */
+struct asn1_algorithm oid_md4_algorithm __asn1_algorithm = {
+	.name = "md4",
+	.digest = &md4_algorithm,
+	.oid = ASN1_CURSOR ( oid_md4 ),
+};
diff -pruN 1.0.0+git-20190125.36a4c85-5.1/src/crypto/mishmash/oid_md5.c 1.21.1+git-20220113.fbbdc3926-0ubuntu1/src/crypto/mishmash/oid_md5.c
--- 1.0.0+git-20190125.36a4c85-5.1/src/crypto/mishmash/oid_md5.c	1970-01-01 00:00:00.000000000 +0000
+++ 1.21.1+git-20220113.fbbdc3926-0ubuntu1/src/crypto/mishmash/oid_md5.c	2022-01-13 13:43:08.000000000 +0000
@@ -0,0 +1,37 @@
+/*
+ * Copyright (C) 2020 Michael Brown <mbrown@fensystems.co.uk>.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of the
+ * License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+ * 02110-1301, USA.
+ *
+ * You can also choose to distribute this program under the terms of
+ * the Unmodified Binary Distribution Licence (as given in the file
+ * COPYING.UBDL), provided that you have satisfied its requirements.
+ */
+
+FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
+
+#include <ipxe/md5.h>
+#include <ipxe/asn1.h>
+
+/** "md5" object identifier */
+static uint8_t oid_md5[] = { ASN1_OID_MD5 };
+
+/** "md5" OID-identified algorithm */
+struct asn1_algorithm oid_md5_algorithm __asn1_algorithm = {
+	.name = "md5",
+	.digest = &md5_algorithm,
+	.oid = ASN1_CURSOR ( oid_md5 ),
+};
diff -pruN 1.0.0+git-20190125.36a4c85-5.1/src/crypto/mishmash/oid_rsa.c 1.21.1+git-20220113.fbbdc3926-0ubuntu1/src/crypto/mishmash/oid_rsa.c
--- 1.0.0+git-20190125.36a4c85-5.1/src/crypto/mishmash/oid_rsa.c	1970-01-01 00:00:00.000000000 +0000
+++ 1.21.1+git-20220113.fbbdc3926-0ubuntu1/src/crypto/mishmash/oid_rsa.c	2022-01-13 13:43:08.000000000 +0000
@@ -0,0 +1,38 @@
+/*
+ * Copyright (C) 2020 Michael Brown <mbrown@fensystems.co.uk>.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of the
+ * License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+ * 02110-1301, USA.
+ *
+ * You can also choose to distribute this program under the terms of
+ * the Unmodified Binary Distribution Licence (as given in the file
+ * COPYING.UBDL), provided that you have satisfied its requirements.
+ */
+
+FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
+
+#include <ipxe/rsa.h>
+#include <ipxe/asn1.h>
+
+/** "rsaEncryption" object identifier */
+static uint8_t oid_rsa_encryption[] = { ASN1_OID_RSAENCRYPTION };
+
+/** "rsaEncryption" OID-identified algorithm */
+struct asn1_algorithm rsa_encryption_algorithm __asn1_algorithm = {
+	.name = "rsaEncryption",
+	.pubkey = &rsa_algorithm,
+	.digest = NULL,
+	.oid = ASN1_CURSOR ( oid_rsa_encryption ),
+};
diff -pruN 1.0.0+git-20190125.36a4c85-5.1/src/crypto/mishmash/oid_sha1.c 1.21.1+git-20220113.fbbdc3926-0ubuntu1/src/crypto/mishmash/oid_sha1.c
--- 1.0.0+git-20190125.36a4c85-5.1/src/crypto/mishmash/oid_sha1.c	1970-01-01 00:00:00.000000000 +0000
+++ 1.21.1+git-20220113.fbbdc3926-0ubuntu1/src/crypto/mishmash/oid_sha1.c	2022-01-13 13:43:08.000000000 +0000
@@ -0,0 +1,37 @@
+/*
+ * Copyright (C) 2020 Michael Brown <mbrown@fensystems.co.uk>.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of the
+ * License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+ * 02110-1301, USA.
+ *
+ * You can also choose to distribute this program under the terms of
+ * the Unmodified Binary Distribution Licence (as given in the file
+ * COPYING.UBDL), provided that you have satisfied its requirements.
+ */
+
+FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
+
+#include <ipxe/sha1.h>
+#include <ipxe/asn1.h>
+
+/** "sha1" object identifier */
+static uint8_t oid_sha1[] = { ASN1_OID_SHA1 };
+
+/** "sha1" OID-identified algorithm */
+struct asn1_algorithm oid_sha1_algorithm __asn1_algorithm = {
+	.name = "sha1",
+	.digest = &sha1_algorithm,
+	.oid = ASN1_CURSOR ( oid_sha1 ),
+};
diff -pruN 1.0.0+git-20190125.36a4c85-5.1/src/crypto/mishmash/oid_sha224.c 1.21.1+git-20220113.fbbdc3926-0ubuntu1/src/crypto/mishmash/oid_sha224.c
--- 1.0.0+git-20190125.36a4c85-5.1/src/crypto/mishmash/oid_sha224.c	1970-01-01 00:00:00.000000000 +0000
+++ 1.21.1+git-20220113.fbbdc3926-0ubuntu1/src/crypto/mishmash/oid_sha224.c	2022-01-13 13:43:08.000000000 +0000
@@ -0,0 +1,37 @@
+/*
+ * Copyright (C) 2020 Michael Brown <mbrown@fensystems.co.uk>.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of the
+ * License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+ * 02110-1301, USA.
+ *
+ * You can also choose to distribute this program under the terms of
+ * the Unmodified Binary Distribution Licence (as given in the file
+ * COPYING.UBDL), provided that you have satisfied its requirements.
+ */
+
+FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
+
+#include <ipxe/sha256.h>
+#include <ipxe/asn1.h>
+
+/** "sha224" object identifier */
+static uint8_t oid_sha224[] = { ASN1_OID_SHA224 };
+
+/** "sha224" OID-identified algorithm */
+struct asn1_algorithm oid_sha224_algorithm __asn1_algorithm = {
+	.name = "sha224",
+	.digest = &sha224_algorithm,
+	.oid = ASN1_CURSOR ( oid_sha224 ),
+};
diff -pruN 1.0.0+git-20190125.36a4c85-5.1/src/crypto/mishmash/oid_sha256.c 1.21.1+git-20220113.fbbdc3926-0ubuntu1/src/crypto/mishmash/oid_sha256.c
--- 1.0.0+git-20190125.36a4c85-5.1/src/crypto/mishmash/oid_sha256.c	1970-01-01 00:00:00.000000000 +0000
+++ 1.21.1+git-20220113.fbbdc3926-0ubuntu1/src/crypto/mishmash/oid_sha256.c	2022-01-13 13:43:08.000000000 +0000
@@ -0,0 +1,37 @@
+/*
+ * Copyright (C) 2020 Michael Brown <mbrown@fensystems.co.uk>.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of the
+ * License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+ * 02110-1301, USA.
+ *
+ * You can also choose to distribute this program under the terms of
+ * the Unmodified Binary Distribution Licence (as given in the file
+ * COPYING.UBDL), provided that you have satisfied its requirements.
+ */
+
+FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
+
+#include <ipxe/sha256.h>
+#include <ipxe/asn1.h>
+
+/** "sha256" object identifier */
+static uint8_t oid_sha256[] = { ASN1_OID_SHA256 };
+
+/** "sha256" OID-identified algorithm */
+struct asn1_algorithm oid_sha256_algorithm __asn1_algorithm = {
+	.name = "sha256",
+	.digest = &sha256_algorithm,
+	.oid = ASN1_CURSOR ( oid_sha256 ),
+};
diff -pruN 1.0.0+git-20190125.36a4c85-5.1/src/crypto/mishmash/oid_sha384.c 1.21.1+git-20220113.fbbdc3926-0ubuntu1/src/crypto/mishmash/oid_sha384.c
--- 1.0.0+git-20190125.36a4c85-5.1/src/crypto/mishmash/oid_sha384.c	1970-01-01 00:00:00.000000000 +0000
+++ 1.21.1+git-20220113.fbbdc3926-0ubuntu1/src/crypto/mishmash/oid_sha384.c	2022-01-13 13:43:08.000000000 +0000
@@ -0,0 +1,37 @@
+/*
+ * Copyright (C) 2020 Michael Brown <mbrown@fensystems.co.uk>.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of the
+ * License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+ * 02110-1301, USA.
+ *
+ * You can also choose to distribute this program under the terms of
+ * the Unmodified Binary Distribution Licence (as given in the file
+ * COPYING.UBDL), provided that you have satisfied its requirements.
+ */
+
+FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
+
+#include <ipxe/sha512.h>
+#include <ipxe/asn1.h>
+
+/** "sha384" object identifier */
+static uint8_t oid_sha384[] = { ASN1_OID_SHA384 };
+
+/** "sha384" OID-identified algorithm */
+struct asn1_algorithm oid_sha384_algorithm __asn1_algorithm = {
+	.name = "sha384",
+	.digest = &sha384_algorithm,
+	.oid = ASN1_CURSOR ( oid_sha384 ),
+};
diff -pruN 1.0.0+git-20190125.36a4c85-5.1/src/crypto/mishmash/oid_sha512_224.c 1.21.1+git-20220113.fbbdc3926-0ubuntu1/src/crypto/mishmash/oid_sha512_224.c
--- 1.0.0+git-20190125.36a4c85-5.1/src/crypto/mishmash/oid_sha512_224.c	1970-01-01 00:00:00.000000000 +0000
+++ 1.21.1+git-20220113.fbbdc3926-0ubuntu1/src/crypto/mishmash/oid_sha512_224.c	2022-01-13 13:43:08.000000000 +0000
@@ -0,0 +1,37 @@
+/*
+ * Copyright (C) 2020 Michael Brown <mbrown@fensystems.co.uk>.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of the
+ * License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+ * 02110-1301, USA.
+ *
+ * You can also choose to distribute this program under the terms of
+ * the Unmodified Binary Distribution Licence (as given in the file
+ * COPYING.UBDL), provided that you have satisfied its requirements.
+ */
+
+FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
+
+#include <ipxe/sha512.h>
+#include <ipxe/asn1.h>
+
+/** "sha512_224" object identifier */
+static uint8_t oid_sha512_224[] = { ASN1_OID_SHA512_224 };
+
+/** "sha512_224" OID-identified algorithm */
+struct asn1_algorithm oid_sha512_224_algorithm __asn1_algorithm = {
+	.name = "sha512/224",
+	.digest = &sha512_224_algorithm,
+	.oid = ASN1_CURSOR ( oid_sha512_224 ),
+};
diff -pruN 1.0.0+git-20190125.36a4c85-5.1/src/crypto/mishmash/oid_sha512_256.c 1.21.1+git-20220113.fbbdc3926-0ubuntu1/src/crypto/mishmash/oid_sha512_256.c
--- 1.0.0+git-20190125.36a4c85-5.1/src/crypto/mishmash/oid_sha512_256.c	1970-01-01 00:00:00.000000000 +0000
+++ 1.21.1+git-20220113.fbbdc3926-0ubuntu1/src/crypto/mishmash/oid_sha512_256.c	2022-01-13 13:43:08.000000000 +0000
@@ -0,0 +1,37 @@
+/*
+ * Copyright (C) 2020 Michael Brown <mbrown@fensystems.co.uk>.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of the
+ * License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+ * 02110-1301, USA.
+ *
+ * You can also choose to distribute this program under the terms of
+ * the Unmodified Binary Distribution Licence (as given in the file
+ * COPYING.UBDL), provided that you have satisfied its requirements.
+ */
+
+FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
+
+#include <ipxe/sha512.h>
+#include <ipxe/asn1.h>
+
+/** "sha512_256" object identifier */
+static uint8_t oid_sha512_256[] = { ASN1_OID_SHA512_256 };
+
+/** "sha512_256" OID-identified algorithm */
+struct asn1_algorithm oid_sha512_256_algorithm __asn1_algorithm = {
+	.name = "sha512/256",
+	.digest = &sha512_256_algorithm,
+	.oid = ASN1_CURSOR ( oid_sha512_256 ),
+};
diff -pruN 1.0.0+git-20190125.36a4c85-5.1/src/crypto/mishmash/oid_sha512.c 1.21.1+git-20220113.fbbdc3926-0ubuntu1/src/crypto/mishmash/oid_sha512.c
--- 1.0.0+git-20190125.36a4c85-5.1/src/crypto/mishmash/oid_sha512.c	1970-01-01 00:00:00.000000000 +0000
+++ 1.21.1+git-20220113.fbbdc3926-0ubuntu1/src/crypto/mishmash/oid_sha512.c	2022-01-13 13:43:08.000000000 +0000
@@ -0,0 +1,37 @@
+/*
+ * Copyright (C) 2020 Michael Brown <mbrown@fensystems.co.uk>.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of the
+ * License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+ * 02110-1301, USA.
+ *
+ * You can also choose to distribute this program under the terms of
+ * the Unmodified Binary Distribution Licence (as given in the file
+ * COPYING.UBDL), provided that you have satisfied its requirements.
+ */
+
+FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
+
+#include <ipxe/sha512.h>
+#include <ipxe/asn1.h>
+
+/** "sha512" object identifier */
+static uint8_t oid_sha512[] = { ASN1_OID_SHA512 };
+
+/** "sha512" OID-identified algorithm */
+struct asn1_algorithm oid_sha512_algorithm __asn1_algorithm = {
+	.name = "sha512",
+	.digest = &sha512_algorithm,
+	.oid = ASN1_CURSOR ( oid_sha512 ),
+};
diff -pruN 1.0.0+git-20190125.36a4c85-5.1/src/crypto/mishmash/rsa_md5.c 1.21.1+git-20220113.fbbdc3926-0ubuntu1/src/crypto/mishmash/rsa_md5.c
--- 1.0.0+git-20190125.36a4c85-5.1/src/crypto/mishmash/rsa_md5.c	2019-02-09 16:03:59.000000000 +0000
+++ 1.21.1+git-20220113.fbbdc3926-0ubuntu1/src/crypto/mishmash/rsa_md5.c	2022-01-13 13:43:08.000000000 +0000
@@ -36,7 +36,7 @@ struct asn1_algorithm md5_with_rsa_encry
 	.name = "md5WithRSAEncryption",
 	.pubkey = &rsa_algorithm,
 	.digest = &md5_algorithm,
-	.oid = ASN1_OID_CURSOR ( oid_md5_with_rsa_encryption ),
+	.oid = ASN1_CURSOR ( oid_md5_with_rsa_encryption ),
 };
 
 /** MD5 digestInfo prefix */
diff -pruN 1.0.0+git-20190125.36a4c85-5.1/src/crypto/mishmash/rsa_sha1.c 1.21.1+git-20220113.fbbdc3926-0ubuntu1/src/crypto/mishmash/rsa_sha1.c
--- 1.0.0+git-20190125.36a4c85-5.1/src/crypto/mishmash/rsa_sha1.c	2019-02-09 16:03:59.000000000 +0000
+++ 1.21.1+git-20220113.fbbdc3926-0ubuntu1/src/crypto/mishmash/rsa_sha1.c	2022-01-13 13:43:08.000000000 +0000
@@ -37,7 +37,7 @@ struct asn1_algorithm sha1_with_rsa_encr
 	.name = "sha1WithRSAEncryption",
 	.pubkey = &rsa_algorithm,
 	.digest = &sha1_algorithm,
-	.oid = ASN1_OID_CURSOR ( oid_sha1_with_rsa_encryption ),
+	.oid = ASN1_CURSOR ( oid_sha1_with_rsa_encryption ),
 };
 
 /** SHA-1 digestInfo prefix */
diff -pruN 1.0.0+git-20190125.36a4c85-5.1/src/crypto/mishmash/rsa_sha224.c 1.21.1+git-20220113.fbbdc3926-0ubuntu1/src/crypto/mishmash/rsa_sha224.c
--- 1.0.0+git-20190125.36a4c85-5.1/src/crypto/mishmash/rsa_sha224.c	2019-02-09 16:03:59.000000000 +0000
+++ 1.21.1+git-20220113.fbbdc3926-0ubuntu1/src/crypto/mishmash/rsa_sha224.c	2022-01-13 13:43:08.000000000 +0000
@@ -37,7 +37,7 @@ struct asn1_algorithm sha224_with_rsa_en
 	.name = "sha224WithRSAEncryption",
 	.pubkey = &rsa_algorithm,
 	.digest = &sha224_algorithm,
-	.oid = ASN1_OID_CURSOR ( oid_sha224_with_rsa_encryption ),
+	.oid = ASN1_CURSOR ( oid_sha224_with_rsa_encryption ),
 };
 
 /** SHA-224 digestInfo prefix */
diff -pruN 1.0.0+git-20190125.36a4c85-5.1/src/crypto/mishmash/rsa_sha256.c 1.21.1+git-20220113.fbbdc3926-0ubuntu1/src/crypto/mishmash/rsa_sha256.c
--- 1.0.0+git-20190125.36a4c85-5.1/src/crypto/mishmash/rsa_sha256.c	2019-02-09 16:03:59.000000000 +0000
+++ 1.21.1+git-20220113.fbbdc3926-0ubuntu1/src/crypto/mishmash/rsa_sha256.c	2022-01-13 13:43:08.000000000 +0000
@@ -37,7 +37,7 @@ struct asn1_algorithm sha256_with_rsa_en
 	.name = "sha256WithRSAEncryption",
 	.pubkey = &rsa_algorithm,
 	.digest = &sha256_algorithm,
-	.oid = ASN1_OID_CURSOR ( oid_sha256_with_rsa_encryption ),
+	.oid = ASN1_CURSOR ( oid_sha256_with_rsa_encryption ),
 };
 
 /** SHA-256 digestInfo prefix */
diff -pruN 1.0.0+git-20190125.36a4c85-5.1/src/crypto/mishmash/rsa_sha384.c 1.21.1+git-20220113.fbbdc3926-0ubuntu1/src/crypto/mishmash/rsa_sha384.c
--- 1.0.0+git-20190125.36a4c85-5.1/src/crypto/mishmash/rsa_sha384.c	2019-02-09 16:03:59.000000000 +0000
+++ 1.21.1+git-20220113.fbbdc3926-0ubuntu1/src/crypto/mishmash/rsa_sha384.c	2022-01-13 13:43:08.000000000 +0000
@@ -37,7 +37,7 @@ struct asn1_algorithm sha384_with_rsa_en
 	.name = "sha384WithRSAEncryption",
 	.pubkey = &rsa_algorithm,
 	.digest = &sha384_algorithm,
-	.oid = ASN1_OID_CURSOR ( oid_sha384_with_rsa_encryption ),
+	.oid = ASN1_CURSOR ( oid_sha384_with_rsa_encryption ),
 };
 
 /** SHA-384 digestInfo prefix */
diff -pruN 1.0.0+git-20190125.36a4c85-5.1/src/crypto/mishmash/rsa_sha512.c 1.21.1+git-20220113.fbbdc3926-0ubuntu1/src/crypto/mishmash/rsa_sha512.c
--- 1.0.0+git-20190125.36a4c85-5.1/src/crypto/mishmash/rsa_sha512.c	2019-02-09 16:03:59.000000000 +0000
+++ 1.21.1+git-20220113.fbbdc3926-0ubuntu1/src/crypto/mishmash/rsa_sha512.c	2022-01-13 13:43:08.000000000 +0000
@@ -37,7 +37,7 @@ struct asn1_algorithm sha512_with_rsa_en
 	.name = "sha512WithRSAEncryption",
 	.pubkey = &rsa_algorithm,
 	.digest = &sha512_algorithm,
-	.oid = ASN1_OID_CURSOR ( oid_sha512_with_rsa_encryption ),
+	.oid = ASN1_CURSOR ( oid_sha512_with_rsa_encryption ),
 };
 
 /** SHA-512 digestInfo prefix */
diff -pruN 1.0.0+git-20190125.36a4c85-5.1/src/crypto/ocsp.c 1.21.1+git-20220113.fbbdc3926-0ubuntu1/src/crypto/ocsp.c
--- 1.0.0+git-20190125.36a4c85-5.1/src/crypto/ocsp.c	2019-02-09 16:03:59.000000000 +0000
+++ 1.21.1+git-20220113.fbbdc3926-0ubuntu1/src/crypto/ocsp.c	2022-01-13 13:43:08.000000000 +0000
@@ -116,7 +116,7 @@ static const uint8_t oid_basic_response_
 
 /** OCSP basic response type cursor */
 static struct asn1_cursor oid_basic_response_type_cursor =
-	ASN1_OID_CURSOR ( oid_basic_response_type );
+	ASN1_CURSOR ( oid_basic_response_type );
 
 /**
  * Free OCSP check
@@ -145,7 +145,7 @@ static void ocsp_free ( struct refcnt *r
 static int ocsp_request ( struct ocsp_check *ocsp ) {
 	struct digest_algorithm *digest = &ocsp_digest_algorithm;
 	struct asn1_builder *builder = &ocsp->request.builder;
-	struct asn1_cursor *cert_id = &ocsp->request.cert_id;
+	struct asn1_cursor *cert_id_tail = &ocsp->request.cert_id_tail;
 	uint8_t digest_ctx[digest->ctxsize];
 	uint8_t name_digest[digest->digestsize];
 	uint8_t pubkey_digest[digest->digestsize];
@@ -186,12 +186,14 @@ static int ocsp_request ( struct ocsp_ch
 	DBGC2_HDA ( ocsp, 0, builder->data, builder->len );
 
 	/* Parse certificate ID for comparison with response */
-	cert_id->data = builder->data;
-	cert_id->len = builder->len;
-	if ( ( rc = ( asn1_enter ( cert_id, ASN1_SEQUENCE ),
-		      asn1_enter ( cert_id, ASN1_SEQUENCE ),
-		      asn1_enter ( cert_id, ASN1_SEQUENCE ),
-		      asn1_enter ( cert_id, ASN1_SEQUENCE ) ) ) != 0 ) {
+	cert_id_tail->data = builder->data;
+	cert_id_tail->len = builder->len;
+	if ( ( rc = ( asn1_enter ( cert_id_tail, ASN1_SEQUENCE ),
+		      asn1_enter ( cert_id_tail, ASN1_SEQUENCE ),
+		      asn1_enter ( cert_id_tail, ASN1_SEQUENCE ),
+		      asn1_enter ( cert_id_tail, ASN1_SEQUENCE ),
+		      asn1_enter ( cert_id_tail, ASN1_SEQUENCE ),
+		      asn1_skip ( cert_id_tail, ASN1_SEQUENCE ) ) ) != 0 ) {
 		DBGC ( ocsp, "OCSP %p \"%s\" could not locate certID: %s\n",
 		       ocsp, x509_name ( ocsp->cert ), strerror ( rc ) );
 		return rc;
@@ -282,7 +284,7 @@ int ocsp_check ( struct x509_certificate
 	/* Sanity checks */
 	assert ( cert != NULL );
 	assert ( issuer != NULL );
-	assert ( x509_is_valid ( issuer ) );
+	assert ( issuer->root != NULL );
 
 	/* Allocate and initialise check */
 	*ocsp = zalloc ( sizeof ( **ocsp ) );
@@ -474,20 +476,46 @@ static int ocsp_parse_responder_id ( str
  */
 static int ocsp_parse_cert_id ( struct ocsp_check *ocsp,
 				const struct asn1_cursor *raw ) {
+	static struct asn1_cursor algorithm = {
+		.data = ocsp_algorithm_id,
+		.len = sizeof ( ocsp_algorithm_id ),
+	};
+	struct asn1_cursor cert_id;
 	struct asn1_cursor cursor;
+	int rc;
 
-	/* Check certID matches request */
-	memcpy ( &cursor, raw, sizeof ( cursor ) );
-	asn1_shrink_any ( &cursor );
-	if ( asn1_compare ( &cursor, &ocsp->request.cert_id ) != 0 ) {
-		DBGC ( ocsp, "OCSP %p \"%s\" certID mismatch:\n",
+	/* Enter cert ID */
+	memcpy ( &cert_id, raw, sizeof ( cert_id ) );
+	asn1_enter ( &cert_id, ASN1_SEQUENCE );
+
+	/* Check certID algorithm (but not parameters) */
+	memcpy ( &cursor, &cert_id, sizeof ( cursor ) );
+	if ( ( rc = ( asn1_enter ( &cursor, ASN1_SEQUENCE ),
+		      asn1_shrink ( &cursor, ASN1_OID ),
+		      asn1_shrink ( &algorithm, ASN1_OID ) ) ) != 0 ) {
+		DBGC ( ocsp, "OCSP %p \"%s\" certID missing algorithm:\n",
+		       ocsp, x509_name ( ocsp->cert ) );
+		DBGC_HDA ( ocsp, 0, cursor.data, cursor.len );
+		return -EACCES_CERT_MISMATCH;
+	}
+	if ( asn1_compare ( &cursor, &algorithm ) != 0 ) {
+		DBGC ( ocsp, "OCSP %p \"%s\" certID wrong algorithm:\n",
 		       ocsp, x509_name ( ocsp->cert ) );
-		DBGC_HDA ( ocsp, 0, ocsp->request.cert_id.data,
-			   ocsp->request.cert_id.len );
 		DBGC_HDA ( ocsp, 0, cursor.data, cursor.len );
 		return -EACCES_CERT_MISMATCH;
 	}
 
+	/* Check remaining certID fields */
+	asn1_skip ( &cert_id, ASN1_SEQUENCE );
+	if ( asn1_compare ( &cert_id, &ocsp->request.cert_id_tail ) != 0 ) {
+		DBGC ( ocsp, "OCSP %p \"%s\" certID mismatch:\n",
+		       ocsp, x509_name ( ocsp->cert ) );
+		DBGC_HDA ( ocsp, 0, ocsp->request.cert_id_tail.data,
+			   ocsp->request.cert_id_tail.len );
+		DBGC_HDA ( ocsp, 0, cert_id.data, cert_id.len );
+		return -EACCES_CERT_MISMATCH;
+	}
+
 	return 0;
 }
 
@@ -805,18 +833,6 @@ int ocsp_response ( struct ocsp_check *o
 }
 
 /**
- * OCSP dummy root certificate store
- *
- * OCSP validation uses no root certificates, since it takes place
- * only when there already exists a validated issuer certificate.
- */
-static struct x509_root ocsp_root = {
-	.digest = &ocsp_digest_algorithm,
-	.count = 0,
-	.fingerprints = NULL,
-};
-
-/**
  * Check OCSP response signature
  *
  * @v ocsp		OCSP check
@@ -899,7 +915,7 @@ int ocsp_validate ( struct ocsp_check *o
 		 */
 		x509_invalidate ( signer );
 		if ( ( rc = x509_validate ( signer, ocsp->issuer, time,
-					    &ocsp_root ) ) != 0 ) {
+					    ocsp->issuer->root ) ) != 0 ) {
 			DBGC ( ocsp, "OCSP %p \"%s\" could not validate ",
 			       ocsp, x509_name ( ocsp->cert ) );
 			DBGC ( ocsp, "signer \"%s\": %s\n",
@@ -945,7 +961,7 @@ int ocsp_validate ( struct ocsp_check *o
 
 	/* Validate certificate against issuer */
 	if ( ( rc = x509_validate ( ocsp->cert, ocsp->issuer, time,
-				    &ocsp_root ) ) != 0 ) {
+				    ocsp->issuer->root ) ) != 0 ) {
 		DBGC ( ocsp, "OCSP %p \"%s\" could not validate certificate: "
 		       "%s\n", ocsp, x509_name ( ocsp->cert ), strerror ( rc ));
 		return rc;
diff -pruN 1.0.0+git-20190125.36a4c85-5.1/src/crypto/privkey.c 1.21.1+git-20220113.fbbdc3926-0ubuntu1/src/crypto/privkey.c
--- 1.0.0+git-20190125.36a4c85-5.1/src/crypto/privkey.c	2019-02-09 16:03:59.000000000 +0000
+++ 1.21.1+git-20220113.fbbdc3926-0ubuntu1/src/crypto/privkey.c	2022-01-13 13:43:08.000000000 +0000
@@ -64,9 +64,12 @@ __asm__ ( ".section \".rodata\", \"a\",
 	  ".previous\n\t" );
 
 /** Private key */
-struct asn1_cursor private_key = {
-	.data = private_key_data,
-	.len = ( ( size_t ) private_key_len ),
+struct private_key private_key = {
+	.refcnt = REF_INIT ( ref_no_free ),
+	.builder = {
+		.data = private_key_data,
+		.len = ( ( size_t ) private_key_len ),
+	},
 };
 
 /** Default private key */
@@ -84,6 +87,19 @@ static struct setting privkey_setting __
 };
 
 /**
+ * Free private key
+ *
+ * @v refcnt		Reference counter
+ */
+void privkey_free ( struct refcnt *refcnt ) {
+	struct private_key *key =
+		container_of ( refcnt, struct private_key, refcnt );
+
+	free ( key->builder.data );
+	free ( key );
+}
+
+/**
  * Apply private key configuration settings
  *
  * @ret rc		Return status code
@@ -98,23 +114,24 @@ static int privkey_apply_settings ( void
 	if ( ALLOW_KEY_OVERRIDE ) {
 
 		/* Restore default private key */
-		memcpy ( &private_key, &default_private_key,
-			 sizeof ( private_key ) );
+		memcpy ( &private_key.builder, &default_private_key,
+			 sizeof ( private_key.builder ) );
 
 		/* Fetch new private key, if any */
 		free ( key_data );
 		if ( ( len = fetch_raw_setting_copy ( NULL, &privkey_setting,
 						      &key_data ) ) >= 0 ) {
-			private_key.data = key_data;
-			private_key.len = len;
+			private_key.builder.data = key_data;
+			private_key.builder.len = len;
 		}
 	}
 
 	/* Debug */
-	if ( private_key.len ) {
+	if ( private_key.builder.len ) {
 		DBGC ( &private_key, "PRIVKEY using %s private key:\n",
 		       ( key_data ? "external" : "built-in" ) );
-		DBGC_HDA ( &private_key, 0, private_key.data, private_key.len );
+		DBGC_HDA ( &private_key, 0, private_key.builder.data,
+			   private_key.builder.len );
 	} else {
 		DBGC ( &private_key, "PRIVKEY has no private key\n" );
 	}
diff -pruN 1.0.0+git-20190125.36a4c85-5.1/src/crypto/rootcert.c 1.21.1+git-20220113.fbbdc3926-0ubuntu1/src/crypto/rootcert.c
--- 1.0.0+git-20190125.36a4c85-5.1/src/crypto/rootcert.c	2019-02-09 16:03:59.000000000 +0000
+++ 1.21.1+git-20220113.fbbdc3926-0ubuntu1/src/crypto/rootcert.c	2022-01-13 13:43:08.000000000 +0000
@@ -71,6 +71,7 @@ static struct setting trust_setting __se
 
 /** Root certificates */
 struct x509_root root_certificates = {
+	.refcnt = REF_INIT ( ref_no_free ),
 	.digest = &sha256_algorithm,
 	.count = ( sizeof ( fingerprints ) / FINGERPRINT_LEN ),
 	.fingerprints = fingerprints,
diff -pruN 1.0.0+git-20190125.36a4c85-5.1/src/crypto/rsa.c 1.21.1+git-20220113.fbbdc3926-0ubuntu1/src/crypto/rsa.c
--- 1.0.0+git-20190125.36a4c85-5.1/src/crypto/rsa.c	2019-02-09 16:03:59.000000000 +0000
+++ 1.21.1+git-20220113.fbbdc3926-0ubuntu1/src/crypto/rsa.c	2022-01-13 13:43:08.000000000 +0000
@@ -47,17 +47,6 @@ FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
 #define EINFO_EACCES_VERIFY \
 	__einfo_uniqify ( EINFO_EACCES, 0x01, "RSA signature incorrect" )
 
-/** "rsaEncryption" object identifier */
-static uint8_t oid_rsa_encryption[] = { ASN1_OID_RSAENCRYPTION };
-
-/** "rsaEncryption" OID-identified algorithm */
-struct asn1_algorithm rsa_encryption_algorithm __asn1_algorithm = {
-	.name = "rsaEncryption",
-	.pubkey = &rsa_algorithm,
-	.digest = NULL,
-	.oid = ASN1_OID_CURSOR ( oid_rsa_encryption ),
-};
-
 /**
  * Identify RSA prefix
  *
@@ -635,3 +624,9 @@ struct pubkey_algorithm rsa_algorithm =
 	.final		= rsa_final,
 	.match		= rsa_match,
 };
+
+/* Drag in objects via rsa_algorithm */
+REQUIRING_SYMBOL ( rsa_algorithm );
+
+/* Drag in crypto configuration */
+REQUIRE_OBJECT ( config_crypto );
diff -pruN 1.0.0+git-20190125.36a4c85-5.1/src/crypto/sha1.c 1.21.1+git-20220113.fbbdc3926-0ubuntu1/src/crypto/sha1.c
--- 1.0.0+git-20190125.36a4c85-5.1/src/crypto/sha1.c	2019-02-09 16:03:59.000000000 +0000
+++ 1.21.1+git-20220113.fbbdc3926-0ubuntu1/src/crypto/sha1.c	2022-01-13 13:43:08.000000000 +0000
@@ -35,7 +35,6 @@ FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
 #include <assert.h>
 #include <ipxe/rotate.h>
 #include <ipxe/crypto.h>
-#include <ipxe/asn1.h>
 #include <ipxe/sha1.h>
 
 /** SHA-1 variables */
@@ -264,13 +263,3 @@ struct digest_algorithm sha1_algorithm =
 	.update		= sha1_update,
 	.final		= sha1_final,
 };
-
-/** "sha1" object identifier */
-static uint8_t oid_sha1[] = { ASN1_OID_SHA1 };
-
-/** "sha1" OID-identified algorithm */
-struct asn1_algorithm oid_sha1_algorithm __asn1_algorithm = {
-	.name = "sha1",
-	.digest = &sha1_algorithm,
-	.oid = ASN1_OID_CURSOR ( oid_sha1 ),
-};
diff -pruN 1.0.0+git-20190125.36a4c85-5.1/src/crypto/sha224.c 1.21.1+git-20220113.fbbdc3926-0ubuntu1/src/crypto/sha224.c
--- 1.0.0+git-20190125.36a4c85-5.1/src/crypto/sha224.c	2019-02-09 16:03:59.000000000 +0000
+++ 1.21.1+git-20220113.fbbdc3926-0ubuntu1/src/crypto/sha224.c	2022-01-13 13:43:08.000000000 +0000
@@ -32,7 +32,6 @@ FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
 #include <stdint.h>
 #include <byteswap.h>
 #include <ipxe/crypto.h>
-#include <ipxe/asn1.h>
 #include <ipxe/sha256.h>
 
 /** SHA-224 initial digest values */
@@ -70,13 +69,3 @@ struct digest_algorithm sha224_algorithm
 	.update		= sha256_update,
 	.final		= sha256_final,
 };
-
-/** "sha224" object identifier */
-static uint8_t oid_sha224[] = { ASN1_OID_SHA224 };
-
-/** "sha224" OID-identified algorithm */
-struct asn1_algorithm oid_sha224_algorithm __asn1_algorithm = {
-	.name = "sha224",
-	.digest = &sha224_algorithm,
-	.oid = ASN1_OID_CURSOR ( oid_sha224 ),
-};
diff -pruN 1.0.0+git-20190125.36a4c85-5.1/src/crypto/sha256.c 1.21.1+git-20220113.fbbdc3926-0ubuntu1/src/crypto/sha256.c
--- 1.0.0+git-20190125.36a4c85-5.1/src/crypto/sha256.c	2019-02-09 16:03:59.000000000 +0000
+++ 1.21.1+git-20220113.fbbdc3926-0ubuntu1/src/crypto/sha256.c	2022-01-13 13:43:08.000000000 +0000
@@ -35,7 +35,6 @@ FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
 #include <assert.h>
 #include <ipxe/rotate.h>
 #include <ipxe/crypto.h>
-#include <ipxe/asn1.h>
 #include <ipxe/sha256.h>
 
 /** SHA-256 variables */
@@ -271,13 +270,3 @@ struct digest_algorithm sha256_algorithm
 	.update		= sha256_update,
 	.final		= sha256_final,
 };
-
-/** "sha256" object identifier */
-static uint8_t oid_sha256[] = { ASN1_OID_SHA256 };
-
-/** "sha256" OID-identified algorithm */
-struct asn1_algorithm oid_sha256_algorithm __asn1_algorithm = {
-	.name = "sha256",
-	.digest = &sha256_algorithm,
-	.oid = ASN1_OID_CURSOR ( oid_sha256 ),
-};
diff -pruN 1.0.0+git-20190125.36a4c85-5.1/src/crypto/sha384.c 1.21.1+git-20220113.fbbdc3926-0ubuntu1/src/crypto/sha384.c
--- 1.0.0+git-20190125.36a4c85-5.1/src/crypto/sha384.c	2019-02-09 16:03:59.000000000 +0000
+++ 1.21.1+git-20220113.fbbdc3926-0ubuntu1/src/crypto/sha384.c	2022-01-13 13:43:08.000000000 +0000
@@ -32,7 +32,6 @@ FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
 #include <stdint.h>
 #include <byteswap.h>
 #include <ipxe/crypto.h>
-#include <ipxe/asn1.h>
 #include <ipxe/sha512.h>
 
 /** SHA-384 initial digest values */
@@ -70,13 +69,3 @@ struct digest_algorithm sha384_algorithm
 	.update		= sha512_update,
 	.final		= sha512_final,
 };
-
-/** "sha384" object identifier */
-static uint8_t oid_sha384[] = { ASN1_OID_SHA384 };
-
-/** "sha384" OID-identified algorithm */
-struct asn1_algorithm oid_sha384_algorithm __asn1_algorithm = {
-	.name = "sha384",
-	.digest = &sha384_algorithm,
-	.oid = ASN1_OID_CURSOR ( oid_sha384 ),
-};
diff -pruN 1.0.0+git-20190125.36a4c85-5.1/src/crypto/sha512_224.c 1.21.1+git-20220113.fbbdc3926-0ubuntu1/src/crypto/sha512_224.c
--- 1.0.0+git-20190125.36a4c85-5.1/src/crypto/sha512_224.c	2019-02-09 16:03:59.000000000 +0000
+++ 1.21.1+git-20220113.fbbdc3926-0ubuntu1/src/crypto/sha512_224.c	2022-01-13 13:43:08.000000000 +0000
@@ -32,7 +32,6 @@ FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
 #include <stdint.h>
 #include <byteswap.h>
 #include <ipxe/crypto.h>
-#include <ipxe/asn1.h>
 #include <ipxe/sha512.h>
 
 /** SHA-512/224 initial digest values */
@@ -71,13 +70,3 @@ struct digest_algorithm sha512_224_algor
 	.update		= sha512_update,
 	.final		= sha512_final,
 };
-
-/** "sha512_224" object identifier */
-static uint8_t oid_sha512_224[] = { ASN1_OID_SHA512_224 };
-
-/** "sha512_224" OID-identified algorithm */
-struct asn1_algorithm oid_sha512_224_algorithm __asn1_algorithm = {
-	.name = "sha512/224",
-	.digest = &sha512_224_algorithm,
-	.oid = ASN1_OID_CURSOR ( oid_sha512_224 ),
-};
diff -pruN 1.0.0+git-20190125.36a4c85-5.1/src/crypto/sha512_256.c 1.21.1+git-20220113.fbbdc3926-0ubuntu1/src/crypto/sha512_256.c
--- 1.0.0+git-20190125.36a4c85-5.1/src/crypto/sha512_256.c	2019-02-09 16:03:59.000000000 +0000
+++ 1.21.1+git-20220113.fbbdc3926-0ubuntu1/src/crypto/sha512_256.c	2022-01-13 13:43:08.000000000 +0000
@@ -32,7 +32,6 @@ FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
 #include <stdint.h>
 #include <byteswap.h>
 #include <ipxe/crypto.h>
-#include <ipxe/asn1.h>
 #include <ipxe/sha512.h>
 
 /** SHA-512/256 initial digest values */
@@ -71,13 +70,3 @@ struct digest_algorithm sha512_256_algor
 	.update		= sha512_update,
 	.final		= sha512_final,
 };
-
-/** "sha512_256" object identifier */
-static uint8_t oid_sha512_256[] = { ASN1_OID_SHA512_256 };
-
-/** "sha512_256" OID-identified algorithm */
-struct asn1_algorithm oid_sha512_256_algorithm __asn1_algorithm = {
-	.name = "sha512/256",
-	.digest = &sha512_256_algorithm,
-	.oid = ASN1_OID_CURSOR ( oid_sha512_256 ),
-};
diff -pruN 1.0.0+git-20190125.36a4c85-5.1/src/crypto/sha512.c 1.21.1+git-20220113.fbbdc3926-0ubuntu1/src/crypto/sha512.c
--- 1.0.0+git-20190125.36a4c85-5.1/src/crypto/sha512.c	2019-02-09 16:03:59.000000000 +0000
+++ 1.21.1+git-20220113.fbbdc3926-0ubuntu1/src/crypto/sha512.c	2022-01-13 13:43:08.000000000 +0000
@@ -35,7 +35,6 @@ FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
 #include <assert.h>
 #include <ipxe/rotate.h>
 #include <ipxe/crypto.h>
-#include <ipxe/asn1.h>
 #include <ipxe/sha512.h>
 
 /** SHA-512 variables */
@@ -291,13 +290,3 @@ struct digest_algorithm sha512_algorithm
 	.update		= sha512_update,
 	.final		= sha512_final,
 };
-
-/** "sha512" object identifier */
-static uint8_t oid_sha512[] = { ASN1_OID_SHA512 };
-
-/** "sha512" OID-identified algorithm */
-struct asn1_algorithm oid_sha512_algorithm __asn1_algorithm = {
-	.name = "sha512",
-	.digest = &sha512_algorithm,
-	.oid = ASN1_OID_CURSOR ( oid_sha512 ),
-};
diff -pruN 1.0.0+git-20190125.36a4c85-5.1/src/crypto/x509.c 1.21.1+git-20220113.fbbdc3926-0ubuntu1/src/crypto/x509.c
--- 1.0.0+git-20190125.36a4c85-5.1/src/crypto/x509.c	2019-02-09 16:03:59.000000000 +0000
+++ 1.21.1+git-20220113.fbbdc3926-0ubuntu1/src/crypto/x509.c	2022-01-13 13:43:08.000000000 +0000
@@ -25,6 +25,7 @@ FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
 
 #include <stdlib.h>
 #include <string.h>
+#include <strings.h>
 #include <errno.h>
 #include <assert.h>
 #include <ipxe/list.h>
@@ -123,6 +124,19 @@ FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
 	__einfo_uniqify ( EINFO_EACCES, 0x0b, "No usable certificates" )
 
 /**
+ * Free X.509 certificate
+ *
+ * @v refcnt		Reference count
+ */
+static void x509_free ( struct refcnt *refcnt ) {
+	struct x509_certificate *cert =
+		container_of ( refcnt, struct x509_certificate, refcnt );
+
+	x509_root_put ( cert->root );
+	free ( cert );
+}
+
+/**
  * Get X.509 certificate display name
  *
  * @v cert		X.509 certificate
@@ -156,7 +170,7 @@ static uint8_t oid_common_name[] = { ASN
 
 /** "commonName" object identifier cursor */
 static struct asn1_cursor oid_common_name_cursor =
-	ASN1_OID_CURSOR ( oid_common_name );
+	ASN1_CURSOR ( oid_common_name );
 
 /**
  * Parse X.509 certificate version
@@ -523,12 +537,12 @@ static struct x509_key_purpose x509_key_
 	{
 		.name = "codeSigning",
 		.bits = X509_CODE_SIGNING,
-		.oid = ASN1_OID_CURSOR ( oid_code_signing ),
+		.oid = ASN1_CURSOR ( oid_code_signing ),
 	},
 	{
 		.name = "ocspSigning",
 		.bits = X509_OCSP_SIGNING,
-		.oid = ASN1_OID_CURSOR ( oid_ocsp_signing ),
+		.oid = ASN1_CURSOR ( oid_ocsp_signing ),
 	},
 };
 
@@ -631,7 +645,7 @@ static uint8_t oid_ad_ocsp[] = { ASN1_OI
 static struct x509_access_method x509_access_methods[] = {
 	{
 		.name = "OCSP",
-		.oid = ASN1_OID_CURSOR ( oid_ad_ocsp ),
+		.oid = ASN1_CURSOR ( oid_ad_ocsp ),
 		.parse = x509_parse_ocsp,
 	},
 };
@@ -768,27 +782,27 @@ static uint8_t oid_ce_subject_alt_name[]
 static struct x509_extension x509_extensions[] = {
 	{
 		.name = "basicConstraints",
-		.oid = ASN1_OID_CURSOR ( oid_ce_basic_constraints ),
+		.oid = ASN1_CURSOR ( oid_ce_basic_constraints ),
 		.parse = x509_parse_basic_constraints,
 	},
 	{
 		.name = "keyUsage",
-		.oid = ASN1_OID_CURSOR ( oid_ce_key_usage ),
+		.oid = ASN1_CURSOR ( oid_ce_key_usage ),
 		.parse = x509_parse_key_usage,
 	},
 	{
 		.name = "extKeyUsage",
-		.oid = ASN1_OID_CURSOR ( oid_ce_ext_key_usage ),
+		.oid = ASN1_CURSOR ( oid_ce_ext_key_usage ),
 		.parse = x509_parse_extended_key_usage,
 	},
 	{
 		.name = "authorityInfoAccess",
-		.oid = ASN1_OID_CURSOR ( oid_pe_authority_info_access ),
+		.oid = ASN1_CURSOR ( oid_pe_authority_info_access ),
 		.parse = x509_parse_authority_info_access,
 	},
 	{
 		.name = "subjectAltName",
-		.oid = ASN1_OID_CURSOR ( oid_ce_subject_alt_name ),
+		.oid = ASN1_CURSOR ( oid_ce_subject_alt_name ),
 		.parse = x509_parse_subject_alt_name,
 	},
 };
@@ -1075,7 +1089,7 @@ int x509_certificate ( const void *data,
 	*cert = zalloc ( sizeof ( **cert ) + cursor.len );
 	if ( ! *cert )
 		return -ENOMEM;
-	ref_init ( &(*cert)->refcnt, NULL );
+	ref_init ( &(*cert)->refcnt, x509_free );
 	raw = ( *cert + 1 );
 
 	/* Copy raw data */
@@ -1296,6 +1310,50 @@ int x509_check_time ( struct x509_certif
 }
 
 /**
+ * Check if X.509 certificate is valid
+ *
+ * @v cert		X.509 certificate
+ * @v root		Root certificate list, or NULL to use default
+ */
+int x509_is_valid ( struct x509_certificate *cert, struct x509_root *root ) {
+
+	/* Use default root certificate store if none specified */
+	if ( ! root )
+		root = &root_certificates;
+
+	return ( cert->root == root );
+}
+
+/**
+ * Set X.509 certificate as validated
+ *
+ * @v cert		X.509 certificate
+ * @v issuer		Issuing X.509 certificate (or NULL)
+ * @v root		Root certificate list
+ */
+static void x509_set_valid ( struct x509_certificate *cert,
+			     struct x509_certificate *issuer,
+			     struct x509_root *root ) {
+	unsigned int max_path_remaining;
+
+	/* Sanity checks */
+	assert ( root != NULL );
+	assert ( ( issuer == NULL ) || ( issuer->path_remaining >= 1 ) );
+
+	/* Record validation root */
+	x509_root_put ( cert->root );
+	cert->root = x509_root_get ( root );
+
+	/* Calculate effective path length */
+	cert->path_remaining = ( cert->extensions.basic.path_len + 1 );
+	if ( issuer ) {
+		max_path_remaining = ( issuer->path_remaining - 1 );
+		if ( cert->path_remaining > max_path_remaining )
+			cert->path_remaining = max_path_remaining;
+	}
+}
+
+/**
  * Validate X.509 certificate
  *
  * @v cert		X.509 certificate
@@ -1313,7 +1371,6 @@ int x509_check_time ( struct x509_certif
 int x509_validate ( struct x509_certificate *cert,
 		    struct x509_certificate *issuer,
 		    time_t time, struct x509_root *root ) {
-	unsigned int max_path_remaining;
 	int rc;
 
 	/* Use default root certificate store if none specified */
@@ -1321,7 +1378,7 @@ int x509_validate ( struct x509_certific
 		root = &root_certificates;
 
 	/* Return success if certificate has already been validated */
-	if ( x509_is_valid ( cert ) )
+	if ( x509_is_valid ( cert, root ) )
 		return 0;
 
 	/* Fail if certificate is invalid at specified time */
@@ -1330,20 +1387,19 @@ int x509_validate ( struct x509_certific
 
 	/* Succeed if certificate is a trusted root certificate */
 	if ( x509_check_root ( cert, root ) == 0 ) {
-		cert->flags |= X509_FL_VALIDATED;
-		cert->path_remaining = ( cert->extensions.basic.path_len + 1 );
+		x509_set_valid ( cert, NULL, root );
 		return 0;
 	}
 
 	/* Fail unless we have an issuer */
 	if ( ! issuer ) {
-		DBGC2 ( cert, "X509 %p \"%s\" has no issuer\n",
+		DBGC2 ( cert, "X509 %p \"%s\" has no trusted issuer\n",
 			cert, x509_name ( cert ) );
 		return -EACCES_UNTRUSTED;
 	}
 
 	/* Fail unless issuer has already been validated */
-	if ( ! x509_is_valid ( issuer ) ) {
+	if ( ! x509_is_valid ( issuer, root ) ) {
 		DBGC ( cert, "X509 %p \"%s\" ", cert, x509_name ( cert ) );
 		DBGC ( cert, "issuer %p \"%s\" has not yet been validated\n",
 		       issuer, x509_name ( issuer ) );
@@ -1369,14 +1425,8 @@ int x509_validate ( struct x509_certific
 		return -EACCES_OCSP_REQUIRED;
 	}
 
-	/* Calculate effective path length */
-	cert->path_remaining = ( issuer->path_remaining - 1 );
-	max_path_remaining = ( cert->extensions.basic.path_len + 1 );
-	if ( cert->path_remaining > max_path_remaining )
-		cert->path_remaining = max_path_remaining;
-
 	/* Mark certificate as valid */
-	cert->flags |= X509_FL_VALIDATED;
+	x509_set_valid ( cert, issuer, root );
 
 	DBGC ( cert, "X509 %p \"%s\" successfully validated using ",
 	       cert, x509_name ( cert ) );
@@ -1415,7 +1465,7 @@ static int x509_check_dnsname ( struct x
 
 	/* Compare names */
 	if ( ! ( ( strlen ( name ) == len ) &&
-		 ( memcmp ( name, dnsname, len ) == 0 ) ) )
+		 ( strncasecmp ( name, dnsname, len ) == 0 ) ) )
 		return -ENOENT;
 
 	if ( name != fullname ) {
diff -pruN 1.0.0+git-20190125.36a4c85-5.1/src/drivers/block/ibft.c 1.21.1+git-20220113.fbbdc3926-0ubuntu1/src/drivers/block/ibft.c
--- 1.0.0+git-20190125.36a4c85-5.1/src/drivers/block/ibft.c	2019-02-09 16:03:59.000000000 +0000
+++ 1.21.1+git-20220113.fbbdc3926-0ubuntu1/src/drivers/block/ibft.c	2022-01-13 13:43:08.000000000 +0000
@@ -48,11 +48,15 @@ FILE_LICENCE ( BSD2 );
  *
  * iSCSI boot firmware table
  *
- * The information in this file is derived from the document "iSCSI
- * Boot Firmware Table (iBFT)" as published by IBM at
+ * The information in this file is originally derived from the document "iSCSI
+ * Boot Firmware Table (iBFT)" as published by IBM at:
  *
  * ftp://ftp.software.ibm.com/systems/support/system_x_pdf/ibm_iscsi_boot_firmware_table_v1.02.pdf
  *
+ * That file is no longer available, but a more recent version is available:
+ *
+ * ftp://ftp.software.ibm.com/systems/support/bladecenter/iscsi_boot_firmware_table_v1.03.pdf
+ *
  */
 
 /**
diff -pruN 1.0.0+git-20190125.36a4c85-5.1/src/drivers/bus/isa.c 1.21.1+git-20220113.fbbdc3926-0ubuntu1/src/drivers/bus/isa.c
--- 1.0.0+git-20190125.36a4c85-5.1/src/drivers/bus/isa.c	2019-02-09 16:03:59.000000000 +0000
+++ 1.21.1+git-20220113.fbbdc3926-0ubuntu1/src/drivers/bus/isa.c	2022-01-13 13:43:08.000000000 +0000
@@ -5,6 +5,7 @@
 #include <errno.h>
 #include <ipxe/io.h>
 #include <ipxe/isa.h>
+#include <config/isa.h>
 
 FILE_LICENCE ( GPL2_OR_LATER );
 
@@ -94,7 +95,7 @@ static void isa_remove ( struct isa_devi
 static int isabus_probe ( struct root_device *rootdev ) {
 	struct isa_device *isa = NULL;
 	struct isa_driver *driver;
-	int ioidx;
+	long ioidx;
 	int rc;
 
 	for_each_table_entry ( driver, ISA_DRIVERS ) {
diff -pruN 1.0.0+git-20190125.36a4c85-5.1/src/drivers/bus/pci.c 1.21.1+git-20220113.fbbdc3926-0ubuntu1/src/drivers/bus/pci.c
--- 1.0.0+git-20190125.36a4c85-5.1/src/drivers/bus/pci.c	2019-02-09 16:03:59.000000000 +0000
+++ 1.21.1+git-20220113.fbbdc3926-0ubuntu1/src/drivers/bus/pci.c	2022-01-13 13:43:08.000000000 +0000
@@ -228,6 +228,9 @@ int pci_read_config ( struct pci_device
  */
 int pci_find_next ( struct pci_device *pci, unsigned int busdevfn ) {
 	static unsigned int end;
+	unsigned int sub_end;
+	uint8_t hdrtype;
+	uint8_t sub;
 	int rc;
 
 	/* Determine number of PCI buses */
@@ -236,10 +239,30 @@ int pci_find_next ( struct pci_device *p
 
 	/* Find next PCI device, if any */
 	for ( ; busdevfn < end ; busdevfn++ ) {
+
+		/* Check for PCI device existence */
 		memset ( pci, 0, sizeof ( *pci ) );
 		pci_init ( pci, busdevfn );
-		if ( ( rc = pci_read_config ( pci ) ) == 0 )
-			return busdevfn;
+		if ( ( rc = pci_read_config ( pci ) ) != 0 )
+			continue;
+
+		/* If device is a bridge, expand the number of PCI
+		 * buses as needed.
+		 */
+		pci_read_config_byte ( pci, PCI_HEADER_TYPE, &hdrtype );
+		hdrtype &= PCI_HEADER_TYPE_MASK;
+		if ( hdrtype == PCI_HEADER_TYPE_BRIDGE ) {
+			pci_read_config_byte ( pci, PCI_SUBORDINATE, &sub );
+			sub_end = PCI_BUSDEVFN ( 0, ( sub + 1 ), 0, 0 );
+			if ( end < sub_end ) {
+				DBGC ( pci, PCI_FMT " found subordinate bus "
+				       "%#02x\n", PCI_ARGS ( pci ), sub );
+				end = sub_end;
+			}
+		}
+
+		/* Return this device */
+		return busdevfn;
 	}
 
 	return -ENODEV;
diff -pruN 1.0.0+git-20190125.36a4c85-5.1/src/drivers/bus/pcimsix.c 1.21.1+git-20220113.fbbdc3926-0ubuntu1/src/drivers/bus/pcimsix.c
--- 1.0.0+git-20190125.36a4c85-5.1/src/drivers/bus/pcimsix.c	1970-01-01 00:00:00.000000000 +0000
+++ 1.21.1+git-20220113.fbbdc3926-0ubuntu1/src/drivers/bus/pcimsix.c	2022-01-13 13:43:08.000000000 +0000
@@ -0,0 +1,251 @@
+/*
+ * Copyright (C) 2019 Michael Brown <mbrown@fensystems.co.uk>.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of the
+ * License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+ * 02110-1301, USA.
+ *
+ * You can also choose to distribute this program under the terms of
+ * the Unmodified Binary Distribution Licence (as given in the file
+ * COPYING.UBDL), provided that you have satisfied its requirements.
+ */
+
+FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
+
+#include <stdint.h>
+#include <errno.h>
+#include <assert.h>
+#include <ipxe/pci.h>
+#include <ipxe/pcimsix.h>
+
+/** @file
+ *
+ * PCI MSI-X interrupts
+ *
+ */
+
+/**
+ * Get MSI-X descriptor name (for debugging)
+ *
+ * @v cfg		Configuration space offset
+ * @ret name		Descriptor name
+ */
+static const char * pci_msix_name ( unsigned int cfg ) {
+
+	switch ( cfg ) {
+	case PCI_MSIX_DESC_TABLE:	return "table";
+	case PCI_MSIX_DESC_PBA:		return "PBA";
+	default:			return "<UNKNOWN>";
+	}
+}
+
+/**
+ * Map MSI-X BAR portion
+ *
+ * @v pci		PCI device
+ * @v msix		MSI-X capability
+ * @v cfg		Configuration space offset
+ * @ret io		I/O address
+ */
+static void * pci_msix_ioremap ( struct pci_device *pci, struct pci_msix *msix,
+				 unsigned int cfg ) {
+	uint32_t desc;
+	unsigned int bar;
+	unsigned long start;
+	unsigned long offset;
+	unsigned long base;
+	void *io;
+
+	/* Read descriptor */
+	pci_read_config_dword ( pci, ( msix->cap + cfg ), &desc );
+
+	/* Get BAR */
+	bar = PCI_MSIX_DESC_BIR ( desc );
+	offset = PCI_MSIX_DESC_OFFSET ( desc );
+	start = pci_bar_start ( pci, PCI_BASE_ADDRESS ( bar ) );
+	if ( ! start ) {
+		DBGC ( msix, "MSI-X %p %s could not find BAR%d\n",
+		       msix, pci_msix_name ( cfg ), bar );
+		return NULL;
+	}
+	base = ( start + offset );
+	DBGC ( msix, "MSI-X %p %s at %#08lx (BAR%d+%#lx)\n",
+	       msix, pci_msix_name ( cfg ), base, bar, offset );
+
+	/* Map BAR portion */
+	io = pci_ioremap ( pci, ( start + offset ), PCI_MSIX_LEN );
+	if ( ! io ) {
+		DBGC ( msix, "MSI-X %p %s could not map %#08lx\n",
+		       msix, pci_msix_name ( cfg ), base );
+		return NULL;
+	}
+
+	return io;
+}
+
+/**
+ * Enable MSI-X interrupts
+ *
+ * @v pci		PCI device
+ * @v msix		MSI-X capability
+ * @ret rc		Return status code
+ */
+int pci_msix_enable ( struct pci_device *pci, struct pci_msix *msix ) {
+	uint16_t ctrl;
+	int rc;
+
+	/* Locate capability */
+	msix->cap = pci_find_capability ( pci, PCI_CAP_ID_MSIX );
+	if ( ! msix->cap ) {
+		DBGC ( msix, "MSI-X %p found no MSI-X capability in "
+		       PCI_FMT "\n", msix, PCI_ARGS ( pci ) );
+		rc = -ENOENT;
+		goto err_cap;
+	}
+
+	/* Extract interrupt count */
+	pci_read_config_word ( pci, ( msix->cap + PCI_MSIX_CTRL ), &ctrl );
+	msix->count = ( PCI_MSIX_CTRL_SIZE ( ctrl ) + 1 );
+	DBGC ( msix, "MSI-X %p has %d vectors for " PCI_FMT "\n",
+	       msix, msix->count, PCI_ARGS ( pci ) );
+
+	/* Map MSI-X table */
+	msix->table = pci_msix_ioremap ( pci, msix, PCI_MSIX_DESC_TABLE );
+	if ( ! msix->table ) {
+		rc = -ENOENT;
+		goto err_table;
+	}
+
+	/* Map pending bit array */
+	msix->pba = pci_msix_ioremap ( pci, msix, PCI_MSIX_DESC_PBA );
+	if ( ! msix->pba ) {
+		rc = -ENOENT;
+		goto err_pba;
+	}
+
+	/* Enable MSI-X */
+	ctrl &= ~PCI_MSIX_CTRL_MASK;
+	ctrl |= PCI_MSIX_CTRL_ENABLE;
+	pci_write_config_word ( pci, ( msix->cap + PCI_MSIX_CTRL ), ctrl );
+
+	return 0;
+
+	iounmap ( msix->pba );
+ err_pba:
+	iounmap ( msix->table );
+ err_table:
+ err_cap:
+	return rc;
+}
+
+/**
+ * Disable MSI-X interrupts
+ *
+ * @v pci		PCI device
+ * @v msix		MSI-X capability
+ */
+void pci_msix_disable ( struct pci_device *pci, struct pci_msix *msix ) {
+	uint16_t ctrl;
+
+	/* Disable MSI-X */
+	pci_read_config_word ( pci, ( msix->cap + PCI_MSIX_CTRL ), &ctrl );
+	ctrl &= ~PCI_MSIX_CTRL_ENABLE;
+	pci_write_config_word ( pci, ( msix->cap + PCI_MSIX_CTRL ), ctrl );
+
+	/* Unmap pending bit array */
+	iounmap ( msix->pba );
+
+	/* Unmap MSI-X table */
+	iounmap ( msix->table );
+}
+
+/**
+ * Map MSI-X interrupt vector
+ *
+ * @v msix		MSI-X capability
+ * @v vector		MSI-X vector
+ * @v address		Message address
+ * @v data		Message data
+ */
+void pci_msix_map ( struct pci_msix *msix, unsigned int vector,
+		    physaddr_t address, uint32_t data ) {
+	void *base;
+
+	/* Sanity check */
+	assert ( vector < msix->count );
+
+	/* Map interrupt vector */
+	base = ( msix->table + PCI_MSIX_VECTOR ( vector ) );
+	writel ( ( address & 0xffffffffUL ), ( base + PCI_MSIX_ADDRESS_LO ) );
+	if ( sizeof ( address ) > sizeof ( uint32_t ) ) {
+		writel ( ( ( ( uint64_t ) address ) >> 32 ),
+			 ( base + PCI_MSIX_ADDRESS_HI ) );
+	} else {
+		writel ( 0, ( base + PCI_MSIX_ADDRESS_HI ) );
+	}
+	writel ( data, ( base + PCI_MSIX_DATA ) );
+}
+
+/**
+ * Control MSI-X interrupt vector
+ *
+ * @v msix		MSI-X capability
+ * @v vector		MSI-X vector
+ * @v mask		Control mask
+ */
+void pci_msix_control ( struct pci_msix *msix, unsigned int vector,
+			uint32_t mask ) {
+	void *base;
+	uint32_t ctrl;
+
+	/* Mask/unmask interrupt vector */
+	base = ( msix->table + PCI_MSIX_VECTOR ( vector ) );
+	ctrl = readl ( base + PCI_MSIX_CONTROL );
+	ctrl &= ~PCI_MSIX_CONTROL_MASK;
+	ctrl |= mask;
+	writel ( ctrl, ( base + PCI_MSIX_CONTROL ) );
+}
+
+/**
+ * Dump MSI-X interrupt state (for debugging)
+ *
+ * @v msix		MSI-X capability
+ * @v vector		MSI-X vector
+ */
+void pci_msix_dump ( struct pci_msix *msix, unsigned int vector ) {
+	void *base;
+	uint32_t address_hi;
+	uint32_t address_lo;
+	physaddr_t address;
+	uint32_t data;
+	uint32_t ctrl;
+	uint32_t pba;
+
+	/* Do nothing in non-debug builds */
+	if ( ! DBG_LOG )
+		return;
+
+	/* Mask/unmask interrupt vector */
+	base = ( msix->table + PCI_MSIX_VECTOR ( vector ) );
+	address_hi = readl ( base + PCI_MSIX_ADDRESS_HI );
+	address_lo = readl ( base + PCI_MSIX_ADDRESS_LO );
+	data = readl ( base + PCI_MSIX_DATA );
+	ctrl = readl ( base + PCI_MSIX_CONTROL );
+	pba = readl ( msix->pba );
+	address = ( ( ( ( uint64_t ) address_hi ) << 32 ) | address_lo );
+	DBGC ( msix, "MSI-X %p vector %d %#08x => %#08lx%s%s\n",
+	       msix, vector, data, address,
+	       ( ( ctrl & PCI_MSIX_CONTROL_MASK ) ? " (masked)" : "" ),
+	       ( ( pba & ( 1 << vector ) ) ? " (pending)" : "" ) );
+}
diff -pruN 1.0.0+git-20190125.36a4c85-5.1/src/drivers/bus/usb.c 1.21.1+git-20220113.fbbdc3926-0ubuntu1/src/drivers/bus/usb.c
--- 1.0.0+git-20190125.36a4c85-5.1/src/drivers/bus/usb.c	2019-02-09 16:03:59.000000000 +0000
+++ 1.21.1+git-20220113.fbbdc3926-0ubuntu1/src/drivers/bus/usb.c	2022-01-13 13:43:08.000000000 +0000
@@ -363,6 +363,35 @@ static int usb_endpoint_clear_tt ( struc
 }
 
 /**
+ * Clear endpoint halt (if applicable)
+ *
+ * @v ep		USB endpoint
+ * @ret rc		Return status code
+ */
+int usb_endpoint_clear_halt ( struct usb_endpoint *ep ) {
+	struct usb_device *usb = ep->usb;
+	unsigned int type;
+	int rc;
+
+	/* Clear transaction translator, if applicable */
+	if ( ( rc = usb_endpoint_clear_tt ( ep ) ) != 0 )
+		return rc;
+
+	/* Clear endpoint halt (if applicable) */
+	type = ( ep->attributes & USB_ENDPOINT_ATTR_TYPE_MASK );
+	if ( ( type != USB_ENDPOINT_ATTR_CONTROL ) &&
+	     ( ( rc = usb_clear_feature ( usb, USB_RECIP_ENDPOINT,
+					  USB_ENDPOINT_HALT,
+					  ep->address ) ) != 0 ) ) {
+		DBGC ( usb, "USB %s %s could not clear endpoint halt: %s\n",
+		       usb->name, usb_endpoint_name ( ep ), strerror ( rc ) );
+		return rc;
+	}
+
+	return 0;
+}
+
+/**
  * Close USB endpoint
  *
  * @v ep		USB endpoint
@@ -399,12 +428,15 @@ void usb_endpoint_close ( struct usb_end
  */
 static int usb_endpoint_reset ( struct usb_endpoint *ep ) {
 	struct usb_device *usb = ep->usb;
-	unsigned int type;
 	int rc;
 
 	/* Sanity check */
 	assert ( ! list_empty ( &ep->halted ) );
 
+	/* Clear device halt, if applicable */
+	if ( ( rc = usb_endpoint_clear_halt ( ep ) ) != 0 )
+		return rc;
+
 	/* Reset endpoint */
 	if ( ( rc = ep->host->reset ( ep ) ) != 0 ) {
 		DBGC ( usb, "USB %s %s could not reset: %s\n",
@@ -412,21 +444,6 @@ static int usb_endpoint_reset ( struct u
 		return rc;
 	}
 
-	/* Clear transaction translator, if applicable */
-	if ( ( rc = usb_endpoint_clear_tt ( ep ) ) != 0 )
-		return rc;
-
-	/* Clear endpoint halt, if applicable */
-	type = ( ep->attributes & USB_ENDPOINT_ATTR_TYPE_MASK );
-	if ( ( type != USB_ENDPOINT_ATTR_CONTROL ) &&
-	     ( ( rc = usb_clear_feature ( usb, USB_RECIP_ENDPOINT,
-					  USB_ENDPOINT_HALT,
-					  ep->address ) ) != 0 ) ) {
-		DBGC ( usb, "USB %s %s could not clear endpoint halt: %s\n",
-		       usb->name, usb_endpoint_name ( ep ), strerror ( rc ) );
-		return rc;
-	}
-
 	/* Remove from list of halted endpoints */
 	list_del ( &ep->halted );
 	INIT_LIST_HEAD ( &ep->halted );
@@ -634,12 +651,13 @@ int usb_prefill ( struct usb_endpoint *e
 }
 
 /**
- * Refill endpoint
+ * Refill endpoint up to specified limit
  *
  * @v ep		USB endpoint
+ * @v max		Fill limit
  * @ret rc		Return status code
  */
-int usb_refill ( struct usb_endpoint *ep ) {
+int usb_refill_limit ( struct usb_endpoint *ep, unsigned int max ) {
 	struct io_buffer *iobuf;
 	size_t reserve = ep->reserve;
 	size_t len = ( ep->len ? ep->len : ep->mtu );
@@ -650,7 +668,9 @@ int usb_refill ( struct usb_endpoint *ep
 	assert ( ep->max > 0 );
 
 	/* Refill endpoint */
-	while ( ep->fill < ep->max ) {
+	if ( max > ep->max )
+		max = ep->max;
+	while ( ep->fill < max ) {
 
 		/* Get or allocate buffer */
 		if ( list_empty ( &ep->recycled ) ) {
@@ -682,6 +702,16 @@ int usb_refill ( struct usb_endpoint *ep
 }
 
 /**
+ * Refill endpoint
+ *
+ * @v ep		USB endpoint
+ * @ret rc		Return status code
+ */
+int usb_refill ( struct usb_endpoint *ep ) {
+	return usb_refill_limit ( ep, ep->max );
+}
+
+/**
  * Discard endpoint recycled buffer list
  *
  * @v ep		USB endpoint
@@ -818,6 +848,7 @@ int usb_control ( struct usb_device *usb
 				       "failed: %s\n", usb->name, request,
 				       value, index, strerror ( rc ) );
 				free_iob ( cmplt );
+				usb_endpoint_reset ( ep );
 				return rc;
 			}
 
@@ -912,9 +943,15 @@ int usb_get_string_descriptor ( struct u
 					 sizeof ( *desc ) ) ) != 0 )
 		goto err_get_descriptor;
 
-	/* Copy to buffer */
+	/* Calculate string length */
+	if ( desc->header.len < sizeof ( desc->header ) ) {
+		rc = -EINVAL;
+		goto err_len;
+	}
 	actual = ( ( desc->header.len - sizeof ( desc->header ) ) /
 		   sizeof ( desc->character[0] ) );
+
+	/* Copy to buffer */
 	for ( i = 0 ; ( ( i < actual ) && ( i < max ) ) ; i++ )
 		buf[i] = le16_to_cpu ( desc->character[i] );
 	if ( len )
@@ -925,6 +962,7 @@ int usb_get_string_descriptor ( struct u
 
 	return actual;
 
+ err_len:
  err_get_descriptor:
 	free ( desc );
  err_alloc:
@@ -1615,7 +1653,9 @@ static int register_usb ( struct usb_dev
 	usb->host->close ( usb );
  err_open:
  err_speed:
-	hub->driver->disable ( hub, port );
+	/* Leave port enabled on failure, to avoid an endless loop of
+	 * failed device registrations.
+	 */
  err_enable:
 	list_del ( &usb->list );
 	port->usb = NULL;
@@ -1634,6 +1674,11 @@ static void unregister_usb ( struct usb_
 	struct io_buffer *iobuf;
 	struct io_buffer *tmp;
 
+	DBGC ( usb, "USB %s addr %d %04x:%04x class %d:%d:%d removed\n",
+	       usb->name, usb->address, le16_to_cpu ( usb->device.vendor ),
+	       le16_to_cpu ( usb->device.product ), usb->device.class.class,
+	       usb->device.class.subclass, usb->device.class.protocol );
+
 	/* Sanity checks */
 	assert ( port->usb == usb );
 
@@ -2233,23 +2278,6 @@ unsigned int usb_route_string ( struct u
 }
 
 /**
- * Get USB depth
- *
- * @v usb		USB device
- * @ret depth		Hub depth
- */
-unsigned int usb_depth ( struct usb_device *usb ) {
-	struct usb_device *parent;
-	unsigned int depth;
-
-	/* Navigate up to root hub, constructing depth as we go */
-	for ( depth = 0 ; ( parent = usb->port->hub->usb ) ; usb = parent )
-		depth++;
-
-	return depth;
-}
-
-/**
  * Get USB root hub port
  *
  * @v usb		USB device
diff -pruN 1.0.0+git-20190125.36a4c85-5.1/src/drivers/bus/virtio-pci.c 1.21.1+git-20220113.fbbdc3926-0ubuntu1/src/drivers/bus/virtio-pci.c
--- 1.0.0+git-20190125.36a4c85-5.1/src/drivers/bus/virtio-pci.c	2019-02-09 16:03:59.000000000 +0000
+++ 1.21.1+git-20220113.fbbdc3926-0ubuntu1/src/drivers/bus/virtio-pci.c	2022-01-13 13:43:08.000000000 +0000
@@ -17,37 +17,47 @@
 #include "ipxe/io.h"
 #include "ipxe/iomap.h"
 #include "ipxe/pci.h"
+#include "ipxe/dma.h"
 #include "ipxe/reboot.h"
 #include "ipxe/virtio-pci.h"
 #include "ipxe/virtio-ring.h"
 
-static int vp_alloc_vq(struct vring_virtqueue *vq, u16 num)
+static int vp_alloc_vq(struct vring_virtqueue *vq, u16 num, size_t header_size)
 {
-    size_t queue_size = PAGE_MASK + vring_size(num);
+    size_t ring_size = PAGE_MASK + vring_size(num);
     size_t vdata_size = num * sizeof(void *);
+    size_t queue_size = ring_size + vdata_size + header_size;
 
-    vq->queue = zalloc(queue_size + vdata_size);
+    vq->queue = dma_alloc(vq->dma, &vq->map, queue_size, queue_size);
     if (!vq->queue) {
         return -ENOMEM;
     }
 
+    memset ( vq->queue, 0, queue_size );
+    vq->queue_size = queue_size;
+
     /* vdata immediately follows the ring */
-    vq->vdata = (void **)(vq->queue + queue_size);
+    vq->vdata = (void **)(vq->queue + ring_size);
+
+    /* empty header immediately follows vdata */
+    vq->empty_header = (struct virtio_net_hdr_modern *)(vq->queue + ring_size + vdata_size);
 
     return 0;
 }
 
 void vp_free_vq(struct vring_virtqueue *vq)
 {
-    if (vq->queue) {
-        free(vq->queue);
+    if (vq->queue && vq->queue_size) {
+        dma_free(&vq->map, vq->queue, vq->queue_size);
         vq->queue = NULL;
         vq->vdata = NULL;
+        vq->queue_size = 0;
     }
 }
 
 int vp_find_vq(unsigned int ioaddr, int queue_index,
-               struct vring_virtqueue *vq)
+               struct vring_virtqueue *vq, struct dma_device *dma_dev,
+               size_t header_size)
 {
    struct vring * vr = &vq->vring;
    u16 num;
@@ -73,9 +83,10 @@ int vp_find_vq(unsigned int ioaddr, int
    }
 
    vq->queue_index = queue_index;
+   vq->dma = dma_dev;
 
    /* initialize the queue */
-   rc = vp_alloc_vq(vq, num);
+   rc = vp_alloc_vq(vq, num, header_size);
    if (rc) {
            DBG("VIRTIO-PCI ERROR: failed to allocate queue memory\n");
            return rc;
@@ -87,8 +98,7 @@ int vp_find_vq(unsigned int ioaddr, int
     * NOTE: vr->desc is initialized by vring_init()
     */
 
-   outl((unsigned long)virt_to_phys(vr->desc) >> PAGE_SHIFT,
-        ioaddr + VIRTIO_PCI_QUEUE_PFN);
+   outl(dma(&vq->map, vr->desc) >> PAGE_SHIFT, ioaddr + VIRTIO_PCI_QUEUE_PFN);
 
    return num;
 }
@@ -321,7 +331,7 @@ int virtio_pci_map_capability(struct pci
             region->flags = VIRTIO_PCI_REGION_PORT;
         } else {
             /* Region mapped into memory space */
-            region->base = ioremap(base + offset, length);
+            region->base = pci_ioremap(pci, base + offset, length);
             region->flags = VIRTIO_PCI_REGION_MEMORY;
         }
     }
@@ -348,7 +358,8 @@ void vpm_notify(struct virtio_pci_modern
 }
 
 int vpm_find_vqs(struct virtio_pci_modern_device *vdev,
-                 unsigned nvqs, struct vring_virtqueue *vqs)
+                 unsigned nvqs, struct vring_virtqueue *vqs,
+                 struct dma_device *dma_dev, size_t header_size)
 {
     unsigned i;
     struct vring_virtqueue *vq;
@@ -392,11 +403,12 @@ int vpm_find_vqs(struct virtio_pci_moder
 
         vq = &vqs[i];
         vq->queue_index = i;
+        vq->dma = dma_dev;
 
         /* get offset of notification word for this vq */
         off = vpm_ioread16(vdev, &vdev->common, COMMON_OFFSET(queue_notify_off));
 
-        err = vp_alloc_vq(vq, size);
+        err = vp_alloc_vq(vq, size, header_size);
         if (err) {
             DBG("VIRTIO-PCI %p: failed to allocate queue memory\n", vdev);
             return err;
@@ -406,13 +418,16 @@ int vpm_find_vqs(struct virtio_pci_moder
         /* activate the queue */
         vpm_iowrite16(vdev, &vdev->common, size, COMMON_OFFSET(queue_size));
 
-        vpm_iowrite64(vdev, &vdev->common, virt_to_phys(vq->vring.desc),
+        vpm_iowrite64(vdev, &vdev->common,
+                      dma(&vq->map, vq->vring.desc),
                       COMMON_OFFSET(queue_desc_lo),
                       COMMON_OFFSET(queue_desc_hi));
-        vpm_iowrite64(vdev, &vdev->common, virt_to_phys(vq->vring.avail),
+        vpm_iowrite64(vdev, &vdev->common,
+                      dma(&vq->map, vq->vring.avail),
                       COMMON_OFFSET(queue_avail_lo),
                       COMMON_OFFSET(queue_avail_hi));
-        vpm_iowrite64(vdev, &vdev->common, virt_to_phys(vq->vring.used),
+        vpm_iowrite64(vdev, &vdev->common,
+                      dma(&vq->map, vq->vring.used),
                       COMMON_OFFSET(queue_used_lo),
                       COMMON_OFFSET(queue_used_hi));
 
diff -pruN 1.0.0+git-20190125.36a4c85-5.1/src/drivers/bus/virtio-ring.c 1.21.1+git-20220113.fbbdc3926-0ubuntu1/src/drivers/bus/virtio-ring.c
--- 1.0.0+git-20190125.36a4c85-5.1/src/drivers/bus/virtio-ring.c	2019-02-09 16:03:59.000000000 +0000
+++ 1.21.1+git-20220113.fbbdc3926-0ubuntu1/src/drivers/bus/virtio-ring.c	2022-01-13 13:43:08.000000000 +0000
@@ -98,7 +98,7 @@ void vring_add_buf(struct vring_virtqueu
    for (i = head; out; i = vr->desc[i].next, out--) {
 
            vr->desc[i].flags = VRING_DESC_F_NEXT;
-           vr->desc[i].addr = (u64)virt_to_phys(list->addr);
+           vr->desc[i].addr = list->addr;
            vr->desc[i].len = list->length;
            prev = i;
            list++;
@@ -106,7 +106,7 @@ void vring_add_buf(struct vring_virtqueu
    for ( ; in; i = vr->desc[i].next, in--) {
 
            vr->desc[i].flags = VRING_DESC_F_NEXT|VRING_DESC_F_WRITE;
-           vr->desc[i].addr = (u64)virt_to_phys(list->addr);
+           vr->desc[i].addr = list->addr;
            vr->desc[i].len = list->length;
            prev = i;
            list++;
diff -pruN 1.0.0+git-20190125.36a4c85-5.1/src/drivers/infiniband/arbel.c 1.21.1+git-20220113.fbbdc3926-0ubuntu1/src/drivers/infiniband/arbel.c
--- 1.0.0+git-20190125.36a4c85-5.1/src/drivers/infiniband/arbel.c	2019-02-09 16:03:59.000000000 +0000
+++ 1.21.1+git-20220113.fbbdc3926-0ubuntu1/src/drivers/infiniband/arbel.c	2022-01-13 13:43:08.000000000 +0000
@@ -639,8 +639,8 @@ static int arbel_create_cq ( struct ib_d
 
 	/* Allocate completion queue itself */
 	arbel_cq->cqe_size = ( cq->num_cqes * sizeof ( arbel_cq->cqe[0] ) );
-	arbel_cq->cqe = malloc_dma ( arbel_cq->cqe_size,
-				     sizeof ( arbel_cq->cqe[0] ) );
+	arbel_cq->cqe = malloc_phys ( arbel_cq->cqe_size,
+				      sizeof ( arbel_cq->cqe[0] ) );
 	if ( ! arbel_cq->cqe ) {
 		rc = -ENOMEM;
 		goto err_cqe;
@@ -697,7 +697,7 @@ static int arbel_create_cq ( struct ib_d
  err_sw2hw_cq:
 	MLX_FILL_1 ( ci_db_rec, 1, res, ARBEL_UAR_RES_NONE );
 	MLX_FILL_1 ( arm_db_rec, 1, res, ARBEL_UAR_RES_NONE );
-	free_dma ( arbel_cq->cqe, arbel_cq->cqe_size );
+	free_phys ( arbel_cq->cqe, arbel_cq->cqe_size );
  err_cqe:
 	free ( arbel_cq );
  err_arbel_cq:
@@ -737,7 +737,7 @@ static void arbel_destroy_cq ( struct ib
 	MLX_FILL_1 ( arm_db_rec, 1, res, ARBEL_UAR_RES_NONE );
 
 	/* Free memory */
-	free_dma ( arbel_cq->cqe, arbel_cq->cqe_size );
+	free_phys ( arbel_cq->cqe, arbel_cq->cqe_size );
 	free ( arbel_cq );
 
 	/* Mark queue number as free */
@@ -873,8 +873,8 @@ static int arbel_create_send_wq ( struct
 	/* Allocate work queue */
 	arbel_send_wq->wqe_size = ( num_wqes *
 				    sizeof ( arbel_send_wq->wqe[0] ) );
-	arbel_send_wq->wqe = malloc_dma ( arbel_send_wq->wqe_size,
-					  sizeof ( arbel_send_wq->wqe[0] ) );
+	arbel_send_wq->wqe = malloc_phys ( arbel_send_wq->wqe_size,
+					   sizeof ( arbel_send_wq->wqe[0] ) );
 	if ( ! arbel_send_wq->wqe )
 		return -ENOMEM;
 	memset ( arbel_send_wq->wqe, 0, arbel_send_wq->wqe_size );
@@ -914,8 +914,8 @@ static int arbel_create_recv_wq ( struct
 	/* Allocate work queue */
 	arbel_recv_wq->wqe_size = ( num_wqes *
 				    sizeof ( arbel_recv_wq->wqe[0] ) );
-	arbel_recv_wq->wqe = malloc_dma ( arbel_recv_wq->wqe_size,
-					  sizeof ( arbel_recv_wq->wqe[0] ) );
+	arbel_recv_wq->wqe = malloc_phys ( arbel_recv_wq->wqe_size,
+					   sizeof ( arbel_recv_wq->wqe[0] ) );
 	if ( ! arbel_recv_wq->wqe ) {
 		rc = -ENOMEM;
 		goto err_alloc_wqe;
@@ -927,8 +927,8 @@ static int arbel_create_recv_wq ( struct
 	     ( type == IB_QPT_UD ) ) {
 		arbel_recv_wq->grh_size = ( num_wqes *
 					    sizeof ( arbel_recv_wq->grh[0] ) );
-		arbel_recv_wq->grh = malloc_dma ( arbel_recv_wq->grh_size,
-						  sizeof ( void * ) );
+		arbel_recv_wq->grh = malloc_phys ( arbel_recv_wq->grh_size,
+						   sizeof ( void * ) );
 		if ( ! arbel_recv_wq->grh ) {
 			rc = -ENOMEM;
 			goto err_alloc_grh;
@@ -954,9 +954,9 @@ static int arbel_create_recv_wq ( struct
 	
 	return 0;
 
-	free_dma ( arbel_recv_wq->grh, arbel_recv_wq->grh_size );
+	free_phys ( arbel_recv_wq->grh, arbel_recv_wq->grh_size );
  err_alloc_grh:
-	free_dma ( arbel_recv_wq->wqe, arbel_recv_wq->wqe_size );
+	free_phys ( arbel_recv_wq->wqe, arbel_recv_wq->wqe_size );
  err_alloc_wqe:
 	return rc;
 }
@@ -1102,10 +1102,10 @@ static int arbel_create_qp ( struct ib_d
 	MLX_FILL_1 ( send_db_rec, 1, res, ARBEL_UAR_RES_NONE );
 	MLX_FILL_1 ( recv_db_rec, 1, res, ARBEL_UAR_RES_NONE );
  err_unsupported_address_split:
-	free_dma ( arbel_qp->recv.grh, arbel_qp->recv.grh_size );
-	free_dma ( arbel_qp->recv.wqe, arbel_qp->recv.wqe_size );
+	free_phys ( arbel_qp->recv.grh, arbel_qp->recv.grh_size );
+	free_phys ( arbel_qp->recv.wqe, arbel_qp->recv.wqe_size );
  err_create_recv_wq:
-	free_dma ( arbel_qp->send.wqe, arbel_qp->send.wqe_size );
+	free_phys ( arbel_qp->send.wqe, arbel_qp->send.wqe_size );
  err_create_send_wq:
 	free ( arbel_qp );
  err_arbel_qp:
@@ -1231,9 +1231,9 @@ static void arbel_destroy_qp ( struct ib
 	MLX_FILL_1 ( recv_db_rec, 1, res, ARBEL_UAR_RES_NONE );
 
 	/* Free memory */
-	free_dma ( arbel_qp->recv.grh, arbel_qp->recv.grh_size );
-	free_dma ( arbel_qp->recv.wqe, arbel_qp->recv.wqe_size );
-	free_dma ( arbel_qp->send.wqe, arbel_qp->send.wqe_size );
+	free_phys ( arbel_qp->recv.grh, arbel_qp->recv.grh_size );
+	free_phys ( arbel_qp->recv.wqe, arbel_qp->recv.wqe_size );
+	free_phys ( arbel_qp->send.wqe, arbel_qp->send.wqe_size );
 	free ( arbel_qp );
 
 	/* Mark queue number as free */
@@ -1758,8 +1758,8 @@ static int arbel_create_eq ( struct arbe
 	/* Allocate event queue itself */
 	arbel_eq->eqe_size =
 		( ARBEL_NUM_EQES * sizeof ( arbel_eq->eqe[0] ) );
-	arbel_eq->eqe = malloc_dma ( arbel_eq->eqe_size,
-				     sizeof ( arbel_eq->eqe[0] ) );
+	arbel_eq->eqe = malloc_phys ( arbel_eq->eqe_size,
+				      sizeof ( arbel_eq->eqe[0] ) );
 	if ( ! arbel_eq->eqe ) {
 		rc = -ENOMEM;
 		goto err_eqe;
@@ -1806,7 +1806,7 @@ static int arbel_create_eq ( struct arbe
  err_map_eq:
 	arbel_cmd_hw2sw_eq ( arbel, arbel_eq->eqn, &eqctx );
  err_sw2hw_eq:
-	free_dma ( arbel_eq->eqe, arbel_eq->eqe_size );
+	free_phys ( arbel_eq->eqe, arbel_eq->eqe_size );
  err_eqe:
 	memset ( arbel_eq, 0, sizeof ( *arbel_eq ) );
 	return rc;
@@ -1844,7 +1844,7 @@ static void arbel_destroy_eq ( struct ar
 	}
 
 	/* Free memory */
-	free_dma ( arbel_eq->eqe, arbel_eq->eqe_size );
+	free_phys ( arbel_eq->eqe, arbel_eq->eqe_size );
 	memset ( arbel_eq, 0, sizeof ( *arbel_eq ) );
 }
 
@@ -2059,7 +2059,8 @@ static int arbel_start_firmware ( struct
 	eq_set_ci_base_addr =
 		( ( (uint64_t) MLX_GET ( &fw, eq_set_ci_base_addr_h ) << 32 ) |
 		  ( (uint64_t) MLX_GET ( &fw, eq_set_ci_base_addr_l ) ) );
-	arbel->eq_ci_doorbells = ioremap ( eq_set_ci_base_addr, 0x200 );
+	arbel->eq_ci_doorbells = pci_ioremap ( arbel->pci, eq_set_ci_base_addr,
+					       0x200 );
 
 	/* Enable locally-attached memory.  Ignore failure; there may
 	 * be no attached memory.
@@ -2454,7 +2455,7 @@ static int arbel_alloc_icm ( struct arbe
 	icm_phys = user_to_phys ( arbel->icm, 0 );
 
 	/* Allocate doorbell UAR */
-	arbel->db_rec = malloc_dma ( ARBEL_PAGE_SIZE, ARBEL_PAGE_SIZE );
+	arbel->db_rec = malloc_phys ( ARBEL_PAGE_SIZE, ARBEL_PAGE_SIZE );
 	if ( ! arbel->db_rec ) {
 		rc = -ENOMEM;
 		goto err_alloc_doorbell;
@@ -2512,7 +2513,7 @@ static int arbel_alloc_icm ( struct arbe
  err_map_icm:
 	arbel_cmd_unmap_icm_aux ( arbel );
  err_map_icm_aux:
-	free_dma ( arbel->db_rec, ARBEL_PAGE_SIZE );
+	free_phys ( arbel->db_rec, ARBEL_PAGE_SIZE );
 	arbel->db_rec= NULL;
  err_alloc_doorbell:
  err_alloc_icm:
@@ -2535,7 +2536,7 @@ static void arbel_free_icm ( struct arbe
 	arbel_cmd_unmap_icm ( arbel, ( arbel->icm_len / ARBEL_PAGE_SIZE ),
 			      &unmap_icm );
 	arbel_cmd_unmap_icm_aux ( arbel );
-	free_dma ( arbel->db_rec, ARBEL_PAGE_SIZE );
+	free_phys ( arbel->db_rec, ARBEL_PAGE_SIZE );
 	arbel->db_rec = NULL;
 }
 
@@ -2983,18 +2984,18 @@ static struct arbel * arbel_alloc ( void
 		goto err_arbel;
 
 	/* Allocate space for mailboxes */
-	arbel->mailbox_in = malloc_dma ( ARBEL_MBOX_SIZE, ARBEL_MBOX_ALIGN );
+	arbel->mailbox_in = malloc_phys ( ARBEL_MBOX_SIZE, ARBEL_MBOX_ALIGN );
 	if ( ! arbel->mailbox_in )
 		goto err_mailbox_in;
-	arbel->mailbox_out = malloc_dma ( ARBEL_MBOX_SIZE, ARBEL_MBOX_ALIGN );
+	arbel->mailbox_out = malloc_phys ( ARBEL_MBOX_SIZE, ARBEL_MBOX_ALIGN );
 	if ( ! arbel->mailbox_out )
 		goto err_mailbox_out;
 
 	return arbel;
 
-	free_dma ( arbel->mailbox_out, ARBEL_MBOX_SIZE );
+	free_phys ( arbel->mailbox_out, ARBEL_MBOX_SIZE );
  err_mailbox_out:
-	free_dma ( arbel->mailbox_in, ARBEL_MBOX_SIZE );
+	free_phys ( arbel->mailbox_in, ARBEL_MBOX_SIZE );
  err_mailbox_in:
 	free ( arbel );
  err_arbel:
@@ -3010,8 +3011,8 @@ static void arbel_free ( struct arbel *a
 
 	ufree ( arbel->icm );
 	ufree ( arbel->firmware_area );
-	free_dma ( arbel->mailbox_out, ARBEL_MBOX_SIZE );
-	free_dma ( arbel->mailbox_in, ARBEL_MBOX_SIZE );
+	free_phys ( arbel->mailbox_out, ARBEL_MBOX_SIZE );
+	free_phys ( arbel->mailbox_in, ARBEL_MBOX_SIZE );
 	free ( arbel );
 }
 
@@ -3025,6 +3026,8 @@ static void arbel_free ( struct arbel *a
 static int arbel_probe ( struct pci_device *pci ) {
 	struct arbel *arbel;
 	struct ib_device *ibdev;
+	unsigned long config;
+	unsigned long uar;
 	int i;
 	int rc;
 
@@ -3041,11 +3044,11 @@ static int arbel_probe ( struct pci_devi
 	adjust_pci_device ( pci );
 
 	/* Map PCI BARs */
-	arbel->config = ioremap ( pci_bar_start ( pci, ARBEL_PCI_CONFIG_BAR ),
-				  ARBEL_PCI_CONFIG_BAR_SIZE );
-	arbel->uar = ioremap ( ( pci_bar_start ( pci, ARBEL_PCI_UAR_BAR ) +
-				 ARBEL_PCI_UAR_IDX * ARBEL_PCI_UAR_SIZE ),
-			       ARBEL_PCI_UAR_SIZE );
+	config = pci_bar_start ( pci, ARBEL_PCI_CONFIG_BAR );
+	arbel->config = pci_ioremap ( pci, config, ARBEL_PCI_CONFIG_BAR_SIZE );
+	uar = ( pci_bar_start ( pci, ARBEL_PCI_UAR_BAR ) +
+		ARBEL_PCI_UAR_IDX * ARBEL_PCI_UAR_SIZE );
+	arbel->uar = pci_ioremap ( pci, uar, ARBEL_PCI_UAR_SIZE );
 
 	/* Allocate Infiniband devices */
 	for ( i = 0 ; i < ARBEL_NUM_PORTS ; i++ ) {
@@ -3058,6 +3061,7 @@ static int arbel_probe ( struct pci_devi
 		ibdev->op = &arbel_ib_operations;
 		ibdev->dev = &pci->dev;
 		ibdev->port = ( ARBEL_PORT_BASE + i );
+		ibdev->ports = ARBEL_NUM_PORTS;
 		ib_set_drvdata ( ibdev, arbel );
 	}
 
diff -pruN 1.0.0+git-20190125.36a4c85-5.1/src/drivers/infiniband/flexboot_nodnic.c 1.21.1+git-20220113.fbbdc3926-0ubuntu1/src/drivers/infiniband/flexboot_nodnic.c
--- 1.0.0+git-20190125.36a4c85-5.1/src/drivers/infiniband/flexboot_nodnic.c	2019-02-09 16:03:59.000000000 +0000
+++ 1.21.1+git-20220113.fbbdc3926-0ubuntu1/src/drivers/infiniband/flexboot_nodnic.c	2022-01-13 13:43:08.000000000 +0000
@@ -365,7 +365,8 @@ static int flexboot_nodnic_create_qp ( s
 		goto qp_alloc_err;
 	}
 
-	status = nodnic_port_create_qp(&port->port_priv, qp->type,
+	status = nodnic_port_create_qp(&port->port_priv,
+			(nodnic_queue_pair_type) qp->type,
 			qp->send.num_wqes * sizeof(struct nodnic_send_wqbb),
 			qp->send.num_wqes,
 			qp->recv.num_wqes * sizeof(struct nodnic_recv_wqe),
@@ -406,7 +407,8 @@ static void flexboot_nodnic_destroy_qp (
 	struct flexboot_nodnic_port *port = &flexboot_nodnic->port[ibdev->port - 1];
 	struct flexboot_nodnic_queue_pair *flexboot_nodnic_qp = ib_qp_get_drvdata ( qp );
 
-	nodnic_port_destroy_qp(&port->port_priv, qp->type,
+	nodnic_port_destroy_qp(&port->port_priv,
+			(nodnic_queue_pair_type) qp->type,
 			flexboot_nodnic_qp->nodnic_queue_pair);
 
 	free(flexboot_nodnic_qp);
@@ -599,7 +601,7 @@ static int flexboot_nodnic_mcast_attach
 
 	switch (qp->type) {
 	case IB_QPT_ETH:
-		memcpy(&mac, &gid, sizeof(mac));
+		memcpy(&mac, gid, sizeof(mac));
 		status = nodnic_port_add_mac_filter(&port->port_priv, mac);
 		MLX_CHECK_STATUS(flexboot_nodnic->device_priv, status, mac_err,
 				"nodnic_port_add_mac_filter failed");
@@ -620,7 +622,7 @@ static void flexboot_nodnic_mcast_detach
 
 	switch (qp->type) {
 	case IB_QPT_ETH:
-		memcpy(&mac, &gid, sizeof(mac));
+		memcpy(&mac, gid, sizeof(mac));
 		status = nodnic_port_remove_mac_filter(&port->port_priv, mac);
 		MLX_CHECK_STATUS(flexboot_nodnic->device_priv, status, mac_err,
 				"nodnic_port_remove_mac_filter failed");
@@ -1163,6 +1165,7 @@ flexboot_nodnic_allocate_infiniband_devi
 		ibdev->op = &flexboot_nodnic_ib_operations;
 		ibdev->dev = &pci->dev;
 		ibdev->port = ( FLEXBOOT_NODNIC_PORT_BASE + i);
+		ibdev->ports = device_priv->device_cap.num_ports;
 		ib_set_drvdata(ibdev, flexboot_nodnic_priv);
 	}
 	return status;
@@ -1459,7 +1462,7 @@ static int flexboot_nodnic_alloc_uar ( s
 		return -EINVAL;
 	}
 	uar->phys = ( pci_bar_start ( pci, FLEXBOOT_NODNIC_HCA_BAR ) + (mlx_uint32)uar->offset );
-	uar->virt = ( void * )( ioremap ( uar->phys, FLEXBOOT_NODNIC_PAGE_SIZE ) );
+	uar->virt = ( void * )( pci_ioremap ( pci, uar->phys, FLEXBOOT_NODNIC_PAGE_SIZE ) );
 
 	return status;
 }
diff -pruN 1.0.0+git-20190125.36a4c85-5.1/src/drivers/infiniband/golan.c 1.21.1+git-20220113.fbbdc3926-0ubuntu1/src/drivers/infiniband/golan.c
--- 1.0.0+git-20190125.36a4c85-5.1/src/drivers/infiniband/golan.c	2019-02-09 16:03:59.000000000 +0000
+++ 1.21.1+git-20220113.fbbdc3926-0ubuntu1/src/drivers/infiniband/golan.c	2022-01-13 13:43:08.000000000 +0000
@@ -585,9 +585,9 @@ static inline int golan_set_access_reg (
 
 static inline void golan_cmd_uninit ( struct golan *golan )
 {
-	free_dma(golan->mboxes.outbox, GOLAN_PAGE_SIZE);
-	free_dma(golan->mboxes.inbox, GOLAN_PAGE_SIZE);
-	free_dma(golan->cmd.addr, GOLAN_PAGE_SIZE);
+	free_phys(golan->mboxes.outbox, GOLAN_PAGE_SIZE);
+	free_phys(golan->mboxes.inbox, GOLAN_PAGE_SIZE);
+	free_phys(golan->cmd.addr, GOLAN_PAGE_SIZE);
 }
 
 /**
@@ -602,17 +602,17 @@ static inline int golan_cmd_init ( struc
 	int rc = 0;
 	uint32_t addr_l_sz;
 
-	if (!(golan->cmd.addr = malloc_dma(GOLAN_PAGE_SIZE , GOLAN_PAGE_SIZE))) {
+	if (!(golan->cmd.addr = malloc_phys(GOLAN_PAGE_SIZE , GOLAN_PAGE_SIZE))) {
 		rc = -ENOMEM;
-		goto malloc_dma_failed;
+		goto malloc_phys_failed;
 	}
-	if (!(golan->mboxes.inbox = malloc_dma(GOLAN_PAGE_SIZE , GOLAN_PAGE_SIZE))) {
+	if (!(golan->mboxes.inbox = malloc_phys(GOLAN_PAGE_SIZE , GOLAN_PAGE_SIZE))) {
 		rc = -ENOMEM;
-		goto malloc_dma_inbox_failed;
+		goto malloc_phys_inbox_failed;
 	}
-	if (!(golan->mboxes.outbox = malloc_dma(GOLAN_PAGE_SIZE , GOLAN_PAGE_SIZE))) {
+	if (!(golan->mboxes.outbox = malloc_phys(GOLAN_PAGE_SIZE , GOLAN_PAGE_SIZE))) {
 		rc = -ENOMEM;
-		goto malloc_dma_outbox_failed;
+		goto malloc_phys_outbox_failed;
 	}
 	addr_l_sz	= be32_to_cpu(readl(&golan->iseg->cmdq_addr_l_sz));
 
@@ -629,11 +629,11 @@ static inline int golan_cmd_init ( struc
 	DBGC( golan , "%s Command interface was initialized\n", __FUNCTION__);
 	return 0;
 
-malloc_dma_outbox_failed:
-	free_dma(golan->mboxes.inbox, GOLAN_PAGE_SIZE);
-malloc_dma_inbox_failed:
-	free_dma(golan->cmd.addr, GOLAN_PAGE_SIZE);
-malloc_dma_failed:
+malloc_phys_outbox_failed:
+	free_phys(golan->mboxes.inbox, GOLAN_PAGE_SIZE);
+malloc_phys_inbox_failed:
+	free_phys(golan->cmd.addr, GOLAN_PAGE_SIZE);
+malloc_phys_failed:
 	DBGC (golan ,"%s Failed to initialize command interface (rc = 0x%x)\n",
 		   __FUNCTION__, rc);
 	return rc;
@@ -693,7 +693,7 @@ static inline int golan_alloc_uar(struct
 	uar->index	= be32_to_cpu(out->uarn) & 0xffffff;
 
 	uar->phys = (pci_bar_start(golan->pci, GOLAN_HCA_BAR) + (uar->index << GOLAN_PAGE_SHIFT));
-	uar->virt = (void *)(ioremap(uar->phys, GOLAN_PAGE_SIZE));
+	uar->virt = (void *)(pci_ioremap(golan->pci, uar->phys, GOLAN_PAGE_SIZE));
 
 	DBGC( golan , "%s: UAR allocated with index 0x%x\n", __FUNCTION__, uar->index);
 	return 0;
@@ -743,7 +743,7 @@ static int golan_create_eq(struct golan
 
 	eq->cons_index	= 0;
 	eq->size	= GOLAN_NUM_EQES * sizeof(eq->eqes[0]);
-	eq->eqes	= malloc_dma ( GOLAN_PAGE_SIZE, GOLAN_PAGE_SIZE );
+	eq->eqes	= malloc_phys ( GOLAN_PAGE_SIZE, GOLAN_PAGE_SIZE );
 	if (!eq->eqes) {
 		rc = -ENOMEM;
 		goto err_create_eq_eqe_alloc;
@@ -781,7 +781,7 @@ static int golan_create_eq(struct golan
 	return 0;
 
 err_create_eq_cmd:
-	free_dma ( eq->eqes , GOLAN_PAGE_SIZE );
+	free_phys ( eq->eqes , GOLAN_PAGE_SIZE );
 err_create_eq_eqe_alloc:
 	DBGC (golan ,"%s [%d] out\n", __FUNCTION__, rc);
 	return rc;
@@ -806,7 +806,7 @@ static void golan_destory_eq(struct gola
 	rc = send_command_and_wait(golan, DEF_CMD_IDX, NO_MBOX, NO_MBOX, __FUNCTION__);
 	GOLAN_PRINT_RC_AND_CMD_STATUS;
 
-	free_dma ( golan->eq.eqes , GOLAN_PAGE_SIZE );
+	free_phys ( golan->eq.eqes , GOLAN_PAGE_SIZE );
 	golan->eq.eqn = 0;
 
 	DBGC( golan, "%s Event queue (0x%x) was destroyed\n", __FUNCTION__, eqn);
@@ -922,8 +922,8 @@ static inline void golan_pci_init(struct
 	adjust_pci_device ( pci );
 
 	/* Get HCA BAR */
-	golan->iseg	= ioremap ( pci_bar_start ( pci, GOLAN_HCA_BAR),
-					GOLAN_PCI_CONFIG_BAR_SIZE );
+	golan->iseg = pci_ioremap ( pci, pci_bar_start ( pci, GOLAN_HCA_BAR),
+				    GOLAN_PCI_CONFIG_BAR_SIZE );
 }
 
 static inline struct golan *golan_alloc()
@@ -962,14 +962,14 @@ static int golan_create_cq(struct ib_dev
 		goto err_create_cq;
 	}
 	golan_cq->size 			= sizeof(golan_cq->cqes[0]) * cq->num_cqes;
-	golan_cq->doorbell_record 	= malloc_dma(GOLAN_CQ_DB_RECORD_SIZE,
+	golan_cq->doorbell_record 	= malloc_phys(GOLAN_CQ_DB_RECORD_SIZE,
 							GOLAN_CQ_DB_RECORD_SIZE);
 	if (!golan_cq->doorbell_record) {
 		rc = -ENOMEM;
 		goto err_create_cq_db_alloc;
 	}
 
-	golan_cq->cqes = malloc_dma ( GOLAN_PAGE_SIZE, GOLAN_PAGE_SIZE );
+	golan_cq->cqes = malloc_phys ( GOLAN_PAGE_SIZE, GOLAN_PAGE_SIZE );
 	if (!golan_cq->cqes) {
 		rc = -ENOMEM;
 		goto err_create_cq_cqe_alloc;
@@ -1008,9 +1008,9 @@ static int golan_create_cq(struct ib_dev
 	return 0;
 
 err_create_cq_cmd:
-	free_dma( golan_cq->cqes , GOLAN_PAGE_SIZE );
+	free_phys( golan_cq->cqes , GOLAN_PAGE_SIZE );
 err_create_cq_cqe_alloc:
-	free_dma(golan_cq->doorbell_record, GOLAN_CQ_DB_RECORD_SIZE);
+	free_phys(golan_cq->doorbell_record, GOLAN_CQ_DB_RECORD_SIZE);
 err_create_cq_db_alloc:
 	free ( golan_cq );
 err_create_cq:
@@ -1045,8 +1045,8 @@ static void golan_destroy_cq(struct ib_d
 	cq->cqn = 0;
 
 	ib_cq_set_drvdata(cq, NULL);
-	free_dma ( golan_cq->cqes , GOLAN_PAGE_SIZE );
-	free_dma(golan_cq->doorbell_record, GOLAN_CQ_DB_RECORD_SIZE);
+	free_phys ( golan_cq->cqes , GOLAN_PAGE_SIZE );
+	free_phys(golan_cq->doorbell_record, GOLAN_CQ_DB_RECORD_SIZE);
 	free(golan_cq);
 
 	DBGC (golan, "%s CQ number 0x%x was destroyed\n", __FUNCTION__, cqn);
@@ -1138,7 +1138,7 @@ static int golan_create_qp_aux(struct ib
 	golan_qp->size = golan_qp->sq.size + golan_qp->rq.size;
 
 	/* allocate dma memory for WQEs (1 page is enough) - should change it */
-	golan_qp->wqes = malloc_dma ( GOLAN_PAGE_SIZE, GOLAN_PAGE_SIZE );
+	golan_qp->wqes = malloc_phys ( GOLAN_PAGE_SIZE, GOLAN_PAGE_SIZE );
 	if (!golan_qp->wqes) {
 		rc = -ENOMEM;
 		goto err_create_qp_wqe_alloc;
@@ -1160,7 +1160,7 @@ static int golan_create_qp_aux(struct ib
 		data++;
 	}
 
-	golan_qp->doorbell_record = malloc_dma(sizeof(struct golan_qp_db),
+	golan_qp->doorbell_record = malloc_phys(sizeof(struct golan_qp_db),
 						sizeof(struct golan_qp_db));
 	if (!golan_qp->doorbell_record) {
 		rc = -ENOMEM;
@@ -1213,9 +1213,9 @@ static int golan_create_qp_aux(struct ib
 	return 0;
 
 err_create_qp_cmd:
-	free_dma(golan_qp->doorbell_record, sizeof(struct golan_qp_db));
+	free_phys(golan_qp->doorbell_record, sizeof(struct golan_qp_db));
 err_create_qp_db_alloc:
-	free_dma ( golan_qp->wqes, GOLAN_PAGE_SIZE );
+	free_phys ( golan_qp->wqes, GOLAN_PAGE_SIZE );
 err_create_qp_wqe_alloc:
 err_create_qp_sq_size:
 err_create_qp_sq_wqe_size:
@@ -1422,8 +1422,8 @@ static void golan_destroy_qp(struct ib_d
 	qp->qpn = 0;
 
 	ib_qp_set_drvdata(qp, NULL);
-	free_dma(golan_qp->doorbell_record, sizeof(struct golan_qp_db));
-	free_dma ( golan_qp->wqes, GOLAN_PAGE_SIZE );
+	free_phys(golan_qp->doorbell_record, sizeof(struct golan_qp_db));
+	free_phys ( golan_qp->wqes, GOLAN_PAGE_SIZE );
 	free(golan_qp);
 
 	DBGC( golan ,"%s QP 0x%lx was destroyed\n", __FUNCTION__, qpn);
@@ -2386,6 +2386,7 @@ static int golan_probe_normal ( struct p
 		ibdev->op = &golan_ib_operations;
 		ibdev->dev = &pci->dev;
 		ibdev->port = (GOLAN_PORT_BASE + i);
+		ibdev->ports = golan->caps.num_ports;
 		ib_set_drvdata( ibdev, golan );
 	}
 
@@ -2640,6 +2641,12 @@ static struct pci_device_id golan_nics[]
 	PCI_ROM ( 0x15b3, 0x1015, "ConnectX-4Lx", "ConnectX-4Lx HCA driver, DevID 4117", 0 ),
 	PCI_ROM ( 0x15b3, 0x1017, "ConnectX-5", "ConnectX-5 HCA driver, DevID 4119", 0 ),
 	PCI_ROM ( 0x15b3, 0x1019, "ConnectX-5EX", "ConnectX-5EX HCA driver, DevID 4121", 0 ),
+	PCI_ROM ( 0x15b3, 0x101b, "ConnectX-6", "ConnectX-6 HCA driver, DevID 4123", 0 ),
+	PCI_ROM ( 0x15b3, 0x101d, "ConnectX-6DX", "ConnectX-6DX HCA driver, DevID 4125", 0 ),
+	PCI_ROM ( 0x15b3, 0x101f, "ConnectX-6Lx", "ConnectX-6LX HCA driver, DevID 4127", 0 ),
+	PCI_ROM ( 0x15b3, 0x1021, "ConnectX-7", "ConnectX-7 HCA driver, DevID 4129", 0 ),
+	PCI_ROM ( 0x15b3, 0xa2d2, "BlueField", "BlueField integrated ConnectX-5 network controller HCA driver, DevID 41682", 0 ),
+	PCI_ROM ( 0x15b3, 0xa2d6, "BlueField-2", "BlueField-2 network controller HCA driver, DevID 41686", 0 ),
 };
 
 struct pci_driver golan_driver __pci_driver = {
diff -pruN 1.0.0+git-20190125.36a4c85-5.1/src/drivers/infiniband/hermon.c 1.21.1+git-20220113.fbbdc3926-0ubuntu1/src/drivers/infiniband/hermon.c
--- 1.0.0+git-20190125.36a4c85-5.1/src/drivers/infiniband/hermon.c	2019-02-09 16:03:59.000000000 +0000
+++ 1.21.1+git-20220113.fbbdc3926-0ubuntu1/src/drivers/infiniband/hermon.c	2022-01-13 13:43:08.000000000 +0000
@@ -137,13 +137,13 @@ static int hermon_cmd_wait ( struct herm
 			     struct hermonprm_hca_command_register *hcr ) {
 	unsigned int wait;
 
-	for ( wait = HERMON_HCR_MAX_WAIT_MS ; wait ; wait-- ) {
+	for ( wait = ( 100 * HERMON_HCR_MAX_WAIT_MS ) ; wait ; wait-- ) {
 		hcr->u.dwords[6] =
 			readl ( hermon->config + HERMON_HCR_REG ( 6 ) );
 		if ( ( MLX_GET ( hcr, go ) == 0 ) &&
 		     ( MLX_GET ( hcr, t ) == hermon->toggle ) )
 			return 0;
-		mdelay ( 1 );
+		udelay ( 10 );
 	}
 	return -EBUSY;
 }
@@ -175,7 +175,7 @@ static int hermon_cmd ( struct hermon *h
 	assert ( in_len <= HERMON_MBOX_SIZE );
 	assert ( out_len <= HERMON_MBOX_SIZE );
 
-	DBGC2 ( hermon, "Hermon %p command %02x in %zx%s out %zx%s\n",
+	DBGC2 ( hermon, "Hermon %p command %04x in %zx%s out %zx%s\n",
 		hermon, opcode, in_len,
 		( ( command & HERMON_HCR_IN_MBOX ) ? "(mbox)" : "" ), out_len,
 		( ( command & HERMON_HCR_OUT_MBOX ) ? "(mbox)" : "" ) );
@@ -214,8 +214,6 @@ static int hermon_cmd ( struct hermon *h
 		     opcode_modifier, op_mod,
 		     go, 1,
 		     t, hermon->toggle );
-	DBGC ( hermon, "Hermon %p issuing command %04x\n",
-	       hermon, opcode );
 	DBGC2_HDA ( hermon, virt_to_phys ( hermon->config + HERMON_HCR_BASE ),
 		    &hcr, sizeof ( hcr ) );
 	if ( in_len && ( command & HERMON_HCR_IN_MBOX ) ) {
@@ -234,8 +232,8 @@ static int hermon_cmd ( struct hermon *h
 
 	/* Wait for command completion */
 	if ( ( rc = hermon_cmd_wait ( hermon, &hcr ) ) != 0 ) {
-		DBGC ( hermon, "Hermon %p timed out waiting for command:\n",
-		       hermon );
+		DBGC ( hermon, "Hermon %p timed out waiting for command "
+		       "%04x:\n", hermon, opcode );
 		DBGC_HDA ( hermon,
 			   virt_to_phys ( hermon->config + HERMON_HCR_BASE ),
 			   &hcr, sizeof ( hcr ) );
@@ -245,8 +243,8 @@ static int hermon_cmd ( struct hermon *h
 	/* Check command status */
 	status = MLX_GET ( &hcr, status );
 	if ( status != 0 ) {
-		DBGC ( hermon, "Hermon %p command failed with status %02x:\n",
-		       hermon, status );
+		DBGC ( hermon, "Hermon %p command %04x failed with status "
+		       "%02x:\n", hermon, opcode, status );
 		DBGC_HDA ( hermon,
 			   virt_to_phys ( hermon->config + HERMON_HCR_BASE ),
 			   &hcr, sizeof ( hcr ) );
@@ -334,6 +332,13 @@ hermon_cmd_sw2hw_mpt ( struct hermon *he
 }
 
 static inline int
+hermon_cmd_hw2sw_mpt ( struct hermon *hermon, unsigned int index ) {
+	return hermon_cmd ( hermon,
+			    HERMON_HCR_VOID_CMD ( HERMON_HCR_HW2SW_MPT ),
+			    0, NULL, index, NULL );
+}
+
+static inline int
 hermon_cmd_write_mtt ( struct hermon *hermon,
 		       const struct hermonprm_write_mtt *write_mtt ) {
 	return hermon_cmd ( hermon,
@@ -638,9 +643,9 @@ static int hermon_alloc_mtt ( struct her
 	mtt_offset = hermon_bitmask_alloc ( hermon->mtt_inuse, HERMON_MAX_MTTS,
 					    num_pages );
 	if ( mtt_offset < 0 ) {
-		DBGC ( hermon, "Hermon %p could not allocate %d MTT entries\n",
-		       hermon, num_pages );
 		rc = mtt_offset;
+		DBGC ( hermon, "Hermon %p could not allocate %d MTT entries: "
+		       "%s\n", hermon, num_pages, strerror ( rc ) );
 		goto err_mtt_offset;
 	}
 	mtt_base_addr = ( ( hermon->cap.reserved_mtts + mtt_offset ) *
@@ -664,8 +669,9 @@ static int hermon_alloc_mtt ( struct her
 			     ptag_l, ( addr >> 3 ) );
 		if ( ( rc = hermon_cmd_write_mtt ( hermon,
 						   &write_mtt ) ) != 0 ) {
-			DBGC ( hermon, "Hermon %p could not write MTT at %x\n",
-			       hermon, mtt_base_addr );
+			DBGC ( hermon, "Hermon %p could not write MTT at %x: "
+			       "%s\n", hermon, mtt_base_addr,
+			       strerror ( rc ) );
 			goto err_write_mtt;
 		}
 		addr += HERMON_PAGE_SIZE;
@@ -817,6 +823,11 @@ hermon_dump_cqctx ( struct hermon *hermo
 	struct hermonprm_completion_queue_context cqctx;
 	int rc;
 
+	/* Do nothing unless debugging is enabled */
+	if ( ! DBG_LOG )
+		return 0;
+
+	/* Dump completion queue context */
 	memset ( &cqctx, 0, sizeof ( cqctx ) );
 	if ( ( rc = hermon_cmd_query_cq ( hermon, cq->cqn, &cqctx ) ) != 0 ) {
 		DBGC ( hermon, "Hermon %p CQN %#lx QUERY_CQ failed: %s\n",
@@ -859,14 +870,18 @@ static int hermon_create_cq ( struct ib_
 	/* Allocate control structures */
 	hermon_cq = zalloc ( sizeof ( *hermon_cq ) );
 	if ( ! hermon_cq ) {
+		DBGC ( hermon, "Hermon %p CQN %#lx could not allocate CQ\n",
+		       hermon, cq->cqn );
 		rc = -ENOMEM;
 		goto err_hermon_cq;
 	}
 
 	/* Allocate doorbell */
-	hermon_cq->doorbell = malloc_dma ( sizeof ( hermon_cq->doorbell[0] ),
-					   sizeof ( hermon_cq->doorbell[0] ) );
+	hermon_cq->doorbell = malloc_phys ( sizeof ( hermon_cq->doorbell[0] ),
+					    sizeof ( hermon_cq->doorbell[0] ) );
 	if ( ! hermon_cq->doorbell ) {
+		DBGC ( hermon, "Hermon %p CQN %#lx could not allocate "
+		       "doorbell\n", hermon, cq->cqn );
 		rc = -ENOMEM;
 		goto err_doorbell;
 	}
@@ -874,9 +889,11 @@ static int hermon_create_cq ( struct ib_
 
 	/* Allocate completion queue itself */
 	hermon_cq->cqe_size = ( cq->num_cqes * sizeof ( hermon_cq->cqe[0] ) );
-	hermon_cq->cqe = malloc_dma ( hermon_cq->cqe_size,
-				      sizeof ( hermon_cq->cqe[0] ) );
+	hermon_cq->cqe = malloc_phys ( hermon_cq->cqe_size,
+				       sizeof ( hermon_cq->cqe[0] ) );
 	if ( ! hermon_cq->cqe ) {
+		DBGC ( hermon, "Hermon %p CQN %#lx could not allocate CQEs\n",
+		       hermon, cq->cqn );
 		rc = -ENOMEM;
 		goto err_cqe;
 	}
@@ -889,8 +906,11 @@ static int hermon_create_cq ( struct ib_
 	/* Allocate MTT entries */
 	if ( ( rc = hermon_alloc_mtt ( hermon, hermon_cq->cqe,
 				       hermon_cq->cqe_size,
-				       &hermon_cq->mtt ) ) != 0 )
+				       &hermon_cq->mtt ) ) != 0 ) {
+		DBGC ( hermon, "Hermon %p CQN %#lx could not allocate MTTs: "
+		       "%s\n", hermon, cq->cqn, strerror ( rc ) );
 		goto err_alloc_mtt;
+	}
 
 	/* Hand queue over to hardware */
 	memset ( &cqctx, 0, sizeof ( cqctx ) );
@@ -925,9 +945,9 @@ static int hermon_create_cq ( struct ib_
  err_sw2hw_cq:
 	hermon_free_mtt ( hermon, &hermon_cq->mtt );
  err_alloc_mtt:
-	free_dma ( hermon_cq->cqe, hermon_cq->cqe_size );
+	free_phys ( hermon_cq->cqe, hermon_cq->cqe_size );
  err_cqe:
-	free_dma ( hermon_cq->doorbell, sizeof ( hermon_cq->doorbell[0] ) );
+	free_phys ( hermon_cq->doorbell, sizeof ( hermon_cq->doorbell[0] ) );
  err_doorbell:
 	free ( hermon_cq );
  err_hermon_cq:
@@ -962,8 +982,8 @@ static void hermon_destroy_cq ( struct i
 	hermon_free_mtt ( hermon, &hermon_cq->mtt );
 
 	/* Free memory */
-	free_dma ( hermon_cq->cqe, hermon_cq->cqe_size );
-	free_dma ( hermon_cq->doorbell, sizeof ( hermon_cq->doorbell[0] ) );
+	free_phys ( hermon_cq->cqe, hermon_cq->cqe_size );
+	free_phys ( hermon_cq->doorbell, sizeof ( hermon_cq->doorbell[0] ) );
 	free ( hermon_cq );
 
 	/* Mark queue number as free */
@@ -1084,16 +1104,30 @@ static uint8_t hermon_qp_st[] = {
  */
 static __attribute__ (( unused )) int
 hermon_dump_qpctx ( struct hermon *hermon, struct ib_queue_pair *qp ) {
+	struct hermon_queue_pair *hermon_qp = ib_qp_get_drvdata ( qp );
 	struct hermonprm_qp_ee_state_transitions qpctx;
+	unsigned int state;
 	int rc;
 
+	/* Do nothing unless debugging is enabled */
+	if ( ! DBG_LOG )
+		return 0;
+
+	/* Dump queue pair context */
 	memset ( &qpctx, 0, sizeof ( qpctx ) );
 	if ( ( rc = hermon_cmd_query_qp ( hermon, qp->qpn, &qpctx ) ) != 0 ) {
 		DBGC ( hermon, "Hermon %p QPN %#lx QUERY_QP failed: %s\n",
 		       hermon, qp->qpn, strerror ( rc ) );
 		return rc;
 	}
-	DBGC ( hermon, "Hermon %p QPN %#lx context:\n", hermon, qp->qpn );
+	state = MLX_GET ( &qpctx, qpc_eec_data.state );
+	if ( state != hermon_qp->state ) {
+		DBGC ( hermon, "Hermon %p QPN %#lx state %d unexpected "
+		       "(should be %d)\n",
+		       hermon, qp->qpn, state, hermon_qp->state );
+	}
+	DBGC ( hermon, "Hermon %p QPN %#lx state %d context:\n",
+	       hermon, qp->qpn, state );
 	DBGC_HDA ( hermon, 0, &qpctx.u.dwords[2], ( sizeof ( qpctx ) - 8 ) );
 
 	return 0;
@@ -1122,15 +1156,19 @@ static int hermon_create_qp ( struct ib_
 	/* Allocate control structures */
 	hermon_qp = zalloc ( sizeof ( *hermon_qp ) );
 	if ( ! hermon_qp ) {
+		DBGC ( hermon, "Hermon %p QPN %#lx could not allocate QP\n",
+		       hermon, qp->qpn );
 		rc = -ENOMEM;
 		goto err_hermon_qp;
 	}
 
 	/* Allocate doorbells */
 	hermon_qp->recv.doorbell =
-		malloc_dma ( sizeof ( hermon_qp->recv.doorbell[0] ),
-			     sizeof ( hermon_qp->recv.doorbell[0] ) );
+		malloc_phys ( sizeof ( hermon_qp->recv.doorbell[0] ),
+			      sizeof ( hermon_qp->recv.doorbell[0] ) );
 	if ( ! hermon_qp->recv.doorbell ) {
+		DBGC ( hermon, "Hermon %p QPN %#lx could not allocate "
+		       "doorbell\n", hermon, qp->qpn );
 		rc = -ENOMEM;
 		goto err_recv_doorbell;
 	}
@@ -1157,9 +1195,11 @@ static int hermon_create_qp ( struct ib_
 	hermon_qp->wqe_size = ( hermon_qp->send.wqe_size +
 				hermon_qp->recv.wqe_size +
 				hermon_qp->recv.grh_size );
-	hermon_qp->wqe = malloc_dma ( hermon_qp->wqe_size,
-				      sizeof ( hermon_qp->send.wqe[0] ) );
+	hermon_qp->wqe = malloc_phys ( hermon_qp->wqe_size,
+				       sizeof ( hermon_qp->send.wqe[0] ) );
 	if ( ! hermon_qp->wqe ) {
+		DBGC ( hermon, "Hermon %p QPN %#lx could not allocate WQEs\n",
+		       hermon, qp->qpn );
 		rc = -ENOMEM;
 		goto err_alloc_wqe;
 	}
@@ -1184,6 +1224,8 @@ static int hermon_create_qp ( struct ib_
 	if ( ( rc = hermon_alloc_mtt ( hermon, hermon_qp->wqe,
 				       hermon_qp->wqe_size,
 				       &hermon_qp->mtt ) ) != 0 ) {
+		DBGC ( hermon, "Hermon %p QPN %#lx could not allocate MTTs: "
+		       "%s\n", hermon, qp->qpn, strerror ( rc ) );
 		goto err_alloc_mtt;
 	}
 
@@ -1248,10 +1290,10 @@ static int hermon_create_qp ( struct ib_
  err_rst2init_qp:
 	hermon_free_mtt ( hermon, &hermon_qp->mtt );
  err_alloc_mtt:
-	free_dma ( hermon_qp->wqe, hermon_qp->wqe_size );
+	free_phys ( hermon_qp->wqe, hermon_qp->wqe_size );
  err_alloc_wqe:
-	free_dma ( hermon_qp->recv.doorbell,
-		   sizeof ( hermon_qp->recv.doorbell[0] ) );
+	free_phys ( hermon_qp->recv.doorbell,
+		    sizeof ( hermon_qp->recv.doorbell[0] ) );
  err_recv_doorbell:
 	free ( hermon_qp );
  err_hermon_qp:
@@ -1363,9 +1405,9 @@ static void hermon_destroy_qp ( struct i
 	hermon_free_mtt ( hermon, &hermon_qp->mtt );
 
 	/* Free memory */
-	free_dma ( hermon_qp->wqe, hermon_qp->wqe_size );
-	free_dma ( hermon_qp->recv.doorbell,
-		   sizeof ( hermon_qp->recv.doorbell[0] ) );
+	free_phys ( hermon_qp->wqe, hermon_qp->wqe_size );
+	free_phys ( hermon_qp->recv.doorbell,
+		    sizeof ( hermon_qp->recv.doorbell[0] ) );
 	free ( hermon_qp );
 
 	/* Mark queue number as free */
@@ -1766,6 +1808,11 @@ static int hermon_complete ( struct ib_d
 	if ( is_send ) {
 		/* Hand off to completion handler */
 		ib_complete_send ( ibdev, qp, iobuf, rc );
+	} else if ( rc != 0 ) {
+		/* Dump queue state (for debugging) */
+		hermon_dump_qpctx ( hermon, qp );
+		/* Hand off to completion handler */
+		ib_complete_recv ( ibdev, qp, NULL, NULL, iobuf, rc );
 	} else {
 		/* Set received length */
 		len = MLX_GET ( &cqe->normal, byte_cnt );
@@ -1808,7 +1855,7 @@ static int hermon_complete ( struct ib_d
 		assert ( len <= iob_tailroom ( iobuf ) );
 		iob_put ( iobuf, len );
 		/* Hand off to completion handler */
-		ib_complete_recv ( ibdev, qp, &recv_dest, source, iobuf, rc );
+		ib_complete_recv ( ibdev, qp, &recv_dest, source, iobuf, 0 );
 	}
 
 	return rc;
@@ -1863,6 +1910,89 @@ static void hermon_poll_cq ( struct ib_d
  */
 
 /**
+ * Dump event queue context (for debugging only)
+ *
+ * @v hermon		Hermon device
+ * @v hermon_eq		Event queue
+ * @ret rc		Return status code
+ */
+static __attribute__ (( unused )) int
+hermon_dump_eqctx ( struct hermon *hermon,
+		    struct hermon_event_queue *hermon_eq ) {
+	struct hermonprm_eqc eqctx;
+	int rc;
+
+	/* Do nothing unless debugging is enabled */
+	if ( ! DBG_LOG )
+		return 0;
+
+	/* Dump event queue context */
+	memset ( &eqctx, 0, sizeof ( eqctx ) );
+	if ( ( rc = hermon_cmd_query_eq ( hermon, hermon_eq->eqn,
+					  &eqctx ) ) != 0 ) {
+		DBGC ( hermon, "Hermon %p EQN %#lx QUERY_EQ failed: %s\n",
+		       hermon, hermon_eq->eqn, strerror ( rc ) );
+		return rc;
+	}
+	DBGC ( hermon, "Hermon %p EQN %#lx context:\n",
+	       hermon, hermon_eq->eqn );
+	DBGC_HDA ( hermon, 0, &eqctx, sizeof ( eqctx ) );
+
+	return 0;
+}
+
+/**
+ * Dump unconsumed event queue entries (for debugging only)
+ *
+ * @v hermon		Hermon device
+ * @v hermon_eq		Event queue
+ * @ret rc		Return status code
+ */
+static __attribute__ (( unused )) int
+hermon_dump_eqes ( struct hermon *hermon,
+		   struct hermon_event_queue *hermon_eq ) {
+	struct hermonprm_eqc eqctx;
+	union hermonprm_event_entry *eqe;
+	unsigned int mask;
+	unsigned int prod;
+	unsigned int cons;
+	unsigned int idx;
+	int rc;
+
+	/* Do nothing unless debugging is enabled */
+	if ( ! DBG_LOG )
+		return 0;
+
+	/* Dump event queue entries */
+	memset ( &eqctx, 0, sizeof ( eqctx ) );
+	if ( ( rc = hermon_cmd_query_eq ( hermon, hermon_eq->eqn,
+					  &eqctx ) ) != 0 ) {
+		DBGC ( hermon, "Hermon %p EQN %#lx QUERY_EQ failed: %s\n",
+		       hermon, hermon_eq->eqn, strerror ( rc ) );
+		return rc;
+	}
+	mask = ( HERMON_NUM_EQES - 1 );
+	prod = MLX_GET ( &eqctx, producer_counter ) & mask;
+	cons = MLX_GET ( &eqctx, consumer_counter ) & mask;
+	idx = hermon_eq->next_idx;
+	if ( ( idx & mask ) != ( cons & mask ) ) {
+		DBGC ( hermon, "Hermon %p EQN %#lx mismatch: SW %#x != HW "
+		       "%#x\n", hermon, hermon_eq->eqn, idx, cons );
+	}
+	for ( ; ( idx & mask ) != ( prod & mask ) ; idx++ ) {
+		eqe = &hermon_eq->eqe[idx & mask];
+		DBGC ( hermon, "Hermon %p EQN %#lx event %#x owner %d type "
+		       "%#02x:%#02x\n", hermon, hermon_eq->eqn, idx,
+		       MLX_GET ( &eqe->generic, owner ),
+		       MLX_GET ( &eqe->generic, event_type ),
+		       MLX_GET ( &eqe->generic, event_sub_type ) );
+		DBGC_HDA ( hermon, 0, eqe, sizeof ( *eqe ) );
+	}
+
+	return 0;
+}
+
+/**
  * Create event queue
  *
  * @v hermon		Hermon device
@@ -1887,9 +2017,11 @@ static int hermon_create_eq ( struct her
 	/* Allocate event queue itself */
 	hermon_eq->eqe_size =
 		( HERMON_NUM_EQES * sizeof ( hermon_eq->eqe[0] ) );
-	hermon_eq->eqe = malloc_dma ( hermon_eq->eqe_size,
-				      sizeof ( hermon_eq->eqe[0] ) );
+	hermon_eq->eqe = malloc_phys ( hermon_eq->eqe_size,
+				       sizeof ( hermon_eq->eqe[0] ) );
 	if ( ! hermon_eq->eqe ) {
+		DBGC ( hermon, "Hermon %p EQN %#lx could not allocate EQEs\n",
+		       hermon, hermon_eq->eqn );
 		rc = -ENOMEM;
 		goto err_eqe;
 	}
@@ -1902,8 +2034,11 @@ static int hermon_create_eq ( struct her
 	/* Allocate MTT entries */
 	if ( ( rc = hermon_alloc_mtt ( hermon, hermon_eq->eqe,
 				       hermon_eq->eqe_size,
-				       &hermon_eq->mtt ) ) != 0 )
+				       &hermon_eq->mtt ) ) != 0 ) {
+		DBGC ( hermon, "Hermon %p EQN %#lx could not allocate MTTs: "
+		       "%s\n", hermon, hermon_eq->eqn, strerror ( rc ) );
 		goto err_alloc_mtt;
+	}
 
 	/* Hand queue over to hardware */
 	memset ( &eqctx, 0, sizeof ( eqctx ) );
@@ -1946,7 +2081,7 @@ static int hermon_create_eq ( struct her
  err_sw2hw_eq:
 	hermon_free_mtt ( hermon, &hermon_eq->mtt );
  err_alloc_mtt:
-	free_dma ( hermon_eq->eqe, hermon_eq->eqe_size );
+	free_phys ( hermon_eq->eqe, hermon_eq->eqe_size );
  err_eqe:
 	memset ( hermon_eq, 0, sizeof ( *hermon_eq ) );
 	return rc;
@@ -1986,7 +2121,7 @@ static void hermon_destroy_eq ( struct h
 	hermon_free_mtt ( hermon, &hermon_eq->mtt );
 
 	/* Free memory */
-	free_dma ( hermon_eq->eqe, hermon_eq->eqe_size );
+	free_phys ( hermon_eq->eqe, hermon_eq->eqe_size );
 	memset ( hermon_eq, 0, sizeof ( *hermon_eq ) );
 }
 
@@ -2020,6 +2155,32 @@ static void hermon_event_port_state_chan
 }
 
 /**
+ * Handle port management event
+ *
+ * @v hermon		Hermon device
+ * @v eqe		Port management change event queue entry
+ */
+static void hermon_event_port_mgmnt_change ( struct hermon *hermon,
+					     union hermonprm_event_entry *eqe){
+	unsigned int port;
+
+	/* Get port */
+	port = ( MLX_GET ( &eqe->port_mgmnt_change, port ) - 1 );
+	DBGC ( hermon, "Hermon %p port %d management change\n",
+	       hermon, ( port + 1 ) );
+
+	/* Sanity check */
+	if ( port >= hermon->cap.num_ports ) {
+		DBGC ( hermon, "Hermon %p port %d does not exist!\n",
+		       hermon, ( port + 1 ) );
+		return;
+	}
+
+	/* Update MAD parameters */
+	ib_smc_update ( hermon->port[port].ibdev, hermon_mad );
+}
+
+/**
  * Poll event queue
  *
  * @v ibdev		Infiniband device
@@ -2029,6 +2190,8 @@ static void hermon_poll_eq ( struct ib_d
 	struct hermon_event_queue *hermon_eq = &hermon->eq;
 	union hermonprm_event_entry *eqe;
 	union hermonprm_doorbell_register db_reg;
+	unsigned long now;
+	unsigned long elapsed;
 	unsigned int eqe_idx_mask;
 	unsigned int event_type;
 
@@ -2037,7 +2200,12 @@ static void hermon_poll_eq ( struct ib_d
 	 */
 	if ( ib_is_open ( ibdev ) &&
 	     ( ibdev->port_state == IB_PORT_STATE_DOWN ) ) {
-		ib_smc_update ( ibdev, hermon_mad );
+		now = currticks();
+		elapsed = ( now - hermon->last_poll );
+		if ( elapsed >= HERMON_LINK_POLL_INTERVAL ) {
+			hermon->last_poll = now;
+			ib_smc_update ( ibdev, hermon_mad );
+		}
 	}
 
 	/* Poll event queue */
@@ -2061,10 +2229,14 @@ static void hermon_poll_eq ( struct ib_d
 		case HERMON_EV_PORT_STATE_CHANGE:
 			hermon_event_port_state_change ( hermon, eqe );
 			break;
+		case HERMON_EV_PORT_MGMNT_CHANGE:
+			hermon_event_port_mgmnt_change ( hermon, eqe );
+			break;
 		default:
 			DBGC ( hermon, "Hermon %p EQN %#lx unrecognised event "
-			       "type %#x:\n",
-			       hermon, hermon_eq->eqn, event_type );
+			       "type %#02x:%#02x\n",
+			       hermon, hermon_eq->eqn, event_type,
+			       MLX_GET ( &eqe->generic, event_sub_type ) );
 			DBGC_HDA ( hermon, virt_to_phys ( eqe ),
 				   eqe, sizeof ( *eqe ) );
 			break;
@@ -2202,6 +2374,8 @@ static int hermon_start_firmware ( struc
 		hermon->firmware_len = fw_len;
 		hermon->firmware_area = umalloc ( hermon->firmware_len );
 		if ( ! hermon->firmware_area ) {
+			DBGC ( hermon, "Hermon %p could not allocate firmware "
+			       "area\n", hermon );
 			rc = -ENOMEM;
 			goto err_alloc_fa;
 		}
@@ -2569,6 +2743,8 @@ static int hermon_map_icm ( struct hermo
 		hermon->icm_aux_len = icm_aux_len;
 		hermon->icm = umalloc ( hermon->icm_aux_len + hermon->icm_len );
 		if ( ! hermon->icm ) {
+			DBGC ( hermon, "Hermon %p could not allocate ICM\n",
+			       hermon );
 			rc = -ENOMEM;
 			goto err_alloc;
 		}
@@ -2650,22 +2826,45 @@ static void hermon_unmap_icm ( struct he
  * Reset device
  *
  * @v hermon		Hermon device
+ * @ret rc		Return status code
  */
-static void hermon_reset ( struct hermon *hermon ) {
+static int hermon_reset ( struct hermon *hermon ) {
 	struct pci_device *pci = hermon->pci;
 	struct pci_config_backup backup;
 	static const uint8_t backup_exclude[] =
 		PCI_CONFIG_BACKUP_EXCLUDE ( 0x58, 0x5c );
+	uint16_t vendor;
+	unsigned int i;
+
+	/* Reset command interface toggle */
+	hermon->toggle = 0;
 
 	/* Perform device reset and preserve PCI configuration */
 	pci_backup ( pci, &backup, backup_exclude );
 	writel ( HERMON_RESET_MAGIC,
 		 ( hermon->config + HERMON_RESET_OFFSET ) );
-	mdelay ( HERMON_RESET_WAIT_TIME_MS );
-	pci_restore ( pci, &backup, backup_exclude );
 
-	/* Reset command interface toggle */
-	hermon->toggle = 0;
+	/* Wait until device starts responding to configuration cycles */
+	for ( i = 0 ; i < HERMON_RESET_MAX_WAIT_MS ; i++ ) {
+
+		/* Read PCI vendor ID */
+		pci_read_config_word ( pci, PCI_VENDOR_ID, &vendor );
+		if ( vendor == pci->vendor ) {
+
+			/* Restore PCI configuration */
+			pci_restore ( pci, &backup, backup_exclude );
+
+			DBGC ( hermon, "Hermon %p reset after %dms\n",
+			       hermon, i );
+			return 0;
+		}
+
+		/* Delay */
+		mdelay ( 1 );
+	}
+
+	DBGC ( hermon, "Hermon %p timed out waiting for reset\n", hermon );
+	return -ETIMEDOUT;
 }
 
 /**
@@ -2709,6 +2908,25 @@ static int hermon_setup_mpt ( struct her
 }
 
 /**
+ * Unmap memory protection table
+ *
+ * @v hermon		Hermon device
+ * @ret rc		Return status code
+ */
+static int hermon_unmap_mpt ( struct hermon *hermon ) {
+	int rc;
+
+	if ( ( rc = hermon_cmd_hw2sw_mpt ( hermon,
+					   hermon->cap.reserved_mrws ) ) != 0 ){
+		DBGC ( hermon, "Hermon %p could not unmap MPT: %s\n",
+		       hermon, strerror ( rc ) );
+		return rc;
+	}
+
+	return 0;
+}
+
+/**
  * Configure special queue pairs
  *
  * @v hermon		Hermon device
@@ -2784,11 +3002,13 @@ static int hermon_start ( struct hermon
 	if ( ( rc = hermon_configure_special_qps ( hermon ) ) != 0 )
 		goto err_conf_special_qps;
 
+	DBGC ( hermon, "Hermon %p device started\n", hermon );
 	return 0;
 
  err_conf_special_qps:
 	hermon_destroy_eq ( hermon );
  err_create_eq:
+	hermon_unmap_mpt ( hermon );
  err_setup_mpt:
 	hermon_cmd_close_hca ( hermon );
  err_init_hca:
@@ -2806,6 +3026,7 @@ static int hermon_start ( struct hermon
  */
 static void hermon_stop ( struct hermon *hermon ) {
 	hermon_destroy_eq ( hermon );
+	hermon_unmap_mpt ( hermon );
 	hermon_cmd_close_hca ( hermon );
 	hermon_unmap_icm ( hermon );
 	hermon_stop_firmware ( hermon );
@@ -3080,6 +3301,9 @@ static int hermon_register_ibdev ( struc
 	struct ib_device *ibdev = port->ibdev;
 	int rc;
 
+	/* Use Ethernet MAC as eIPoIB local EMAC */
+	memcpy ( ibdev->lemac, port->eth_mac.raw, ETH_ALEN );
+
 	/* Initialise parameters using SMC */
 	ib_smc_init ( ibdev, hermon_mad );
 
@@ -3137,13 +3361,13 @@ static struct hermon_port_type hermon_po
  */
 
 /** Number of Hermon Ethernet send work queue entries */
-#define HERMON_ETH_NUM_SEND_WQES 2
+#define HERMON_ETH_NUM_SEND_WQES 16
 
 /** Number of Hermon Ethernet receive work queue entries */
-#define HERMON_ETH_NUM_RECV_WQES 4
+#define HERMON_ETH_NUM_RECV_WQES 8
 
 /** Number of Hermon Ethernet completion entries */
-#define HERMON_ETH_NUM_CQES 8
+#define HERMON_ETH_NUM_CQES 32
 
 /**
  * Transmit packet via Hermon Ethernet device
@@ -3207,22 +3431,16 @@ static void hermon_eth_complete_recv ( s
 				       struct ib_address_vector *source,
 				       struct io_buffer *iobuf, int rc ) {
 	struct net_device *netdev = ib_qp_get_ownerdata ( qp );
-	struct net_device *vlan;
+	unsigned int tag;
 
-	/* Find VLAN device, if applicable */
-	if ( source->vlan_present ) {
-		if ( ( vlan = vlan_find ( netdev, source->vlan ) ) != NULL ) {
-			netdev = vlan;
-		} else if ( rc == 0 ) {
-			rc = -ENODEV;
-		}
-	}
+	/* Identify VLAN tag, if applicable */
+	tag = ( source->vlan_present ? source->vlan : 0 );
 
 	/* Hand off to network layer */
 	if ( rc == 0 ) {
-		netdev_rx ( netdev, iobuf );
+		vlan_netdev_rx ( netdev, tag, iobuf );
 	} else {
-		netdev_rx_err ( netdev, iobuf, rc );
+		vlan_netdev_rx_err ( netdev, tag, iobuf, rc );
 	}
 }
 
@@ -3402,24 +3620,10 @@ static int hermon_register_netdev ( stru
 				    struct hermon_port *port ) {
 	struct net_device *netdev = port->netdev;
 	struct ib_device *ibdev = port->ibdev;
-	struct hermonprm_query_port_cap query_port;
-	union {
-		uint8_t bytes[8];
-		uint32_t dwords[2];
-	} mac;
 	int rc;
 
-	/* Retrieve MAC address */
-	if ( ( rc = hermon_cmd_query_port ( hermon, ibdev->port,
-					    &query_port ) ) != 0 ) {
-		DBGC ( hermon, "Hermon %p port %d could not query port: %s\n",
-		       hermon, ibdev->port, strerror ( rc ) );
-		goto err_query_port;
-	}
-	mac.dwords[0] = htonl ( MLX_GET ( &query_port, mac_47_32 ) );
-	mac.dwords[1] = htonl ( MLX_GET ( &query_port, mac_31_0 ) );
-	memcpy ( netdev->hw_addr,
-		 &mac.bytes[ sizeof ( mac.bytes ) - ETH_ALEN ], ETH_ALEN );
+	/* Set MAC address */
+	memcpy ( netdev->hw_addr, port->eth_mac.raw, ETH_ALEN );
 
 	/* Register network device */
 	if ( ( rc = register_netdev ( netdev ) ) != 0 ) {
@@ -3443,7 +3647,6 @@ static int hermon_register_netdev ( stru
  err_register_nvo:
 	unregister_netdev ( netdev );
  err_register_netdev:
- err_query_port:
 	return rc;
 }
 
@@ -3581,6 +3784,10 @@ static int hermon_set_port_type ( struct
 	       ( ( ib_supported && eth_supported ) ? " and" : "" ),
 	       ( eth_supported ? " Ethernet" : "" ) );
 
+	/* Record Ethernet MAC address */
+	port->eth_mac.part.h = htons ( MLX_GET ( &query_port, mac_47_32 ) );
+	port->eth_mac.part.l = htonl ( MLX_GET ( &query_port, mac_31_0 ) );
+
 	/* Sense network, if applicable */
 	if ( ib_supported && eth_supported ) {
 
@@ -3593,6 +3800,9 @@ static int hermon_set_port_type ( struct
 				rc = port_type;
 				return rc;
 			}
+
+			/* Avoid spamming debug output */
+			mdelay ( 50 );
 		} while ( ( port_type == HERMON_PORT_TYPE_UNKNOWN ) &&
 			  ( ( elapsed = ( currticks() - start ) ) <
 			    HERMON_SENSE_PORT_TIMEOUT ) );
@@ -3742,20 +3952,20 @@ static struct hermon * hermon_alloc ( vo
 		goto err_hermon;
 
 	/* Allocate space for mailboxes */
-	hermon->mailbox_in = malloc_dma ( HERMON_MBOX_SIZE,
-					  HERMON_MBOX_ALIGN );
+	hermon->mailbox_in = malloc_phys ( HERMON_MBOX_SIZE,
+					   HERMON_MBOX_ALIGN );
 	if ( ! hermon->mailbox_in )
 		goto err_mailbox_in;
-	hermon->mailbox_out = malloc_dma ( HERMON_MBOX_SIZE,
-					   HERMON_MBOX_ALIGN );
+	hermon->mailbox_out = malloc_phys ( HERMON_MBOX_SIZE,
+					    HERMON_MBOX_ALIGN );
 	if ( ! hermon->mailbox_out )
 		goto err_mailbox_out;
 
 	return hermon;
 
-	free_dma ( hermon->mailbox_out, HERMON_MBOX_SIZE );
+	free_phys ( hermon->mailbox_out, HERMON_MBOX_SIZE );
  err_mailbox_out:
-	free_dma ( hermon->mailbox_in, HERMON_MBOX_SIZE );
+	free_phys ( hermon->mailbox_in, HERMON_MBOX_SIZE );
  err_mailbox_in:
 	free ( hermon );
  err_hermon:
@@ -3771,8 +3981,8 @@ static void hermon_free ( struct hermon
 
 	ufree ( hermon->icm );
 	ufree ( hermon->firmware_area );
-	free_dma ( hermon->mailbox_out, HERMON_MBOX_SIZE );
-	free_dma ( hermon->mailbox_in, HERMON_MBOX_SIZE );
+	free_phys ( hermon->mailbox_out, HERMON_MBOX_SIZE );
+	free_phys ( hermon->mailbox_in, HERMON_MBOX_SIZE );
 	free ( hermon );
 }
 
@@ -3788,6 +3998,8 @@ static int hermon_probe ( struct pci_dev
 	struct ib_device *ibdev;
 	struct net_device *netdev;
 	struct hermon_port *port;
+	unsigned long config;
+	unsigned long uar;
 	unsigned int i;
 	int rc;
 
@@ -3804,13 +4016,16 @@ static int hermon_probe ( struct pci_dev
 	adjust_pci_device ( pci );
 
 	/* Map PCI BARs */
-	hermon->config = ioremap ( pci_bar_start ( pci, HERMON_PCI_CONFIG_BAR ),
-				   HERMON_PCI_CONFIG_BAR_SIZE );
-	hermon->uar = ioremap ( pci_bar_start ( pci, HERMON_PCI_UAR_BAR ),
-				HERMON_UAR_NON_EQ_PAGE * HERMON_PAGE_SIZE );
+	config = pci_bar_start ( pci, HERMON_PCI_CONFIG_BAR );
+	hermon->config = pci_ioremap ( pci, config,
+				       HERMON_PCI_CONFIG_BAR_SIZE );
+	uar = pci_bar_start ( pci, HERMON_PCI_UAR_BAR );
+	hermon->uar = pci_ioremap ( pci, uar,
+				    HERMON_UAR_NON_EQ_PAGE * HERMON_PAGE_SIZE );
 
 	/* Reset device */
-	hermon_reset ( hermon );
+	if ( ( rc = hermon_reset ( hermon ) ) != 0 )
+		goto err_reset;
 
 	/* Start firmware */
 	if ( ( rc = hermon_start_firmware ( hermon ) ) != 0 )
@@ -3822,7 +4037,7 @@ static int hermon_probe ( struct pci_dev
 
 	/* Allocate Infiniband devices */
 	for ( i = 0 ; i < hermon->cap.num_ports ; i++ ) {
-	        ibdev = alloc_ibdev ( 0 );
+		ibdev = alloc_ibdev ( 0 );
 		if ( ! ibdev ) {
 			rc = -ENOMEM;
 			goto err_alloc_ibdev;
@@ -3831,6 +4046,7 @@ static int hermon_probe ( struct pci_dev
 		ibdev->op = &hermon_ib_operations;
 		ibdev->dev = &pci->dev;
 		ibdev->port = ( HERMON_PORT_BASE + i );
+		ibdev->ports = hermon->cap.num_ports;
 		ib_set_drvdata ( ibdev, hermon );
 	}
 
@@ -3902,6 +4118,7 @@ static int hermon_probe ( struct pci_dev
  err_get_cap:
 	hermon_stop_firmware ( hermon );
  err_start_firmware:
+ err_reset:
 	iounmap ( hermon->uar );
 	iounmap ( hermon->config );
 	hermon_free ( hermon );
@@ -3943,6 +4160,7 @@ static void hermon_remove ( struct pci_d
  */
 static int hermon_bofm_probe ( struct pci_device *pci ) {
 	struct hermon *hermon;
+	unsigned long config;
 	int rc;
 
 	/* Allocate Hermon device */
@@ -3958,8 +4176,9 @@ static int hermon_bofm_probe ( struct pc
 	adjust_pci_device ( pci );
 
 	/* Map PCI BAR */
-	hermon->config = ioremap ( pci_bar_start ( pci, HERMON_PCI_CONFIG_BAR ),
-				   HERMON_PCI_CONFIG_BAR_SIZE );
+	config = pci_bar_start ( pci, HERMON_PCI_CONFIG_BAR );
+	hermon->config = pci_ioremap ( pci, config,
+				       HERMON_PCI_CONFIG_BAR_SIZE );
 
 	/* Initialise BOFM device */
 	bofm_init ( &hermon->bofm, pci, &hermon_bofm_operations );
@@ -3994,18 +4213,29 @@ static void hermon_bofm_remove ( struct
 }
 
 static struct pci_device_id hermon_nics[] = {
+	/* Mellanox ConnectX VPI (ethernet + infiniband) */
 	PCI_ROM ( 0x15b3, 0x6340, "mt25408", "MT25408 HCA driver", 0 ),
 	PCI_ROM ( 0x15b3, 0x634a, "mt25418", "MT25418 HCA driver", 0 ),
+
+	/* Mellanox ConnectX EN (ethernet only) */
+	PCI_ROM ( 0x15b3, 0x6368, "mt25448", "MT25448 HCA driver", 0 ),
+	PCI_ROM ( 0x15b3, 0x6372, "mt25458", "MT25458 HCA driver", 0 ),
+
+	/* Mellanox ConnectX-2 VPI (ethernet + infiniband) */
 	PCI_ROM ( 0x15b3, 0x6732, "mt26418", "MT26418 HCA driver", 0 ),
 	PCI_ROM ( 0x15b3, 0x673c, "mt26428", "MT26428 HCA driver", 0 ),
 	PCI_ROM ( 0x15b3, 0x6746, "mt26438", "MT26438 HCA driver", 0 ),
 	PCI_ROM ( 0x15b3, 0x6778, "mt26488", "MT26488 HCA driver", 0 ),
-	PCI_ROM ( 0x15b3, 0x6368, "mt25448", "MT25448 HCA driver", 0 ),
+
+	/* Mellanox ConnectX-2 EN (ethernet only) */
 	PCI_ROM ( 0x15b3, 0x6750, "mt26448", "MT26448 HCA driver", 0 ),
-	PCI_ROM ( 0x15b3, 0x6372, "mt25458", "MT25458 HCA driver", 0 ),
 	PCI_ROM ( 0x15b3, 0x675a, "mt26458", "MT26458 HCA driver", 0 ),
 	PCI_ROM ( 0x15b3, 0x6764, "mt26468", "MT26468 HCA driver", 0 ),
 	PCI_ROM ( 0x15b3, 0x676e, "mt26478", "MT26478 HCA driver", 0 ),
+
+	/* Mellanox ConnectX-3 VPI (ethernet + infiniband) */
+	PCI_ROM ( 0x15b3, 0x1003, "mt4099", "ConnectX-3 HCA driver", 0 ),
+	PCI_ROM ( 0x15b3, 0x1007, "mt4103", "ConnectX-3 Pro HCA driver", 0 ),
 };
 
 struct pci_driver hermon_driver __pci_driver = {
diff -pruN 1.0.0+git-20190125.36a4c85-5.1/src/drivers/infiniband/hermon.h 1.21.1+git-20220113.fbbdc3926-0ubuntu1/src/drivers/infiniband/hermon.h
--- 1.0.0+git-20190125.36a4c85-5.1/src/drivers/infiniband/hermon.h	2019-02-09 16:03:59.000000000 +0000
+++ 1.21.1+git-20220113.fbbdc3926-0ubuntu1/src/drivers/infiniband/hermon.h	2022-01-13 13:43:08.000000000 +0000
@@ -34,8 +34,8 @@ FILE_LICENCE ( GPL2_OR_LATER );
 
 /* Device reset */
 #define HERMON_RESET_OFFSET		0x0f0010
-#define HERMON_RESET_MAGIC		0x01000000UL
-#define HERMON_RESET_WAIT_TIME_MS	1000
+#define HERMON_RESET_MAGIC		0x01000001UL
+#define HERMON_RESET_MAX_WAIT_MS	1000
 
 /* Work queue entry and completion queue entry opcodes */
 #define HERMON_OPCODE_NOP		0x00
@@ -52,6 +52,7 @@ FILE_LICENCE ( GPL2_OR_LATER );
 #define HERMON_HCR_CLOSE_PORT		0x000a
 #define HERMON_HCR_SET_PORT		0x000c
 #define HERMON_HCR_SW2HW_MPT		0x000d
+#define HERMON_HCR_HW2SW_MPT		0x000f
 #define HERMON_HCR_WRITE_MTT		0x0011
 #define HERMON_HCR_MAP_EQ		0x0012
 #define HERMON_HCR_SW2HW_EQ		0x0013
@@ -122,6 +123,7 @@ FILE_LICENCE ( GPL2_OR_LATER );
 #define HERMON_SET_PORT_GID_TABLE	0x0500
 
 #define HERMON_EV_PORT_STATE_CHANGE	0x09
+#define HERMON_EV_PORT_MGMNT_CHANGE	0x1d
 
 #define HERMON_SCHED_QP0		0x3f
 #define HERMON_SCHED_DEFAULT		0x83
@@ -216,6 +218,13 @@ struct hermonprm_port_state_change_event
 	struct hermonprm_port_state_change_st data;
 } __attribute__ (( packed ));
 
+struct hermonprm_port_mgmnt_change_event_st {
+	pseudo_bit_t reserved[0x00020];
+/* -------------- */
+	pseudo_bit_t port[0x00008];
+	pseudo_bit_t reserved0[0x00018];
+} __attribute__ (( packed ));
+
 struct hermonprm_sense_port_st {
 	pseudo_bit_t reserved0[0x00020];
 /* -------------- */
@@ -459,6 +468,7 @@ struct MLX_DECLARE_STRUCT ( hermonprm_mo
 struct MLX_DECLARE_STRUCT ( hermonprm_mpt );
 struct MLX_DECLARE_STRUCT ( hermonprm_mtt );
 struct MLX_DECLARE_STRUCT ( hermonprm_port_state_change_event );
+struct MLX_DECLARE_STRUCT ( hermonprm_port_mgmnt_change_event );
 struct MLX_DECLARE_STRUCT ( hermonprm_qp_db_record );
 struct MLX_DECLARE_STRUCT ( hermonprm_qp_ee_state_transitions );
 struct MLX_DECLARE_STRUCT ( hermonprm_query_dev_cap );
@@ -529,6 +539,7 @@ union hermonprm_completion_entry {
 union hermonprm_event_entry {
 	struct hermonprm_event_queue_entry generic;
 	struct hermonprm_port_state_change_event port_state_change;
+	struct hermonprm_port_mgmnt_change_event port_mgmnt_change;
 } __attribute__ (( packed ));
 
 union hermonprm_doorbell_register {
@@ -822,6 +833,15 @@ struct hermon_port_type {
 				    struct hermon_port *port );
 };
 
+/** A Hermon port Ethernet MAC address */
+union hermon_port_mac {
+	struct {
+		uint16_t h;
+		uint32_t l;
+	} __attribute__ (( packed )) part;
+	uint8_t raw[ETH_ALEN];
+};
+
 /** A Hermon port */
 struct hermon_port {
 	/** Infiniband device */
@@ -832,6 +852,8 @@ struct hermon_port {
 	struct ib_completion_queue *eth_cq;
 	/** Ethernet queue pair */
 	struct ib_queue_pair *eth_qp;
+	/** Ethernet MAC */
+	union hermon_port_mac eth_mac;
 	/** Port type */
 	struct hermon_port_type *type;
 	/** Non-volatile option storage */
@@ -882,6 +904,8 @@ struct hermon {
 
 	/** Event queue */
 	struct hermon_event_queue eq;
+	/** Last unsolicited link state poll */
+	unsigned long last_poll;
 	/** Unrestricted LKey
 	 *
 	 * Used to get unrestricted memory access.
@@ -918,6 +942,13 @@ struct hermon {
 /** Memory key prefix */
 #define HERMON_MKEY_PREFIX		0x77000000UL
 
+/** Link poll interval
+ *
+ * Used when we need to poll for link state (rather than relying upon
+ * receiving an event).
+ */
+#define HERMON_LINK_POLL_INTERVAL	( TICKS_PER_SEC / 2 )
+
 /*
  * HCA commands
  *
@@ -925,7 +956,7 @@ struct hermon {
 
 #define HERMON_HCR_BASE			0x80680
 #define HERMON_HCR_REG(x)		( HERMON_HCR_BASE + 4 * (x) )
-#define HERMON_HCR_MAX_WAIT_MS		2000
+#define HERMON_HCR_MAX_WAIT_MS		10000
 #define HERMON_MBOX_ALIGN		4096
 #define HERMON_MBOX_SIZE		1024
 
diff -pruN 1.0.0+git-20190125.36a4c85-5.1/src/drivers/infiniband/linda.c 1.21.1+git-20220113.fbbdc3926-0ubuntu1/src/drivers/infiniband/linda.c
--- 1.0.0+git-20190125.36a4c85-5.1/src/drivers/infiniband/linda.c	1970-01-01 00:00:00.000000000 +0000
+++ 1.21.1+git-20220113.fbbdc3926-0ubuntu1/src/drivers/infiniband/linda.c	2022-01-13 13:43:08.000000000 +0000
@@ -0,0 +1,2430 @@
+/*
+ * Copyright (C) 2008 Michael Brown <mbrown@fensystems.co.uk>.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of the
+ * License, or any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+ * 02110-1301, USA.
+ *
+ * You can also choose to distribute this program under the terms of
+ * the Unmodified Binary Distribution Licence (as given in the file
+ * COPYING.UBDL), provided that you have satisfied its requirements.
+ */
+
+FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
+
+#include <stdint.h>
+#include <stdlib.h>
+#include <errno.h>
+#include <unistd.h>
+#include <assert.h>
+#include <ipxe/io.h>
+#include <ipxe/pci.h>
+#include <ipxe/infiniband.h>
+#include <ipxe/i2c.h>
+#include <ipxe/bitbash.h>
+#include <ipxe/malloc.h>
+#include <ipxe/iobuf.h>
+#include "linda.h"
+
+/**
+ * @file
+ *
+ * QLogic Linda Infiniband HCA
+ *
+ */
+
+/** A Linda send work queue */
+struct linda_send_work_queue {
+	/** Send buffer usage */
+	uint8_t *send_buf;
+	/** Producer index */
+	unsigned int prod;
+	/** Consumer index */
+	unsigned int cons;
+};
+
+/** A Linda receive work queue */
+struct linda_recv_work_queue {
+	/** Receive header ring */
+	void *header;
+	/** Receive header producer offset (written by hardware) */
+	struct QIB_7220_scalar header_prod;
+	/** Receive header consumer offset */
+	unsigned int header_cons;
+	/** Offset within register space of the eager array */
+	unsigned long eager_array;
+	/** Number of entries in eager array */
+	unsigned int eager_entries;
+	/** Eager array producer index */
+	unsigned int eager_prod;
+	/** Eager array consumer index */
+	unsigned int eager_cons;
+};
+
+/** A Linda HCA */
+struct linda {
+	/** Registers */
+	void *regs;
+
+	/** In-use contexts */
+	uint8_t used_ctx[LINDA_NUM_CONTEXTS];
+	/** Send work queues */
+	struct linda_send_work_queue send_wq[LINDA_NUM_CONTEXTS];
+	/** Receive work queues */
+	struct linda_recv_work_queue recv_wq[LINDA_NUM_CONTEXTS];
+
+	/** Offset within register space of the first send buffer */
+	unsigned long send_buffer_base;
+	/** Send buffer availability (reported by hardware) */
+	struct QIB_7220_SendBufAvail *sendbufavail;
+	/** Send buffer availability (maintained by software) */
+	uint8_t send_buf[LINDA_MAX_SEND_BUFS];
+	/** Send buffer availability producer counter */
+	unsigned int send_buf_prod;
+	/** Send buffer availability consumer counter */
+	unsigned int send_buf_cons;
+	/** Number of reserved send buffers (across all QPs) */
+	unsigned int reserved_send_bufs;
+
+	/** I2C bit-bashing interface */
+	struct i2c_bit_basher i2c;
+	/** I2C serial EEPROM */
+	struct i2c_device eeprom;
+};
+
+/***************************************************************************
+ *
+ * Linda register access
+ *
+ ***************************************************************************
+ *
+ * This card requires atomic 64-bit accesses.  Strange things happen
+ * if you try to use 32-bit accesses; sometimes they work, sometimes
+ * they don't, sometimes you get random data.
+ */
+
+/**
+ * Read Linda qword register
+ *
+ * @v linda		Linda device
+ * @v qword		Register buffer to read into
+ * @v offset		Register offset
+ */
+static void linda_readq ( struct linda *linda, uint64_t *qword,
+			  unsigned long offset ) {
+	*qword = readq ( linda->regs + offset );
+}
+#define linda_readq( _linda, _ptr, _offset ) \
+	linda_readq ( (_linda), (_ptr)->u.qwords, (_offset) )
+#define linda_readq_array8b( _linda, _ptr, _offset, _idx ) \
+	linda_readq ( (_linda), (_ptr), ( (_offset) + ( (_idx) * 8 ) ) )
+#define linda_readq_array64k( _linda, _ptr, _offset, _idx ) \
+	linda_readq ( (_linda), (_ptr), ( (_offset) + ( (_idx) * 65536 ) ) )
+
+/**
+ * Write Linda qword register
+ *
+ * @v linda		Linda device
+ * @v qword		Register buffer to write
+ * @v offset		Register offset
+ */
+static void linda_writeq ( struct linda *linda, const uint64_t *qword,
+			   unsigned long offset ) {
+	writeq ( *qword, ( linda->regs + offset ) );
+}
+#define linda_writeq( _linda, _ptr, _offset ) \
+	linda_writeq ( (_linda), (_ptr)->u.qwords, (_offset) )
+#define linda_writeq_array8b( _linda, _ptr, _offset, _idx ) \
+	linda_writeq ( (_linda), (_ptr), ( (_offset) + ( (_idx) * 8 ) ) )
+#define linda_writeq_array64k( _linda, _ptr, _offset, _idx ) \
+	linda_writeq ( (_linda), (_ptr), ( (_offset) + ( (_idx) * 65536 ) ) )
+
+/**
+ * Write Linda dword register
+ *
+ * @v linda		Linda device
+ * @v dword		Value to write
+ * @v offset		Register offset
+ */
+static void linda_writel ( struct linda *linda, uint32_t dword,
+			   unsigned long offset ) {
+	writel ( dword, ( linda->regs + offset ) );
+}
+
+/***************************************************************************
+ *
+ * Link state management
+ *
+ ***************************************************************************
+ */
+
+/**
+ * Textual representation of link state
+ *
+ * @v link_state	Link state
+ * @ret link_text	Link state text
+ */
+static const char * linda_link_state_text ( unsigned int link_state ) {
+	switch ( link_state ) {
+	case LINDA_LINK_STATE_DOWN:	return "DOWN";
+	case LINDA_LINK_STATE_INIT:	return "INIT";
+	case LINDA_LINK_STATE_ARM:	return "ARM";
+	case LINDA_LINK_STATE_ACTIVE:	return "ACTIVE";
+	case LINDA_LINK_STATE_ACT_DEFER:return "ACT_DEFER";
+	default:			return "UNKNOWN";
+	}
+}
+
+/**
+ * Handle link state change
+ *
+ * @v linda		Linda device
+ */
+static void linda_link_state_changed ( struct ib_device *ibdev ) {
+	struct linda *linda = ib_get_drvdata ( ibdev );
+	struct QIB_7220_IBCStatus ibcstatus;
+	struct QIB_7220_EXTCtrl extctrl;
+	unsigned int link_state;
+	unsigned int link_width;
+	unsigned int link_speed;
+
+	/* Read link state */
+	linda_readq ( linda, &ibcstatus, QIB_7220_IBCStatus_offset );
+	link_state = BIT_GET ( &ibcstatus, LinkState );
+	link_width = BIT_GET ( &ibcstatus, LinkWidthActive );
+	link_speed = BIT_GET ( &ibcstatus, LinkSpeedActive );
+	DBGC ( linda, "Linda %p link state %s (%s %s)\n", linda,
+	       linda_link_state_text ( link_state ),
+	       ( link_speed ? "DDR" : "SDR" ), ( link_width ? "x4" : "x1" ) );
+
+	/* Set LEDs according to link state */
+	linda_readq ( linda, &extctrl, QIB_7220_EXTCtrl_offset );
+	BIT_SET ( &extctrl, LEDPriPortGreenOn,
+		  ( ( link_state >= LINDA_LINK_STATE_INIT ) ? 1 : 0 ) );
+	BIT_SET ( &extctrl, LEDPriPortYellowOn,
+		  ( ( link_state >= LINDA_LINK_STATE_ACTIVE ) ? 1 : 0 ) );
+	linda_writeq ( linda, &extctrl, QIB_7220_EXTCtrl_offset );
+
+	/* Notify Infiniband core of link state change */
+	ibdev->port_state = ( link_state + 1 );
+	ibdev->link_width_active =
+		( link_width ? IB_LINK_WIDTH_4X : IB_LINK_WIDTH_1X );
+	ibdev->link_speed_active =
+		( link_speed ? IB_LINK_SPEED_DDR : IB_LINK_SPEED_SDR );
+	ib_link_state_changed ( ibdev );
+}
+
+/**
+ * Wait for link state change to take effect
+ *
+ * @v linda		Linda device
+ * @v new_link_state	Expected link state
+ * @ret rc		Return status code
+ */
+static int linda_link_state_check ( struct linda *linda,
+				    unsigned int new_link_state ) {
+	struct QIB_7220_IBCStatus ibcstatus;
+	unsigned int link_state;
+	unsigned int i;
+
+	for ( i = 0 ; i < LINDA_LINK_STATE_MAX_WAIT_US ; i++ ) {
+		linda_readq ( linda, &ibcstatus, QIB_7220_IBCStatus_offset );
+		link_state = BIT_GET ( &ibcstatus, LinkState );
+		if ( link_state == new_link_state )
+			return 0;
+		udelay ( 1 );
+	}
+
+	DBGC ( linda, "Linda %p timed out waiting for link state %s\n",
+	       linda, linda_link_state_text ( link_state ) );
+	return -ETIMEDOUT;
+}
+
+/**
+ * Set port information
+ *
+ * @v ibdev		Infiniband device
+ * @v mad		Set port information MAD
+ */
+static int linda_set_port_info ( struct ib_device *ibdev, union ib_mad *mad ) {
+	struct linda *linda = ib_get_drvdata ( ibdev );
+	struct ib_port_info *port_info = &mad->smp.smp_data.port_info;
+	struct QIB_7220_IBCCtrl ibcctrl;
+	unsigned int port_state;
+	unsigned int link_state;
+
+	/* Set new link state */
+	port_state = ( port_info->link_speed_supported__port_state & 0xf );
+	if ( port_state ) {
+		link_state = ( port_state - 1 );
+		DBGC ( linda, "Linda %p set link state to %s (%x)\n", linda,
+		       linda_link_state_text ( link_state ), link_state );
+		linda_readq ( linda, &ibcctrl, QIB_7220_IBCCtrl_offset );
+		BIT_SET ( &ibcctrl, LinkCmd, link_state );
+		linda_writeq ( linda, &ibcctrl, QIB_7220_IBCCtrl_offset );
+
+		/* Wait for link state change to take effect.  Ignore
+		 * errors; the current link state will be returned via
+		 * the GetResponse MAD.
+		 */
+		linda_link_state_check ( linda, link_state );
+	}
+
+	/* Detect and report link state change */
+	linda_link_state_changed ( ibdev );
+
+	return 0;
+}
+
+/**
+ * Set partition key table
+ *
+ * @v ibdev		Infiniband device
+ * @v mad		Set partition key table MAD
+ */
+static int linda_set_pkey_table ( struct ib_device *ibdev __unused,
+				  union ib_mad *mad __unused ) {
+	/* Nothing to do */
+	return 0;
+}
+
+/***************************************************************************
+ *
+ * Context allocation
+ *
+ ***************************************************************************
+ */
+
+/**
+ * Map context number to QPN
+ *
+ * @v ctx		Context index
+ * @ret qpn		Queue pair number
+ */
+static int linda_ctx_to_qpn ( unsigned int ctx ) {
+	/* This mapping is fixed by hardware */
+	return ( ctx * 2 );
+}
+
+/**
+ * Map QPN to context number
+ *
+ * @v qpn		Queue pair number
+ * @ret ctx		Context index
+ */
+static int linda_qpn_to_ctx ( unsigned int qpn ) {
+	/* This mapping is fixed by hardware */
+	return ( qpn / 2 );
+}
+
+/**
+ * Allocate a context
+ *
+ * @v linda		Linda device
+ * @ret ctx		Context index, or negative error
+ */
+static int linda_alloc_ctx ( struct linda *linda ) {
+	unsigned int ctx;
+
+	for ( ctx = 0 ; ctx < LINDA_NUM_CONTEXTS ; ctx++ ) {
+
+		if ( ! linda->used_ctx[ctx] ) {
+			linda->used_ctx[ctx ] = 1;
+			DBGC2 ( linda, "Linda %p CTX %d allocated\n",
+				linda, ctx );
+			return ctx;
+		}
+	}
+
+	DBGC ( linda, "Linda %p out of available contexts\n", linda );
+	return -ENOENT;
+}
+
+/**
+ * Free a context
+ *
+ * @v linda		Linda device
+ * @v ctx		Context index
+ */
+static void linda_free_ctx ( struct linda *linda, unsigned int ctx ) {
+
+	linda->used_ctx[ctx] = 0;
+	DBGC2 ( linda, "Linda %p CTX %d freed\n", linda, ctx );
+}
+
+/***************************************************************************
+ *
+ * Send datapath
+ *
+ ***************************************************************************
+ */
+
+/** Send buffer toggle bit
+ *
+ * We encode send buffers as 7 bits of send buffer index plus a single
+ * bit which should match the "check" bit in the SendBufAvail array.
+ */
+#define LINDA_SEND_BUF_TOGGLE 0x80
+
+/**
+ * Allocate a send buffer
+ *
+ * @v linda		Linda device
+ * @ret send_buf	Send buffer
+ *
+ * You must guarantee that a send buffer is available.  This is done
+ * by refusing to allocate more TX WQEs in total than the number of
+ * available send buffers.
+ */
+static unsigned int linda_alloc_send_buf ( struct linda *linda ) {
+	unsigned int send_buf;
+
+	send_buf = linda->send_buf[linda->send_buf_cons];
+	send_buf ^= LINDA_SEND_BUF_TOGGLE;
+	linda->send_buf_cons = ( ( linda->send_buf_cons + 1 ) %
+				 LINDA_MAX_SEND_BUFS );
+	return send_buf;
+}
+
+/**
+ * Free a send buffer
+ *
+ * @v linda		Linda device
+ * @v send_buf		Send buffer
+ */
+static void linda_free_send_buf ( struct linda *linda,
+				  unsigned int send_buf ) {
+	linda->send_buf[linda->send_buf_prod] = send_buf;
+	linda->send_buf_prod = ( ( linda->send_buf_prod + 1 ) %
+				 LINDA_MAX_SEND_BUFS );
+}
+
+/**
+ * Check to see if send buffer is in use
+ *
+ * @v linda		Linda device
+ * @v send_buf		Send buffer
+ * @ret in_use		Send buffer is in use
+ */
+static int linda_send_buf_in_use ( struct linda *linda,
+				   unsigned int send_buf ) {
+	unsigned int send_idx;
+	unsigned int send_check;
+	unsigned int inusecheck;
+	unsigned int inuse;
+	unsigned int check;
+
+	send_idx = ( send_buf & ~LINDA_SEND_BUF_TOGGLE );
+	send_check = ( !! ( send_buf & LINDA_SEND_BUF_TOGGLE ) );
+	inusecheck = BIT_GET ( linda->sendbufavail, InUseCheck[send_idx] );
+	inuse = ( !! ( inusecheck & 0x02 ) );
+	check = ( !! ( inusecheck & 0x01 ) );
+	return ( inuse || ( check != send_check ) );
+}
+
+/**
+ * Calculate starting offset for send buffer
+ *
+ * @v linda		Linda device
+ * @v send_buf		Send buffer
+ * @ret offset		Starting offset
+ */
+static unsigned long linda_send_buffer_offset ( struct linda *linda,
+						unsigned int send_buf ) {
+	return ( linda->send_buffer_base +
+		 ( ( send_buf & ~LINDA_SEND_BUF_TOGGLE ) *
+		   LINDA_SEND_BUF_SIZE ) );
+}
+
+/**
+ * Create send work queue
+ *
+ * @v linda		Linda device
+ * @v qp		Queue pair
+ */
+static int linda_create_send_wq ( struct linda *linda,
+				  struct ib_queue_pair *qp ) {
+	struct ib_work_queue *wq = &qp->send;
+	struct linda_send_work_queue *linda_wq = ib_wq_get_drvdata ( wq );
+	int rc;
+
+	/* Reserve send buffers */
+	if ( ( linda->reserved_send_bufs + qp->send.num_wqes ) >
+	     LINDA_MAX_SEND_BUFS ) {
+		DBGC ( linda, "Linda %p out of send buffers (have %d, used "
+		       "%d, need %d)\n", linda, LINDA_MAX_SEND_BUFS,
+		       linda->reserved_send_bufs, qp->send.num_wqes );
+		rc = -ENOBUFS;
+		goto err_reserve_bufs;
+	}
+	linda->reserved_send_bufs += qp->send.num_wqes;
+
+	/* Reset work queue */
+	linda_wq->prod = 0;
+	linda_wq->cons = 0;
+
+	/* Allocate space for send buffer uasge list */
+	linda_wq->send_buf = zalloc ( qp->send.num_wqes *
+				      sizeof ( linda_wq->send_buf[0] ) );
+	if ( ! linda_wq->send_buf ) {
+		rc = -ENOBUFS;
+		goto err_alloc_send_buf;
+	}
+
+	return 0;
+
+	free ( linda_wq->send_buf );
+ err_alloc_send_buf:
+	linda->reserved_send_bufs -= qp->send.num_wqes;
+ err_reserve_bufs:
+	return rc;
+}
+
+/**
+ * Destroy send work queue
+ *
+ * @v linda		Linda device
+ * @v qp		Queue pair
+ */
+static void linda_destroy_send_wq ( struct linda *linda,
+				    struct ib_queue_pair *qp ) {
+	struct ib_work_queue *wq = &qp->send;
+	struct linda_send_work_queue *linda_wq = ib_wq_get_drvdata ( wq );
+
+	free ( linda_wq->send_buf );
+	linda->reserved_send_bufs -= qp->send.num_wqes;
+}
+
+/**
+ * Initialise send datapath
+ *
+ * @v linda		Linda device
+ * @ret rc		Return status code
+ */
+static int linda_init_send ( struct linda *linda ) {
+	struct QIB_7220_SendBufBase sendbufbase;
+	struct QIB_7220_SendBufAvailAddr sendbufavailaddr;
+	struct QIB_7220_SendCtrl sendctrl;
+	unsigned int i;
+	int rc;
+
+	/* Retrieve SendBufBase */
+	linda_readq ( linda, &sendbufbase, QIB_7220_SendBufBase_offset );
+	linda->send_buffer_base = BIT_GET ( &sendbufbase,
+					    BaseAddr_SmallPIO );
+	DBGC ( linda, "Linda %p send buffers at %lx\n",
+	       linda, linda->send_buffer_base );
+
+	/* Initialise the send_buf[] array */
+	for ( i = 0 ; i < LINDA_MAX_SEND_BUFS ; i++ )
+		linda->send_buf[i] = i;
+
+	/* Allocate space for the SendBufAvail array */
+	linda->sendbufavail = malloc_phys ( sizeof ( *linda->sendbufavail ),
+					    LINDA_SENDBUFAVAIL_ALIGN );
+	if ( ! linda->sendbufavail ) {
+		rc = -ENOMEM;
+		goto err_alloc_sendbufavail;
+	}
+	memset ( linda->sendbufavail, 0, sizeof ( *linda->sendbufavail ) );
+
+	/* Program SendBufAvailAddr into the hardware */
+	memset ( &sendbufavailaddr, 0, sizeof ( sendbufavailaddr ) );
+	BIT_FILL_1 ( &sendbufavailaddr, SendBufAvailAddr,
+		     ( virt_to_bus ( linda->sendbufavail ) >> 6 ) );
+	linda_writeq ( linda, &sendbufavailaddr,
+		       QIB_7220_SendBufAvailAddr_offset );
+
+	/* Enable sending and DMA of SendBufAvail */
+	memset ( &sendctrl, 0, sizeof ( sendctrl ) );
+	BIT_FILL_2 ( &sendctrl,
+		     SendBufAvailUpd, 1,
+		     SPioEnable, 1 );
+	linda_writeq ( linda, &sendctrl, QIB_7220_SendCtrl_offset );
+
+	return 0;
+
+	free_phys ( linda->sendbufavail, sizeof ( *linda->sendbufavail ) );
+ err_alloc_sendbufavail:
+	return rc;
+}
+
+/**
+ * Shut down send datapath
+ *
+ * @v linda		Linda device
+ */
+static void linda_fini_send ( struct linda *linda ) {
+	struct QIB_7220_SendCtrl sendctrl;
+
+	/* Disable sending and DMA of SendBufAvail */
+	memset ( &sendctrl, 0, sizeof ( sendctrl ) );
+	linda_writeq ( linda, &sendctrl, QIB_7220_SendCtrl_offset );
+	mb();
+
+	/* Ensure hardware has seen this disable */
+	linda_readq ( linda, &sendctrl, QIB_7220_SendCtrl_offset );
+
+	free_phys ( linda->sendbufavail, sizeof ( *linda->sendbufavail ) );
+}
+
+/***************************************************************************
+ *
+ * Receive datapath
+ *
+ ***************************************************************************
+ */
+
+/**
+ * Create receive work queue
+ *
+ * @v linda		Linda device
+ * @v qp		Queue pair
+ * @ret rc		Return status code
+ */
+static int linda_create_recv_wq ( struct linda *linda,
+				  struct ib_queue_pair *qp ) {
+	struct ib_work_queue *wq = &qp->recv;
+	struct linda_recv_work_queue *linda_wq = ib_wq_get_drvdata ( wq );
+	struct QIB_7220_RcvHdrAddr0 rcvhdraddr;
+	struct QIB_7220_RcvHdrTailAddr0 rcvhdrtailaddr;
+	struct QIB_7220_RcvHdrHead0 rcvhdrhead;
+	struct QIB_7220_scalar rcvegrindexhead;
+	struct QIB_7220_RcvCtrl rcvctrl;
+	unsigned int ctx = linda_qpn_to_ctx ( qp->qpn );
+	int rc;
+
+	/* Reset context information */
+	memset ( &linda_wq->header_prod, 0,
+		 sizeof ( linda_wq->header_prod ) );
+	linda_wq->header_cons = 0;
+	linda_wq->eager_prod = 0;
+	linda_wq->eager_cons = 0;
+
+	/* Allocate receive header buffer */
+	linda_wq->header = malloc_phys ( LINDA_RECV_HEADERS_SIZE,
+					 LINDA_RECV_HEADERS_ALIGN );
+	if ( ! linda_wq->header ) {
+		rc = -ENOMEM;
+		goto err_alloc_header;
+	}
+
+	/* Enable context in hardware */
+	memset ( &rcvhdraddr, 0, sizeof ( rcvhdraddr ) );
+	BIT_FILL_1 ( &rcvhdraddr, RcvHdrAddr0,
+		     ( virt_to_bus ( linda_wq->header ) >> 2 ) );
+	linda_writeq_array8b ( linda, &rcvhdraddr,
+			       QIB_7220_RcvHdrAddr0_offset, ctx );
+	memset ( &rcvhdrtailaddr, 0, sizeof ( rcvhdrtailaddr ) );
+	BIT_FILL_1 ( &rcvhdrtailaddr, RcvHdrTailAddr0,
+		     ( virt_to_bus ( &linda_wq->header_prod ) >> 2 ) );
+	linda_writeq_array8b ( linda, &rcvhdrtailaddr,
+			       QIB_7220_RcvHdrTailAddr0_offset, ctx );
+	memset ( &rcvhdrhead, 0, sizeof ( rcvhdrhead ) );
+	BIT_FILL_1 ( &rcvhdrhead, counter, 1 );
+	linda_writeq_array64k ( linda, &rcvhdrhead,
+				QIB_7220_RcvHdrHead0_offset, ctx );
+	memset ( &rcvegrindexhead, 0, sizeof ( rcvegrindexhead ) );
+	BIT_FILL_1 ( &rcvegrindexhead, Value, 1 );
+	linda_writeq_array64k ( linda, &rcvegrindexhead,
+				QIB_7220_RcvEgrIndexHead0_offset, ctx );
+	linda_readq ( linda, &rcvctrl, QIB_7220_RcvCtrl_offset );
+	BIT_SET ( &rcvctrl, PortEnable[ctx], 1 );
+	BIT_SET ( &rcvctrl, IntrAvail[ctx], 1 );
+	linda_writeq ( linda, &rcvctrl, QIB_7220_RcvCtrl_offset );
+
+	DBGC ( linda, "Linda %p QPN %ld CTX %d hdrs [%lx,%lx) prod %lx\n",
+	       linda, qp->qpn, ctx, virt_to_bus ( linda_wq->header ),
+	       ( virt_to_bus ( linda_wq->header ) + LINDA_RECV_HEADERS_SIZE ),
+	       virt_to_bus ( &linda_wq->header_prod ) );
+	return 0;
+
+	free_phys ( linda_wq->header, LINDA_RECV_HEADERS_SIZE );
+ err_alloc_header:
+	return rc;
+}
+
+/**
+ * Destroy receive work queue
+ *
+ * @v linda		Linda device
+ * @v qp		Queue pair
+ */
+static void linda_destroy_recv_wq ( struct linda *linda,
+				    struct ib_queue_pair *qp ) {
+	struct ib_work_queue *wq = &qp->recv;
+	struct linda_recv_work_queue *linda_wq = ib_wq_get_drvdata ( wq );
+	struct QIB_7220_RcvCtrl rcvctrl;
+	unsigned int ctx = linda_qpn_to_ctx ( qp->qpn );
+
+	/* Disable context in hardware */
+	linda_readq ( linda, &rcvctrl, QIB_7220_RcvCtrl_offset );
+	BIT_SET ( &rcvctrl, PortEnable[ctx], 0 );
+	BIT_SET ( &rcvctrl, IntrAvail[ctx], 0 );
+	linda_writeq ( linda, &rcvctrl, QIB_7220_RcvCtrl_offset );
+
+	/* Make sure the hardware has seen that the context is disabled */
+	linda_readq ( linda, &rcvctrl, QIB_7220_RcvCtrl_offset );
+	mb();
+
+	/* Free headers ring */
+	free_phys ( linda_wq->header, LINDA_RECV_HEADERS_SIZE );
+
+	/* Free context */
+	linda_free_ctx ( linda, ctx );
+}
+
+/**
+ * Initialise receive datapath
+ *
+ * @v linda		Linda device
+ * @ret rc		Return status code
+ */
+static int linda_init_recv ( struct linda *linda ) {
+	struct QIB_7220_RcvCtrl rcvctrl;
+	struct QIB_7220_scalar rcvegrbase;
+	struct QIB_7220_scalar rcvhdrentsize;
+	struct QIB_7220_scalar rcvhdrcnt;
+	struct QIB_7220_RcvBTHQP rcvbthqp;
+	unsigned int portcfg;
+	unsigned long egrbase;
+	unsigned int eager_array_size_0;
+	unsigned int eager_array_size_other;
+	unsigned int ctx;
+
+	/* Select configuration based on number of contexts */
+	switch ( LINDA_NUM_CONTEXTS ) {
+	case 5:
+		portcfg = LINDA_PORTCFG_5CTX;
+		eager_array_size_0 = LINDA_EAGER_ARRAY_SIZE_5CTX_0;
+		eager_array_size_other = LINDA_EAGER_ARRAY_SIZE_5CTX_OTHER;
+		break;
+	case 9:
+		portcfg = LINDA_PORTCFG_9CTX;
+		eager_array_size_0 = LINDA_EAGER_ARRAY_SIZE_9CTX_0;
+		eager_array_size_other = LINDA_EAGER_ARRAY_SIZE_9CTX_OTHER;
+		break;
+	case 17:
+		portcfg = LINDA_PORTCFG_17CTX;
+		eager_array_size_0 = LINDA_EAGER_ARRAY_SIZE_17CTX_0;
+		eager_array_size_other = LINDA_EAGER_ARRAY_SIZE_17CTX_OTHER;
+		break;
+	default:
+		linker_assert ( 0, invalid_LINDA_NUM_CONTEXTS );
+		return -EINVAL;
+	}
+
+	/* Configure number of contexts */
+	memset ( &rcvctrl, 0, sizeof ( rcvctrl ) );
+	BIT_FILL_3 ( &rcvctrl,
+		     TailUpd, 1,
+		     PortCfg, portcfg,
+		     RcvQPMapEnable, 1 );
+	linda_writeq ( linda, &rcvctrl, QIB_7220_RcvCtrl_offset );
+
+	/* Configure receive header buffer sizes */
+	memset ( &rcvhdrcnt, 0, sizeof ( rcvhdrcnt ) );
+	BIT_FILL_1 ( &rcvhdrcnt, Value, LINDA_RECV_HEADER_COUNT );
+	linda_writeq ( linda, &rcvhdrcnt, QIB_7220_RcvHdrCnt_offset );
+	memset ( &rcvhdrentsize, 0, sizeof ( rcvhdrentsize ) );
+	BIT_FILL_1 ( &rcvhdrentsize, Value, ( LINDA_RECV_HEADER_SIZE >> 2 ) );
+	linda_writeq ( linda, &rcvhdrentsize, QIB_7220_RcvHdrEntSize_offset );
+
+	/* Calculate eager array start addresses for each context */
+	linda_readq ( linda, &rcvegrbase, QIB_7220_RcvEgrBase_offset );
+	egrbase = BIT_GET ( &rcvegrbase, Value );
+	linda->recv_wq[0].eager_array = egrbase;
+	linda->recv_wq[0].eager_entries = eager_array_size_0;
+	egrbase += ( eager_array_size_0 * sizeof ( struct QIB_7220_RcvEgr ) );
+	for ( ctx = 1 ; ctx < LINDA_NUM_CONTEXTS ; ctx++ ) {
+		linda->recv_wq[ctx].eager_array = egrbase;
+		linda->recv_wq[ctx].eager_entries = eager_array_size_other;
+		egrbase += ( eager_array_size_other *
+			     sizeof ( struct QIB_7220_RcvEgr ) );
+	}
+	for ( ctx = 0 ; ctx < LINDA_NUM_CONTEXTS ; ctx++ ) {
+		DBGC ( linda, "Linda %p CTX %d eager array at %lx (%d "
+		       "entries)\n", linda, ctx,
+		       linda->recv_wq[ctx].eager_array,
+		       linda->recv_wq[ctx].eager_entries );
+	}
+
+	/* Set the BTH QP for Infinipath packets to an unused value */
+	memset ( &rcvbthqp, 0, sizeof ( rcvbthqp ) );
+	BIT_FILL_1 ( &rcvbthqp, RcvBTHQP, LINDA_QP_IDETH );
+	linda_writeq ( linda, &rcvbthqp, QIB_7220_RcvBTHQP_offset );
+
+	return 0;
+}
+
+/**
+ * Shut down receive datapath
+ *
+ * @v linda		Linda device
+ */
+static void linda_fini_recv ( struct linda *linda __unused ) {
+	/* Nothing to do; all contexts were already disabled when the
+	 * queue pairs were destroyed
+	 */
+}
+
+/***************************************************************************
+ *
+ * Completion queue operations
+ *
+ ***************************************************************************
+ */
+
+/**
+ * Create completion queue
+ *
+ * @v ibdev		Infiniband device
+ * @v cq		Completion queue
+ * @ret rc		Return status code
+ */
+static int linda_create_cq ( struct ib_device *ibdev,
+			     struct ib_completion_queue *cq ) {
+	struct linda *linda = ib_get_drvdata ( ibdev );
+	static int cqn;
+
+	/* The hardware has no concept of completion queues.  We
+	 * simply use the association between CQs and WQs (already
+	 * handled by the IB core) to decide which WQs to poll.
+	 *
+	 * We do set a CQN, just to avoid confusing debug messages
+	 * from the IB core.
+	 */
+	cq->cqn = ++cqn;
+	DBGC ( linda, "Linda %p CQN %ld created\n", linda, cq->cqn );
+
+	return 0;
+}
+
+/**
+ * Destroy completion queue
+ *
+ * @v ibdev		Infiniband device
+ * @v cq		Completion queue
+ */
+static void linda_destroy_cq ( struct ib_device *ibdev,
+			       struct ib_completion_queue *cq ) {
+	struct linda *linda = ib_get_drvdata ( ibdev );
+
+	/* Nothing to do */
+	DBGC ( linda, "Linda %p CQN %ld destroyed\n", linda, cq->cqn );
+}
+
+/***************************************************************************
+ *
+ * Queue pair operations
+ *
+ ***************************************************************************
+ */
+
+/**
+ * Create queue pair
+ *
+ * @v ibdev		Infiniband device
+ * @v qp		Queue pair
+ * @ret rc		Return status code
+ */
+static int linda_create_qp ( struct ib_device *ibdev,
+			     struct ib_queue_pair *qp ) {
+	struct linda *linda = ib_get_drvdata ( ibdev );
+	int ctx;
+	int rc;
+
+	/* Locate an available context */
+	ctx = linda_alloc_ctx ( linda );
+	if ( ctx < 0 ) {
+		rc = ctx;
+		goto err_alloc_ctx;
+	}
+
+	/* Set queue pair number based on context index */
+	qp->qpn = linda_ctx_to_qpn ( ctx );
+
+	/* Set work-queue private data pointers */
+	ib_wq_set_drvdata ( &qp->send, &linda->send_wq[ctx] );
+	ib_wq_set_drvdata ( &qp->recv, &linda->recv_wq[ctx] );
+
+	/* Create receive work queue */
+	if ( ( rc = linda_create_recv_wq ( linda, qp ) ) != 0 )
+		goto err_create_recv_wq;
+
+	/* Create send work queue */
+	if ( ( rc = linda_create_send_wq ( linda, qp ) ) != 0 )
+		goto err_create_send_wq;
+
+	return 0;
+
+	linda_destroy_send_wq ( linda, qp );
+ err_create_send_wq:
+	linda_destroy_recv_wq ( linda, qp );
+ err_create_recv_wq:
+	linda_free_ctx ( linda, ctx );
+ err_alloc_ctx:
+	return rc;
+}
+
+/**
+ * Modify queue pair
+ *
+ * @v ibdev		Infiniband device
+ * @v qp		Queue pair
+ * @ret rc		Return status code
+ */
+static int linda_modify_qp ( struct ib_device *ibdev,
+			     struct ib_queue_pair *qp ) {
+	struct linda *linda = ib_get_drvdata ( ibdev );
+
+	/* Nothing to do; the hardware doesn't have a notion of queue
+	 * keys
+	 */
+	DBGC ( linda, "Linda %p QPN %ld modified\n", linda, qp->qpn );
+	return 0;
+}
+
+/**
+ * Destroy queue pair
+ *
+ * @v ibdev		Infiniband device
+ * @v qp		Queue pair
+ */
+static void linda_destroy_qp ( struct ib_device *ibdev,
+			       struct ib_queue_pair *qp ) {
+	struct linda *linda = ib_get_drvdata ( ibdev );
+
+	linda_destroy_send_wq ( linda, qp );
+	linda_destroy_recv_wq ( linda, qp );
+}
+
+/***************************************************************************
+ *
+ * Work request operations
+ *
+ ***************************************************************************
+ */
+
+/**
+ * Post send work queue entry
+ *
+ * @v ibdev		Infiniband device
+ * @v qp		Queue pair
+ * @v dest		Destination address vector
+ * @v iobuf		I/O buffer
+ * @ret rc		Return status code
+ */
+static int linda_post_send ( struct ib_device *ibdev,
+			     struct ib_queue_pair *qp,
+			     struct ib_address_vector *dest,
+			     struct io_buffer *iobuf ) {
+	struct linda *linda = ib_get_drvdata ( ibdev );
+	struct ib_work_queue *wq = &qp->send;
+	struct linda_send_work_queue *linda_wq = ib_wq_get_drvdata ( wq );
+	struct QIB_7220_SendPbc sendpbc;
+	uint8_t header_buf[IB_MAX_HEADER_SIZE];
+	struct io_buffer headers;
+	unsigned int send_buf;
+	unsigned long start_offset;
+	unsigned long offset;
+	size_t len;
+	ssize_t frag_len;
+	uint32_t *data;
+
+	/* Allocate send buffer and calculate offset */
+	send_buf = linda_alloc_send_buf ( linda );
+	start_offset = offset = linda_send_buffer_offset ( linda, send_buf );
+
+	/* Store I/O buffer and send buffer index */
+	assert ( wq->iobufs[linda_wq->prod] == NULL );
+	wq->iobufs[linda_wq->prod] = iobuf;
+	linda_wq->send_buf[linda_wq->prod] = send_buf;
+
+	/* Construct headers */
+	iob_populate ( &headers, header_buf, 0, sizeof ( header_buf ) );
+	iob_reserve ( &headers, sizeof ( header_buf ) );
+	ib_push ( ibdev, &headers, qp, iob_len ( iobuf ), dest );
+
+	/* Calculate packet length */
+	len = ( ( sizeof ( sendpbc ) + iob_len ( &headers ) +
+		  iob_len ( iobuf ) + 3 ) & ~3 );
+
+	/* Construct send per-buffer control word */
+	memset ( &sendpbc, 0, sizeof ( sendpbc ) );
+	BIT_FILL_2 ( &sendpbc,
+		     LengthP1_toibc, ( ( len >> 2 ) - 1 ),
+		     VL15, 1 );
+
+	/* Write SendPbc */
+	DBG_DISABLE ( DBGLVL_IO );
+	linda_writeq ( linda, &sendpbc, offset );
+	offset += sizeof ( sendpbc );
+
+	/* Write headers */
+	for ( data = headers.data, frag_len = iob_len ( &headers ) ;
+	      frag_len > 0 ; data++, offset += 4, frag_len -= 4 ) {
+		linda_writel ( linda, *data, offset );
+	}
+
+	/* Write data */
+	for ( data = iobuf->data, frag_len = iob_len ( iobuf ) ;
+	      frag_len > 0 ; data++, offset += 4, frag_len -= 4 ) {
+		linda_writel ( linda, *data, offset );
+	}
+	DBG_ENABLE ( DBGLVL_IO );
+
+	assert ( ( start_offset + len ) == offset );
+	DBGC2 ( linda, "Linda %p QPN %ld TX %d(%d) posted [%lx,%lx)\n",
+		linda, qp->qpn, send_buf, linda_wq->prod,
+		start_offset, offset );
+
+	/* Increment producer counter */
+	linda_wq->prod = ( ( linda_wq->prod + 1 ) & ( wq->num_wqes - 1 ) );
+
+	return 0;
+}
+
+/**
+ * Complete send work queue entry
+ *
+ * @v ibdev		Infiniband device
+ * @v qp		Queue pair
+ * @v wqe_idx		Work queue entry index
+ */
+static void linda_complete_send ( struct ib_device *ibdev,
+				  struct ib_queue_pair *qp,
+				  unsigned int wqe_idx ) {
+	struct linda *linda = ib_get_drvdata ( ibdev );
+	struct ib_work_queue *wq = &qp->send;
+	struct linda_send_work_queue *linda_wq = ib_wq_get_drvdata ( wq );
+	struct io_buffer *iobuf;
+	unsigned int send_buf;
+
+	/* Parse completion */
+	send_buf = linda_wq->send_buf[wqe_idx];
+	DBGC2 ( linda, "Linda %p QPN %ld TX %d(%d) complete\n",
+		linda, qp->qpn, send_buf, wqe_idx );
+
+	/* Complete work queue entry */
+	iobuf = wq->iobufs[wqe_idx];
+	assert ( iobuf != NULL );
+	ib_complete_send ( ibdev, qp, iobuf, 0 );
+	wq->iobufs[wqe_idx] = NULL;
+
+	/* Free send buffer */
+	linda_free_send_buf ( linda, send_buf );
+}
+
+/**
+ * Poll send work queue
+ *
+ * @v ibdev		Infiniband device
+ * @v qp		Queue pair
+ */
+static void linda_poll_send_wq ( struct ib_device *ibdev,
+				 struct ib_queue_pair *qp ) {
+	struct linda *linda = ib_get_drvdata ( ibdev );
+	struct ib_work_queue *wq = &qp->send;
+	struct linda_send_work_queue *linda_wq = ib_wq_get_drvdata ( wq );
+	unsigned int send_buf;
+
+	/* Look for completions */
+	while ( wq->fill ) {
+
+		/* Check to see if send buffer has completed */
+		send_buf = linda_wq->send_buf[linda_wq->cons];
+		if ( linda_send_buf_in_use ( linda, send_buf ) )
+			break;
+
+		/* Complete this buffer */
+		linda_complete_send ( ibdev, qp, linda_wq->cons );
+
+		/* Increment consumer counter */
+		linda_wq->cons = ( ( linda_wq->cons + 1 ) &
+				   ( wq->num_wqes - 1 ) );
+	}
+}
+
+/**
+ * Post receive work queue entry
+ *
+ * @v ibdev		Infiniband device
+ * @v qp		Queue pair
+ * @v iobuf		I/O buffer
+ * @ret rc		Return status code
+ */
+static int linda_post_recv ( struct ib_device *ibdev,
+			     struct ib_queue_pair *qp,
+			     struct io_buffer *iobuf ) {
+	struct linda *linda = ib_get_drvdata ( ibdev );
+	struct ib_work_queue *wq = &qp->recv;
+	struct linda_recv_work_queue *linda_wq = ib_wq_get_drvdata ( wq );
+	struct QIB_7220_RcvEgr rcvegr;
+	struct QIB_7220_scalar rcvegrindexhead;
+	unsigned int ctx = linda_qpn_to_ctx ( qp->qpn );
+	physaddr_t addr;
+	size_t len;
+	unsigned int wqe_idx;
+	unsigned int bufsize;
+
+	/* Sanity checks */
+	addr = virt_to_bus ( iobuf->data );
+	len = iob_tailroom ( iobuf );
+	if ( addr & ( LINDA_EAGER_BUFFER_ALIGN - 1 ) ) {
+		DBGC ( linda, "Linda %p QPN %ld misaligned RX buffer "
+		       "(%08lx)\n", linda, qp->qpn, addr );
+		return -EINVAL;
+	}
+	if ( len != LINDA_RECV_PAYLOAD_SIZE ) {
+		DBGC ( linda, "Linda %p QPN %ld wrong RX buffer size (%zd)\n",
+		       linda, qp->qpn, len );
+		return -EINVAL;
+	}
+
+	/* Calculate eager producer index and WQE index */
+	wqe_idx = ( linda_wq->eager_prod & ( wq->num_wqes - 1 ) );
+	assert ( wq->iobufs[wqe_idx] == NULL );
+
+	/* Store I/O buffer */
+	wq->iobufs[wqe_idx] = iobuf;
+
+	/* Calculate buffer size */
+	switch ( LINDA_RECV_PAYLOAD_SIZE ) {
+	case 2048:  bufsize = LINDA_EAGER_BUFFER_2K;  break;
+	case 4096:  bufsize = LINDA_EAGER_BUFFER_4K;  break;
+	case 8192:  bufsize = LINDA_EAGER_BUFFER_8K;  break;
+	case 16384: bufsize = LINDA_EAGER_BUFFER_16K; break;
+	case 32768: bufsize = LINDA_EAGER_BUFFER_32K; break;
+	case 65536: bufsize = LINDA_EAGER_BUFFER_64K; break;
+	default:    linker_assert ( 0, invalid_rx_payload_size );
+		    bufsize = LINDA_EAGER_BUFFER_NONE;
+	}
+
+	/* Post eager buffer */
+	memset ( &rcvegr, 0, sizeof ( rcvegr ) );
+	BIT_FILL_2 ( &rcvegr,
+		     Addr, ( addr >> 11 ),
+		     BufSize, bufsize );
+	linda_writeq_array8b ( linda, &rcvegr,
+			       linda_wq->eager_array, linda_wq->eager_prod );
+	DBGC2 ( linda, "Linda %p QPN %ld RX egr %d(%d) posted [%lx,%lx)\n",
+		linda, qp->qpn, linda_wq->eager_prod, wqe_idx,
+		addr, ( addr + len ) );
+
+	/* Increment producer index */
+	linda_wq->eager_prod = ( ( linda_wq->eager_prod + 1 ) &
+				 ( linda_wq->eager_entries - 1 ) );
+
+	/* Update head index */
+	memset ( &rcvegrindexhead, 0, sizeof ( rcvegrindexhead ) );
+	BIT_FILL_1 ( &rcvegrindexhead,
+		     Value, ( ( linda_wq->eager_prod + 1 ) &
+			      ( linda_wq->eager_entries - 1 ) ) );
+	linda_writeq_array64k ( linda, &rcvegrindexhead,
+				QIB_7220_RcvEgrIndexHead0_offset, ctx );
+
+	return 0;
+}
+
+/**
+ * Complete receive work queue entry
+ *
+ * @v ibdev		Infiniband device
+ * @v qp		Queue pair
+ * @v header_offs	Header offset
+ */
+static void linda_complete_recv ( struct ib_device *ibdev,
+				  struct ib_queue_pair *qp,
+				  unsigned int header_offs ) {
+	struct linda *linda = ib_get_drvdata ( ibdev );
+	struct ib_work_queue *wq = &qp->recv;
+	struct linda_recv_work_queue *linda_wq = ib_wq_get_drvdata ( wq );
+	struct QIB_7220_RcvHdrFlags *rcvhdrflags;
+	struct QIB_7220_RcvEgr rcvegr;
+	struct io_buffer headers;
+	struct io_buffer *iobuf;
+	struct ib_queue_pair *intended_qp;
+	struct ib_address_vector dest;
+	struct ib_address_vector source;
+	unsigned int rcvtype;
+	unsigned int pktlen;
+	unsigned int egrindex;
+	unsigned int useegrbfr;
+	unsigned int iberr, mkerr, tiderr, khdrerr, mtuerr;
+	unsigned int lenerr, parityerr, vcrcerr, icrcerr;
+	unsigned int err;
+	unsigned int hdrqoffset;
+	unsigned int header_len;
+	unsigned int padded_payload_len;
+	unsigned int wqe_idx;
+	size_t payload_len;
+	int qp0;
+	int rc;
+
+	/* RcvHdrFlags are at the end of the header entry */
+	rcvhdrflags = ( linda_wq->header + header_offs +
+			LINDA_RECV_HEADER_SIZE - sizeof ( *rcvhdrflags ) );
+	rcvtype = BIT_GET ( rcvhdrflags, RcvType );
+	pktlen = ( BIT_GET ( rcvhdrflags, PktLen ) << 2 );
+	egrindex = BIT_GET ( rcvhdrflags, EgrIndex );
+	useegrbfr = BIT_GET ( rcvhdrflags, UseEgrBfr );
+	hdrqoffset = ( BIT_GET ( rcvhdrflags, HdrqOffset ) << 2 );
+	iberr = BIT_GET ( rcvhdrflags, IBErr );
+	mkerr = BIT_GET ( rcvhdrflags, MKErr );
+	tiderr = BIT_GET ( rcvhdrflags, TIDErr );
+	khdrerr = BIT_GET ( rcvhdrflags, KHdrErr );
+	mtuerr = BIT_GET ( rcvhdrflags, MTUErr );
+	lenerr = BIT_GET ( rcvhdrflags, LenErr );
+	parityerr = BIT_GET ( rcvhdrflags, ParityErr );
+	vcrcerr = BIT_GET ( rcvhdrflags, VCRCErr );
+	icrcerr = BIT_GET ( rcvhdrflags, ICRCErr );
+	header_len = ( LINDA_RECV_HEADER_SIZE - hdrqoffset -
+		       sizeof ( *rcvhdrflags ) );
+	padded_payload_len = ( pktlen - header_len - 4 /* ICRC */ );
+	err = ( iberr | mkerr | tiderr | khdrerr | mtuerr |
+		lenerr | parityerr | vcrcerr | icrcerr );
+	/* IB header is placed immediately before RcvHdrFlags */
+	iob_populate ( &headers, ( ( ( void * ) rcvhdrflags ) - header_len ),
+		       header_len, header_len );
+
+	/* Dump diagnostic information */
+	if ( err || ( ! useegrbfr ) ) {
+		DBGC ( linda, "Linda %p QPN %ld RX egr %d%s hdr %d type %d "
+		       "len %d(%d+%d+4)%s%s%s%s%s%s%s%s%s%s%s\n", linda,
+		       qp->qpn, egrindex, ( useegrbfr ? "" : "(unused)" ),
+		       ( header_offs / LINDA_RECV_HEADER_SIZE ), rcvtype,
+		       pktlen, header_len, padded_payload_len,
+		       ( err ? " [Err" : "" ), ( iberr ? " IB" : "" ),
+		       ( mkerr ? " MK" : "" ), ( tiderr ? " TID" : "" ),
+		       ( khdrerr ? " KHdr" : "" ), ( mtuerr ? " MTU" : "" ),
+		       ( lenerr ? " Len" : "" ), ( parityerr ? " Parity" : ""),
+		       ( vcrcerr ? " VCRC" : "" ), ( icrcerr ? " ICRC" : "" ),
+		       ( err ? "]" : "" ) );
+	} else {
+		DBGC2 ( linda, "Linda %p QPN %ld RX egr %d hdr %d type %d "
+			"len %d(%d+%d+4)\n", linda, qp->qpn, egrindex,
+			( header_offs / LINDA_RECV_HEADER_SIZE ), rcvtype,
+			pktlen, header_len, padded_payload_len );
+	}
+	DBGCP_HDA ( linda, hdrqoffset, headers.data,
+		    ( header_len + sizeof ( *rcvhdrflags ) ) );
+
+	/* Parse header to generate address vector */
+	qp0 = ( qp->qpn == 0 );
+	intended_qp = NULL;
+	if ( ( rc = ib_pull ( ibdev, &headers, ( qp0 ? &intended_qp : NULL ),
+			      &payload_len, &dest, &source ) ) != 0 ) {
+		DBGC ( linda, "Linda %p could not parse headers: %s\n",
+		       linda, strerror ( rc ) );
+		err = 1;
+	}
+	if ( ! intended_qp )
+		intended_qp = qp;
+
+	/* Complete this buffer and any skipped buffers.  Note that
+	 * when the hardware runs out of buffers, it will repeatedly
+	 * report the same buffer (the tail) as a TID error, and that
+	 * it also has a habit of sometimes skipping over several
+	 * buffers at once.
+	 */
+	while ( 1 ) {
+
+		/* If we have caught up to the producer counter, stop.
+		 * This will happen when the hardware first runs out
+		 * of buffers and starts reporting TID errors against
+		 * the eager buffer it wants to use next.
+		 */
+		if ( linda_wq->eager_cons == linda_wq->eager_prod )
+			break;
+
+		/* If we have caught up to where we should be after
+		 * completing this egrindex, stop.  We phrase the test
+		 * this way to avoid completing the entire ring when
+		 * we receive the same egrindex twice in a row.
+		 */
+		if ( ( linda_wq->eager_cons ==
+		       ( ( egrindex + 1 ) & ( linda_wq->eager_entries - 1 ) )))
+			break;
+
+		/* Identify work queue entry and corresponding I/O
+		 * buffer.
+		 */
+		wqe_idx = ( linda_wq->eager_cons & ( wq->num_wqes - 1 ) );
+		iobuf = wq->iobufs[wqe_idx];
+		assert ( iobuf != NULL );
+		wq->iobufs[wqe_idx] = NULL;
+
+		/* Complete the eager buffer */
+		if ( linda_wq->eager_cons == egrindex ) {
+			/* Completing the eager buffer described in
+			 * this header entry.
+			 */
+			if ( payload_len <= iob_tailroom ( iobuf ) ) {
+				iob_put ( iobuf, payload_len );
+				rc = ( err ?
+				       -EIO : ( useegrbfr ? 0 : -ECANCELED ) );
+			} else {
+				DBGC ( linda, "Linda %p bad payload len %zd\n",
+				       linda, payload_len );
+				rc = -EPROTO;
+			}
+			/* Redirect to target QP if necessary */
+			if ( qp != intended_qp ) {
+				DBGC ( linda, "Linda %p redirecting QPN %ld "
+				       "=> %ld\n",
+				       linda, qp->qpn, intended_qp->qpn );
+				/* Compensate for incorrect fill levels */
+				qp->recv.fill--;
+				intended_qp->recv.fill++;
+			}
+			ib_complete_recv ( ibdev, intended_qp, &dest, &source,
+					   iobuf, rc );
+		} else {
+			/* Completing on a skipped-over eager buffer */
+			ib_complete_recv ( ibdev, qp, &dest, &source, iobuf,
+					   -ECANCELED );
+		}
+
+		/* Clear eager buffer */
+		memset ( &rcvegr, 0, sizeof ( rcvegr ) );
+		linda_writeq_array8b ( linda, &rcvegr, linda_wq->eager_array,
+				       linda_wq->eager_cons );
+
+		/* Increment consumer index */
+		linda_wq->eager_cons = ( ( linda_wq->eager_cons + 1 ) &
+					 ( linda_wq->eager_entries - 1 ) );
+	}
+}
+
+/**
+ * Poll receive work queue
+ *
+ * @v ibdev		Infiniband device
+ * @v qp		Queue pair
+ */
+static void linda_poll_recv_wq ( struct ib_device *ibdev,
+				 struct ib_queue_pair *qp ) {
+	struct linda *linda = ib_get_drvdata ( ibdev );
+	struct ib_work_queue *wq = &qp->recv;
+	struct linda_recv_work_queue *linda_wq = ib_wq_get_drvdata ( wq );
+	struct QIB_7220_RcvHdrHead0 rcvhdrhead;
+	unsigned int ctx = linda_qpn_to_ctx ( qp->qpn );
+	unsigned int header_prod;
+
+	/* Check for received packets */
+	header_prod = ( BIT_GET ( &linda_wq->header_prod, Value ) << 2 );
+	if ( header_prod == linda_wq->header_cons )
+		return;
+
+	/* Process all received packets */
+	while ( linda_wq->header_cons != header_prod ) {
+
+		/* Complete the receive */
+		linda_complete_recv ( ibdev, qp, linda_wq->header_cons );
+
+		/* Increment the consumer offset */
+		linda_wq->header_cons += LINDA_RECV_HEADER_SIZE;
+		linda_wq->header_cons %= LINDA_RECV_HEADERS_SIZE;
+	}
+
+	/* Update consumer offset */
+	memset ( &rcvhdrhead, 0, sizeof ( rcvhdrhead ) );
+	BIT_FILL_2 ( &rcvhdrhead,
+		     RcvHeadPointer, ( linda_wq->header_cons >> 2 ),
+		     counter, 1 );
+	linda_writeq_array64k ( linda, &rcvhdrhead,
+				QIB_7220_RcvHdrHead0_offset, ctx );
+}
+
+/**
+ * Poll completion queue
+ *
+ * @v ibdev		Infiniband device
+ * @v cq		Completion queue
+ */
+static void linda_poll_cq ( struct ib_device *ibdev,
+			    struct ib_completion_queue *cq ) {
+	struct ib_work_queue *wq;
+
+	/* Poll associated send and receive queues */
+	list_for_each_entry ( wq, &cq->work_queues, list ) {
+		if ( wq->is_send ) {
+			linda_poll_send_wq ( ibdev, wq->qp );
+		} else {
+			linda_poll_recv_wq ( ibdev, wq->qp );
+		}
+	}
+}
+
+/***************************************************************************
+ *
+ * Event queues
+ *
+ ***************************************************************************
+ */
+
+/**
+ * Poll event queue
+ *
+ * @v ibdev		Infiniband device
+ */
+static void linda_poll_eq ( struct ib_device *ibdev ) {
+	struct linda *linda = ib_get_drvdata ( ibdev );
+	struct QIB_7220_ErrStatus errstatus;
+	struct QIB_7220_ErrClear errclear;
+
+	/* Check for link status changes */
+	DBG_DISABLE ( DBGLVL_IO );
+	linda_readq ( linda, &errstatus, QIB_7220_ErrStatus_offset );
+	DBG_ENABLE ( DBGLVL_IO );
+	if ( BIT_GET ( &errstatus, IBStatusChanged ) ) {
+		linda_link_state_changed ( ibdev );
+		memset ( &errclear, 0, sizeof ( errclear ) );
+		BIT_FILL_1 ( &errclear, IBStatusChangedClear, 1 );
+		linda_writeq ( linda, &errclear, QIB_7220_ErrClear_offset );
+	}
+}
+
+/***************************************************************************
+ *
+ * Infiniband link-layer operations
+ *
+ ***************************************************************************
+ */
+
+/**
+ * Initialise Infiniband link
+ *
+ * @v ibdev		Infiniband device
+ * @ret rc		Return status code
+ */
+static int linda_open ( struct ib_device *ibdev ) {
+	struct linda *linda = ib_get_drvdata ( ibdev );
+	struct QIB_7220_Control control;
+
+	/* Disable link */
+	linda_readq ( linda, &control, QIB_7220_Control_offset );
+	BIT_SET ( &control, LinkEn, 1 );
+	linda_writeq ( linda, &control, QIB_7220_Control_offset );
+	return 0;
+}
+
+/**
+ * Close Infiniband link
+ *
+ * @v ibdev		Infiniband device
+ */
+static void linda_close ( struct ib_device *ibdev ) {
+	struct linda *linda = ib_get_drvdata ( ibdev );
+	struct QIB_7220_Control control;
+
+	/* Disable link */
+	linda_readq ( linda, &control, QIB_7220_Control_offset );
+	BIT_SET ( &control, LinkEn, 0 );
+	linda_writeq ( linda, &control, QIB_7220_Control_offset );
+}
+
+/***************************************************************************
+ *
+ * Multicast group operations
+ *
+ ***************************************************************************
+ */
+
+/**
+ * Attach to multicast group
+ *
+ * @v ibdev		Infiniband device
+ * @v qp		Queue pair
+ * @v gid		Multicast GID
+ * @ret rc		Return status code
+ */
+static int linda_mcast_attach ( struct ib_device *ibdev,
+				struct ib_queue_pair *qp,
+				union ib_gid *gid ) {
+	struct linda *linda = ib_get_drvdata ( ibdev );
+
+	( void ) linda;
+	( void ) qp;
+	( void ) gid;
+	return 0;
+}
+
+/**
+ * Detach from multicast group
+ *
+ * @v ibdev		Infiniband device
+ * @v qp		Queue pair
+ * @v gid		Multicast GID
+ */
+static void linda_mcast_detach ( struct ib_device *ibdev,
+				 struct ib_queue_pair *qp,
+				 union ib_gid *gid ) {
+	struct linda *linda = ib_get_drvdata ( ibdev );
+
+	( void ) linda;
+	( void ) qp;
+	( void ) gid;
+}
+
+/** Linda Infiniband operations */
+static struct ib_device_operations linda_ib_operations = {
+	.create_cq	= linda_create_cq,
+	.destroy_cq	= linda_destroy_cq,
+	.create_qp	= linda_create_qp,
+	.modify_qp	= linda_modify_qp,
+	.destroy_qp	= linda_destroy_qp,
+	.post_send	= linda_post_send,
+	.post_recv	= linda_post_recv,
+	.poll_cq	= linda_poll_cq,
+	.poll_eq	= linda_poll_eq,
+	.open		= linda_open,
+	.close		= linda_close,
+	.mcast_attach	= linda_mcast_attach,
+	.mcast_detach	= linda_mcast_detach,
+	.set_port_info	= linda_set_port_info,
+	.set_pkey_table	= linda_set_pkey_table,
+};
+
+/***************************************************************************
+ *
+ * I2C bus operations
+ *
+ ***************************************************************************
+ */
+
+/** Linda I2C bit to GPIO mappings */
+static unsigned int linda_i2c_bits[] = {
+	[I2C_BIT_SCL] = ( 1 << LINDA_GPIO_SCL ),
+	[I2C_BIT_SDA] = ( 1 << LINDA_GPIO_SDA ),
+};
+
+/**
+ * Read Linda I2C line status
+ *
+ * @v basher		Bit-bashing interface
+ * @v bit_id		Bit number
+ * @ret zero		Input is a logic 0
+ * @ret non-zero	Input is a logic 1
+ */
+static int linda_i2c_read_bit ( struct bit_basher *basher,
+				unsigned int bit_id ) {
+	struct linda *linda =
+		container_of ( basher, struct linda, i2c.basher );
+	struct QIB_7220_EXTStatus extstatus;
+	unsigned int status;
+
+	DBG_DISABLE ( DBGLVL_IO );
+
+	linda_readq ( linda, &extstatus, QIB_7220_EXTStatus_offset );
+	status = ( BIT_GET ( &extstatus, GPIOIn ) & linda_i2c_bits[bit_id] );
+
+	DBG_ENABLE ( DBGLVL_IO );
+
+	return status;
+}
+
+/**
+ * Write Linda I2C line status
+ *
+ * @v basher		Bit-bashing interface
+ * @v bit_id		Bit number
+ * @v data		Value to write
+ */
+static void linda_i2c_write_bit ( struct bit_basher *basher,
+				  unsigned int bit_id, unsigned long data ) {
+	struct linda *linda =
+		container_of ( basher, struct linda, i2c.basher );
+	struct QIB_7220_EXTCtrl extctrl;
+	struct QIB_7220_GPIO gpioout;
+	unsigned int bit = linda_i2c_bits[bit_id];
+	unsigned int outputs = 0;
+	unsigned int output_enables = 0;
+
+	DBG_DISABLE ( DBGLVL_IO );
+
+	/* Read current GPIO mask and outputs */
+	linda_readq ( linda, &extctrl, QIB_7220_EXTCtrl_offset );
+	linda_readq ( linda, &gpioout, QIB_7220_GPIOOut_offset );
+
+	/* Update outputs and output enables.  I2C lines are tied
+	 * high, so we always set the output to 0 and use the output
+	 * enable to control the line.
+	 */
+	output_enables = BIT_GET ( &extctrl, GPIOOe );
+	output_enables = ( ( output_enables & ~bit ) | ( ~data & bit ) );
+	outputs = BIT_GET ( &gpioout, GPIO );
+	outputs = ( outputs & ~bit );
+	BIT_SET ( &extctrl, GPIOOe, output_enables );
+	BIT_SET ( &gpioout, GPIO, outputs );
+
+	/* Write the output enable first; that way we avoid logic
+	 * hazards.
+	 */
+	linda_writeq ( linda, &extctrl, QIB_7220_EXTCtrl_offset );
+	linda_writeq ( linda, &gpioout, QIB_7220_GPIOOut_offset );
+	mb();
+
+	DBG_ENABLE ( DBGLVL_IO );
+}
+
+/** Linda I2C bit-bashing interface operations */
+static struct bit_basher_operations linda_i2c_basher_ops = {
+	.read	= linda_i2c_read_bit,
+	.write	= linda_i2c_write_bit,
+};
+
+/**
+ * Initialise Linda I2C subsystem
+ *
+ * @v linda		Linda device
+ * @ret rc		Return status code
+ */
+static int linda_init_i2c ( struct linda *linda ) {
+	static int try_eeprom_address[] = { 0x51, 0x50 };
+	unsigned int i;
+	int rc;
+
+	/* Initialise bus */
+	if ( ( rc = init_i2c_bit_basher ( &linda->i2c,
+					  &linda_i2c_basher_ops ) ) != 0 ) {
+		DBGC ( linda, "Linda %p could not initialise I2C bus: %s\n",
+		       linda, strerror ( rc ) );
+		return rc;
+	}
+
+	/* Probe for devices */
+	for ( i = 0 ; i < ( sizeof ( try_eeprom_address ) /
+			    sizeof ( try_eeprom_address[0] ) ) ; i++ ) {
+		init_i2c_eeprom ( &linda->eeprom, try_eeprom_address[i] );
+		if ( ( rc = i2c_check_presence ( &linda->i2c.i2c,
+						 &linda->eeprom ) ) == 0 ) {
+			DBGC2 ( linda, "Linda %p found EEPROM at %02x\n",
+				linda, try_eeprom_address[i] );
+			return 0;
+		}
+	}
+
+	DBGC ( linda, "Linda %p could not find EEPROM\n", linda );
+	return -ENODEV;
+}
+
+/**
+ * Read EEPROM parameters
+ *
+ * @v linda		Linda device
+ * @v guid		GUID to fill in
+ * @ret rc		Return status code
+ */
+static int linda_read_eeprom ( struct linda *linda, union ib_guid *guid ) {
+	struct i2c_interface *i2c = &linda->i2c.i2c;
+	int rc;
+
+	/* Read GUID */
+	if ( ( rc = i2c->read ( i2c, &linda->eeprom, LINDA_EEPROM_GUID_OFFSET,
+				guid->bytes, sizeof ( *guid ) ) ) != 0 ) {
+		DBGC ( linda, "Linda %p could not read GUID: %s\n",
+		       linda, strerror ( rc ) );
+		return rc;
+	}
+	DBGC2 ( linda, "Linda %p has GUID " IB_GUID_FMT "\n",
+		linda, IB_GUID_ARGS ( guid ) );
+
+	/* Read serial number (debug only) */
+	if ( DBG_LOG ) {
+		uint8_t serial[LINDA_EEPROM_SERIAL_SIZE + 1];
+
+		serial[ sizeof ( serial ) - 1 ] = '\0';
+		if ( ( rc = i2c->read ( i2c, &linda->eeprom,
+					LINDA_EEPROM_SERIAL_OFFSET, serial,
+					( sizeof ( serial ) - 1 ) ) ) != 0 ) {
+			DBGC ( linda, "Linda %p could not read serial: %s\n",
+			       linda, strerror ( rc ) );
+			return rc;
+		}
+		DBGC2 ( linda, "Linda %p has serial number \"%s\"\n",
+			linda, serial );
+	}
+
+	return 0;
+}
+
+/***************************************************************************
+ *
+ * External parallel bus access
+ *
+ ***************************************************************************
+ */
+
+/**
+ * Request ownership of the IB external parallel bus
+ *
+ * @v linda		Linda device
+ * @ret rc		Return status code
+ */
+static int linda_ib_epb_request ( struct linda *linda ) {
+	struct QIB_7220_ibsd_epb_access_ctrl access;
+	unsigned int i;
+
+	/* Request ownership */
+	memset ( &access, 0, sizeof ( access ) );
+	BIT_FILL_1 ( &access, sw_ib_epb_req, 1 );
+	linda_writeq ( linda, &access, QIB_7220_ibsd_epb_access_ctrl_offset );
+
+	/* Wait for ownership to be granted */
+	for ( i = 0 ; i < LINDA_EPB_REQUEST_MAX_WAIT_US ; i++ ) {
+		linda_readq ( linda, &access,
+			      QIB_7220_ibsd_epb_access_ctrl_offset );
+		if ( BIT_GET ( &access, sw_ib_epb_req_granted ) )
+			return 0;
+		udelay ( 1 );
+	}
+
+	DBGC ( linda, "Linda %p timed out waiting for IB EPB request\n",
+	       linda );
+	return -ETIMEDOUT;
+}
+
+/**
+ * Wait for IB external parallel bus transaction to complete
+ *
+ * @v linda		Linda device
+ * @v xact		Buffer to hold transaction result
+ * @ret rc		Return status code
+ */
+static int linda_ib_epb_wait ( struct linda *linda,
+			    struct QIB_7220_ibsd_epb_transaction_reg *xact ) {
+	unsigned int i;
+
+	/* Discard first read to allow for signals crossing clock domains */
+	linda_readq ( linda, xact, QIB_7220_ibsd_epb_transaction_reg_offset );
+
+	for ( i = 0 ; i < LINDA_EPB_XACT_MAX_WAIT_US ; i++ ) {
+		linda_readq ( linda, xact,
+			      QIB_7220_ibsd_epb_transaction_reg_offset );
+		if ( BIT_GET ( xact, ib_epb_rdy ) ) {
+			if ( BIT_GET ( xact, ib_epb_req_error ) ) {
+				DBGC ( linda, "Linda %p EPB transaction "
+				       "failed\n", linda );
+				return -EIO;
+			} else {
+				return 0;
+			}
+		}
+		udelay ( 1 );
+	}
+
+	DBGC ( linda, "Linda %p timed out waiting for IB EPB transaction\n",
+	       linda );
+	return -ETIMEDOUT;
+}
+
+/**
+ * Release ownership of the IB external parallel bus
+ *
+ * @v linda		Linda device
+ */
+static void linda_ib_epb_release ( struct linda *linda ) {
+	struct QIB_7220_ibsd_epb_access_ctrl access;
+
+	memset ( &access, 0, sizeof ( access ) );
+	BIT_FILL_1 ( &access, sw_ib_epb_req, 0 );
+	linda_writeq ( linda, &access, QIB_7220_ibsd_epb_access_ctrl_offset );
+}
+
+/**
+ * Read data via IB external parallel bus
+ *
+ * @v linda		Linda device
+ * @v location		EPB location
+ * @ret data		Data read, or negative error
+ *
+ * You must have already acquired ownership of the IB external
+ * parallel bus.
+ */
+static int linda_ib_epb_read ( struct linda *linda, unsigned int location ) {
+	struct QIB_7220_ibsd_epb_transaction_reg xact;
+	unsigned int data;
+	int rc;
+
+	/* Ensure no transaction is currently in progress */
+	if ( ( rc = linda_ib_epb_wait ( linda, &xact ) ) != 0 )
+		return rc;
+
+	/* Process data */
+	memset ( &xact, 0, sizeof ( xact ) );
+	BIT_FILL_3 ( &xact,
+		     ib_epb_address, LINDA_EPB_LOC_ADDRESS ( location ),
+		     ib_epb_read_write, LINDA_EPB_READ,
+		     ib_epb_cs, LINDA_EPB_LOC_CS ( location ) );
+	linda_writeq ( linda, &xact,
+		       QIB_7220_ibsd_epb_transaction_reg_offset );
+
+	/* Wait for transaction to complete */
+	if ( ( rc = linda_ib_epb_wait ( linda, &xact ) ) != 0 )
+		return rc;
+
+	data = BIT_GET ( &xact, ib_epb_data );
+	return data;
+}
+
+/**
+ * Write data via IB external parallel bus
+ *
+ * @v linda		Linda device
+ * @v location		EPB location
+ * @v data		Data to write
+ * @ret rc		Return status code
+ *
+ * You must have already acquired ownership of the IB external
+ * parallel bus.
+ */
+static int linda_ib_epb_write ( struct linda *linda, unsigned int location,
+				unsigned int data ) {
+	struct QIB_7220_ibsd_epb_transaction_reg xact;
+	int rc;
+
+	/* Ensure no transaction is currently in progress */
+	if ( ( rc = linda_ib_epb_wait ( linda, &xact ) ) != 0 )
+		return rc;
+
+	/* Process data */
+	memset ( &xact, 0, sizeof ( xact ) );
+	BIT_FILL_4 ( &xact,
+		     ib_epb_data, data,
+		     ib_epb_address, LINDA_EPB_LOC_ADDRESS ( location ),
+		     ib_epb_read_write, LINDA_EPB_WRITE,
+		     ib_epb_cs, LINDA_EPB_LOC_CS ( location ) );
+	linda_writeq ( linda, &xact,
+		       QIB_7220_ibsd_epb_transaction_reg_offset );
+
+	/* Wait for transaction to complete */
+	if ( ( rc = linda_ib_epb_wait ( linda, &xact ) ) != 0 )
+		return rc;
+
+	return 0;
+}
+
+/**
+ * Read/modify/write EPB register
+ *
+ * @v linda		Linda device
+ * @v cs		Chip select
+ * @v channel		Channel
+ * @v element		Element
+ * @v reg		Register
+ * @v value		Value to set
+ * @v mask		Mask to apply to old value
+ * @ret rc		Return status code
+ */
+static int linda_ib_epb_mod_reg ( struct linda *linda, unsigned int cs,
+				  unsigned int channel, unsigned int element,
+				  unsigned int reg, unsigned int value,
+				  unsigned int mask ) {
+	unsigned int location;
+	int old_value;
+	int rc;
+
+	DBG_DISABLE ( DBGLVL_IO );
+
+	/* Sanity check */
+	assert ( ( value & mask ) == value );
+
+	/* Acquire bus ownership */
+	if ( ( rc = linda_ib_epb_request ( linda ) ) != 0 )
+		goto out;
+
+	/* Read existing value, if necessary */
+	location = LINDA_EPB_LOC ( cs, channel, element, reg );
+	if ( (~mask) & 0xff ) {
+		old_value = linda_ib_epb_read ( linda, location );
+		if ( old_value < 0 ) {
+			rc = old_value;
+			goto out_release;
+		}
+	} else {
+		old_value = 0;
+	}
+
+	/* Update value */
+	value = ( ( old_value & ~mask ) | value );
+	DBGCP ( linda, "Linda %p CS %d EPB(%d,%d,%#02x) %#02x => %#02x\n",
+		linda, cs, channel, element, reg, old_value, value );
+	if ( ( rc = linda_ib_epb_write ( linda, location, value ) ) != 0 )
+		goto out_release;
+
+ out_release:
+	/* Release bus */
+	linda_ib_epb_release ( linda );
+ out:
+	DBG_ENABLE ( DBGLVL_IO );
+	return rc;
+}
+
+/**
+ * Transfer data to/from microcontroller RAM
+ *
+ * @v linda		Linda device
+ * @v address		Starting address
+ * @v write		Data to write, or NULL
+ * @v read		Data to read, or NULL
+ * @v len		Length of data
+ * @ret rc		Return status code
+ */
+static int linda_ib_epb_ram_xfer ( struct linda *linda, unsigned int address,
+				   const void *write, void *read,
+				   size_t len ) {
+	unsigned int control;
+	unsigned int address_hi;
+	unsigned int address_lo;
+	int data;
+	int rc;
+
+	DBG_DISABLE ( DBGLVL_IO );
+
+	assert ( ! ( write && read ) );
+	assert ( ( address % LINDA_EPB_UC_CHUNK_SIZE ) == 0 );
+	assert ( ( len % LINDA_EPB_UC_CHUNK_SIZE ) == 0 );
+
+	/* Acquire bus ownership */
+	if ( ( rc = linda_ib_epb_request ( linda ) ) != 0 )
+		goto out;
+
+	/* Process data */
+	while ( len ) {
+
+		/* Reset the address for each new chunk */
+		if ( ( address % LINDA_EPB_UC_CHUNK_SIZE ) == 0 ) {
+
+			/* Write the control register */
+			control = ( read ? LINDA_EPB_UC_CTL_READ :
+				    LINDA_EPB_UC_CTL_WRITE );
+			if ( ( rc = linda_ib_epb_write ( linda,
+							 LINDA_EPB_UC_CTL,
+							 control ) ) != 0 )
+				break;
+
+			/* Write the address registers */
+			address_hi = ( address >> 8 );
+			if ( ( rc = linda_ib_epb_write ( linda,
+							 LINDA_EPB_UC_ADDR_HI,
+							 address_hi ) ) != 0 )
+				break;
+			address_lo = ( address & 0xff );
+			if ( ( rc = linda_ib_epb_write ( linda,
+							 LINDA_EPB_UC_ADDR_LO,
+							 address_lo ) ) != 0 )
+				break;
+		}
+
+		/* Read or write the data */
+		if ( read ) {
+			data = linda_ib_epb_read ( linda, LINDA_EPB_UC_DATA );
+			if ( data < 0 ) {
+				rc = data;
+				break;
+			}
+			*( ( uint8_t * ) read++ ) = data;
+		} else {
+			data = *( ( uint8_t * ) write++ );
+			if ( ( rc = linda_ib_epb_write ( linda,
+							 LINDA_EPB_UC_DATA,
+							 data ) ) != 0 )
+				break;
+		}
+		address++;
+		len--;
+
+		/* Reset the control byte after each chunk */
+		if ( ( address % LINDA_EPB_UC_CHUNK_SIZE ) == 0 ) {
+			if ( ( rc = linda_ib_epb_write ( linda,
+							 LINDA_EPB_UC_CTL,
+							 0 ) ) != 0 )
+				break;
+		}
+	}
+
+	/* Release bus */
+	linda_ib_epb_release ( linda );
+
+ out:
+	DBG_ENABLE ( DBGLVL_IO );
+	return rc;
+}
+
+/***************************************************************************
+ *
+ * Infiniband SerDes initialisation
+ *
+ ***************************************************************************
+ */
+
+/** A Linda SerDes parameter */
+struct linda_serdes_param {
+	/** EPB address as constructed by LINDA_EPB_ADDRESS() */
+	uint16_t address;
+	/** Value to set */
+	uint8_t value;
+	/** Mask to apply to old value */
+	uint8_t mask;
+} __packed;
+
+/** Magic "all channels" channel number */
+#define LINDA_EPB_ALL_CHANNELS 31
+
+/** End of SerDes parameter list marker */
+#define LINDA_SERDES_PARAM_END { 0, 0, 0 }
+
+/**
+ * Program IB SerDes register(s)
+ *
+ * @v linda		Linda device
+ * @v param		SerDes parameter
+ * @ret rc		Return status code
+ */
+static int linda_set_serdes_param ( struct linda *linda,
+				    struct linda_serdes_param *param ) {
+	unsigned int channel;
+	unsigned int channel_start;
+	unsigned int channel_end;
+	unsigned int element;
+	unsigned int reg;
+	int rc;
+
+	/* Break down the EPB address and determine channels */
+	channel = LINDA_EPB_ADDRESS_CHANNEL ( param->address );
+	element = LINDA_EPB_ADDRESS_ELEMENT ( param->address );
+	reg = LINDA_EPB_ADDRESS_REG ( param->address );
+	if ( channel == LINDA_EPB_ALL_CHANNELS ) {
+		channel_start = 0;
+		channel_end = 3;
+	} else {
+		channel_start = channel_end = channel;
+	}
+
+	/* Modify register for each specified channel */
+	for ( channel = channel_start ; channel <= channel_end ; channel++ ) {
+		if ( ( rc = linda_ib_epb_mod_reg ( linda, LINDA_EPB_CS_SERDES,
+						   channel, element, reg,
+						   param->value,
+						   param->mask ) ) != 0 )
+			return rc;
+	}
+
+	return 0;
+}
+
+/**
+ * Program IB SerDes registers
+ *
+ * @v linda		Linda device
+ * @v param		SerDes parameters
+ * @v count		Number of parameters
+ * @ret rc		Return status code
+ */
+static int linda_set_serdes_params ( struct linda *linda,
+				     struct linda_serdes_param *params ) {
+	int rc;
+
+	for ( ; params->mask != 0 ; params++ ){
+		if ( ( rc = linda_set_serdes_param ( linda,
+							 params ) ) != 0 )
+			return rc;
+	}
+
+	return 0;
+}
+
+#define LINDA_DDS_VAL( amp_d, main_d, ipst_d, ipre_d,			\
+		       amp_s, main_s, ipst_s, ipre_s )			\
+	{ LINDA_EPB_ADDRESS ( LINDA_EPB_ALL_CHANNELS, 9, 0x00 ),	\
+	  ( ( ( amp_d & 0x1f ) << 1 ) | 1 ), 0xff },			\
+	{ LINDA_EPB_ADDRESS ( LINDA_EPB_ALL_CHANNELS, 9, 0x01 ),	\
+	  ( ( ( amp_s & 0x1f ) << 1 ) | 1 ), 0xff },			\
+	{ LINDA_EPB_ADDRESS ( LINDA_EPB_ALL_CHANNELS, 9, 0x09 ),	\
+	  ( ( main_d << 3 ) | 4 | ( ipre_d >> 2 ) ), 0xff },		\
+	{ LINDA_EPB_ADDRESS ( LINDA_EPB_ALL_CHANNELS, 9, 0x0a ),	\
+	  ( ( main_s << 3 ) | 4 | ( ipre_s >> 2 ) ), 0xff },		\
+	{ LINDA_EPB_ADDRESS ( LINDA_EPB_ALL_CHANNELS, 9, 0x06 ),	\
+	  ( ( ( ipst_d & 0xf ) << 1 ) |					\
+	    ( ( ipre_d & 3 ) << 6 ) | 0x21 ), 0xff },			\
+	{ LINDA_EPB_ADDRESS ( LINDA_EPB_ALL_CHANNELS, 9, 0x07 ),	\
+	  ( ( ( ipst_s & 0xf ) << 1 ) |					\
+	    ( ( ipre_s & 3 ) << 6) | 0x21 ), 0xff }
+
+/**
+ * Linda SerDes default parameters
+ *
+ * These magic start-of-day values are taken from the Linux driver.
+ */
+static struct linda_serdes_param linda_serdes_defaults1[] = {
+	/* RXHSCTRL0 */
+	{ LINDA_EPB_ADDRESS ( LINDA_EPB_ALL_CHANNELS, 6, 0x00 ), 0xd4, 0xff },
+	/* VCDL_DAC2 */
+	{ LINDA_EPB_ADDRESS ( LINDA_EPB_ALL_CHANNELS, 6, 0x05 ), 0x2d, 0xff },
+	/* VCDL_CTRL2 */
+	{ LINDA_EPB_ADDRESS ( LINDA_EPB_ALL_CHANNELS, 6, 0x08 ), 0x03, 0x0f },
+	/* START_EQ1 */
+	{ LINDA_EPB_ADDRESS ( LINDA_EPB_ALL_CHANNELS, 7, 0x27 ), 0x10, 0xff },
+	/* START_EQ2 */
+	{ LINDA_EPB_ADDRESS ( LINDA_EPB_ALL_CHANNELS, 7, 0x28 ), 0x30, 0xff },
+	/* BACTRL */
+	{ LINDA_EPB_ADDRESS ( LINDA_EPB_ALL_CHANNELS, 6, 0x0e ), 0x40, 0xff },
+	/* LDOUTCTRL1 */
+	{ LINDA_EPB_ADDRESS ( LINDA_EPB_ALL_CHANNELS, 7, 0x06 ), 0x04, 0xff },
+	/* RXHSSTATUS */
+	{ LINDA_EPB_ADDRESS ( LINDA_EPB_ALL_CHANNELS, 6, 0x0f ), 0x04, 0xff },
+	/* End of this block */
+	LINDA_SERDES_PARAM_END
+};
+static struct linda_serdes_param linda_serdes_defaults2[] = {
+	/* LDOUTCTRL1 */
+	{ LINDA_EPB_ADDRESS ( LINDA_EPB_ALL_CHANNELS, 7, 0x06 ), 0x00, 0xff },
+	/* DDS values */
+	LINDA_DDS_VAL ( 31, 19, 12, 0, 29, 22, 9, 0 ),
+	/* Set Rcv Eq. to Preset node */
+	{ LINDA_EPB_ADDRESS ( LINDA_EPB_ALL_CHANNELS, 7, 0x27 ), 0x10, 0xff },
+	/* DFELTHFDR */
+	{ LINDA_EPB_ADDRESS ( LINDA_EPB_ALL_CHANNELS, 7, 0x08 ), 0x00, 0xff },
+	/* DFELTHHDR */
+	{ LINDA_EPB_ADDRESS ( LINDA_EPB_ALL_CHANNELS, 7, 0x21 ), 0x00, 0xff },
+	/* TLTHFDR */
+	{ LINDA_EPB_ADDRESS ( LINDA_EPB_ALL_CHANNELS, 7, 0x09 ), 0x02, 0xff },
+	/* TLTHHDR */
+	{ LINDA_EPB_ADDRESS ( LINDA_EPB_ALL_CHANNELS, 7, 0x23 ), 0x02, 0xff },
+	/* ZFR */
+	{ LINDA_EPB_ADDRESS ( LINDA_EPB_ALL_CHANNELS, 7, 0x1b ), 0x0c, 0xff },
+	/* ZCNT) */
+	{ LINDA_EPB_ADDRESS ( LINDA_EPB_ALL_CHANNELS, 7, 0x1c ), 0x0c, 0xff },
+	/* GFR */
+	{ LINDA_EPB_ADDRESS ( LINDA_EPB_ALL_CHANNELS, 7, 0x1e ), 0x10, 0xff },
+	/* GHR */
+	{ LINDA_EPB_ADDRESS ( LINDA_EPB_ALL_CHANNELS, 7, 0x1f ), 0x10, 0xff },
+	/* VCDL_CTRL0 toggle */
+	{ LINDA_EPB_ADDRESS ( LINDA_EPB_ALL_CHANNELS, 6, 0x06 ), 0x20, 0xff },
+	{ LINDA_EPB_ADDRESS ( LINDA_EPB_ALL_CHANNELS, 6, 0x06 ), 0x00, 0xff },
+	/* CMUCTRL5 */
+	{ LINDA_EPB_ADDRESS (			   7, 0, 0x15 ), 0x80, 0xff },
+	/* End of this block */
+	LINDA_SERDES_PARAM_END
+};
+static struct linda_serdes_param linda_serdes_defaults3[] = {
+	/* START_EQ1 */
+	{ LINDA_EPB_ADDRESS ( LINDA_EPB_ALL_CHANNELS, 7, 0x27 ), 0x00, 0x38 },
+	/* End of this block */
+	LINDA_SERDES_PARAM_END
+};
+
+/**
+ * Program the microcontroller RAM
+ *
+ * @v linda		Linda device
+ * @ret rc		Return status code
+ */
+static int linda_program_uc_ram ( struct linda *linda ) {
+	int rc;
+
+	if ( ( rc = linda_ib_epb_ram_xfer ( linda, 0, linda_ib_fw, NULL,
+					    sizeof ( linda_ib_fw ) ) ) != 0 ){
+		DBGC ( linda, "Linda %p could not load IB firmware: %s\n",
+		       linda, strerror ( rc ) );
+		return rc;
+	}
+
+	return 0;
+}
+
+/**
+ * Verify the microcontroller RAM
+ *
+ * @v linda		Linda device
+ * @ret rc		Return status code
+ */
+static int linda_verify_uc_ram ( struct linda *linda ) {
+	uint8_t verify[LINDA_EPB_UC_CHUNK_SIZE];
+	unsigned int offset;
+	int rc;
+
+	for ( offset = 0 ; offset < sizeof ( linda_ib_fw );
+	      offset += sizeof ( verify ) ) {
+		if ( ( rc = linda_ib_epb_ram_xfer ( linda, offset,
+						    NULL, verify,
+						    sizeof (verify) )) != 0 ){
+			DBGC ( linda, "Linda %p could not read back IB "
+			       "firmware: %s\n", linda, strerror ( rc ) );
+			return rc;
+		}
+		if ( memcmp ( ( linda_ib_fw + offset ), verify,
+			      sizeof ( verify ) ) != 0 ) {
+			DBGC ( linda, "Linda %p firmware verification failed "
+			       "at offset %#x\n", linda, offset );
+			DBGC_HDA ( linda, offset, ( linda_ib_fw + offset ),
+				   sizeof ( verify ) );
+			DBGC_HDA ( linda, offset, verify, sizeof ( verify ) );
+			return -EIO;
+		}
+	}
+
+	DBGC2 ( linda, "Linda %p firmware verified ok\n", linda );
+	return 0;
+}
+
+/**
+ * Use the microcontroller to trim the IB link
+ *
+ * @v linda		Linda device
+ * @ret rc		Return status code
+ */
+static int linda_trim_ib ( struct linda *linda ) {
+	struct QIB_7220_IBSerDesCtrl ctrl;
+	struct QIB_7220_IntStatus intstatus;
+	unsigned int i;
+	int rc;
+
+	/* Bring the microcontroller out of reset */
+	linda_readq ( linda, &ctrl, QIB_7220_IBSerDesCtrl_offset );
+	BIT_SET ( &ctrl, ResetIB_uC_Core, 0 );
+	linda_writeq ( linda, &ctrl, QIB_7220_IBSerDesCtrl_offset );
+
+	/* Wait for the "trim done" signal */
+	for ( i = 0 ; i < LINDA_TRIM_DONE_MAX_WAIT_MS ; i++ ) {
+		linda_readq ( linda, &intstatus, QIB_7220_IntStatus_offset );
+		if ( BIT_GET ( &intstatus, IBSerdesTrimDone ) ) {
+			rc = 0;
+			goto out_reset;
+		}
+		mdelay ( 1 );
+	}
+
+	DBGC ( linda, "Linda %p timed out waiting for trim done\n", linda );
+	rc = -ETIMEDOUT;
+ out_reset:
+	/* Put the microcontroller back into reset */
+	BIT_SET ( &ctrl, ResetIB_uC_Core, 1 );
+	linda_writeq ( linda, &ctrl, QIB_7220_IBSerDesCtrl_offset );
+
+	return rc;
+}
+
+/**
+ * Initialise the IB SerDes
+ *
+ * @v linda		Linda device
+ * @ret rc		Return status code
+ */
+static int linda_init_ib_serdes ( struct linda *linda ) {
+	struct QIB_7220_Control control;
+	struct QIB_7220_IBCCtrl ibcctrl;
+	struct QIB_7220_IBCDDRCtrl ibcddrctrl;
+	struct QIB_7220_XGXSCfg xgxscfg;
+	int rc;
+
+	/* Disable link */
+	linda_readq ( linda, &control, QIB_7220_Control_offset );
+	BIT_SET ( &control, LinkEn, 0 );
+	linda_writeq ( linda, &control, QIB_7220_Control_offset );
+
+	/* Configure sensible defaults for IBC */
+	memset ( &ibcctrl, 0, sizeof ( ibcctrl ) );
+	BIT_FILL_6 ( &ibcctrl, /* Tuning values taken from Linux driver */
+		     FlowCtrlPeriod, 0x03,
+		     FlowCtrlWaterMark, 0x05,
+		     MaxPktLen, ( ( LINDA_RECV_HEADER_SIZE +
+				    LINDA_RECV_PAYLOAD_SIZE +
+				    4 /* ICRC */ ) >> 2 ),
+		     PhyerrThreshold, 0xf,
+		     OverrunThreshold, 0xf,
+		     CreditScale, 0x4 );
+	linda_writeq ( linda, &ibcctrl, QIB_7220_IBCCtrl_offset );
+
+	/* Force SDR only to avoid needing all the DDR tuning,
+	 * Mellanox compatibility hacks etc.  SDR is plenty for
+	 * boot-time operation.
+	 */
+	linda_readq ( linda, &ibcddrctrl, QIB_7220_IBCDDRCtrl_offset );
+	BIT_SET ( &ibcddrctrl, IB_ENHANCED_MODE, 0 );
+	BIT_SET ( &ibcddrctrl, SD_SPEED_SDR, 1 );
+	BIT_SET ( &ibcddrctrl, SD_SPEED_DDR, 0 );
+	BIT_SET ( &ibcddrctrl, SD_SPEED_QDR, 0 );
+	BIT_SET ( &ibcddrctrl, HRTBT_ENB, 0 );
+	BIT_SET ( &ibcddrctrl, HRTBT_AUTO, 0 );
+	linda_writeq ( linda, &ibcddrctrl, QIB_7220_IBCDDRCtrl_offset );
+
+	/* Set default SerDes parameters */
+	if ( ( rc = linda_set_serdes_params ( linda,
+					      linda_serdes_defaults1 ) ) != 0 )
+		return rc;
+	udelay ( 415 ); /* Magic delay while SerDes sorts itself out */
+	if ( ( rc = linda_set_serdes_params ( linda,
+					      linda_serdes_defaults2 ) ) != 0 )
+		return rc;
+
+	/* Program the microcontroller RAM */
+	if ( ( rc = linda_program_uc_ram ( linda ) ) != 0 )
+		return rc;
+
+	/* Verify the microcontroller RAM contents */
+	if ( DBGLVL_LOG ) {
+		if ( ( rc = linda_verify_uc_ram ( linda ) ) != 0 )
+			return rc;
+	}
+
+	/* More SerDes tuning */
+	if ( ( rc = linda_set_serdes_params ( linda,
+					      linda_serdes_defaults3 ) ) != 0 )
+		return rc;
+
+	/* Use the microcontroller to trim the IB link */
+	if ( ( rc = linda_trim_ib ( linda ) ) != 0 )
+		return rc;
+
+	/* Bring XGXS out of reset */
+	linda_readq ( linda, &xgxscfg, QIB_7220_XGXSCfg_offset );
+	BIT_SET ( &xgxscfg, tx_rx_reset, 0 );
+	BIT_SET ( &xgxscfg, xcv_reset, 0 );
+	linda_writeq ( linda, &xgxscfg, QIB_7220_XGXSCfg_offset );
+
+	return rc;
+}
+
+/***************************************************************************
+ *
+ * PCI layer interface
+ *
+ ***************************************************************************
+ */
+
+/**
+ * Probe PCI device
+ *
+ * @v pci		PCI device
+ * @v id		PCI ID
+ * @ret rc		Return status code
+ */
+static int linda_probe ( struct pci_device *pci ) {
+	struct ib_device *ibdev;
+	struct linda *linda;
+	struct QIB_7220_Revision revision;
+	int rc;
+
+	/* Allocate Infiniband device */
+	ibdev = alloc_ibdev ( sizeof ( *linda ) );
+	if ( ! ibdev ) {
+		rc = -ENOMEM;
+		goto err_alloc_ibdev;
+	}
+	pci_set_drvdata ( pci, ibdev );
+	linda = ib_get_drvdata ( ibdev );
+	ibdev->op = &linda_ib_operations;
+	ibdev->dev = &pci->dev;
+	ibdev->port = 1;
+	ibdev->ports = 1;
+
+	/* Fix up PCI device */
+	adjust_pci_device ( pci );
+
+	/* Map PCI BARs */
+	linda->regs = pci_ioremap ( pci, pci->membase, LINDA_BAR0_SIZE );
+	DBGC2 ( linda, "Linda %p has BAR at %08lx\n", linda, pci->membase );
+
+	/* Print some general data */
+	linda_readq ( linda, &revision, QIB_7220_Revision_offset );
+	DBGC2 ( linda, "Linda %p board %02lx v%ld.%ld.%ld.%ld\n", linda,
+		BIT_GET ( &revision, BoardID ),
+		BIT_GET ( &revision, R_SW ),
+		BIT_GET ( &revision, R_Arch ),
+		BIT_GET ( &revision, R_ChipRevMajor ),
+		BIT_GET ( &revision, R_ChipRevMinor ) );
+
+	/* Record link capabilities.  Note that we force SDR only to
+	 * avoid having to carry extra code for DDR tuning etc.
+	 */
+	ibdev->link_width_enabled = ibdev->link_width_supported =
+		( IB_LINK_WIDTH_4X | IB_LINK_WIDTH_1X );
+	ibdev->link_speed_enabled = ibdev->link_speed_supported =
+		IB_LINK_SPEED_SDR;
+
+	/* Initialise I2C subsystem */
+	if ( ( rc = linda_init_i2c ( linda ) ) != 0 )
+		goto err_init_i2c;
+
+	/* Read EEPROM parameters */
+	if ( ( rc = linda_read_eeprom ( linda, &ibdev->node_guid ) ) != 0 )
+		goto err_read_eeprom;
+	memcpy ( &ibdev->gid.s.guid, &ibdev->node_guid,
+		 sizeof ( ibdev->gid.s.guid ) );
+
+	/* Initialise send datapath */
+	if ( ( rc = linda_init_send ( linda ) ) != 0 )
+		goto err_init_send;
+
+	/* Initialise receive datapath */
+	if ( ( rc = linda_init_recv ( linda ) ) != 0 )
+		goto err_init_recv;
+
+	/* Initialise the IB SerDes */
+	if ( ( rc = linda_init_ib_serdes ( linda ) ) != 0 )
+		goto err_init_ib_serdes;
+
+	/* Register Infiniband device */
+	if ( ( rc = register_ibdev ( ibdev ) ) != 0 ) {
+		DBGC ( linda, "Linda %p could not register IB "
+		       "device: %s\n", linda, strerror ( rc ) );
+		goto err_register_ibdev;
+	}
+
+	return 0;
+
+	unregister_ibdev ( ibdev );
+ err_register_ibdev:
+	linda_fini_recv ( linda );
+ err_init_recv:
+	linda_fini_send ( linda );
+ err_init_send:
+ err_init_ib_serdes:
+ err_read_eeprom:
+ err_init_i2c:
+	iounmap ( linda->regs );
+	ibdev_put ( ibdev );
+ err_alloc_ibdev:
+	return rc;
+}
+
+/**
+ * Remove PCI device
+ *
+ * @v pci		PCI device
+ */
+static void linda_remove ( struct pci_device *pci ) {
+	struct ib_device *ibdev = pci_get_drvdata ( pci );
+	struct linda *linda = ib_get_drvdata ( ibdev );
+
+	unregister_ibdev ( ibdev );
+	linda_fini_recv ( linda );
+	linda_fini_send ( linda );
+	iounmap ( linda->regs );
+	ibdev_put ( ibdev );
+}
+
+static struct pci_device_id linda_nics[] = {
+	PCI_ROM ( 0x1077, 0x7220, "iba7220", "QLE7240/7280 HCA driver", 0 ),
+};
+
+struct pci_driver linda_driver __pci_driver = {
+	.ids = linda_nics,
+	.id_count = ( sizeof ( linda_nics ) / sizeof ( linda_nics[0] ) ),
+	.probe = linda_probe,
+	.remove = linda_remove,
+};
diff -pruN 1.0.0+git-20190125.36a4c85-5.1/src/drivers/infiniband/linda_fw.c 1.21.1+git-20220113.fbbdc3926-0ubuntu1/src/drivers/infiniband/linda_fw.c
--- 1.0.0+git-20190125.36a4c85-5.1/src/drivers/infiniband/linda_fw.c	1970-01-01 00:00:00.000000000 +0000
+++ 1.21.1+git-20220113.fbbdc3926-0ubuntu1/src/drivers/infiniband/linda_fw.c	2022-01-13 13:43:08.000000000 +0000
@@ -0,0 +1,1069 @@
+/*
+ * Copyright (c) 2007, 2008 QLogic Corporation. All rights reserved.
+ *
+ * This software is available to you under a choice of one of two
+ * licenses.  You may choose to be licensed under the terms of the GNU
+ * General Public License (GPL) Version 2, available from the file
+ * COPYING in the main directory of this source tree, or the
+ * OpenIB.org BSD license below:
+ *
+ *     Redistribution and use in source and binary forms, with or
+ *     without modification, are permitted provided that the following
+ *     conditions are met:
+ *
+ *      - Redistributions of source code must retain the above
+ *        copyright notice, this list of conditions and the following
+ *        disclaimer.
+ *
+ *      - Redistributions in binary form must reproduce the above
+ *        copyright notice, this list of conditions and the following
+ *        disclaimer in the documentation and/or other materials
+ *        provided with the distribution.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
+ * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
+ * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ */
+
+FILE_LICENCE ( GPL2_ONLY );
+
+/*
+ * This file contains the memory image from the vendor, to be copied into
+ * the IB SERDES of the IBA7220 during initialization.
+ * The file also includes the two functions which use this image.
+ */
+
+#include <stdint.h>
+#include "linda.h"
+
+uint8_t linda_ib_fw[8192] = {
+/*0000*/0x02, 0x0A, 0x29, 0x02, 0x0A, 0x87, 0xE5, 0xE6,
+	0x30, 0xE6, 0x04, 0x7F, 0x01, 0x80, 0x02, 0x7F,
+/*0010*/0x00, 0xE5, 0xE2, 0x30, 0xE4, 0x04, 0x7E, 0x01,
+	0x80, 0x02, 0x7E, 0x00, 0xEE, 0x5F, 0x60, 0x08,
+/*0020*/0x53, 0xF9, 0xF7, 0xE4, 0xF5, 0xFE, 0x80, 0x08,
+	0x7F, 0x0A, 0x12, 0x17, 0x31, 0x12, 0x0E, 0xA2,
+/*0030*/0x75, 0xFC, 0x08, 0xE4, 0xF5, 0xFD, 0xE5, 0xE7,
+	0x20, 0xE7, 0x03, 0x43, 0xF9, 0x08, 0x22, 0x00,
+/*0040*/0x01, 0x20, 0x11, 0x00, 0x04, 0x20, 0x00, 0x75,
+	0x51, 0x01, 0xE4, 0xF5, 0x52, 0xF5, 0x53, 0xF5,
+/*0050*/0x52, 0xF5, 0x7E, 0x7F, 0x04, 0x02, 0x04, 0x38,
+	0xC2, 0x36, 0x05, 0x52, 0xE5, 0x52, 0xD3, 0x94,
+/*0060*/0x0C, 0x40, 0x05, 0x75, 0x52, 0x01, 0xD2, 0x36,
+	0x90, 0x07, 0x0C, 0x74, 0x07, 0xF0, 0xA3, 0x74,
+/*0070*/0xFF, 0xF0, 0xE4, 0xF5, 0x0C, 0xA3, 0xF0, 0x90,
+	0x07, 0x14, 0xF0, 0xA3, 0xF0, 0x75, 0x0B, 0x20,
+/*0080*/0xF5, 0x09, 0xE4, 0xF5, 0x08, 0xE5, 0x08, 0xD3,
+	0x94, 0x30, 0x40, 0x03, 0x02, 0x04, 0x04, 0x12,
+/*0090*/0x00, 0x06, 0x15, 0x0B, 0xE5, 0x08, 0x70, 0x04,
+	0x7F, 0x01, 0x80, 0x02, 0x7F, 0x00, 0xE5, 0x09,
+/*00A0*/0x70, 0x04, 0x7E, 0x01, 0x80, 0x02, 0x7E, 0x00,
+	0xEE, 0x5F, 0x60, 0x05, 0x12, 0x18, 0x71, 0xD2,
+/*00B0*/0x35, 0x53, 0xE1, 0xF7, 0xE5, 0x08, 0x45, 0x09,
+	0xFF, 0xE5, 0x0B, 0x25, 0xE0, 0x25, 0xE0, 0x24,
+/*00C0*/0x83, 0xF5, 0x82, 0xE4, 0x34, 0x07, 0xF5, 0x83,
+	0xEF, 0xF0, 0x85, 0xE2, 0x20, 0xE5, 0x52, 0xD3,
+/*00D0*/0x94, 0x01, 0x40, 0x0D, 0x12, 0x19, 0xF3, 0xE0,
+	0x54, 0xA0, 0x64, 0x40, 0x70, 0x03, 0x02, 0x03,
+/*00E0*/0xFB, 0x53, 0xF9, 0xF8, 0x90, 0x94, 0x70, 0xE4,
+	0xF0, 0xE0, 0xF5, 0x10, 0xAF, 0x09, 0x12, 0x1E,
+/*00F0*/0xB3, 0xAF, 0x08, 0xEF, 0x44, 0x08, 0xF5, 0x82,
+	0x75, 0x83, 0x80, 0xE0, 0xF5, 0x29, 0xEF, 0x44,
+/*0100*/0x07, 0x12, 0x1A, 0x3C, 0xF5, 0x22, 0x54, 0x40,
+	0xD3, 0x94, 0x00, 0x40, 0x1E, 0xE5, 0x29, 0x54,
+/*0110*/0xF0, 0x70, 0x21, 0x12, 0x19, 0xF3, 0xE0, 0x44,
+	0x80, 0xF0, 0xE5, 0x22, 0x54, 0x30, 0x65, 0x08,
+/*0120*/0x70, 0x09, 0x12, 0x19, 0xF3, 0xE0, 0x54, 0xBF,
+	0xF0, 0x80, 0x09, 0x12, 0x19, 0xF3, 0x74, 0x40,
+/*0130*/0xF0, 0x02, 0x03, 0xFB, 0x12, 0x1A, 0x12, 0x75,
+	0x83, 0xAE, 0x74, 0xFF, 0xF0, 0xAF, 0x08, 0x7E,
+/*0140*/0x00, 0xEF, 0x44, 0x07, 0xF5, 0x82, 0xE0, 0xFD,
+	0xE5, 0x0B, 0x25, 0xE0, 0x25, 0xE0, 0x24, 0x81,
+/*0150*/0xF5, 0x82, 0xE4, 0x34, 0x07, 0xF5, 0x83, 0xED,
+	0xF0, 0x90, 0x07, 0x0E, 0xE0, 0x04, 0xF0, 0xEF,
+/*0160*/0x44, 0x07, 0xF5, 0x82, 0x75, 0x83, 0x98, 0xE0,
+	0xF5, 0x28, 0x12, 0x1A, 0x23, 0x40, 0x0C, 0x12,
+/*0170*/0x19, 0xF3, 0xE0, 0x44, 0x01, 0x12, 0x1A, 0x32,
+	0x02, 0x03, 0xF6, 0xAF, 0x08, 0x7E, 0x00, 0x74,
+/*0180*/0x80, 0xCD, 0xEF, 0xCD, 0x8D, 0x82, 0xF5, 0x83,
+	0xE0, 0x30, 0xE0, 0x0A, 0x12, 0x19, 0xF3, 0xE0,
+/*0190*/0x44, 0x20, 0xF0, 0x02, 0x03, 0xFB, 0x12, 0x19,
+	0xF3, 0xE0, 0x54, 0xDF, 0xF0, 0xEE, 0x44, 0xAE,
+/*01A0*/0x12, 0x1A, 0x43, 0x30, 0xE4, 0x03, 0x02, 0x03,
+	0xFB, 0x74, 0x9E, 0x12, 0x1A, 0x05, 0x20, 0xE0,
+/*01B0*/0x03, 0x02, 0x03, 0xFB, 0x8F, 0x82, 0x8E, 0x83,
+	0xE0, 0x20, 0xE0, 0x03, 0x02, 0x03, 0xFB, 0x12,
+/*01C0*/0x19, 0xF3, 0xE0, 0x44, 0x10, 0xF0, 0xE5, 0xE3,
+	0x20, 0xE7, 0x08, 0xE5, 0x08, 0x12, 0x1A, 0x3A,
+/*01D0*/0x44, 0x04, 0xF0, 0xAF, 0x08, 0x7E, 0x00, 0xEF,
+	0x12, 0x1A, 0x3A, 0x20, 0xE2, 0x34, 0x12, 0x19,
+/*01E0*/0xF3, 0xE0, 0x44, 0x08, 0xF0, 0xE5, 0xE4, 0x30,
+	0xE6, 0x04, 0x7D, 0x01, 0x80, 0x02, 0x7D, 0x00,
+/*01F0*/0xE5, 0x7E, 0xC3, 0x94, 0x04, 0x50, 0x04, 0x7C,
+	0x01, 0x80, 0x02, 0x7C, 0x00, 0xEC, 0x4D, 0x60,
+/*0200*/0x05, 0xC2, 0x35, 0x02, 0x03, 0xFB, 0xEE, 0x44,
+	0xD2, 0x12, 0x1A, 0x43, 0x44, 0x40, 0xF0, 0x02,
+/*0210*/0x03, 0xFB, 0x12, 0x19, 0xF3, 0xE0, 0x54, 0xF7,
+	0xF0, 0x12, 0x1A, 0x12, 0x75, 0x83, 0xD2, 0xE0,
+/*0220*/0x54, 0xBF, 0xF0, 0x90, 0x07, 0x14, 0xE0, 0x04,
+	0xF0, 0xE5, 0x7E, 0x70, 0x03, 0x75, 0x7E, 0x01,
+/*0230*/0xAF, 0x08, 0x7E, 0x00, 0x12, 0x1A, 0x23, 0x40,
+	0x12, 0x12, 0x19, 0xF3, 0xE0, 0x44, 0x01, 0x12,
+/*0240*/0x19, 0xF2, 0xE0, 0x54, 0x02, 0x12, 0x1A, 0x32,
+	0x02, 0x03, 0xFB, 0x12, 0x19, 0xF3, 0xE0, 0x44,
+/*0250*/0x02, 0x12, 0x19, 0xF2, 0xE0, 0x54, 0xFE, 0xF0,
+	0xC2, 0x35, 0xEE, 0x44, 0x8A, 0x8F, 0x82, 0xF5,
+/*0260*/0x83, 0xE0, 0xF5, 0x17, 0x54, 0x8F, 0x44, 0x40,
+	0xF0, 0x74, 0x90, 0xFC, 0xE5, 0x08, 0x44, 0x07,
+/*0270*/0xFD, 0xF5, 0x82, 0x8C, 0x83, 0xE0, 0x54, 0x3F,
+	0x90, 0x07, 0x02, 0xF0, 0xE0, 0x54, 0xC0, 0x8D,
+/*0280*/0x82, 0x8C, 0x83, 0xF0, 0x74, 0x92, 0x12, 0x1A,
+	0x05, 0x90, 0x07, 0x03, 0x12, 0x1A, 0x19, 0x74,
+/*0290*/0x82, 0x12, 0x1A, 0x05, 0x90, 0x07, 0x04, 0x12,
+	0x1A, 0x19, 0x74, 0xB4, 0x12, 0x1A, 0x05, 0x90,
+/*02A0*/0x07, 0x05, 0x12, 0x1A, 0x19, 0x74, 0x94, 0xFE,
+	0xE5, 0x08, 0x44, 0x06, 0x12, 0x1A, 0x0A, 0xF5,
+/*02B0*/0x10, 0x30, 0xE0, 0x04, 0xD2, 0x37, 0x80, 0x02,
+	0xC2, 0x37, 0xE5, 0x10, 0x54, 0x7F, 0x8F, 0x82,
+/*02C0*/0x8E, 0x83, 0xF0, 0x30, 0x44, 0x30, 0x12, 0x1A,
+	0x03, 0x54, 0x80, 0xD3, 0x94, 0x00, 0x40, 0x04,
+/*02D0*/0xD2, 0x39, 0x80, 0x02, 0xC2, 0x39, 0x8F, 0x82,
+	0x8E, 0x83, 0xE0, 0x44, 0x80, 0xF0, 0x12, 0x1A,
+/*02E0*/0x03, 0x54, 0x40, 0xD3, 0x94, 0x00, 0x40, 0x04,
+	0xD2, 0x3A, 0x80, 0x02, 0xC2, 0x3A, 0x8F, 0x82,
+/*02F0*/0x8E, 0x83, 0xE0, 0x44, 0x40, 0xF0, 0x74, 0x92,
+	0xFE, 0xE5, 0x08, 0x44, 0x06, 0x12, 0x1A, 0x0A,
+/*0300*/0x30, 0xE7, 0x04, 0xD2, 0x38, 0x80, 0x02, 0xC2,
+	0x38, 0x8F, 0x82, 0x8E, 0x83, 0xE0, 0x54, 0x7F,
+/*0310*/0xF0, 0x12, 0x1E, 0x46, 0xE4, 0xF5, 0x0A, 0x20,
+	0x03, 0x02, 0x80, 0x03, 0x30, 0x43, 0x03, 0x12,
+/*0320*/0x19, 0x95, 0x20, 0x02, 0x02, 0x80, 0x03, 0x30,
+	0x42, 0x03, 0x12, 0x0C, 0x8F, 0x30, 0x30, 0x06,
+/*0330*/0x12, 0x19, 0x95, 0x12, 0x0C, 0x8F, 0x12, 0x0D,
+	0x47, 0x12, 0x19, 0xF3, 0xE0, 0x54, 0xFB, 0xF0,
+/*0340*/0xE5, 0x0A, 0xC3, 0x94, 0x01, 0x40, 0x46, 0x43,
+	0xE1, 0x08, 0x12, 0x19, 0xF3, 0xE0, 0x44, 0x04,
+/*0350*/0xF0, 0xE5, 0xE4, 0x20, 0xE7, 0x2A, 0x12, 0x1A,
+	0x12, 0x75, 0x83, 0xD2, 0xE0, 0x54, 0x08, 0xD3,
+/*0360*/0x94, 0x00, 0x40, 0x04, 0x7F, 0x01, 0x80, 0x02,
+	0x7F, 0x00, 0xE5, 0x0A, 0xC3, 0x94, 0x01, 0x40,
+/*0370*/0x04, 0x7E, 0x01, 0x80, 0x02, 0x7E, 0x00, 0xEF,
+	0x5E, 0x60, 0x05, 0x12, 0x1D, 0xD7, 0x80, 0x17,
+/*0380*/0x12, 0x1A, 0x12, 0x75, 0x83, 0xD2, 0xE0, 0x44,
+	0x08, 0xF0, 0x02, 0x03, 0xFB, 0x12, 0x1A, 0x12,
+/*0390*/0x75, 0x83, 0xD2, 0xE0, 0x54, 0xF7, 0xF0, 0x12,
+	0x1E, 0x46, 0x7F, 0x08, 0x12, 0x17, 0x31, 0x74,
+/*03A0*/0x8E, 0xFE, 0x12, 0x1A, 0x12, 0x8E, 0x83, 0xE0,
+	0xF5, 0x10, 0x54, 0xFE, 0xF0, 0xE5, 0x10, 0x44,
+/*03B0*/0x01, 0xFF, 0xE5, 0x08, 0xFD, 0xED, 0x44, 0x07,
+	0xF5, 0x82, 0xEF, 0xF0, 0xE5, 0x10, 0x54, 0xFE,
+/*03C0*/0xFF, 0xED, 0x44, 0x07, 0xF5, 0x82, 0xEF, 0x12,
+	0x1A, 0x11, 0x75, 0x83, 0x86, 0xE0, 0x44, 0x10,
+/*03D0*/0x12, 0x1A, 0x11, 0xE0, 0x44, 0x10, 0xF0, 0x12,
+	0x19, 0xF3, 0xE0, 0x54, 0xFD, 0x44, 0x01, 0xFF,
+/*03E0*/0x12, 0x19, 0xF3, 0xEF, 0x12, 0x1A, 0x32, 0x30,
+	0x32, 0x0C, 0xE5, 0x08, 0x44, 0x08, 0xF5, 0x82,
+/*03F0*/0x75, 0x83, 0x82, 0x74, 0x05, 0xF0, 0xAF, 0x0B,
+	0x12, 0x18, 0xD7, 0x74, 0x10, 0x25, 0x08, 0xF5,
+/*0400*/0x08, 0x02, 0x00, 0x85, 0x05, 0x09, 0xE5, 0x09,
+	0xD3, 0x94, 0x07, 0x50, 0x03, 0x02, 0x00, 0x82,
+/*0410*/0xE5, 0x7E, 0xD3, 0x94, 0x00, 0x40, 0x04, 0x7F,
+	0x01, 0x80, 0x02, 0x7F, 0x00, 0xE5, 0x7E, 0xC3,
+/*0420*/0x94, 0xFA, 0x50, 0x04, 0x7E, 0x01, 0x80, 0x02,
+	0x7E, 0x00, 0xEE, 0x5F, 0x60, 0x02, 0x05, 0x7E,
+/*0430*/0x30, 0x35, 0x0B, 0x43, 0xE1, 0x01, 0x7F, 0x09,
+	0x12, 0x17, 0x31, 0x02, 0x00, 0x58, 0x53, 0xE1,
+/*0440*/0xFE, 0x02, 0x00, 0x58, 0x8E, 0x6A, 0x8F, 0x6B,
+	0x8C, 0x6C, 0x8D, 0x6D, 0x75, 0x6E, 0x01, 0x75,
+/*0450*/0x6F, 0x01, 0x75, 0x70, 0x01, 0xE4, 0xF5, 0x73,
+	0xF5, 0x74, 0xF5, 0x75, 0x90, 0x07, 0x2F, 0xF0,
+/*0460*/0xF5, 0x3C, 0xF5, 0x3E, 0xF5, 0x46, 0xF5, 0x47,
+	0xF5, 0x3D, 0xF5, 0x3F, 0xF5, 0x6F, 0xE5, 0x6F,
+/*0470*/0x70, 0x0F, 0xE5, 0x6B, 0x45, 0x6A, 0x12, 0x07,
+	0x2A, 0x75, 0x83, 0x80, 0x74, 0x3A, 0xF0, 0x80,
+/*0480*/0x09, 0x12, 0x07, 0x2A, 0x75, 0x83, 0x80, 0x74,
+	0x1A, 0xF0, 0xE4, 0xF5, 0x6E, 0xC3, 0x74, 0x3F,
+/*0490*/0x95, 0x6E, 0xFF, 0x12, 0x08, 0x65, 0x75, 0x83,
+	0x82, 0xEF, 0xF0, 0x12, 0x1A, 0x4D, 0x12, 0x08,
+/*04A0*/0xC6, 0xE5, 0x33, 0xF0, 0x12, 0x08, 0xFA, 0x12,
+	0x08, 0xB1, 0x40, 0xE1, 0xE5, 0x6F, 0x70, 0x0B,
+/*04B0*/0x12, 0x07, 0x2A, 0x75, 0x83, 0x80, 0x74, 0x36,
+	0xF0, 0x80, 0x09, 0x12, 0x07, 0x2A, 0x75, 0x83,
+/*04C0*/0x80, 0x74, 0x16, 0xF0, 0x75, 0x6E, 0x01, 0x12,
+	0x07, 0x2A, 0x75, 0x83, 0xB4, 0xE5, 0x6E, 0xF0,
+/*04D0*/0x12, 0x1A, 0x4D, 0x74, 0x3F, 0x25, 0x6E, 0xF5,
+	0x82, 0xE4, 0x34, 0x00, 0xF5, 0x83, 0xE5, 0x33,
+/*04E0*/0xF0, 0x74, 0xBF, 0x25, 0x6E, 0xF5, 0x82, 0xE4,
+	0x34, 0x00, 0x12, 0x08, 0xB1, 0x40, 0xD8, 0xE4,
+/*04F0*/0xF5, 0x70, 0xF5, 0x46, 0xF5, 0x47, 0xF5, 0x6E,
+	0x12, 0x08, 0xFA, 0xF5, 0x83, 0xE0, 0xFE, 0x12,
+/*0500*/0x08, 0xC6, 0xE0, 0x7C, 0x00, 0x24, 0x00, 0xFF,
+	0xEC, 0x3E, 0xFE, 0xAD, 0x3B, 0xD3, 0xEF, 0x9D,
+/*0510*/0xEE, 0x9C, 0x50, 0x04, 0x7B, 0x01, 0x80, 0x02,
+	0x7B, 0x00, 0xE5, 0x70, 0x70, 0x04, 0x7A, 0x01,
+/*0520*/0x80, 0x02, 0x7A, 0x00, 0xEB, 0x5A, 0x60, 0x06,
+	0x85, 0x6E, 0x46, 0x75, 0x70, 0x01, 0xD3, 0xEF,
+/*0530*/0x9D, 0xEE, 0x9C, 0x50, 0x04, 0x7F, 0x01, 0x80,
+	0x02, 0x7F, 0x00, 0xE5, 0x70, 0xB4, 0x01, 0x04,
+/*0540*/0x7E, 0x01, 0x80, 0x02, 0x7E, 0x00, 0xEF, 0x5E,
+	0x60, 0x03, 0x85, 0x6E, 0x47, 0x05, 0x6E, 0xE5,
+/*0550*/0x6E, 0x64, 0x7F, 0x70, 0xA3, 0xE5, 0x46, 0x60,
+	0x05, 0xE5, 0x47, 0xB4, 0x7E, 0x03, 0x85, 0x46,
+/*0560*/0x47, 0xE5, 0x6F, 0x70, 0x08, 0x85, 0x46, 0x76,
+	0x85, 0x47, 0x77, 0x80, 0x0E, 0xC3, 0x74, 0x7F,
+/*0570*/0x95, 0x46, 0xF5, 0x78, 0xC3, 0x74, 0x7F, 0x95,
+	0x47, 0xF5, 0x79, 0xE5, 0x6F, 0x70, 0x37, 0xE5,
+/*0580*/0x46, 0x65, 0x47, 0x70, 0x0C, 0x75, 0x73, 0x01,
+	0x75, 0x74, 0x01, 0xF5, 0x3C, 0xF5, 0x3D, 0x80,
+/*0590*/0x35, 0xE4, 0xF5, 0x4E, 0xC3, 0xE5, 0x47, 0x95,
+	0x46, 0xF5, 0x3C, 0xC3, 0x13, 0xF5, 0x71, 0x25,
+/*05A0*/0x46, 0xF5, 0x72, 0xC3, 0x94, 0x3F, 0x40, 0x05,
+	0xE4, 0xF5, 0x3D, 0x80, 0x40, 0xC3, 0x74, 0x3F,
+/*05B0*/0x95, 0x72, 0xF5, 0x3D, 0x80, 0x37, 0xE5, 0x46,
+	0x65, 0x47, 0x70, 0x0F, 0x75, 0x73, 0x01, 0x75,
+/*05C0*/0x75, 0x01, 0xF5, 0x3E, 0xF5, 0x3F, 0x75, 0x4E,
+	0x01, 0x80, 0x22, 0xE4, 0xF5, 0x4E, 0xC3, 0xE5,
+/*05D0*/0x47, 0x95, 0x46, 0xF5, 0x3E, 0xC3, 0x13, 0xF5,
+	0x71, 0x25, 0x46, 0xF5, 0x72, 0xD3, 0x94, 0x3F,
+/*05E0*/0x50, 0x05, 0xE4, 0xF5, 0x3F, 0x80, 0x06, 0xE5,
+	0x72, 0x24, 0xC1, 0xF5, 0x3F, 0x05, 0x6F, 0xE5,
+/*05F0*/0x6F, 0xC3, 0x94, 0x02, 0x50, 0x03, 0x02, 0x04,
+	0x6E, 0xE5, 0x6D, 0x45, 0x6C, 0x70, 0x02, 0x80,
+/*0600*/0x04, 0xE5, 0x74, 0x45, 0x75, 0x90, 0x07, 0x2F,
+	0xF0, 0x7F, 0x01, 0xE5, 0x3E, 0x60, 0x04, 0xE5,
+/*0610*/0x3C, 0x70, 0x14, 0xE4, 0xF5, 0x3C, 0xF5, 0x3D,
+	0xF5, 0x3E, 0xF5, 0x3F, 0x12, 0x08, 0xD2, 0x70,
+/*0620*/0x04, 0xF0, 0x02, 0x06, 0xA4, 0x80, 0x7A, 0xE5,
+	0x3C, 0xC3, 0x95, 0x3E, 0x40, 0x07, 0xE5, 0x3C,
+/*0630*/0x95, 0x3E, 0xFF, 0x80, 0x06, 0xC3, 0xE5, 0x3E,
+	0x95, 0x3C, 0xFF, 0xE5, 0x76, 0xD3, 0x95, 0x79,
+/*0640*/0x40, 0x05, 0x85, 0x76, 0x7A, 0x80, 0x03, 0x85,
+	0x79, 0x7A, 0xE5, 0x77, 0xC3, 0x95, 0x78, 0x50,
+/*0650*/0x05, 0x85, 0x77, 0x7B, 0x80, 0x03, 0x85, 0x78,
+	0x7B, 0xE5, 0x7B, 0xD3, 0x95, 0x7A, 0x40, 0x30,
+/*0660*/0xE5, 0x7B, 0x95, 0x7A, 0xF5, 0x3C, 0xF5, 0x3E,
+	0xC3, 0xE5, 0x7B, 0x95, 0x7A, 0x90, 0x07, 0x19,
+/*0670*/0xF0, 0xE5, 0x3C, 0xC3, 0x13, 0xF5, 0x71, 0x25,
+	0x7A, 0xF5, 0x72, 0xC3, 0x94, 0x3F, 0x40, 0x05,
+/*0680*/0xE4, 0xF5, 0x3D, 0x80, 0x1F, 0xC3, 0x74, 0x3F,
+	0x95, 0x72, 0xF5, 0x3D, 0xF5, 0x3F, 0x80, 0x14,
+/*0690*/0xE4, 0xF5, 0x3C, 0xF5, 0x3E, 0x90, 0x07, 0x19,
+	0xF0, 0x12, 0x08, 0xD2, 0x70, 0x03, 0xF0, 0x80,
+/*06A0*/0x03, 0x74, 0x01, 0xF0, 0x12, 0x08, 0x65, 0x75,
+	0x83, 0xD0, 0xE0, 0x54, 0x0F, 0xFE, 0xAD, 0x3C,
+/*06B0*/0x70, 0x02, 0x7E, 0x07, 0xBE, 0x0F, 0x02, 0x7E,
+	0x80, 0xEE, 0xFB, 0xEF, 0xD3, 0x9B, 0x74, 0x80,
+/*06C0*/0xF8, 0x98, 0x40, 0x1F, 0xE4, 0xF5, 0x3C, 0xF5,
+	0x3E, 0x12, 0x08, 0xD2, 0x70, 0x03, 0xF0, 0x80,
+/*06D0*/0x12, 0x74, 0x01, 0xF0, 0xE5, 0x08, 0xFB, 0xEB,
+	0x44, 0x07, 0xF5, 0x82, 0x75, 0x83, 0xD2, 0xE0,
+/*06E0*/0x44, 0x10, 0xF0, 0xE5, 0x08, 0xFB, 0xEB, 0x44,
+	0x09, 0xF5, 0x82, 0x75, 0x83, 0x9E, 0xED, 0xF0,
+/*06F0*/0xEB, 0x44, 0x07, 0xF5, 0x82, 0x75, 0x83, 0xCA,
+	0xED, 0xF0, 0x12, 0x08, 0x65, 0x75, 0x83, 0xCC,
+/*0700*/0xEF, 0xF0, 0x22, 0xE5, 0x08, 0x44, 0x07, 0xF5,
+	0x82, 0x75, 0x83, 0xBC, 0xE0, 0x54, 0xF0, 0xF0,
+/*0710*/0xE5, 0x08, 0x44, 0x07, 0xF5, 0x82, 0x75, 0x83,
+	0xBE, 0xE0, 0x54, 0xF0, 0xF0, 0xE5, 0x08, 0x44,
+/*0720*/0x07, 0xF5, 0x82, 0x75, 0x83, 0xC0, 0xE0, 0x54,
+	0xF0, 0xF0, 0xE5, 0x08, 0x44, 0x07, 0xF5, 0x82,
+/*0730*/0x22, 0xF0, 0x90, 0x07, 0x28, 0xE0, 0xFE, 0xA3,
+	0xE0, 0xF5, 0x82, 0x8E, 0x83, 0x22, 0x85, 0x42,
+/*0740*/0x42, 0x85, 0x41, 0x41, 0x85, 0x40, 0x40, 0x74,
+	0xC0, 0x2F, 0xF5, 0x82, 0x74, 0x02, 0x3E, 0xF5,
+/*0750*/0x83, 0xE5, 0x42, 0xF0, 0x74, 0xE0, 0x2F, 0xF5,
+	0x82, 0x74, 0x02, 0x3E, 0xF5, 0x83, 0x22, 0xE5,
+/*0760*/0x42, 0x29, 0xFD, 0xE4, 0x33, 0xFC, 0xE5, 0x3C,
+	0xC3, 0x9D, 0xEC, 0x64, 0x80, 0xF8, 0x74, 0x80,
+/*0770*/0x98, 0x22, 0xF5, 0x83, 0xE0, 0x90, 0x07, 0x22,
+	0x54, 0x1F, 0xFD, 0xE0, 0xFA, 0xA3, 0xE0, 0xF5,
+/*0780*/0x82, 0x8A, 0x83, 0xED, 0xF0, 0x22, 0x90, 0x07,
+	0x22, 0xE0, 0xFC, 0xA3, 0xE0, 0xF5, 0x82, 0x8C,
+/*0790*/0x83, 0x22, 0x90, 0x07, 0x24, 0xFF, 0xED, 0x44,
+	0x07, 0xCF, 0xF0, 0xA3, 0xEF, 0xF0, 0x22, 0x85,
+/*07A0*/0x38, 0x38, 0x85, 0x39, 0x39, 0x85, 0x3A, 0x3A,
+	0x74, 0xC0, 0x2F, 0xF5, 0x82, 0x74, 0x02, 0x3E,
+/*07B0*/0xF5, 0x83, 0x22, 0x90, 0x07, 0x26, 0xFF, 0xED,
+	0x44, 0x07, 0xCF, 0xF0, 0xA3, 0xEF, 0xF0, 0x22,
+/*07C0*/0xF0, 0x74, 0xA0, 0x2F, 0xF5, 0x82, 0x74, 0x02,
+	0x3E, 0xF5, 0x83, 0x22, 0x74, 0xC0, 0x25, 0x11,
+/*07D0*/0xF5, 0x82, 0xE4, 0x34, 0x01, 0xF5, 0x83, 0x22,
+	0x74, 0x00, 0x25, 0x11, 0xF5, 0x82, 0xE4, 0x34,
+/*07E0*/0x02, 0xF5, 0x83, 0x22, 0x74, 0x60, 0x25, 0x11,
+	0xF5, 0x82, 0xE4, 0x34, 0x03, 0xF5, 0x83, 0x22,
+/*07F0*/0x74, 0x80, 0x25, 0x11, 0xF5, 0x82, 0xE4, 0x34,
+	0x03, 0xF5, 0x83, 0x22, 0x74, 0xE0, 0x25, 0x11,
+/*0800*/0xF5, 0x82, 0xE4, 0x34, 0x03, 0xF5, 0x83, 0x22,
+	0x74, 0x40, 0x25, 0x11, 0xF5, 0x82, 0xE4, 0x34,
+/*0810*/0x06, 0xF5, 0x83, 0x22, 0x74, 0x80, 0x2F, 0xF5,
+	0x82, 0x74, 0x02, 0x3E, 0xF5, 0x83, 0x22, 0xAF,
+/*0820*/0x08, 0x7E, 0x00, 0xEF, 0x44, 0x07, 0xF5, 0x82,
+	0x22, 0xF5, 0x83, 0xE5, 0x82, 0x44, 0x07, 0xF5,
+/*0830*/0x82, 0xE5, 0x40, 0xF0, 0x22, 0x74, 0x40, 0x25,
+	0x11, 0xF5, 0x82, 0xE4, 0x34, 0x02, 0xF5, 0x83,
+/*0840*/0x22, 0x74, 0xC0, 0x25, 0x11, 0xF5, 0x82, 0xE4,
+	0x34, 0x03, 0xF5, 0x83, 0x22, 0x74, 0x00, 0x25,
+/*0850*/0x11, 0xF5, 0x82, 0xE4, 0x34, 0x06, 0xF5, 0x83,
+	0x22, 0x74, 0x20, 0x25, 0x11, 0xF5, 0x82, 0xE4,
+/*0860*/0x34, 0x06, 0xF5, 0x83, 0x22, 0xE5, 0x08, 0xFD,
+	0xED, 0x44, 0x07, 0xF5, 0x82, 0x22, 0xE5, 0x41,
+/*0870*/0xF0, 0xE5, 0x65, 0x64, 0x01, 0x45, 0x64, 0x22,
+	0x7E, 0x00, 0xFB, 0x7A, 0x00, 0xFD, 0x7C, 0x00,
+/*0880*/0x22, 0x74, 0x20, 0x25, 0x11, 0xF5, 0x82, 0xE4,
+	0x34, 0x02, 0x22, 0x74, 0xA0, 0x25, 0x11, 0xF5,
+/*0890*/0x82, 0xE4, 0x34, 0x03, 0x22, 0x85, 0x3E, 0x42,
+	0x85, 0x3F, 0x41, 0x8F, 0x40, 0x22, 0x85, 0x3C,
+/*08A0*/0x42, 0x85, 0x3D, 0x41, 0x8F, 0x40, 0x22, 0x75,
+	0x45, 0x3F, 0x90, 0x07, 0x20, 0xE4, 0xF0, 0xA3,
+/*08B0*/0x22, 0xF5, 0x83, 0xE5, 0x32, 0xF0, 0x05, 0x6E,
+	0xE5, 0x6E, 0xC3, 0x94, 0x40, 0x22, 0xF0, 0xE5,
+/*08C0*/0x08, 0x44, 0x06, 0xF5, 0x82, 0x22, 0x74, 0x00,
+	0x25, 0x6E, 0xF5, 0x82, 0xE4, 0x34, 0x00, 0xF5,
+/*08D0*/0x83, 0x22, 0xE5, 0x6D, 0x45, 0x6C, 0x90, 0x07,
+	0x2F, 0x22, 0xE4, 0xF9, 0xE5, 0x3C, 0xD3, 0x95,
+/*08E0*/0x3E, 0x22, 0x74, 0x80, 0x2E, 0xF5, 0x82, 0xE4,
+	0x34, 0x02, 0xF5, 0x83, 0xE0, 0x22, 0x74, 0xA0,
+/*08F0*/0x2E, 0xF5, 0x82, 0xE4, 0x34, 0x02, 0xF5, 0x83,
+	0xE0, 0x22, 0x74, 0x80, 0x25, 0x6E, 0xF5, 0x82,
+/*0900*/0xE4, 0x34, 0x00, 0x22, 0x25, 0x42, 0xFD, 0xE4,
+	0x33, 0xFC, 0x22, 0x85, 0x42, 0x42, 0x85, 0x41,
+/*0910*/0x41, 0x85, 0x40, 0x40, 0x22, 0xED, 0x4C, 0x60,
+	0x03, 0x02, 0x09, 0xE5, 0xEF, 0x4E, 0x70, 0x37,
+/*0920*/0x90, 0x07, 0x26, 0x12, 0x07, 0x89, 0xE0, 0xFD,
+	0x12, 0x07, 0xCC, 0xED, 0xF0, 0x90, 0x07, 0x28,
+/*0930*/0x12, 0x07, 0x89, 0xE0, 0xFD, 0x12, 0x07, 0xD8,
+	0xED, 0xF0, 0x12, 0x07, 0x86, 0xE0, 0x54, 0x1F,
+/*0940*/0xFD, 0x12, 0x08, 0x81, 0xF5, 0x83, 0xED, 0xF0,
+	0x90, 0x07, 0x24, 0x12, 0x07, 0x89, 0xE0, 0x54,
+/*0950*/0x1F, 0xFD, 0x12, 0x08, 0x35, 0xED, 0xF0, 0xEF,
+	0x64, 0x04, 0x4E, 0x70, 0x37, 0x90, 0x07, 0x26,
+/*0960*/0x12, 0x07, 0x89, 0xE0, 0xFD, 0x12, 0x07, 0xE4,
+	0xED, 0xF0, 0x90, 0x07, 0x28, 0x12, 0x07, 0x89,
+/*0970*/0xE0, 0xFD, 0x12, 0x07, 0xF0, 0xED, 0xF0, 0x12,
+	0x07, 0x86, 0xE0, 0x54, 0x1F, 0xFD, 0x12, 0x08,
+/*0980*/0x8B, 0xF5, 0x83, 0xED, 0xF0, 0x90, 0x07, 0x24,
+	0x12, 0x07, 0x89, 0xE0, 0x54, 0x1F, 0xFD, 0x12,
+/*0990*/0x08, 0x41, 0xED, 0xF0, 0xEF, 0x64, 0x01, 0x4E,
+	0x70, 0x04, 0x7D, 0x01, 0x80, 0x02, 0x7D, 0x00,
+/*09A0*/0xEF, 0x64, 0x02, 0x4E, 0x70, 0x04, 0x7F, 0x01,
+	0x80, 0x02, 0x7F, 0x00, 0xEF, 0x4D, 0x60, 0x78,
+/*09B0*/0x90, 0x07, 0x26, 0x12, 0x07, 0x35, 0xE0, 0xFF,
+	0x12, 0x07, 0xFC, 0xEF, 0x12, 0x07, 0x31, 0xE0,
+/*09C0*/0xFF, 0x12, 0x08, 0x08, 0xEF, 0xF0, 0x90, 0x07,
+	0x22, 0x12, 0x07, 0x35, 0xE0, 0x54, 0x1F, 0xFF,
+/*09D0*/0x12, 0x08, 0x4D, 0xEF, 0xF0, 0x90, 0x07, 0x24,
+	0x12, 0x07, 0x35, 0xE0, 0x54, 0x1F, 0xFF, 0x12,
+/*09E0*/0x08, 0x59, 0xEF, 0xF0, 0x22, 0x12, 0x07, 0xCC,
+	0xE4, 0xF0, 0x12, 0x07, 0xD8, 0xE4, 0xF0, 0x12,
+/*09F0*/0x08, 0x81, 0xF5, 0x83, 0xE4, 0xF0, 0x12, 0x08,
+	0x35, 0x74, 0x14, 0xF0, 0x12, 0x07, 0xE4, 0xE4,
+/*0A00*/0xF0, 0x12, 0x07, 0xF0, 0xE4, 0xF0, 0x12, 0x08,
+	0x8B, 0xF5, 0x83, 0xE4, 0xF0, 0x12, 0x08, 0x41,
+/*0A10*/0x74, 0x14, 0xF0, 0x12, 0x07, 0xFC, 0xE4, 0xF0,
+	0x12, 0x08, 0x08, 0xE4, 0xF0, 0x12, 0x08, 0x4D,
+/*0A20*/0xE4, 0xF0, 0x12, 0x08, 0x59, 0x74, 0x14, 0xF0,
+	0x22, 0x53, 0xF9, 0xF7, 0x75, 0xFC, 0x10, 0xE4,
+/*0A30*/0xF5, 0xFD, 0x75, 0xFE, 0x30, 0xF5, 0xFF, 0xE5,
+	0xE7, 0x20, 0xE7, 0x03, 0x43, 0xF9, 0x08, 0xE5,
+/*0A40*/0xE6, 0x20, 0xE7, 0x0B, 0x78, 0xFF, 0xE4, 0xF6,
+	0xD8, 0xFD, 0x53, 0xE6, 0xFE, 0x80, 0x09, 0x78,
+/*0A50*/0x08, 0xE4, 0xF6, 0xD8, 0xFD, 0x53, 0xE6, 0xFE,
+	0x75, 0x81, 0x80, 0xE4, 0xF5, 0xA8, 0xD2, 0xA8,
+/*0A60*/0xC2, 0xA9, 0xD2, 0xAF, 0xE5, 0xE2, 0x20, 0xE5,
+	0x05, 0x20, 0xE6, 0x02, 0x80, 0x03, 0x43, 0xE1,
+/*0A70*/0x02, 0xE5, 0xE2, 0x20, 0xE0, 0x0E, 0x90, 0x00,
+	0x00, 0x7F, 0x00, 0x7E, 0x08, 0xE4, 0xF0, 0xA3,
+/*0A80*/0xDF, 0xFC, 0xDE, 0xFA, 0x02, 0x0A, 0xDB, 0x43,
+	0xFA, 0x01, 0xC0, 0xE0, 0xC0, 0xF0, 0xC0, 0x83,
+/*0A90*/0xC0, 0x82, 0xC0, 0xD0, 0x12, 0x1C, 0xE7, 0xD0,
+	0xD0, 0xD0, 0x82, 0xD0, 0x83, 0xD0, 0xF0, 0xD0,
+/*0AA0*/0xE0, 0x53, 0xFA, 0xFE, 0x32, 0x02, 0x1B, 0x55,
+	0xE4, 0x93, 0xA3, 0xF8, 0xE4, 0x93, 0xA3, 0xF6,
+/*0AB0*/0x08, 0xDF, 0xF9, 0x80, 0x29, 0xE4, 0x93, 0xA3,
+	0xF8, 0x54, 0x07, 0x24, 0x0C, 0xC8, 0xC3, 0x33,
+/*0AC0*/0xC4, 0x54, 0x0F, 0x44, 0x20, 0xC8, 0x83, 0x40,
+	0x04, 0xF4, 0x56, 0x80, 0x01, 0x46, 0xF6, 0xDF,
+/*0AD0*/0xE4, 0x80, 0x0B, 0x01, 0x02, 0x04, 0x08, 0x10,
+	0x20, 0x40, 0x80, 0x90, 0x00, 0x3F, 0xE4, 0x7E,
+/*0AE0*/0x01, 0x93, 0x60, 0xC1, 0xA3, 0xFF, 0x54, 0x3F,
+	0x30, 0xE5, 0x09, 0x54, 0x1F, 0xFE, 0xE4, 0x93,
+/*0AF0*/0xA3, 0x60, 0x01, 0x0E, 0xCF, 0x54, 0xC0, 0x25,
+	0xE0, 0x60, 0xAD, 0x40, 0xB8, 0x80, 0xFE, 0x8C,
+/*0B00*/0x64, 0x8D, 0x65, 0x8A, 0x66, 0x8B, 0x67, 0xE4,
+	0xF5, 0x69, 0xEF, 0x4E, 0x70, 0x03, 0x02, 0x1D,
+/*0B10*/0x55, 0xE4, 0xF5, 0x68, 0xE5, 0x67, 0x45, 0x66,
+	0x70, 0x32, 0x12, 0x07, 0x2A, 0x75, 0x83, 0x90,
+/*0B20*/0xE4, 0x12, 0x07, 0x29, 0x75, 0x83, 0xC2, 0xE4,
+	0x12, 0x07, 0x29, 0x75, 0x83, 0xC4, 0xE4, 0x12,
+/*0B30*/0x08, 0x70, 0x70, 0x29, 0x12, 0x07, 0x2A, 0x75,
+	0x83, 0x92, 0xE4, 0x12, 0x07, 0x29, 0x75, 0x83,
+/*0B40*/0xC6, 0xE4, 0x12, 0x07, 0x29, 0x75, 0x83, 0xC8,
+	0xE4, 0xF0, 0x80, 0x11, 0x90, 0x07, 0x26, 0x12,
+/*0B50*/0x07, 0x35, 0xE4, 0x12, 0x08, 0x70, 0x70, 0x05,
+	0x12, 0x07, 0x32, 0xE4, 0xF0, 0x12, 0x1D, 0x55,
+/*0B60*/0x12, 0x1E, 0xBF, 0xE5, 0x67, 0x45, 0x66, 0x70,
+	0x33, 0x12, 0x07, 0x2A, 0x75, 0x83, 0x90, 0xE5,
+/*0B70*/0x41, 0x12, 0x07, 0x29, 0x75, 0x83, 0xC2, 0xE5,
+	0x41, 0x12, 0x07, 0x29, 0x75, 0x83, 0xC4, 0x12,
+/*0B80*/0x08, 0x6E, 0x70, 0x29, 0x12, 0x07, 0x2A, 0x75,
+	0x83, 0x92, 0xE5, 0x40, 0x12, 0x07, 0x29, 0x75,
+/*0B90*/0x83, 0xC6, 0xE5, 0x40, 0x12, 0x07, 0x29, 0x75,
+	0x83, 0xC8, 0x80, 0x0E, 0x90, 0x07, 0x26, 0x12,
+/*0BA0*/0x07, 0x35, 0x12, 0x08, 0x6E, 0x70, 0x06, 0x12,
+	0x07, 0x32, 0xE5, 0x40, 0xF0, 0xAF, 0x69, 0x7E,
+/*0BB0*/0x00, 0xAD, 0x67, 0xAC, 0x66, 0x12, 0x04, 0x44,
+	0x12, 0x07, 0x2A, 0x75, 0x83, 0xCA, 0xE0, 0xD3,
+/*0BC0*/0x94, 0x00, 0x50, 0x0C, 0x05, 0x68, 0xE5, 0x68,
+	0xC3, 0x94, 0x05, 0x50, 0x03, 0x02, 0x0B, 0x14,
+/*0BD0*/0x22, 0x8C, 0x60, 0x8D, 0x61, 0x12, 0x08, 0xDA,
+	0x74, 0x20, 0x40, 0x0D, 0x2F, 0xF5, 0x82, 0x74,
+/*0BE0*/0x03, 0x3E, 0xF5, 0x83, 0xE5, 0x3E, 0xF0, 0x80,
+	0x0B, 0x2F, 0xF5, 0x82, 0x74, 0x03, 0x3E, 0xF5,
+/*0BF0*/0x83, 0xE5, 0x3C, 0xF0, 0xE5, 0x3C, 0xD3, 0x95,
+	0x3E, 0x40, 0x3C, 0xE5, 0x61, 0x45, 0x60, 0x70,
+/*0C00*/0x10, 0xE9, 0x12, 0x09, 0x04, 0xE5, 0x3E, 0x12,
+	0x07, 0x68, 0x40, 0x3B, 0x12, 0x08, 0x95, 0x80,
+/*0C10*/0x18, 0xE5, 0x3E, 0xC3, 0x95, 0x38, 0x40, 0x1D,
+	0x85, 0x3E, 0x38, 0xE5, 0x3E, 0x60, 0x05, 0x85,
+/*0C20*/0x3F, 0x39, 0x80, 0x03, 0x85, 0x39, 0x39, 0x8F,
+	0x3A, 0x12, 0x08, 0x14, 0xE5, 0x3E, 0x12, 0x07,
+/*0C30*/0xC0, 0xE5, 0x3F, 0xF0, 0x22, 0x80, 0x43, 0xE5,
+	0x61, 0x45, 0x60, 0x70, 0x19, 0x12, 0x07, 0x5F,
+/*0C40*/0x40, 0x05, 0x12, 0x08, 0x9E, 0x80, 0x27, 0x12,
+	0x09, 0x0B, 0x12, 0x08, 0x14, 0xE5, 0x42, 0x12,
+/*0C50*/0x07, 0xC0, 0xE5, 0x41, 0xF0, 0x22, 0xE5, 0x3C,
+	0xC3, 0x95, 0x38, 0x40, 0x1D, 0x85, 0x3C, 0x38,
+/*0C60*/0xE5, 0x3C, 0x60, 0x05, 0x85, 0x3D, 0x39, 0x80,
+	0x03, 0x85, 0x39, 0x39, 0x8F, 0x3A, 0x12, 0x08,
+/*0C70*/0x14, 0xE5, 0x3C, 0x12, 0x07, 0xC0, 0xE5, 0x3D,
+	0xF0, 0x22, 0x85, 0x38, 0x38, 0x85, 0x39, 0x39,
+/*0C80*/0x85, 0x3A, 0x3A, 0x12, 0x08, 0x14, 0xE5, 0x38,
+	0x12, 0x07, 0xC0, 0xE5, 0x39, 0xF0, 0x22, 0x7F,
+/*0C90*/0x06, 0x12, 0x17, 0x31, 0x12, 0x1D, 0x23, 0x12,
+	0x0E, 0x04, 0x12, 0x0E, 0x33, 0xE0, 0x44, 0x0A,
+/*0CA0*/0xF0, 0x74, 0x8E, 0xFE, 0x12, 0x0E, 0x04, 0x12,
+	0x0E, 0x0B, 0xEF, 0xF0, 0xE5, 0x28, 0x30, 0xE5,
+/*0CB0*/0x03, 0xD3, 0x80, 0x01, 0xC3, 0x40, 0x05, 0x75,
+	0x14, 0x20, 0x80, 0x03, 0x75, 0x14, 0x08, 0x12,
+/*0CC0*/0x0E, 0x04, 0x75, 0x83, 0x8A, 0xE5, 0x14, 0xF0,
+	0xB4, 0xFF, 0x05, 0x75, 0x12, 0x80, 0x80, 0x06,
+/*0CD0*/0xE5, 0x14, 0xC3, 0x13, 0xF5, 0x12, 0xE4, 0xF5,
+	0x16, 0xF5, 0x7F, 0x12, 0x19, 0x36, 0x12, 0x13,
+/*0CE0*/0xA3, 0xE5, 0x0A, 0xC3, 0x94, 0x01, 0x50, 0x09,
+	0x05, 0x16, 0xE5, 0x16, 0xC3, 0x94, 0x14, 0x40,
+/*0CF0*/0xEA, 0xE5, 0xE4, 0x20, 0xE7, 0x28, 0x12, 0x0E,
+	0x04, 0x75, 0x83, 0xD2, 0xE0, 0x54, 0x08, 0xD3,
+/*0D00*/0x94, 0x00, 0x40, 0x04, 0x7F, 0x01, 0x80, 0x02,
+	0x7F, 0x00, 0xE5, 0x0A, 0xC3, 0x94, 0x01, 0x40,
+/*0D10*/0x04, 0x7E, 0x01, 0x80, 0x02, 0x7E, 0x00, 0xEF,
+	0x5E, 0x60, 0x03, 0x12, 0x1D, 0xD7, 0xE5, 0x7F,
+/*0D20*/0xC3, 0x94, 0x11, 0x40, 0x14, 0x12, 0x0E, 0x04,
+	0x75, 0x83, 0xD2, 0xE0, 0x44, 0x80, 0xF0, 0xE5,
+/*0D30*/0xE4, 0x20, 0xE7, 0x0F, 0x12, 0x1D, 0xD7, 0x80,
+	0x0A, 0x12, 0x0E, 0x04, 0x75, 0x83, 0xD2, 0xE0,
+/*0D40*/0x54, 0x7F, 0xF0, 0x12, 0x1D, 0x23, 0x22, 0x74,
+	0x8A, 0x85, 0x08, 0x82, 0xF5, 0x83, 0xE5, 0x17,
+/*0D50*/0xF0, 0x12, 0x0E, 0x3A, 0xE4, 0xF0, 0x90, 0x07,
+	0x02, 0xE0, 0x12, 0x0E, 0x17, 0x75, 0x83, 0x90,
+/*0D60*/0xEF, 0xF0, 0x74, 0x92, 0xFE, 0xE5, 0x08, 0x44,
+	0x07, 0xFF, 0xF5, 0x82, 0x8E, 0x83, 0xE0, 0x54,
+/*0D70*/0xC0, 0xFD, 0x90, 0x07, 0x03, 0xE0, 0x54, 0x3F,
+	0x4D, 0x8F, 0x82, 0x8E, 0x83, 0xF0, 0x90, 0x07,
+/*0D80*/0x04, 0xE0, 0x12, 0x0E, 0x17, 0x75, 0x83, 0x82,
+	0xEF, 0xF0, 0x90, 0x07, 0x05, 0xE0, 0xFF, 0xED,
+/*0D90*/0x44, 0x07, 0xF5, 0x82, 0x75, 0x83, 0xB4, 0xEF,
+	0x12, 0x0E, 0x03, 0x75, 0x83, 0x80, 0xE0, 0x54,
+/*0DA0*/0xBF, 0xF0, 0x30, 0x37, 0x0A, 0x12, 0x0E, 0x91,
+	0x75, 0x83, 0x94, 0xE0, 0x44, 0x80, 0xF0, 0x30,
+/*0DB0*/0x38, 0x0A, 0x12, 0x0E, 0x91, 0x75, 0x83, 0x92,
+	0xE0, 0x44, 0x80, 0xF0, 0xE5, 0x28, 0x30, 0xE4,
+/*0DC0*/0x1A, 0x20, 0x39, 0x0A, 0x12, 0x0E, 0x04, 0x75,
+	0x83, 0x88, 0xE0, 0x54, 0x7F, 0xF0, 0x20, 0x3A,
+/*0DD0*/0x0A, 0x12, 0x0E, 0x04, 0x75, 0x83, 0x88, 0xE0,
+	0x54, 0xBF, 0xF0, 0x74, 0x8C, 0xFE, 0x12, 0x0E,
+/*0DE0*/0x04, 0x8E, 0x83, 0xE0, 0x54, 0x0F, 0x12, 0x0E,
+	0x03, 0x75, 0x83, 0x86, 0xE0, 0x54, 0xBF, 0xF0,
+/*0DF0*/0xE5, 0x08, 0x44, 0x06, 0x12, 0x0D, 0xFD, 0x75,
+	0x83, 0x8A, 0xE4, 0xF0, 0x22, 0xF5, 0x82, 0x75,
+/*0E00*/0x83, 0x82, 0xE4, 0xF0, 0xE5, 0x08, 0x44, 0x07,
+	0xF5, 0x82, 0x22, 0x8E, 0x83, 0xE0, 0xF5, 0x10,
+/*0E10*/0x54, 0xFE, 0xF0, 0xE5, 0x10, 0x44, 0x01, 0xFF,
+	0xE5, 0x08, 0xFD, 0xED, 0x44, 0x07, 0xF5, 0x82,
+/*0E20*/0x22, 0xE5, 0x15, 0xC4, 0x54, 0x07, 0xFF, 0xE5,
+	0x08, 0xFD, 0xED, 0x44, 0x08, 0xF5, 0x82, 0x75,
+/*0E30*/0x83, 0x82, 0x22, 0x75, 0x83, 0x80, 0xE0, 0x44,
+	0x40, 0xF0, 0xE5, 0x08, 0x44, 0x08, 0xF5, 0x82,
+/*0E40*/0x75, 0x83, 0x8A, 0x22, 0xE5, 0x16, 0x25, 0xE0,
+	0x25, 0xE0, 0x24, 0xAF, 0xF5, 0x82, 0xE4, 0x34,
+/*0E50*/0x1A, 0xF5, 0x83, 0xE4, 0x93, 0xF5, 0x0D, 0x22,
+	0x43, 0xE1, 0x10, 0x43, 0xE1, 0x80, 0x53, 0xE1,
+/*0E60*/0xFD, 0x85, 0xE1, 0x10, 0x22, 0xE5, 0x16, 0x25,
+	0xE0, 0x25, 0xE0, 0x24, 0xB2, 0xF5, 0x82, 0xE4,
+/*0E70*/0x34, 0x1A, 0xF5, 0x83, 0xE4, 0x93, 0x22, 0x85,
+	0x55, 0x82, 0x85, 0x54, 0x83, 0xE5, 0x15, 0xF0,
+/*0E80*/0x22, 0xE5, 0xE2, 0x54, 0x20, 0xD3, 0x94, 0x00,
+	0x22, 0xE5, 0xE2, 0x54, 0x40, 0xD3, 0x94, 0x00,
+/*0E90*/0x22, 0xE5, 0x08, 0x44, 0x06, 0xF5, 0x82, 0x22,
+	0xFD, 0xE5, 0x08, 0xFB, 0xEB, 0x44, 0x07, 0xF5,
+/*0EA0*/0x82, 0x22, 0x53, 0xF9, 0xF7, 0x75, 0xFE, 0x30,
+	0x22, 0xEF, 0x4E, 0x70, 0x26, 0x12, 0x07, 0xCC,
+/*0EB0*/0xE0, 0xFD, 0x90, 0x07, 0x26, 0x12, 0x07, 0x7B,
+	0x12, 0x07, 0xD8, 0xE0, 0xFD, 0x90, 0x07, 0x28,
+/*0EC0*/0x12, 0x07, 0x7B, 0x12, 0x08, 0x81, 0x12, 0x07,
+	0x72, 0x12, 0x08, 0x35, 0xE0, 0x90, 0x07, 0x24,
+/*0ED0*/0x12, 0x07, 0x78, 0xEF, 0x64, 0x04, 0x4E, 0x70,
+	0x29, 0x12, 0x07, 0xE4, 0xE0, 0xFD, 0x90, 0x07,
+/*0EE0*/0x26, 0x12, 0x07, 0x7B, 0x12, 0x07, 0xF0, 0xE0,
+	0xFD, 0x90, 0x07, 0x28, 0x12, 0x07, 0x7B, 0x12,
+/*0EF0*/0x08, 0x8B, 0x12, 0x07, 0x72, 0x12, 0x08, 0x41,
+	0xE0, 0x54, 0x1F, 0xFD, 0x90, 0x07, 0x24, 0x12,
+/*0F00*/0x07, 0x7B, 0xEF, 0x64, 0x01, 0x4E, 0x70, 0x04,
+	0x7D, 0x01, 0x80, 0x02, 0x7D, 0x00, 0xEF, 0x64,
+/*0F10*/0x02, 0x4E, 0x70, 0x04, 0x7F, 0x01, 0x80, 0x02,
+	0x7F, 0x00, 0xEF, 0x4D, 0x60, 0x35, 0x12, 0x07,
+/*0F20*/0xFC, 0xE0, 0xFF, 0x90, 0x07, 0x26, 0x12, 0x07,
+	0x89, 0xEF, 0xF0, 0x12, 0x08, 0x08, 0xE0, 0xFF,
+/*0F30*/0x90, 0x07, 0x28, 0x12, 0x07, 0x89, 0xEF, 0xF0,
+	0x12, 0x08, 0x4D, 0xE0, 0x54, 0x1F, 0xFF, 0x12,
+/*0F40*/0x07, 0x86, 0xEF, 0xF0, 0x12, 0x08, 0x59, 0xE0,
+	0x54, 0x1F, 0xFF, 0x90, 0x07, 0x24, 0x12, 0x07,
+/*0F50*/0x89, 0xEF, 0xF0, 0x22, 0xE4, 0xF5, 0x53, 0x12,
+	0x0E, 0x81, 0x40, 0x04, 0x7F, 0x01, 0x80, 0x02,
+/*0F60*/0x7F, 0x00, 0x12, 0x0E, 0x89, 0x40, 0x04, 0x7E,
+	0x01, 0x80, 0x02, 0x7E, 0x00, 0xEE, 0x4F, 0x70,
+/*0F70*/0x03, 0x02, 0x0F, 0xF6, 0x85, 0xE1, 0x10, 0x43,
+	0xE1, 0x02, 0x53, 0xE1, 0x0F, 0x85, 0xE1, 0x10,
+/*0F80*/0xE4, 0xF5, 0x51, 0xE5, 0xE3, 0x54, 0x3F, 0xF5,
+	0x52, 0x12, 0x0E, 0x89, 0x40, 0x1D, 0xAD, 0x52,
+/*0F90*/0xAF, 0x51, 0x12, 0x11, 0x18, 0xEF, 0x60, 0x08,
+	0x85, 0xE1, 0x10, 0x43, 0xE1, 0x40, 0x80, 0x0B,
+/*0FA0*/0x53, 0xE1, 0xBF, 0x12, 0x0E, 0x58, 0x12, 0x00,
+	0x06, 0x80, 0xFB, 0xE5, 0xE3, 0x54, 0x3F, 0xF5,
+/*0FB0*/0x51, 0xE5, 0xE4, 0x54, 0x3F, 0xF5, 0x52, 0x12,
+	0x0E, 0x81, 0x40, 0x1D, 0xAD, 0x52, 0xAF, 0x51,
+/*0FC0*/0x12, 0x11, 0x18, 0xEF, 0x60, 0x08, 0x85, 0xE1,
+	0x10, 0x43, 0xE1, 0x20, 0x80, 0x0B, 0x53, 0xE1,
+/*0FD0*/0xDF, 0x12, 0x0E, 0x58, 0x12, 0x00, 0x06, 0x80,
+	0xFB, 0x12, 0x0E, 0x81, 0x40, 0x04, 0x7F, 0x01,
+/*0FE0*/0x80, 0x02, 0x7F, 0x00, 0x12, 0x0E, 0x89, 0x40,
+	0x04, 0x7E, 0x01, 0x80, 0x02, 0x7E, 0x00, 0xEE,
+/*0FF0*/0x4F, 0x60, 0x03, 0x12, 0x0E, 0x5B, 0x22, 0x12,
+	0x0E, 0x21, 0xEF, 0xF0, 0x12, 0x10, 0x91, 0x22,
+/*1000*/0x02, 0x11, 0x00, 0x02, 0x10, 0x40, 0x02, 0x10,
+	0x90, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+/*1010*/0x01, 0x20, 0x01, 0x20, 0xE4, 0xF5, 0x57, 0x12,
+	0x16, 0xBD, 0x12, 0x16, 0x44, 0xE4, 0x12, 0x10,
+/*1020*/0x56, 0x12, 0x14, 0xB7, 0x90, 0x07, 0x26, 0x12,
+	0x07, 0x35, 0xE4, 0x12, 0x07, 0x31, 0xE4, 0xF0,
+/*1030*/0x12, 0x10, 0x56, 0x12, 0x14, 0xB7, 0x90, 0x07,
+	0x26, 0x12, 0x07, 0x35, 0xE5, 0x41, 0x12, 0x07,
+/*1040*/0x31, 0xE5, 0x40, 0xF0, 0xAF, 0x57, 0x7E, 0x00,
+	0xAD, 0x56, 0x7C, 0x00, 0x12, 0x04, 0x44, 0xAF,
+/*1050*/0x56, 0x7E, 0x00, 0x02, 0x11, 0xEE, 0xFF, 0x90,
+	0x07, 0x20, 0xA3, 0xE0, 0xFD, 0xE4, 0xF5, 0x56,
+/*1060*/0xF5, 0x40, 0xFE, 0xFC, 0xAB, 0x56, 0xFA, 0x12,
+	0x11, 0x51, 0x7F, 0x0F, 0x7D, 0x18, 0xE4, 0xF5,
+/*1070*/0x56, 0xF5, 0x40, 0xFE, 0xFC, 0xAB, 0x56, 0xFA,
+	0x12, 0x15, 0x41, 0xAF, 0x56, 0x7E, 0x00, 0x12,
+/*1080*/0x1A, 0xFF, 0xE4, 0xFF, 0xF5, 0x56, 0x7D, 0x1F,
+	0xF5, 0x40, 0xFE, 0xFC, 0xAB, 0x56, 0xFA, 0x22,
+/*1090*/0x22, 0xE4, 0xF5, 0x55, 0xE5, 0x08, 0xFD, 0x74,
+	0xA0, 0xF5, 0x56, 0xED, 0x44, 0x07, 0xF5, 0x57,
+/*10A0*/0xE5, 0x28, 0x30, 0xE5, 0x03, 0xD3, 0x80, 0x01,
+	0xC3, 0x40, 0x05, 0x7F, 0x28, 0xEF, 0x80, 0x04,
+/*10B0*/0x7F, 0x14, 0xEF, 0xC3, 0x13, 0xF5, 0x54, 0xE4,
+	0xF9, 0x12, 0x0E, 0x18, 0x75, 0x83, 0x8E, 0xE0,
+/*10C0*/0xF5, 0x10, 0xCE, 0xEF, 0xCE, 0xEE, 0xD3, 0x94,
+	0x00, 0x40, 0x26, 0xE5, 0x10, 0x54, 0xFE, 0x12,
+/*10D0*/0x0E, 0x98, 0x75, 0x83, 0x8E, 0xED, 0xF0, 0xE5,
+	0x10, 0x44, 0x01, 0xFD, 0xEB, 0x44, 0x07, 0xF5,
+/*10E0*/0x82, 0xED, 0xF0, 0x85, 0x57, 0x82, 0x85, 0x56,
+	0x83, 0xE0, 0x30, 0xE3, 0x01, 0x09, 0x1E, 0x80,
+/*10F0*/0xD4, 0xC2, 0x34, 0xE9, 0xC3, 0x95, 0x54, 0x40,
+	0x02, 0xD2, 0x34, 0x22, 0x02, 0x00, 0x06, 0x22,
+/*1100*/0x30, 0x30, 0x11, 0x90, 0x10, 0x00, 0xE4, 0x93,
+	0xF5, 0x10, 0x90, 0x10, 0x10, 0xE4, 0x93, 0xF5,
+/*1110*/0x10, 0x12, 0x10, 0x90, 0x12, 0x11, 0x50, 0x22,
+	0xE4, 0xFC, 0xC3, 0xED, 0x9F, 0xFA, 0xEF, 0xF5,
+/*1120*/0x83, 0x75, 0x82, 0x00, 0x79, 0xFF, 0xE4, 0x93,
+	0xCC, 0x6C, 0xCC, 0xA3, 0xD9, 0xF8, 0xDA, 0xF6,
+/*1130*/0xE5, 0xE2, 0x30, 0xE4, 0x02, 0x8C, 0xE5, 0xED,
+	0x24, 0xFF, 0xFF, 0xEF, 0x75, 0x82, 0xFF, 0xF5,
+/*1140*/0x83, 0xE4, 0x93, 0x6C, 0x70, 0x03, 0x7F, 0x01,
+	0x22, 0x7F, 0x00, 0x22, 0x22, 0x11, 0x00, 0x00,
+/*1150*/0x22, 0x8E, 0x58, 0x8F, 0x59, 0x8C, 0x5A, 0x8D,
+	0x5B, 0x8A, 0x5C, 0x8B, 0x5D, 0x75, 0x5E, 0x01,
+/*1160*/0xE4, 0xF5, 0x5F, 0xF5, 0x60, 0xF5, 0x62, 0x12,
+	0x07, 0x2A, 0x75, 0x83, 0xD0, 0xE0, 0xFF, 0xC4,
+/*1170*/0x54, 0x0F, 0xF5, 0x61, 0x12, 0x1E, 0xA5, 0x85,
+	0x59, 0x5E, 0xD3, 0xE5, 0x5E, 0x95, 0x5B, 0xE5,
+/*1180*/0x5A, 0x12, 0x07, 0x6B, 0x50, 0x4B, 0x12, 0x07,
+	0x03, 0x75, 0x83, 0xBC, 0xE0, 0x45, 0x5E, 0x12,
+/*1190*/0x07, 0x29, 0x75, 0x83, 0xBE, 0xE0, 0x45, 0x5E,
+	0x12, 0x07, 0x29, 0x75, 0x83, 0xC0, 0xE0, 0x45,
+/*11A0*/0x5E, 0xF0, 0xAF, 0x5F, 0xE5, 0x60, 0x12, 0x08,
+	0x78, 0x12, 0x0A, 0xFF, 0xAF, 0x62, 0x7E, 0x00,
+/*11B0*/0xAD, 0x5D, 0xAC, 0x5C, 0x12, 0x04, 0x44, 0xE5,
+	0x61, 0xAF, 0x5E, 0x7E, 0x00, 0xB4, 0x03, 0x05,
+/*11C0*/0x12, 0x1E, 0x21, 0x80, 0x07, 0xAD, 0x5D, 0xAC,
+	0x5C, 0x12, 0x13, 0x17, 0x05, 0x5E, 0x02, 0x11,
+/*11D0*/0x7A, 0x12, 0x07, 0x03, 0x75, 0x83, 0xBC, 0xE0,
+	0x45, 0x40, 0x12, 0x07, 0x29, 0x75, 0x83, 0xBE,
+/*11E0*/0xE0, 0x45, 0x40, 0x12, 0x07, 0x29, 0x75, 0x83,
+	0xC0, 0xE0, 0x45, 0x40, 0xF0, 0x22, 0x8E, 0x58,
+/*11F0*/0x8F, 0x59, 0x75, 0x5A, 0x01, 0x79, 0x01, 0x75,
+	0x5B, 0x01, 0xE4, 0xFB, 0x12, 0x07, 0x2A, 0x75,
+/*1200*/0x83, 0xAE, 0xE0, 0x54, 0x1A, 0xFF, 0x12, 0x08,
+	0x65, 0xE0, 0xC4, 0x13, 0x54, 0x07, 0xFE, 0xEF,
+/*1210*/0x70, 0x0C, 0xEE, 0x65, 0x35, 0x70, 0x07, 0x90,
+	0x07, 0x2F, 0xE0, 0xB4, 0x01, 0x0D, 0xAF, 0x35,
+/*1220*/0x7E, 0x00, 0x12, 0x0E, 0xA9, 0xCF, 0xEB, 0xCF,
+	0x02, 0x1E, 0x60, 0xE5, 0x59, 0x64, 0x02, 0x45,
+/*1230*/0x58, 0x70, 0x04, 0x7F, 0x01, 0x80, 0x02, 0x7F,
+	0x00, 0xE5, 0x59, 0x45, 0x58, 0x70, 0x04, 0x7E,
+/*1240*/0x01, 0x80, 0x02, 0x7E, 0x00, 0xEE, 0x4F, 0x60,
+	0x23, 0x85, 0x41, 0x49, 0x85, 0x40, 0x4B, 0xE5,
+/*1250*/0x59, 0x45, 0x58, 0x70, 0x2C, 0xAF, 0x5A, 0xFE,
+	0xCD, 0xE9, 0xCD, 0xFC, 0xAB, 0x59, 0xAA, 0x58,
+/*1260*/0x12, 0x0A, 0xFF, 0xAF, 0x5B, 0x7E, 0x00, 0x12,
+	0x1E, 0x60, 0x80, 0x15, 0xAF, 0x5B, 0x7E, 0x00,
+/*1270*/0x12, 0x1E, 0x60, 0x90, 0x07, 0x26, 0x12, 0x07,
+	0x35, 0xE5, 0x49, 0x12, 0x07, 0x31, 0xE5, 0x4B,
+/*1280*/0xF0, 0xE4, 0xFD, 0xAF, 0x35, 0xFE, 0xFC, 0x12,
+	0x09, 0x15, 0x22, 0x8C, 0x64, 0x8D, 0x65, 0x12,
+/*1290*/0x08, 0xDA, 0x40, 0x3C, 0xE5, 0x65, 0x45, 0x64,
+	0x70, 0x10, 0x12, 0x09, 0x04, 0xC3, 0xE5, 0x3E,
+/*12A0*/0x12, 0x07, 0x69, 0x40, 0x3B, 0x12, 0x08, 0x95,
+	0x80, 0x18, 0xE5, 0x3E, 0xC3, 0x95, 0x38, 0x40,
+/*12B0*/0x1D, 0x85, 0x3E, 0x38, 0xE5, 0x3E, 0x60, 0x05,
+	0x85, 0x3F, 0x39, 0x80, 0x03, 0x85, 0x39, 0x39,
+/*12C0*/0x8F, 0x3A, 0x12, 0x07, 0xA8, 0xE5, 0x3E, 0x12,
+	0x07, 0x53, 0xE5, 0x3F, 0xF0, 0x22, 0x80, 0x3B,
+/*12D0*/0xE5, 0x65, 0x45, 0x64, 0x70, 0x11, 0x12, 0x07,
+	0x5F, 0x40, 0x05, 0x12, 0x08, 0x9E, 0x80, 0x1F,
+/*12E0*/0x12, 0x07, 0x3E, 0xE5, 0x41, 0xF0, 0x22, 0xE5,
+	0x3C, 0xC3, 0x95, 0x38, 0x40, 0x1D, 0x85, 0x3C,
+/*12F0*/0x38, 0xE5, 0x3C, 0x60, 0x05, 0x85, 0x3D, 0x39,
+	0x80, 0x03, 0x85, 0x39, 0x39, 0x8F, 0x3A, 0x12,
+/*1300*/0x07, 0xA8, 0xE5, 0x3C, 0x12, 0x07, 0x53, 0xE5,
+	0x3D, 0xF0, 0x22, 0x12, 0x07, 0x9F, 0xE5, 0x38,
+/*1310*/0x12, 0x07, 0x53, 0xE5, 0x39, 0xF0, 0x22, 0x8C,
+	0x63, 0x8D, 0x64, 0x12, 0x08, 0xDA, 0x40, 0x3C,
+/*1320*/0xE5, 0x64, 0x45, 0x63, 0x70, 0x10, 0x12, 0x09,
+	0x04, 0xC3, 0xE5, 0x3E, 0x12, 0x07, 0x69, 0x40,
+/*1330*/0x3B, 0x12, 0x08, 0x95, 0x80, 0x18, 0xE5, 0x3E,
+	0xC3, 0x95, 0x38, 0x40, 0x1D, 0x85, 0x3E, 0x38,
+/*1340*/0xE5, 0x3E, 0x60, 0x05, 0x85, 0x3F, 0x39, 0x80,
+	0x03, 0x85, 0x39, 0x39, 0x8F, 0x3A, 0x12, 0x07,
+/*1350*/0xA8, 0xE5, 0x3E, 0x12, 0x07, 0x53, 0xE5, 0x3F,
+	0xF0, 0x22, 0x80, 0x3B, 0xE5, 0x64, 0x45, 0x63,
+/*1360*/0x70, 0x11, 0x12, 0x07, 0x5F, 0x40, 0x05, 0x12,
+	0x08, 0x9E, 0x80, 0x1F, 0x12, 0x07, 0x3E, 0xE5,
+/*1370*/0x41, 0xF0, 0x22, 0xE5, 0x3C, 0xC3, 0x95, 0x38,
+	0x40, 0x1D, 0x85, 0x3C, 0x38, 0xE5, 0x3C, 0x60,
+/*1380*/0x05, 0x85, 0x3D, 0x39, 0x80, 0x03, 0x85, 0x39,
+	0x39, 0x8F, 0x3A, 0x12, 0x07, 0xA8, 0xE5, 0x3C,
+/*1390*/0x12, 0x07, 0x53, 0xE5, 0x3D, 0xF0, 0x22, 0x12,
+	0x07, 0x9F, 0xE5, 0x38, 0x12, 0x07, 0x53, 0xE5,
+/*13A0*/0x39, 0xF0, 0x22, 0xE5, 0x0D, 0xFE, 0xE5, 0x08,
+	0x8E, 0x54, 0x44, 0x05, 0xF5, 0x55, 0x75, 0x15,
+/*13B0*/0x0F, 0xF5, 0x82, 0x12, 0x0E, 0x7A, 0x12, 0x17,
+	0xA3, 0x20, 0x31, 0x05, 0x75, 0x15, 0x03, 0x80,
+/*13C0*/0x03, 0x75, 0x15, 0x0B, 0xE5, 0x0A, 0xC3, 0x94,
+	0x01, 0x50, 0x38, 0x12, 0x14, 0x20, 0x20, 0x31,
+/*13D0*/0x06, 0x05, 0x15, 0x05, 0x15, 0x80, 0x04, 0x15,
+	0x15, 0x15, 0x15, 0xE5, 0x0A, 0xC3, 0x94, 0x01,
+/*13E0*/0x50, 0x21, 0x12, 0x14, 0x20, 0x20, 0x31, 0x04,
+	0x05, 0x15, 0x80, 0x02, 0x15, 0x15, 0xE5, 0x0A,
+/*13F0*/0xC3, 0x94, 0x01, 0x50, 0x0E, 0x12, 0x0E, 0x77,
+	0x12, 0x17, 0xA3, 0x20, 0x31, 0x05, 0x05, 0x15,
+/*1400*/0x12, 0x0E, 0x77, 0xE5, 0x15, 0xB4, 0x08, 0x04,
+	0x7F, 0x01, 0x80, 0x02, 0x7F, 0x00, 0xE5, 0x15,
+/*1410*/0xB4, 0x07, 0x04, 0x7E, 0x01, 0x80, 0x02, 0x7E,
+	0x00, 0xEE, 0x4F, 0x60, 0x02, 0x05, 0x7F, 0x22,
+/*1420*/0x85, 0x55, 0x82, 0x85, 0x54, 0x83, 0xE5, 0x15,
+	0xF0, 0x12, 0x17, 0xA3, 0x22, 0x12, 0x07, 0x2A,
+/*1430*/0x75, 0x83, 0xAE, 0x74, 0xFF, 0x12, 0x07, 0x29,
+	0xE0, 0x54, 0x1A, 0xF5, 0x34, 0xE0, 0xC4, 0x13,
+/*1440*/0x54, 0x07, 0xF5, 0x35, 0x24, 0xFE, 0x60, 0x24,
+	0x24, 0xFE, 0x60, 0x3C, 0x24, 0x04, 0x70, 0x63,
+/*1450*/0x75, 0x31, 0x2D, 0xE5, 0x08, 0xFD, 0x74, 0xB6,
+	0x12, 0x07, 0x92, 0x74, 0xBC, 0x90, 0x07, 0x22,
+/*1460*/0x12, 0x07, 0x95, 0x74, 0x90, 0x12, 0x07, 0xB3,
+	0x74, 0x92, 0x80, 0x3C, 0x75, 0x31, 0x3A, 0xE5,
+/*1470*/0x08, 0xFD, 0x74, 0xBA, 0x12, 0x07, 0x92, 0x74,
+	0xC0, 0x90, 0x07, 0x22, 0x12, 0x07, 0xB6, 0x74,
+/*1480*/0xC4, 0x12, 0x07, 0xB3, 0x74, 0xC8, 0x80, 0x20,
+	0x75, 0x31, 0x35, 0xE5, 0x08, 0xFD, 0x74, 0xB8,
+/*1490*/0x12, 0x07, 0x92, 0x74, 0xBE, 0xFF, 0xED, 0x44,
+	0x07, 0x90, 0x07, 0x22, 0xCF, 0xF0, 0xA3, 0xEF,
+/*14A0*/0xF0, 0x74, 0xC2, 0x12, 0x07, 0xB3, 0x74, 0xC6,
+	0xFF, 0xED, 0x44, 0x07, 0xA3, 0xCF, 0xF0, 0xA3,
+/*14B0*/0xEF, 0xF0, 0x22, 0x75, 0x34, 0x01, 0x22, 0x8E,
+	0x58, 0x8F, 0x59, 0x8C, 0x5A, 0x8D, 0x5B, 0x8A,
+/*14C0*/0x5C, 0x8B, 0x5D, 0x75, 0x5E, 0x01, 0xE4, 0xF5,
+	0x5F, 0x12, 0x1E, 0xA5, 0x85, 0x59, 0x5E, 0xD3,
+/*14D0*/0xE5, 0x5E, 0x95, 0x5B, 0xE5, 0x5A, 0x12, 0x07,
+	0x6B, 0x50, 0x57, 0xE5, 0x5D, 0x45, 0x5C, 0x70,
+/*14E0*/0x30, 0x12, 0x07, 0x2A, 0x75, 0x83, 0x92, 0xE5,
+	0x5E, 0x12, 0x07, 0x29, 0x75, 0x83, 0xC6, 0xE5,
+/*14F0*/0x5E, 0x12, 0x07, 0x29, 0x75, 0x83, 0xC8, 0xE5,
+	0x5E, 0x12, 0x07, 0x29, 0x75, 0x83, 0x90, 0xE5,
+/*1500*/0x5E, 0x12, 0x07, 0x29, 0x75, 0x83, 0xC2, 0xE5,
+	0x5E, 0x12, 0x07, 0x29, 0x75, 0x83, 0xC4, 0x80,
+/*1510*/0x03, 0x12, 0x07, 0x32, 0xE5, 0x5E, 0xF0, 0xAF,
+	0x5F, 0x7E, 0x00, 0xAD, 0x5D, 0xAC, 0x5C, 0x12,
+/*1520*/0x04, 0x44, 0xAF, 0x5E, 0x7E, 0x00, 0xAD, 0x5D,
+	0xAC, 0x5C, 0x12, 0x0B, 0xD1, 0x05, 0x5E, 0x02,
+/*1530*/0x14, 0xCF, 0xAB, 0x5D, 0xAA, 0x5C, 0xAD, 0x5B,
+	0xAC, 0x5A, 0xAF, 0x59, 0xAE, 0x58, 0x02, 0x1B,
+/*1540*/0xFB, 0x8C, 0x5C, 0x8D, 0x5D, 0x8A, 0x5E, 0x8B,
+	0x5F, 0x75, 0x60, 0x01, 0xE4, 0xF5, 0x61, 0xF5,
+/*1550*/0x62, 0xF5, 0x63, 0x12, 0x1E, 0xA5, 0x8F, 0x60,
+	0xD3, 0xE5, 0x60, 0x95, 0x5D, 0xE5, 0x5C, 0x12,
+/*1560*/0x07, 0x6B, 0x50, 0x61, 0xE5, 0x5F, 0x45, 0x5E,
+	0x70, 0x27, 0x12, 0x07, 0x2A, 0x75, 0x83, 0xB6,
+/*1570*/0xE5, 0x60, 0x12, 0x07, 0x29, 0x75, 0x83, 0xB8,
+	0xE5, 0x60, 0x12, 0x07, 0x29, 0x75, 0x83, 0xBA,
+/*1580*/0xE5, 0x60, 0xF0, 0xAF, 0x61, 0x7E, 0x00, 0xE5,
+	0x62, 0x12, 0x08, 0x7A, 0x12, 0x0A, 0xFF, 0x80,
+/*1590*/0x19, 0x90, 0x07, 0x24, 0x12, 0x07, 0x35, 0xE5,
+	0x60, 0x12, 0x07, 0x29, 0x75, 0x83, 0x8E, 0xE4,
+/*15A0*/0x12, 0x07, 0x29, 0x74, 0x01, 0x12, 0x07, 0x29,
+	0xE4, 0xF0, 0xAF, 0x63, 0x7E, 0x00, 0xAD, 0x5F,
+/*15B0*/0xAC, 0x5E, 0x12, 0x04, 0x44, 0xAF, 0x60, 0x7E,
+	0x00, 0xAD, 0x5F, 0xAC, 0x5E, 0x12, 0x12, 0x8B,
+/*15C0*/0x05, 0x60, 0x02, 0x15, 0x58, 0x22, 0x90, 0x11,
+	0x4D, 0xE4, 0x93, 0x90, 0x07, 0x2E, 0xF0, 0x12,
+/*15D0*/0x08, 0x1F, 0x75, 0x83, 0xAE, 0xE0, 0x54, 0x1A,
+	0xF5, 0x34, 0x70, 0x67, 0xEF, 0x44, 0x07, 0xF5,
+/*15E0*/0x82, 0x75, 0x83, 0xCE, 0xE0, 0xFF, 0x13, 0x13,
+	0x13, 0x54, 0x07, 0xF5, 0x36, 0x54, 0x0F, 0xD3,
+/*15F0*/0x94, 0x00, 0x40, 0x06, 0x12, 0x14, 0x2D, 0x12,
+	0x1B, 0xA9, 0xE5, 0x36, 0x54, 0x0F, 0x24, 0xFE,
+/*1600*/0x60, 0x0C, 0x14, 0x60, 0x0C, 0x14, 0x60, 0x19,
+	0x24, 0x03, 0x70, 0x37, 0x80, 0x10, 0x02, 0x1E,
+/*1610*/0x91, 0x12, 0x1E, 0x91, 0x12, 0x07, 0x2A, 0x75,
+	0x83, 0xCE, 0xE0, 0x54, 0xEF, 0xF0, 0x02, 0x1D,
+/*1620*/0xAE, 0x12, 0x10, 0x14, 0xE4, 0xF5, 0x55, 0x12,
+	0x1D, 0x85, 0x05, 0x55, 0xE5, 0x55, 0xC3, 0x94,
+/*1630*/0x05, 0x40, 0xF4, 0x12, 0x07, 0x2A, 0x75, 0x83,
+	0xCE, 0xE0, 0x54, 0xC7, 0x12, 0x07, 0x29, 0xE0,
+/*1640*/0x44, 0x08, 0xF0, 0x22, 0xE4, 0xF5, 0x58, 0xF5,
+	0x59, 0xAF, 0x08, 0xEF, 0x44, 0x07, 0xF5, 0x82,
+/*1650*/0x75, 0x83, 0xD0, 0xE0, 0xFD, 0xC4, 0x54, 0x0F,
+	0xF5, 0x5A, 0xEF, 0x44, 0x07, 0xF5, 0x82, 0x75,
+/*1660*/0x83, 0x80, 0x74, 0x01, 0xF0, 0x12, 0x08, 0x21,
+	0x75, 0x83, 0x82, 0xE5, 0x45, 0xF0, 0xEF, 0x44,
+/*1670*/0x07, 0xF5, 0x82, 0x75, 0x83, 0x8A, 0x74, 0xFF,
+	0xF0, 0x12, 0x1A, 0x4D, 0x12, 0x07, 0x2A, 0x75,
+/*1680*/0x83, 0xBC, 0xE0, 0x54, 0xEF, 0x12, 0x07, 0x29,
+	0x75, 0x83, 0xBE, 0xE0, 0x54, 0xEF, 0x12, 0x07,
+/*1690*/0x29, 0x75, 0x83, 0xC0, 0xE0, 0x54, 0xEF, 0x12,
+	0x07, 0x29, 0x75, 0x83, 0xBC, 0xE0, 0x44, 0x10,
+/*16A0*/0x12, 0x07, 0x29, 0x75, 0x83, 0xBE, 0xE0, 0x44,
+	0x10, 0x12, 0x07, 0x29, 0x75, 0x83, 0xC0, 0xE0,
+/*16B0*/0x44, 0x10, 0xF0, 0xAF, 0x58, 0xE5, 0x59, 0x12,
+	0x08, 0x78, 0x02, 0x0A, 0xFF, 0xE4, 0xF5, 0x58,
+/*16C0*/0x7D, 0x01, 0xF5, 0x59, 0xAF, 0x35, 0xFE, 0xFC,
+	0x12, 0x09, 0x15, 0x12, 0x07, 0x2A, 0x75, 0x83,
+/*16D0*/0xB6, 0x74, 0x10, 0x12, 0x07, 0x29, 0x75, 0x83,
+	0xB8, 0x74, 0x10, 0x12, 0x07, 0x29, 0x75, 0x83,
+/*16E0*/0xBA, 0x74, 0x10, 0x12, 0x07, 0x29, 0x75, 0x83,
+	0xBC, 0x74, 0x10, 0x12, 0x07, 0x29, 0x75, 0x83,
+/*16F0*/0xBE, 0x74, 0x10, 0x12, 0x07, 0x29, 0x75, 0x83,
+	0xC0, 0x74, 0x10, 0x12, 0x07, 0x29, 0x75, 0x83,
+/*1700*/0x90, 0xE4, 0x12, 0x07, 0x29, 0x75, 0x83, 0xC2,
+	0xE4, 0x12, 0x07, 0x29, 0x75, 0x83, 0xC4, 0xE4,
+/*1710*/0x12, 0x07, 0x29, 0x75, 0x83, 0x92, 0xE4, 0x12,
+	0x07, 0x29, 0x75, 0x83, 0xC6, 0xE4, 0x12, 0x07,
+/*1720*/0x29, 0x75, 0x83, 0xC8, 0xE4, 0xF0, 0xAF, 0x58,
+	0xFE, 0xE5, 0x59, 0x12, 0x08, 0x7A, 0x02, 0x0A,
+/*1730*/0xFF, 0xE5, 0xE2, 0x30, 0xE4, 0x6C, 0xE5, 0xE7,
+	0x54, 0xC0, 0x64, 0x40, 0x70, 0x64, 0xE5, 0x09,
+/*1740*/0xC4, 0x54, 0x30, 0xFE, 0xE5, 0x08, 0x25, 0xE0,
+	0x25, 0xE0, 0x54, 0xC0, 0x4E, 0xFE, 0xEF, 0x54,
+/*1750*/0x3F, 0x4E, 0xFD, 0xE5, 0x2B, 0xAE, 0x2A, 0x78,
+	0x02, 0xC3, 0x33, 0xCE, 0x33, 0xCE, 0xD8, 0xF9,
+/*1760*/0xF5, 0x82, 0x8E, 0x83, 0xED, 0xF0, 0xE5, 0x2B,
+	0xAE, 0x2A, 0x78, 0x02, 0xC3, 0x33, 0xCE, 0x33,
+/*1770*/0xCE, 0xD8, 0xF9, 0xFF, 0xF5, 0x82, 0x8E, 0x83,
+	0xA3, 0xE5, 0xFE, 0xF0, 0x8F, 0x82, 0x8E, 0x83,
+/*1780*/0xA3, 0xA3, 0xE5, 0xFD, 0xF0, 0x8F, 0x82, 0x8E,
+	0x83, 0xA3, 0xA3, 0xA3, 0xE5, 0xFC, 0xF0, 0xC3,
+/*1790*/0xE5, 0x2B, 0x94, 0xFA, 0xE5, 0x2A, 0x94, 0x00,
+	0x50, 0x08, 0x05, 0x2B, 0xE5, 0x2B, 0x70, 0x02,
+/*17A0*/0x05, 0x2A, 0x22, 0xE4, 0xFF, 0xE4, 0xF5, 0x58,
+	0xF5, 0x56, 0xF5, 0x57, 0x74, 0x82, 0xFC, 0x12,
+/*17B0*/0x0E, 0x04, 0x8C, 0x83, 0xE0, 0xF5, 0x10, 0x54,
+	0x7F, 0xF0, 0xE5, 0x10, 0x44, 0x80, 0x12, 0x0E,
+/*17C0*/0x98, 0xED, 0xF0, 0x7E, 0x0A, 0x12, 0x0E, 0x04,
+	0x75, 0x83, 0xA0, 0xE0, 0x20, 0xE0, 0x26, 0xDE,
+/*17D0*/0xF4, 0x05, 0x57, 0xE5, 0x57, 0x70, 0x02, 0x05,
+	0x56, 0xE5, 0x14, 0x24, 0x01, 0xFD, 0xE4, 0x33,
+/*17E0*/0xFC, 0xD3, 0xE5, 0x57, 0x9D, 0xE5, 0x56, 0x9C,
+	0x40, 0xD9, 0xE5, 0x0A, 0x94, 0x20, 0x50, 0x02,
+/*17F0*/0x05, 0x0A, 0x43, 0xE1, 0x08, 0xC2, 0x31, 0x12,
+	0x0E, 0x04, 0x75, 0x83, 0xA6, 0xE0, 0x55, 0x12,
+/*1800*/0x65, 0x12, 0x70, 0x03, 0xD2, 0x31, 0x22, 0xC2,
+	0x31, 0x22, 0x90, 0x07, 0x26, 0xE0, 0xFA, 0xA3,
+/*1810*/0xE0, 0xF5, 0x82, 0x8A, 0x83, 0xE0, 0xF5, 0x41,
+	0xE5, 0x39, 0xC3, 0x95, 0x41, 0x40, 0x26, 0xE5,
+/*1820*/0x39, 0x95, 0x41, 0xC3, 0x9F, 0xEE, 0x12, 0x07,
+	0x6B, 0x40, 0x04, 0x7C, 0x01, 0x80, 0x02, 0x7C,
+/*1830*/0x00, 0xE5, 0x41, 0x64, 0x3F, 0x60, 0x04, 0x7B,
+	0x01, 0x80, 0x02, 0x7B, 0x00, 0xEC, 0x5B, 0x60,
+/*1840*/0x29, 0x05, 0x41, 0x80, 0x28, 0xC3, 0xE5, 0x41,
+	0x95, 0x39, 0xC3, 0x9F, 0xEE, 0x12, 0x07, 0x6B,
+/*1850*/0x40, 0x04, 0x7F, 0x01, 0x80, 0x02, 0x7F, 0x00,
+	0xE5, 0x41, 0x60, 0x04, 0x7E, 0x01, 0x80, 0x02,
+/*1860*/0x7E, 0x00, 0xEF, 0x5E, 0x60, 0x04, 0x15, 0x41,
+	0x80, 0x03, 0x85, 0x39, 0x41, 0x85, 0x3A, 0x40,
+/*1870*/0x22, 0xE5, 0xE2, 0x30, 0xE4, 0x60, 0xE5, 0xE1,
+	0x30, 0xE2, 0x5B, 0xE5, 0x09, 0x70, 0x04, 0x7F,
+/*1880*/0x01, 0x80, 0x02, 0x7F, 0x00, 0xE5, 0x08, 0x70,
+	0x04, 0x7E, 0x01, 0x80, 0x02, 0x7E, 0x00, 0xEE,
+/*1890*/0x5F, 0x60, 0x43, 0x53, 0xF9, 0xF8, 0xE5, 0xE2,
+	0x30, 0xE4, 0x3B, 0xE5, 0xE1, 0x30, 0xE2, 0x2E,
+/*18A0*/0x43, 0xFA, 0x02, 0x53, 0xFA, 0xFB, 0xE4, 0xF5,
+	0x10, 0x90, 0x94, 0x70, 0xE5, 0x10, 0xF0, 0xE5,
+/*18B0*/0xE1, 0x30, 0xE2, 0xE7, 0x90, 0x94, 0x70, 0xE0,
+	0x65, 0x10, 0x60, 0x03, 0x43, 0xFA, 0x04, 0x05,
+/*18C0*/0x10, 0x90, 0x94, 0x70, 0xE5, 0x10, 0xF0, 0x70,
+	0xE6, 0x12, 0x00, 0x06, 0x80, 0xE1, 0x53, 0xFA,
+/*18D0*/0xFD, 0x53, 0xFA, 0xFB, 0x80, 0xC0, 0x22, 0x8F,
+	0x54, 0x12, 0x00, 0x06, 0xE5, 0xE1, 0x30, 0xE0,
+/*18E0*/0x04, 0x7F, 0x01, 0x80, 0x02, 0x7F, 0x00, 0xE5,
+	0x7E, 0xD3, 0x94, 0x05, 0x40, 0x04, 0x7E, 0x01,
+/*18F0*/0x80, 0x02, 0x7E, 0x00, 0xEE, 0x4F, 0x60, 0x3D,
+	0x85, 0x54, 0x11, 0xE5, 0xE2, 0x20, 0xE1, 0x32,
+/*1900*/0x74, 0xCE, 0x12, 0x1A, 0x05, 0x30, 0xE7, 0x04,
+	0x7D, 0x01, 0x80, 0x02, 0x7D, 0x00, 0x8F, 0x82,
+/*1910*/0x8E, 0x83, 0xE0, 0x30, 0xE6, 0x04, 0x7F, 0x01,
+	0x80, 0x02, 0x7F, 0x00, 0xEF, 0x5D, 0x70, 0x15,
+/*1920*/0x12, 0x15, 0xC6, 0x74, 0xCE, 0x12, 0x1A, 0x05,
+	0x30, 0xE6, 0x07, 0xE0, 0x44, 0x80, 0xF0, 0x43,
+/*1930*/0xF9, 0x80, 0x12, 0x18, 0x71, 0x22, 0x12, 0x0E,
+	0x44, 0xE5, 0x16, 0x25, 0xE0, 0x25, 0xE0, 0x24,
+/*1940*/0xB0, 0xF5, 0x82, 0xE4, 0x34, 0x1A, 0xF5, 0x83,
+	0xE4, 0x93, 0xF5, 0x0F, 0xE5, 0x16, 0x25, 0xE0,
+/*1950*/0x25, 0xE0, 0x24, 0xB1, 0xF5, 0x82, 0xE4, 0x34,
+	0x1A, 0xF5, 0x83, 0xE4, 0x93, 0xF5, 0x0E, 0x12,
+/*1960*/0x0E, 0x65, 0xF5, 0x10, 0xE5, 0x0F, 0x54, 0xF0,
+	0x12, 0x0E, 0x17, 0x75, 0x83, 0x8C, 0xEF, 0xF0,
+/*1970*/0xE5, 0x0F, 0x30, 0xE0, 0x0C, 0x12, 0x0E, 0x04,
+	0x75, 0x83, 0x86, 0xE0, 0x44, 0x40, 0xF0, 0x80,
+/*1980*/0x0A, 0x12, 0x0E, 0x04, 0x75, 0x83, 0x86, 0xE0,
+	0x54, 0xBF, 0xF0, 0x12, 0x0E, 0x91, 0x75, 0x83,
+/*1990*/0x82, 0xE5, 0x0E, 0xF0, 0x22, 0x7F, 0x05, 0x12,
+	0x17, 0x31, 0x12, 0x0E, 0x04, 0x12, 0x0E, 0x33,
+/*19A0*/0x74, 0x02, 0xF0, 0x74, 0x8E, 0xFE, 0x12, 0x0E,
+	0x04, 0x12, 0x0E, 0x0B, 0xEF, 0xF0, 0x75, 0x15,
+/*19B0*/0x70, 0x12, 0x0F, 0xF7, 0x20, 0x34, 0x05, 0x75,
+	0x15, 0x10, 0x80, 0x03, 0x75, 0x15, 0x50, 0x12,
+/*19C0*/0x0F, 0xF7, 0x20, 0x34, 0x04, 0x74, 0x10, 0x80,
+	0x02, 0x74, 0xF0, 0x25, 0x15, 0xF5, 0x15, 0x12,
+/*19D0*/0x0E, 0x21, 0xEF, 0xF0, 0x12, 0x10, 0x91, 0x20,
+	0x34, 0x17, 0xE5, 0x15, 0x64, 0x30, 0x60, 0x0C,
+/*19E0*/0x74, 0x10, 0x25, 0x15, 0xF5, 0x15, 0xB4, 0x80,
+	0x03, 0xE4, 0xF5, 0x15, 0x12, 0x0E, 0x21, 0xEF,
+/*19F0*/0xF0, 0x22, 0xF0, 0xE5, 0x0B, 0x25, 0xE0, 0x25,
+	0xE0, 0x24, 0x82, 0xF5, 0x82, 0xE4, 0x34, 0x07,
+/*1A00*/0xF5, 0x83, 0x22, 0x74, 0x88, 0xFE, 0xE5, 0x08,
+	0x44, 0x07, 0xFF, 0xF5, 0x82, 0x8E, 0x83, 0xE0,
+/*1A10*/0x22, 0xF0, 0xE5, 0x08, 0x44, 0x07, 0xF5, 0x82,
+	0x22, 0xF0, 0xE0, 0x54, 0xC0, 0x8F, 0x82, 0x8E,
+/*1A20*/0x83, 0xF0, 0x22, 0xEF, 0x44, 0x07, 0xF5, 0x82,
+	0x75, 0x83, 0x86, 0xE0, 0x54, 0x10, 0xD3, 0x94,
+/*1A30*/0x00, 0x22, 0xF0, 0x90, 0x07, 0x15, 0xE0, 0x04,
+	0xF0, 0x22, 0x44, 0x06, 0xF5, 0x82, 0x75, 0x83,
+/*1A40*/0x9E, 0xE0, 0x22, 0xFE, 0xEF, 0x44, 0x07, 0xF5,
+	0x82, 0x8E, 0x83, 0xE0, 0x22, 0xE4, 0x90, 0x07,
+/*1A50*/0x2A, 0xF0, 0xA3, 0xF0, 0x12, 0x07, 0x2A, 0x75,
+	0x83, 0x82, 0xE0, 0x54, 0x7F, 0x12, 0x07, 0x29,
+/*1A60*/0xE0, 0x44, 0x80, 0xF0, 0x12, 0x10, 0xFC, 0x12,
+	0x08, 0x1F, 0x75, 0x83, 0xA0, 0xE0, 0x20, 0xE0,
+/*1A70*/0x1A, 0x90, 0x07, 0x2B, 0xE0, 0x04, 0xF0, 0x70,
+	0x06, 0x90, 0x07, 0x2A, 0xE0, 0x04, 0xF0, 0x90,
+/*1A80*/0x07, 0x2A, 0xE0, 0xB4, 0x10, 0xE1, 0xA3, 0xE0,
+	0xB4, 0x00, 0xDC, 0xEE, 0x44, 0xA6, 0xFC, 0xEF,
+/*1A90*/0x44, 0x07, 0xF5, 0x82, 0x8C, 0x83, 0xE0, 0xF5,
+	0x32, 0xEE, 0x44, 0xA8, 0xFE, 0xEF, 0x44, 0x07,
+/*1AA0*/0xF5, 0x82, 0x8E, 0x83, 0xE0, 0xF5, 0x33, 0x22,
+	0x01, 0x20, 0x11, 0x00, 0x04, 0x20, 0x00, 0x90,
+/*1AB0*/0x00, 0x20, 0x0F, 0x92, 0x00, 0x21, 0x0F, 0x94,
+	0x00, 0x22, 0x0F, 0x96, 0x00, 0x23, 0x0F, 0x98,
+/*1AC0*/0x00, 0x24, 0x0F, 0x9A, 0x00, 0x25, 0x0F, 0x9C,
+	0x00, 0x26, 0x0F, 0x9E, 0x00, 0x27, 0x0F, 0xA0,
+/*1AD0*/0x01, 0x20, 0x01, 0xA2, 0x01, 0x21, 0x01, 0xA4,
+	0x01, 0x22, 0x01, 0xA6, 0x01, 0x23, 0x01, 0xA8,
+/*1AE0*/0x01, 0x24, 0x01, 0xAA, 0x01, 0x25, 0x01, 0xAC,
+	0x01, 0x26, 0x01, 0xAE, 0x01, 0x27, 0x01, 0xB0,
+/*1AF0*/0x01, 0x28, 0x01, 0xB4, 0x00, 0x28, 0x0F, 0xB6,
+	0x40, 0x28, 0x0F, 0xB8, 0x61, 0x28, 0x01, 0xCB,
+/*1B00*/0xEF, 0xCB, 0xCA, 0xEE, 0xCA, 0x7F, 0x01, 0xE4,
+	0xFD, 0xEB, 0x4A, 0x70, 0x24, 0xE5, 0x08, 0xF5,
+/*1B10*/0x82, 0x74, 0xB6, 0x12, 0x08, 0x29, 0xE5, 0x08,
+	0xF5, 0x82, 0x74, 0xB8, 0x12, 0x08, 0x29, 0xE5,
+/*1B20*/0x08, 0xF5, 0x82, 0x74, 0xBA, 0x12, 0x08, 0x29,
+	0x7E, 0x00, 0x7C, 0x00, 0x12, 0x0A, 0xFF, 0x80,
+/*1B30*/0x12, 0x90, 0x07, 0x26, 0x12, 0x07, 0x35, 0xE5,
+	0x41, 0xF0, 0x90, 0x07, 0x24, 0x12, 0x07, 0x35,
+/*1B40*/0xE5, 0x40, 0xF0, 0x12, 0x07, 0x2A, 0x75, 0x83,
+	0x8E, 0xE4, 0x12, 0x07, 0x29, 0x74, 0x01, 0x12,
+/*1B50*/0x07, 0x29, 0xE4, 0xF0, 0x22, 0xE4, 0xF5, 0x26,
+	0xF5, 0x27, 0x53, 0xE1, 0xFE, 0xF5, 0x2A, 0x75,
+/*1B60*/0x2B, 0x01, 0xF5, 0x08, 0x7F, 0x01, 0x12, 0x17,
+	0x31, 0x30, 0x30, 0x1C, 0x90, 0x1A, 0xA9, 0xE4,
+/*1B70*/0x93, 0xF5, 0x10, 0x90, 0x1F, 0xF9, 0xE4, 0x93,
+	0xF5, 0x10, 0x90, 0x00, 0x41, 0xE4, 0x93, 0xF5,
+/*1B80*/0x10, 0x90, 0x1E, 0xCA, 0xE4, 0x93, 0xF5, 0x10,
+	0x7F, 0x02, 0x12, 0x17, 0x31, 0x12, 0x0F, 0x54,
+/*1B90*/0x7F, 0x03, 0x12, 0x17, 0x31, 0x12, 0x00, 0x06,
+	0xE5, 0xE2, 0x30, 0xE7, 0x09, 0x12, 0x10, 0x00,
+/*1BA0*/0x30, 0x30, 0x03, 0x12, 0x11, 0x00, 0x02, 0x00,
+	0x47, 0x12, 0x08, 0x1F, 0x75, 0x83, 0xD0, 0xE0,
+/*1BB0*/0xC4, 0x54, 0x0F, 0xFD, 0x75, 0x43, 0x01, 0x75,
+	0x44, 0xFF, 0x12, 0x08, 0xAA, 0x74, 0x04, 0xF0,
+/*1BC0*/0x75, 0x3B, 0x01, 0xED, 0x14, 0x60, 0x0C, 0x14,
+	0x60, 0x0B, 0x14, 0x60, 0x0F, 0x24, 0x03, 0x70,
+/*1BD0*/0x0B, 0x80, 0x09, 0x80, 0x00, 0x12, 0x08, 0xA7,
+	0x04, 0xF0, 0x80, 0x06, 0x12, 0x08, 0xA7, 0x74,
+/*1BE0*/0x04, 0xF0, 0xEE, 0x44, 0x82, 0xFE, 0xEF, 0x44,
+	0x07, 0xF5, 0x82, 0x8E, 0x83, 0xE5, 0x45, 0x12,
+/*1BF0*/0x08, 0xBE, 0x75, 0x83, 0x82, 0xE5, 0x31, 0xF0,
+	0x02, 0x11, 0x4C, 0x8E, 0x60, 0x8F, 0x61, 0x12,
+/*1C00*/0x1E, 0xA5, 0xE4, 0xFF, 0xCE, 0xED, 0xCE, 0xEE,
+	0xD3, 0x95, 0x61, 0xE5, 0x60, 0x12, 0x07, 0x6B,
+/*1C10*/0x40, 0x39, 0x74, 0x20, 0x2E, 0xF5, 0x82, 0xE4,
+	0x34, 0x03, 0xF5, 0x83, 0xE0, 0x70, 0x03, 0xFF,
+/*1C20*/0x80, 0x26, 0x12, 0x08, 0xE2, 0xFD, 0xC3, 0x9F,
+	0x40, 0x1E, 0xCF, 0xED, 0xCF, 0xEB, 0x4A, 0x70,
+/*1C30*/0x0B, 0x8D, 0x42, 0x12, 0x08, 0xEE, 0xF5, 0x41,
+	0x8E, 0x40, 0x80, 0x0C, 0x12, 0x08, 0xE2, 0xF5,
+/*1C40*/0x38, 0x12, 0x08, 0xEE, 0xF5, 0x39, 0x8E, 0x3A,
+	0x1E, 0x80, 0xBC, 0x22, 0x75, 0x58, 0x01, 0xE5,
+/*1C50*/0x35, 0x70, 0x0C, 0x12, 0x07, 0xCC, 0xE0, 0xF5,
+	0x4A, 0x12, 0x07, 0xD8, 0xE0, 0xF5, 0x4C, 0xE5,
+/*1C60*/0x35, 0xB4, 0x04, 0x0C, 0x12, 0x07, 0xE4, 0xE0,
+	0xF5, 0x4A, 0x12, 0x07, 0xF0, 0xE0, 0xF5, 0x4C,
+/*1C70*/0xE5, 0x35, 0xB4, 0x01, 0x04, 0x7F, 0x01, 0x80,
+	0x02, 0x7F, 0x00, 0xE5, 0x35, 0xB4, 0x02, 0x04,
+/*1C80*/0x7E, 0x01, 0x80, 0x02, 0x7E, 0x00, 0xEE, 0x4F,
+	0x60, 0x0C, 0x12, 0x07, 0xFC, 0xE0, 0xF5, 0x4A,
+/*1C90*/0x12, 0x08, 0x08, 0xE0, 0xF5, 0x4C, 0x85, 0x41,
+	0x49, 0x85, 0x40, 0x4B, 0x22, 0x75, 0x5B, 0x01,
+/*1CA0*/0x90, 0x07, 0x24, 0x12, 0x07, 0x35, 0xE0, 0x54,
+	0x1F, 0xFF, 0xD3, 0x94, 0x02, 0x50, 0x04, 0x8F,
+/*1CB0*/0x58, 0x80, 0x05, 0xEF, 0x24, 0xFE, 0xF5, 0x58,
+	0xEF, 0xC3, 0x94, 0x18, 0x40, 0x05, 0x75, 0x59,
+/*1CC0*/0x18, 0x80, 0x04, 0xEF, 0x04, 0xF5, 0x59, 0x85,
+	0x43, 0x5A, 0xAF, 0x58, 0x7E, 0x00, 0xAD, 0x59,
+/*1CD0*/0x7C, 0x00, 0xAB, 0x5B, 0x7A, 0x00, 0x12, 0x15,
+	0x41, 0xAF, 0x5A, 0x7E, 0x00, 0x12, 0x18, 0x0A,
+/*1CE0*/0xAF, 0x5B, 0x7E, 0x00, 0x02, 0x1A, 0xFF, 0xE5,
+	0xE2, 0x30, 0xE7, 0x0E, 0x12, 0x10, 0x03, 0xC2,
+/*1CF0*/0x30, 0x30, 0x30, 0x03, 0x12, 0x10, 0xFF, 0x20,
+	0x33, 0x28, 0xE5, 0xE7, 0x30, 0xE7, 0x05, 0x12,
+/*1D00*/0x0E, 0xA2, 0x80, 0x0D, 0xE5, 0xFE, 0xC3, 0x94,
+	0x20, 0x50, 0x06, 0x12, 0x0E, 0xA2, 0x43, 0xF9,
+/*1D10*/0x08, 0xE5, 0xF2, 0x30, 0xE7, 0x03, 0x53, 0xF9,
+	0x7F, 0xE5, 0xF1, 0x54, 0x70, 0xD3, 0x94, 0x00,
+/*1D20*/0x50, 0xD8, 0x22, 0x12, 0x0E, 0x04, 0x75, 0x83,
+	0x80, 0xE4, 0xF0, 0xE5, 0x08, 0x44, 0x07, 0x12,
+/*1D30*/0x0D, 0xFD, 0x75, 0x83, 0x84, 0x12, 0x0E, 0x02,
+	0x75, 0x83, 0x86, 0x12, 0x0E, 0x02, 0x75, 0x83,
+/*1D40*/0x8C, 0xE0, 0x54, 0xF3, 0x12, 0x0E, 0x03, 0x75,
+	0x83, 0x8E, 0x12, 0x0E, 0x02, 0x75, 0x83, 0x94,
+/*1D50*/0xE0, 0x54, 0xFB, 0xF0, 0x22, 0x12, 0x07, 0x2A,
+	0x75, 0x83, 0x8E, 0xE4, 0x12, 0x07, 0x29, 0x74,
+/*1D60*/0x01, 0x12, 0x07, 0x29, 0xE4, 0x12, 0x08, 0xBE,
+	0x75, 0x83, 0x8C, 0xE0, 0x44, 0x20, 0x12, 0x08,
+/*1D70*/0xBE, 0xE0, 0x54, 0xDF, 0xF0, 0x74, 0x84, 0x85,
+	0x08, 0x82, 0xF5, 0x83, 0xE0, 0x54, 0x7F, 0xF0,
+/*1D80*/0xE0, 0x44, 0x80, 0xF0, 0x22, 0x75, 0x56, 0x01,
+	0xE4, 0xFD, 0xF5, 0x57, 0xAF, 0x35, 0xFE, 0xFC,
+/*1D90*/0x12, 0x09, 0x15, 0x12, 0x1C, 0x9D, 0x12, 0x1E,
+	0x7A, 0x12, 0x1C, 0x4C, 0xAF, 0x57, 0x7E, 0x00,
+/*1DA0*/0xAD, 0x56, 0x7C, 0x00, 0x12, 0x04, 0x44, 0xAF,
+	0x56, 0x7E, 0x00, 0x02, 0x11, 0xEE, 0x75, 0x56,
+/*1DB0*/0x01, 0xE4, 0xFD, 0xF5, 0x57, 0xAF, 0x35, 0xFE,
+	0xFC, 0x12, 0x09, 0x15, 0x12, 0x1C, 0x9D, 0x12,
+/*1DC0*/0x1E, 0x7A, 0x12, 0x1C, 0x4C, 0xAF, 0x57, 0x7E,
+	0x00, 0xAD, 0x56, 0x7C, 0x00, 0x12, 0x04, 0x44,
+/*1DD0*/0xAF, 0x56, 0x7E, 0x00, 0x02, 0x11, 0xEE, 0xE4,
+	0xF5, 0x16, 0x12, 0x0E, 0x44, 0xFE, 0xE5, 0x08,
+/*1DE0*/0x44, 0x05, 0xFF, 0x12, 0x0E, 0x65, 0x8F, 0x82,
+	0x8E, 0x83, 0xF0, 0x05, 0x16, 0xE5, 0x16, 0xC3,
+/*1DF0*/0x94, 0x14, 0x40, 0xE6, 0xE5, 0x08, 0x12, 0x0E,
+	0x2B, 0xE4, 0xF0, 0x22, 0xE4, 0xF5, 0x58, 0xF5,
+/*1E00*/0x59, 0xF5, 0x5A, 0xFF, 0xFE, 0xAD, 0x58, 0xFC,
+	0x12, 0x09, 0x15, 0x7F, 0x04, 0x7E, 0x00, 0xAD,
+/*1E10*/0x58, 0x7C, 0x00, 0x12, 0x09, 0x15, 0x7F, 0x02,
+	0x7E, 0x00, 0xAD, 0x58, 0x7C, 0x00, 0x02, 0x09,
+/*1E20*/0x15, 0xE5, 0x3C, 0x25, 0x3E, 0xFC, 0xE5, 0x42,
+	0x24, 0x00, 0xFB, 0xE4, 0x33, 0xFA, 0xEC, 0xC3,
+/*1E30*/0x9B, 0xEA, 0x12, 0x07, 0x6B, 0x40, 0x0B, 0x8C,
+	0x42, 0xE5, 0x3D, 0x25, 0x3F, 0xF5, 0x41, 0x8F,
+/*1E40*/0x40, 0x22, 0x12, 0x09, 0x0B, 0x22, 0x74, 0x84,
+	0xF5, 0x18, 0x85, 0x08, 0x19, 0x85, 0x19, 0x82,
+/*1E50*/0x85, 0x18, 0x83, 0xE0, 0x54, 0x7F, 0xF0, 0xE0,
+	0x44, 0x80, 0xF0, 0xE0, 0x44, 0x80, 0xF0, 0x22,
+/*1E60*/0xEF, 0x4E, 0x70, 0x0B, 0x12, 0x07, 0x2A, 0x75,
+	0x83, 0xD2, 0xE0, 0x54, 0xDF, 0xF0, 0x22, 0x12,
+/*1E70*/0x07, 0x2A, 0x75, 0x83, 0xD2, 0xE0, 0x44, 0x20,
+	0xF0, 0x22, 0x75, 0x58, 0x01, 0x90, 0x07, 0x26,
+/*1E80*/0x12, 0x07, 0x35, 0xE0, 0x54, 0x3F, 0xF5, 0x41,
+	0x12, 0x07, 0x32, 0xE0, 0x54, 0x3F, 0xF5, 0x40,
+/*1E90*/0x22, 0x75, 0x56, 0x02, 0xE4, 0xF5, 0x57, 0x12,
+	0x1D, 0xFC, 0xAF, 0x57, 0x7E, 0x00, 0xAD, 0x56,
+/*1EA0*/0x7C, 0x00, 0x02, 0x04, 0x44, 0xE4, 0xF5, 0x42,
+	0xF5, 0x41, 0xF5, 0x40, 0xF5, 0x38, 0xF5, 0x39,
+/*1EB0*/0xF5, 0x3A, 0x22, 0xEF, 0x54, 0x07, 0xFF, 0xE5,
+	0xF9, 0x54, 0xF8, 0x4F, 0xF5, 0xF9, 0x22, 0x7F,
+/*1EC0*/0x01, 0xE4, 0xFE, 0x0F, 0x0E, 0xBE, 0xFF, 0xFB,
+	0x22, 0x01, 0x20, 0x00, 0x01, 0x04, 0x20, 0x00,
+/*1ED0*/0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+/*1EE0*/0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+/*1EF0*/0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+/*1F00*/0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+/*1F10*/0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+/*1F20*/0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+/*1F30*/0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+/*1F40*/0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+/*1F50*/0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+/*1F60*/0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+/*1F70*/0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+/*1F80*/0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+/*1F90*/0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+/*1FA0*/0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+/*1FB0*/0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+/*1FC0*/0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+/*1FD0*/0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+/*1FE0*/0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+/*1FF0*/0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x01, 0x20, 0x11, 0x00, 0x04, 0x20, 0x00, 0x81
+};
diff -pruN 1.0.0+git-20190125.36a4c85-5.1/src/drivers/infiniband/linda.h 1.21.1+git-20220113.fbbdc3926-0ubuntu1/src/drivers/infiniband/linda.h
--- 1.0.0+git-20190125.36a4c85-5.1/src/drivers/infiniband/linda.h	1970-01-01 00:00:00.000000000 +0000
+++ 1.21.1+git-20220113.fbbdc3926-0ubuntu1/src/drivers/infiniband/linda.h	2022-01-13 13:43:08.000000000 +0000
@@ -0,0 +1,281 @@
+#ifndef _LINDA_H
+#define _LINDA_H
+
+/*
+ * Copyright (C) 2008 Michael Brown <mbrown@fensystems.co.uk>.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of the
+ * License, or any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+ * 02110-1301, USA.
+ *
+ * You can also choose to distribute this program under the terms of
+ * the Unmodified Binary Distribution Licence (as given in the file
+ * COPYING.UBDL), provided that you have satisfied its requirements.
+ */
+
+FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
+
+/**
+ * @file
+ *
+ * QLogic Linda Infiniband HCA
+ *
+ */
+
+#define PSEUDOBIT_LITTLE_ENDIAN
+#include <ipxe/pseudobit.h>
+#include "qib_7220_regs.h"
+
+struct ib_device;
+
+/** A Linda GPIO register */
+struct QIB_7220_GPIO_pb {
+	pseudo_bit_t GPIO[16];
+	pseudo_bit_t Reserved[48];
+};
+struct QIB_7220_GPIO {
+	PSEUDO_BIT_STRUCT ( struct QIB_7220_GPIO_pb );
+};
+
+/** A Linda general scalar register */
+struct QIB_7220_scalar_pb {
+	pseudo_bit_t Value[64];
+};
+struct QIB_7220_scalar {
+	PSEUDO_BIT_STRUCT ( struct QIB_7220_scalar_pb );
+};
+
+/** Linda send per-buffer control word */
+struct QIB_7220_SendPbc_pb {
+	pseudo_bit_t LengthP1_toibc[11];
+	pseudo_bit_t Reserved1[4];
+	pseudo_bit_t LengthP1_trigger[11];
+	pseudo_bit_t Reserved2[3];
+	pseudo_bit_t TestEbp[1];
+	pseudo_bit_t Test[1];
+	pseudo_bit_t Intr[1];
+	pseudo_bit_t Reserved3[31];
+	pseudo_bit_t VL15[1];
+};
+struct QIB_7220_SendPbc {
+	PSEUDO_BIT_STRUCT ( struct QIB_7220_SendPbc_pb );
+};
+
+/** Linda send buffer availability */
+struct QIB_7220_SendBufAvail_pb {
+	pseudo_bit_t InUseCheck[144][2];
+	pseudo_bit_t Reserved[32];
+};
+struct QIB_7220_SendBufAvail {
+	PSEUDO_BIT_STRUCT ( struct QIB_7220_SendBufAvail_pb );
+};
+
+/** DMA alignment for send buffer availability */
+#define LINDA_SENDBUFAVAIL_ALIGN 64
+
+/** A Linda eager receive descriptor */
+struct QIB_7220_RcvEgr_pb {
+	pseudo_bit_t Addr[37];
+	pseudo_bit_t BufSize[3];
+	pseudo_bit_t Reserved[24];
+};
+struct QIB_7220_RcvEgr {
+	PSEUDO_BIT_STRUCT ( struct QIB_7220_RcvEgr_pb );
+};
+
+/** Linda receive header flags */
+struct QIB_7220_RcvHdrFlags_pb {
+	pseudo_bit_t PktLen[11];
+	pseudo_bit_t RcvType[3];
+	pseudo_bit_t SoftB[1];
+	pseudo_bit_t SoftA[1];
+	pseudo_bit_t EgrIndex[12];
+	pseudo_bit_t Reserved1[3];
+	pseudo_bit_t UseEgrBfr[1];
+	pseudo_bit_t RcvSeq[4];
+	pseudo_bit_t HdrqOffset[11];
+	pseudo_bit_t Reserved2[8];
+	pseudo_bit_t IBErr[1];
+	pseudo_bit_t MKErr[1];
+	pseudo_bit_t TIDErr[1];
+	pseudo_bit_t KHdrErr[1];
+	pseudo_bit_t MTUErr[1];
+	pseudo_bit_t LenErr[1];
+	pseudo_bit_t ParityErr[1];
+	pseudo_bit_t VCRCErr[1];
+	pseudo_bit_t ICRCErr[1];
+};
+struct QIB_7220_RcvHdrFlags {
+	PSEUDO_BIT_STRUCT ( struct QIB_7220_RcvHdrFlags_pb );
+};
+
+/** Linda memory BAR size */
+#define LINDA_BAR0_SIZE 0x400000
+
+/** Linda I2C SCL line GPIO number */
+#define LINDA_GPIO_SCL 0
+
+/** Linda I2C SDA line GPIO number */
+#define LINDA_GPIO_SDA 1
+
+/** GUID offset within EEPROM */
+#define LINDA_EEPROM_GUID_OFFSET 3
+
+/** GUID size within EEPROM */
+#define LINDA_EEPROM_GUID_SIZE 8
+
+/** Board serial number offset within EEPROM */
+#define LINDA_EEPROM_SERIAL_OFFSET 12
+
+/** Board serial number size within EEPROM */
+#define LINDA_EEPROM_SERIAL_SIZE 12
+
+/** Maximum number of send buffers used
+ *
+ * This is a policy decision.  Must be less than or equal to the total
+ * number of send buffers supported by the hardware (128).
+ */
+#define LINDA_MAX_SEND_BUFS 32
+
+/** Linda send buffer size */
+#define LINDA_SEND_BUF_SIZE 4096
+
+/** Number of contexts (including kernel context)
+ *
+ * This is a policy decision.  Must be 5, 9 or 17.
+ */
+#define LINDA_NUM_CONTEXTS 5
+
+/** PortCfg values for different numbers of contexts */
+enum linda_portcfg {
+	LINDA_PORTCFG_5CTX = 0,
+	LINDA_PORTCFG_9CTX = 1,
+	LINDA_PORTCFG_17CTX = 2,
+};
+
+/** PortCfg values for different numbers of contexts */
+#define LINDA_EAGER_ARRAY_SIZE_5CTX_0 2048
+#define LINDA_EAGER_ARRAY_SIZE_5CTX_OTHER 4096
+#define LINDA_EAGER_ARRAY_SIZE_9CTX_0 2048
+#define LINDA_EAGER_ARRAY_SIZE_9CTX_OTHER 2048
+#define LINDA_EAGER_ARRAY_SIZE_17CTX_0 2048
+#define LINDA_EAGER_ARRAY_SIZE_17CTX_OTHER 1024
+
+/** Eager buffer required alignment */
+#define LINDA_EAGER_BUFFER_ALIGN 2048
+
+/** Eager buffer size encodings */
+enum linda_eager_buffer_size {
+	LINDA_EAGER_BUFFER_NONE = 0,
+	LINDA_EAGER_BUFFER_2K = 1,
+	LINDA_EAGER_BUFFER_4K = 2,
+	LINDA_EAGER_BUFFER_8K = 3,
+	LINDA_EAGER_BUFFER_16K = 4,
+	LINDA_EAGER_BUFFER_32K = 5,
+	LINDA_EAGER_BUFFER_64K = 6,
+};
+
+/** Number of RX headers per context
+ *
+ * This is a policy decision.
+ */
+#define LINDA_RECV_HEADER_COUNT 8
+
+/** Maximum size of each RX header
+ *
+ * This is a policy decision.  Must be divisible by 4.
+ */
+#define LINDA_RECV_HEADER_SIZE 96
+
+/** Total size of an RX header ring */
+#define LINDA_RECV_HEADERS_SIZE \
+	( LINDA_RECV_HEADER_SIZE * LINDA_RECV_HEADER_COUNT )
+
+/** RX header alignment */
+#define LINDA_RECV_HEADERS_ALIGN 64
+
+/** RX payload size
+ *
+ * This is a policy decision.  Must be a valid eager buffer size.
+ */
+#define LINDA_RECV_PAYLOAD_SIZE 2048
+
+/** QPN used for Infinipath Packets
+ *
+ * This is a policy decision.  Must have bit 0 clear.  Must not be a
+ * QPN that we will use.
+ */
+#define LINDA_QP_IDETH 0xdead0
+
+/** Maximum time for wait for external parallel bus request, in us */
+#define LINDA_EPB_REQUEST_MAX_WAIT_US 500
+
+/** Maximum time for wait for external parallel bus transaction, in us */
+#define LINDA_EPB_XACT_MAX_WAIT_US 500
+
+/** Linda external parallel bus chip selects */
+#define LINDA_EPB_CS_SERDES 1
+#define LINDA_EPB_CS_UC 2
+
+/** Linda external parallel bus read/write operations */
+#define LINDA_EPB_WRITE 0
+#define LINDA_EPB_READ 1
+
+/** Linda external parallel bus register addresses */
+#define LINDA_EPB_ADDRESS( _channel, _element, _reg ) \
+	( (_element) | ( (_channel) << 4 ) | ( (_reg) << 9 ) )
+#define LINDA_EPB_ADDRESS_CHANNEL( _address )	( ( (_address) >> 4 ) & 0x1f )
+#define LINDA_EPB_ADDRESS_ELEMENT( _address )	( ( (_address) >> 0 ) & 0x0f )
+#define LINDA_EPB_ADDRESS_REG( _address )	( ( (_address) >> 9 ) & 0x3f )
+
+/** Linda external parallel bus locations
+ *
+ * The location is used by the driver to encode both the chip select
+ * and the EPB address.
+ */
+#define LINDA_EPB_LOC( _cs, _channel, _element, _reg) \
+	( ( (_cs) << 16 ) | LINDA_EPB_ADDRESS ( _channel, _element, _reg ) )
+#define LINDA_EPB_LOC_ADDRESS( _loc )	( (_loc) & 0xffff )
+#define LINDA_EPB_LOC_CS( _loc )	( (_loc) >> 16 )
+
+/** Linda external parallel bus microcontroller register addresses */
+#define LINDA_EPB_UC_CHANNEL 6
+#define LINDA_EPB_UC_LOC( _reg ) \
+	LINDA_EPB_LOC ( LINDA_EPB_CS_UC, LINDA_EPB_UC_CHANNEL, 0, (_reg) )
+#define LINDA_EPB_UC_CTL	LINDA_EPB_UC_LOC ( 0 )
+#define LINDA_EPB_UC_CTL_WRITE	1
+#define LINDA_EPB_UC_CTL_READ	2
+#define LINDA_EPB_UC_ADDR_LO	LINDA_EPB_UC_LOC ( 2 )
+#define LINDA_EPB_UC_ADDR_HI	LINDA_EPB_UC_LOC ( 3 )
+#define LINDA_EPB_UC_DATA	LINDA_EPB_UC_LOC ( 4 )
+#define LINDA_EPB_UC_CHUNK_SIZE	64
+
+extern uint8_t linda_ib_fw[8192];
+
+/** Maximum time to wait for "trim done" signal, in ms */
+#define LINDA_TRIM_DONE_MAX_WAIT_MS 1000
+
+/** Linda link states */
+enum linda_link_state {
+	LINDA_LINK_STATE_DOWN = 0,
+	LINDA_LINK_STATE_INIT = 1,
+	LINDA_LINK_STATE_ARM = 2,
+	LINDA_LINK_STATE_ACTIVE = 3,
+	LINDA_LINK_STATE_ACT_DEFER = 4,
+};
+
+/** Maximum time to wait for link state changes, in us */
+#define LINDA_LINK_STATE_MAX_WAIT_US 20
+
+#endif /* _LINDA_H */
diff -pruN 1.0.0+git-20190125.36a4c85-5.1/src/drivers/infiniband/mlx_utils_flexboot/src/mlx_memory_priv.c 1.21.1+git-20220113.fbbdc3926-0ubuntu1/src/drivers/infiniband/mlx_utils_flexboot/src/mlx_memory_priv.c
--- 1.0.0+git-20190125.36a4c85-5.1/src/drivers/infiniband/mlx_utils_flexboot/src/mlx_memory_priv.c	2019-02-09 16:03:59.000000000 +0000
+++ 1.21.1+git-20220113.fbbdc3926-0ubuntu1/src/drivers/infiniband/mlx_utils_flexboot/src/mlx_memory_priv.c	2022-01-13 13:43:08.000000000 +0000
@@ -61,7 +61,7 @@ mlx_memory_alloc_dma_priv(
 					)
 {
 	mlx_status status = MLX_SUCCESS;
-	*ptr = malloc_dma(size, align);
+	*ptr = malloc_phys(size, align);
 	if (*ptr == NULL) {
 		status = MLX_OUT_OF_RESOURCES;
 	} else {
@@ -78,7 +78,7 @@ mlx_memory_free_dma_priv(
 					)
 {
 	mlx_status status = MLX_SUCCESS;
-	free_dma(ptr, size);
+	free_phys(ptr, size);
 	return status;
 }
 mlx_status
diff -pruN 1.0.0+git-20190125.36a4c85-5.1/src/drivers/infiniband/mlx_utils_flexboot/src/mlx_pci_priv.c 1.21.1+git-20220113.fbbdc3926-0ubuntu1/src/drivers/infiniband/mlx_utils_flexboot/src/mlx_pci_priv.c
--- 1.0.0+git-20190125.36a4c85-5.1/src/drivers/infiniband/mlx_utils_flexboot/src/mlx_pci_priv.c	2019-02-09 16:03:59.000000000 +0000
+++ 1.21.1+git-20220113.fbbdc3926-0ubuntu1/src/drivers/infiniband/mlx_utils_flexboot/src/mlx_pci_priv.c	2022-01-13 13:43:08.000000000 +0000
@@ -115,7 +115,7 @@ mlx_pci_init_priv(
 	mlx_status status = MLX_SUCCESS;
 	adjust_pci_device ( utils->pci );
 #ifdef DEVICE_CX3
-	utils->config = ioremap ( pci_bar_start ( utils->pci, PCI_BASE_ADDRESS_0),
+	utils->config = pci_ioremap ( utils->pci, pci_bar_start ( utils->pci, PCI_BASE_ADDRESS_0),
 			0x100000 );
 #endif
 	return status;
diff -pruN 1.0.0+git-20190125.36a4c85-5.1/src/drivers/infiniband/MT25218_PRM.h 1.21.1+git-20220113.fbbdc3926-0ubuntu1/src/drivers/infiniband/MT25218_PRM.h
--- 1.0.0+git-20190125.36a4c85-5.1/src/drivers/infiniband/MT25218_PRM.h	2019-02-09 16:03:59.000000000 +0000
+++ 1.21.1+git-20220113.fbbdc3926-0ubuntu1/src/drivers/infiniband/MT25218_PRM.h	2022-01-13 13:43:08.000000000 +0000
@@ -73,7 +73,7 @@ struct arbelprm_ud_address_vector_st {	/
 /* -------------- */
     pseudo_bit_t	rgid_31_0[0x00020];    /* Remote GID[31:0] if G bit is set. Must be set to 0x2 if G bit is cleared. */
 /* -------------- */
-}; 
+};
 
 /* Send doorbell */
 
@@ -88,7 +88,7 @@ struct arbelprm_send_doorbell_st {	/* Li
     pseudo_bit_t	reserved1[0x00002];
     pseudo_bit_t	qpn[0x00018];          /* QP number this doorbell is rung on */
 /* -------------- */
-}; 
+};
 
 /* ACCESS_LAM_inject_errors_input_modifier */
 
@@ -102,7 +102,7 @@ struct arbelprm_access_lam_inject_errors
     pseudo_bit_t	index0[0x00007];
     pseudo_bit_t	q0[0x00001];
 /* -------------- */
-}; 
+};
 
 /* ACCESS_LAM_inject_errors_input_parameter */
 
@@ -114,7 +114,7 @@ struct arbelprm_access_lam_inject_errors
     pseudo_bit_t	ra[0x00010];           /* Row Address */
     pseudo_bit_t	ca[0x00010];           /* Column Address */
 /* -------------- */
-}; 
+};
 
 /*  */
 
@@ -127,7 +127,7 @@ struct arbelprm_recv_wqe_segment_next_st
                                                   */
     pseudo_bit_t	reserved1[0x0001a];
 /* -------------- */
-}; 
+};
 
 /* Send wqe segment data inline */
 
@@ -141,7 +141,7 @@ struct arbelprm_wqe_segment_data_inline_
 /* -------------- */
     pseudo_bit_t	reserved2[0x00040];
 /* -------------- */
-}; 
+};
 
 /* Send wqe segment data ptr */
 
@@ -155,7 +155,7 @@ struct arbelprm_wqe_segment_data_ptr_st
 /* -------------- */
     pseudo_bit_t	local_address_l[0x00020];
 /* -------------- */
-}; 
+};
 
 /* Send wqe segment rd */
 
@@ -167,7 +167,7 @@ struct arbelprm_local_invalidate_segment
 /* -------------- */
     pseudo_bit_t	reserved2[0x000a0];
 /* -------------- */
-}; 
+};
 
 /* Fast_Registration_Segment */
 
@@ -197,7 +197,7 @@ struct arbelprm_fast_registration_segmen
 /* -------------- */
     pseudo_bit_t	reg_len_l[0x00020];    /* Region Length[31:0] */
 /* -------------- */
-}; 
+};
 
 /* Send wqe segment atomic */
 
@@ -210,7 +210,7 @@ struct arbelprm_wqe_segment_atomic_st {
 /* -------------- */
     pseudo_bit_t	compare_l[0x00020];
 /* -------------- */
-}; 
+};
 
 /* Send wqe segment remote address */
 
@@ -223,7 +223,7 @@ struct arbelprm_wqe_segment_remote_addre
 /* -------------- */
     pseudo_bit_t	reserved0[0x00020];
 /* -------------- */
-}; 
+};
 
 /* end wqe segment bind */
 
@@ -253,7 +253,7 @@ struct arbelprm_wqe_segment_bind_st {	/*
 /* -------------- */
     pseudo_bit_t	length_l[0x00020];
 /* -------------- */
-}; 
+};
 
 /* Send wqe segment ud */
 
@@ -267,7 +267,7 @@ struct arbelprm_wqe_segment_ud_st {	/* L
 /* -------------- */
     pseudo_bit_t	reserved1[0x00040];
 /* -------------- */
-}; 
+};
 
 /* Send wqe segment rd */
 
@@ -279,7 +279,7 @@ struct arbelprm_wqe_segment_rd_st {	/* L
 /* -------------- */
     pseudo_bit_t	reserved1[0x00040];
 /* -------------- */
-}; 
+};
 
 /* Send wqe segment ctrl */
 
@@ -296,7 +296,7 @@ struct arbelprm_wqe_segment_ctrl_send_st
 /* -------------- */
     pseudo_bit_t	immediate[0x00020];    /* If the OpCode encodes an operation with Immediate (RDMA-write/SEND), This field will hold the Immediate data to be sent. If the OpCode encodes send and invalidate operations, this field holds the Invalidation key to be inserted into the packet; otherwise, this field is reserved. */
 /* -------------- */
-}; 
+};
 
 /* Send wqe segment next */
 
@@ -338,7 +338,7 @@ struct arbelprm_wqe_segment_next_st {	/*
     pseudo_bit_t	always1[0x00001];
     pseudo_bit_t	reserved1[0x00018];
 /* -------------- */
-}; 
+};
 
 /* Address Path */
 
@@ -384,7 +384,7 @@ struct arbelprm_address_path_st {	/* Lit
 /* -------------- */
     pseudo_bit_t	rgid_31_0[0x00020];    /* Remote GID[31:0] */
 /* -------------- */
-}; 
+};
 
 /* HCA Command Register (HCR) */
 
@@ -414,7 +414,7 @@ struct arbelprm_hca_command_register_st
     pseudo_bit_t	status[0x00008];       /* Command execution status report. Valid only if command interface in under SW ownership (Go bit is cleared)
                                                  0 - command completed without error. If different than zero, command execution completed with error. Syndrom encoding is depended on command executed and is defined for each command */
 /* -------------- */
-}; 
+};
 
 /* CQ Doorbell */
 
@@ -435,7 +435,7 @@ struct arbelprm_cq_cmd_doorbell_st {	/*
 /* -------------- */
     pseudo_bit_t	cq_param[0x00020];     /* parameter to be used by CQ command */
 /* -------------- */
-}; 
+};
 
 /* RD-send doorbell */
 
@@ -449,7 +449,7 @@ struct arbelprm_rd_send_doorbell_st {	/*
 /* -------------- */
     struct arbelprm_send_doorbell_st	send_doorbell;/* Send Parameters */
 /* -------------- */
-}; 
+};
 
 /* Multicast Group Member QP */
 
@@ -458,7 +458,7 @@ struct arbelprm_mgmqp_st {	/* Little End
     pseudo_bit_t	reserved0[0x00007];
     pseudo_bit_t	qi[0x00001];           /* Qi: QPN_i is valid */
 /* -------------- */
-}; 
+};
 
 /* vsd */
 
@@ -575,7 +575,7 @@ struct arbelprm_vsd_st {	/* Little Endia
 /* -------------- */
     pseudo_bit_t	vsd_dw55[0x00020];
 /* -------------- */
-}; 
+};
 
 /* ACCESS_LAM_inject_errors */
 
@@ -586,7 +586,7 @@ struct arbelprm_access_lam_inject_errors
 /* -------------- */
     pseudo_bit_t	reserved0[0x00020];
 /* -------------- */
-}; 
+};
 
 /* Logical DIMM Information */
 
@@ -626,7 +626,7 @@ struct arbelprm_dimminfo_st {	/* Little
 /* -------------- */
     pseudo_bit_t	reserved4[0x00040];
 /* -------------- */
-}; 
+};
 
 /* UAR Parameters */
 
@@ -661,7 +661,7 @@ struct arbelprm_uar_params_st {	/* Littl
                                                  Number of entries in table is 2^log_max_uars. 
                                                  Table must be aligned to its size. */
 /* -------------- */
-}; 
+};
 
 /* Translation and Protection Tables Parameters */
 
@@ -695,7 +695,7 @@ struct arbelprm_tptparams_st {	/* Little
 /* -------------- */
     pseudo_bit_t	reserved3[0x00040];
 /* -------------- */
-}; 
+};
 
 /* Multicast Support Parameters */
 
@@ -729,7 +729,7 @@ struct arbelprm_multicastparam_st {	/* L
 /* -------------- */
     pseudo_bit_t	reserved5[0x00020];
 /* -------------- */
-}; 
+};
 
 /* QPC/EEC/CQC/EQC/RDB Parameters */
 
@@ -821,7 +821,7 @@ struct arbelprm_qpcbaseaddr_st {	/* Litt
 /* -------------- */
     pseudo_bit_t	reserved10[0x00040];
 /* -------------- */
-}; 
+};
 
 /* Header_Log_Register */
 
@@ -830,7 +830,7 @@ struct arbelprm_header_log_register_st {
 /* -------------- */
     pseudo_bit_t	reserved0[0x00060];
 /* -------------- */
-}; 
+};
 
 /* Performance Monitors */
 
@@ -862,7 +862,7 @@ struct arbelprm_performance_monitors_st
 /* -------------- */
     pseudo_bit_t	event_counter2[0x00020];/* Read/write event counter, counting events specified by EvCntl and EvCnt2 fields repsectively. When the event counter reaches is maximum value of 0xFFFFFF, the next event will cause it to roll over to zero, set F1 or F2 bit respectively and generate interrupt by I1 I2 bit respectively. */
 /* -------------- */
-}; 
+};
 
 /* Receive segment format */
 
@@ -876,7 +876,7 @@ struct arbelprm_wqe_segment_ctrl_recv_st
 /* -------------- */
     pseudo_bit_t	reserved4[0x00020];
 /* -------------- */
-}; 
+};
 
 /* MLX WQE segment format */
 
@@ -895,7 +895,7 @@ struct arbelprm_wqe_segment_ctrl_mlx_st
     pseudo_bit_t	vcrc[0x00010];         /* Packet's VCRC (if not 0 - otherwise computed by HW) */
     pseudo_bit_t	rlid[0x00010];         /* Destination LID (must match given headers) */
 /* -------------- */
-}; 
+};
 
 /* Send WQE segment format */
 
@@ -926,7 +926,7 @@ struct arbelprm_send_wqe_segment_st {	/*
 /* -------------- */
     pseudo_bit_t	reserved1[0x00200];
 /* -------------- */
-}; 
+};
 
 /* QP and EE Context Entry */
 
@@ -1118,7 +1118,7 @@ struct arbelprm_queue_pair_ee_context_en
 /* -------------- */
     pseudo_bit_t	reserved33[0x00040];
 /* -------------- */
-}; 
+};
 
 /* Clear Interrupt [63:0] */
 
@@ -1132,7 +1132,7 @@ struct arbelprm_clr_int_st {	/* Little E
                                                  Write transactions to this register will clear (de-assert) the virtual interrupt output pins of InfiniHost-III-EX. The value to be written in this register is obtained by executing QUERY_ADAPTER command on command interface after system boot. 
                                                  This register is write-only. Reading from this register will cause undefined result */
 /* -------------- */
-}; 
+};
 
 /* EQ_Arm_DB_Region */
 
@@ -1143,7 +1143,7 @@ struct arbelprm_eq_arm_db_region_st {	/*
     pseudo_bit_t	eq_x_arm_l[0x00020];   /* EQ[31:0]  X state.
                                                  This register is used to Arm EQs when setting the appropriate bits. */
 /* -------------- */
-}; 
+};
 
 /* EQ Set CI DBs Table */
 
@@ -1404,7 +1404,7 @@ struct arbelprm_eq_set_ci_table_st {	/*
 /* -------------- */
     pseudo_bit_t	reserved63[0x00020];
 /* -------------- */
-}; 
+};
 
 /* InfiniHost-III-EX Configuration Registers */
 
@@ -1415,7 +1415,7 @@ struct arbelprm_configuration_registers_
 /* -------------- */
     pseudo_bit_t	reserved1[0x3fcb20];
 /* -------------- */
-}; 
+};
 
 /* QP_DB_Record */
 
@@ -1429,7 +1429,7 @@ struct arbelprm_qp_db_record_st {	/* Lit
                                                  0x5 for SRQ */
     pseudo_bit_t	qp_number[0x00018];    /* QP number */
 /* -------------- */
-}; 
+};
 
 /* CQ_ARM_DB_Record */
 
@@ -1445,7 +1445,7 @@ struct arbelprm_cq_arm_db_record_st {	/*
     pseudo_bit_t	res[0x00003];          /* Must be 0x2 */
     pseudo_bit_t	cq_number[0x00018];    /* CQ number */
 /* -------------- */
-}; 
+};
 
 /* CQ_CI_DB_Record */
 
@@ -1456,7 +1456,7 @@ struct arbelprm_cq_ci_db_record_st {	/*
     pseudo_bit_t	res[0x00003];          /* Must be 0x1 */
     pseudo_bit_t	cq_number[0x00018];    /* CQ number */
 /* -------------- */
-}; 
+};
 
 /* Virtual_Physical_Mapping */
 
@@ -1472,7 +1472,7 @@ struct arbelprm_virtual_physical_mapping
     pseudo_bit_t	reserved1[0x00006];
     pseudo_bit_t	pa_l[0x00014];         /* Physical Address[31:12] */
 /* -------------- */
-}; 
+};
 
 /* MOD_STAT_CFG */
 
@@ -1485,7 +1485,7 @@ struct arbelprm_mod_stat_cfg_st {	/* Lit
 /* -------------- */
     pseudo_bit_t	reserved2[0x007e0];
 /* -------------- */
-}; 
+};
 
 /* SRQ Context */
 
@@ -1528,7 +1528,7 @@ struct arbelprm_srq_context_st {	/* Litt
 /* -------------- */
     pseudo_bit_t	reserved4[0x00060];
 /* -------------- */
-}; 
+};
 
 /* PBL */
 
@@ -1549,7 +1549,7 @@ struct arbelprm_pbl_st {	/* Little Endia
 /* -------------- */
     pseudo_bit_t	mtt_3_l[0x00020];      /* Fourth MTT[31:0] */
 /* -------------- */
-}; 
+};
 
 /* Performance Counters */
 
@@ -1580,7 +1580,7 @@ struct arbelprm_performance_counters_st
 /* -------------- */
     pseudo_bit_t	reserved3[0x00620];
 /* -------------- */
-}; 
+};
 
 /* Transport and CI Error Counters */
 
@@ -1724,7 +1724,7 @@ struct arbelprm_transport_and_ci_error_c
 /* -------------- */
     pseudo_bit_t	reserved12[0x002a0];
 /* -------------- */
-}; 
+};
 
 /* Event_data Field - HCR Completion Event */
 
@@ -1743,7 +1743,7 @@ struct arbelprm_hcr_completion_event_st
 /* -------------- */
     pseudo_bit_t	reserved3[0x00020];
 /* -------------- */
-}; 
+};
 
 /* Completion with Error CQE */
 
@@ -1791,7 +1791,7 @@ struct arbelprm_completion_with_error_st
                                                  0xFE - For completion with error on Receive Queues
                                                  0xFF - For completion with error on Send Queues */
 /* -------------- */
-}; 
+};
 
 /* Resize CQ Input Mailbox */
 
@@ -1814,7 +1814,7 @@ struct arbelprm_resize_cq_st {	/* Little
 /* -------------- */
     pseudo_bit_t	reserved4[0x00100];
 /* -------------- */
-}; 
+};
 
 /* MAD_IFC Input Modifier */
 
@@ -1826,7 +1826,7 @@ struct arbelprm_mad_ifc_input_modifier_s
     pseudo_bit_t	rlid[0x00010];         /* Remote (source) LID  from the received MAD.
                                                  This field is required for trap generation upon MKey/BKey validation. */
 /* -------------- */
-}; 
+};
 
 /* MAD_IFC Input Mailbox */
 
@@ -1863,7 +1863,7 @@ struct arbelprm_mad_ifc_st {	/* Little E
 /* -------------- */
     pseudo_bit_t	reserved5[0x004c0];
 /* -------------- */
-}; 
+};
 
 /* Query Debug Message */
 
@@ -1924,7 +1924,7 @@ struct arbelprm_query_debug_msg_st {	/*
 /* -------------- */
     pseudo_bit_t	reserved3[0x00400];
 /* -------------- */
-}; 
+};
 
 /* User Access Region */
 
@@ -1939,7 +1939,7 @@ struct arbelprm_uar_st {	/* Little Endia
 /* -------------- */
     pseudo_bit_t	reserved1[0x03ec0];
 /* -------------- */
-}; 
+};
 
 /* Receive doorbell */
 
@@ -1953,7 +1953,7 @@ struct arbelprm_receive_doorbell_st {	/*
     pseudo_bit_t	reserved3[0x00002];
     pseudo_bit_t	qpn[0x00018];          /* QP number or SRQ number this doorbell is rung on */
 /* -------------- */
-}; 
+};
 
 /* SET_IB Parameters */
 
@@ -1974,7 +1974,7 @@ struct arbelprm_set_ib_st {	/* Little En
 /* -------------- */
     pseudo_bit_t	reserved2[0x00180];
 /* -------------- */
-}; 
+};
 
 /* Multicast Group Member */
 
@@ -2014,7 +2014,7 @@ struct arbelprm_mgm_entry_st {	/* Little
 /* -------------- */
     struct arbelprm_mgmqp_st	mgmqp_7;   /* Multicast Group Member QP */
 /* -------------- */
-}; 
+};
 
 /* INIT_IB Parameters */
 
@@ -2068,7 +2068,7 @@ struct arbelprm_init_ib_st {	/* Little E
 /* -------------- */
     pseudo_bit_t	reserved5[0x006c0];
 /* -------------- */
-}; 
+};
 
 /* Query Device Limitations */
 
@@ -2285,7 +2285,7 @@ struct arbelprm_query_dev_lim_st {	/* Li
 /* -------------- */
     pseudo_bit_t	reserved41[0x002c0];
 /* -------------- */
-}; 
+};
 
 /* QUERY_ADAPTER Parameters Block */
 
@@ -2299,7 +2299,7 @@ struct arbelprm_query_adapter_st {	/* Li
 /* -------------- */
     struct arbelprm_vsd_st	vsd;
 /* -------------- */
-}; 
+};
 
 /* QUERY_FW Parameters Block */
 
@@ -2375,7 +2375,7 @@ struct arbelprm_query_fw_st {	/* Little
 /* -------------- */
     pseudo_bit_t	reserved6[0x004c0];
 /* -------------- */
-}; 
+};
 
 /* ACCESS_LAM */
 
@@ -2384,7 +2384,7 @@ struct arbelprm_access_lam_st {	/* Littl
 /* -------------- */
     pseudo_bit_t	reserved0[0x00080];
 /* -------------- */
-}; 
+};
 
 /* ENABLE_LAM Parameters Block */
 
@@ -2418,7 +2418,7 @@ struct arbelprm_enable_lam_st {	/* Littl
 /* -------------- */
     pseudo_bit_t	reserved2[0x00400];
 /* -------------- */
-}; 
+};
 
 /* Memory Access Parameters for UD Address Vector Table */
 
@@ -2430,7 +2430,7 @@ struct arbelprm_udavtable_memory_paramet
     pseudo_bit_t	xlation_en[0x00001];   /* When cleared, address is physical address and no translation will be done. When set, address is virtual. */
     pseudo_bit_t	reserved1[0x00002];
 /* -------------- */
-}; 
+};
 
 /* INIT_HCA & QUERY_HCA Parameters Block */
 
@@ -2495,7 +2495,7 @@ struct arbelprm_init_hca_st {	/* Little
 /* -------------- */
     pseudo_bit_t	reserved11[0x00600];
 /* -------------- */
-}; 
+};
 
 /* Event Queue Context Table Entry */
 
@@ -2555,7 +2555,7 @@ struct arbelprm_eqc_st {	/* Little Endia
 /* -------------- */
     pseudo_bit_t	reserved9[0x00080];
 /* -------------- */
-}; 
+};
 
 /* Memory Translation Table (MTT) Entry */
 
@@ -2566,7 +2566,7 @@ struct arbelprm_mtt_st {	/* Little Endia
     pseudo_bit_t	reserved0[0x0000b];
     pseudo_bit_t	ptag_l[0x00014];       /* Low-order bits of Physical tag. The size of the field depends on the page size of the region. Maximum PTAG size is 52 bits. */
 /* -------------- */
-}; 
+};
 
 /* Memory Protection Table (MPT) Entry */
 
@@ -2641,7 +2641,7 @@ struct arbelprm_mpt_st {	/* Little Endia
 /* -------------- */
     pseudo_bit_t	reserved8[0x00040];
 /* -------------- */
-}; 
+};
 
 /* Completion Queue Context Table Entry */
 
@@ -2719,7 +2719,7 @@ struct arbelprm_completion_queue_context
 /* -------------- */
     pseudo_bit_t	reserved8[0x00020];
 /* -------------- */
-}; 
+};
 
 /* GPIO_event_data */
 
@@ -2732,7 +2732,7 @@ struct arbelprm_gpio_event_data_st {	/*
 /* -------------- */
     pseudo_bit_t	reserved1[0x00020];
 /* -------------- */
-}; 
+};
 
 /* Event_data Field - QP/EE Events */
 
@@ -2749,7 +2749,7 @@ struct arbelprm_qp_ee_event_st {	/* Litt
 /* -------------- */
     pseudo_bit_t	reserved4[0x00060];
 /* -------------- */
-}; 
+};
 
 /* InfiniHost-III-EX Type0 Configuration Header */
 
@@ -2947,7 +2947,7 @@ struct arbelprm_mt25208_type0_st {	/* Li
 /* -------------- */
     pseudo_bit_t	reserved13[0x006a0];
 /* -------------- */
-}; 
+};
 
 /* Event Data Field - Performance Monitor */
 
@@ -2965,7 +2965,7 @@ struct arbelprm_performance_monitor_even
 /* -------------- */
     pseudo_bit_t	reserved1[0x00040];
 /* -------------- */
-}; 
+};
 
 /* Event_data Field - Page Faults */
 
@@ -2989,7 +2989,7 @@ struct arbelprm_page_fault_event_data_st
 /* -------------- */
     pseudo_bit_t	prefetch_len[0x00020]; /* Indicates how many subsequent pages in the same memory region/window will be accessed by the following transaction after this page fault is resolved. measured in bytes. SW can use this information in order to page-in the subsequent pages if they are not present. */
 /* -------------- */
-}; 
+};
 
 /* WQE segments format */
 
@@ -3006,7 +3006,7 @@ struct arbelprm_wqe_segment_st {	/* Litt
 /* -------------- */
     pseudo_bit_t	reserved2[0x00080];
 /* -------------- */
-}; 
+};
 
 /* Event_data Field - Port State Change */
 
@@ -3019,7 +3019,7 @@ struct arbelprm_port_state_change_st {	/
 /* -------------- */
     pseudo_bit_t	reserved3[0x00060];
 /* -------------- */
-}; 
+};
 
 /* Event_data Field - Completion Queue Error */
 
@@ -3036,7 +3036,7 @@ struct arbelprm_completion_queue_error_s
 /* -------------- */
     pseudo_bit_t	reserved3[0x00060];
 /* -------------- */
-}; 
+};
 
 /* Event_data Field - Completion Event */
 
@@ -3046,7 +3046,7 @@ struct arbelprm_completion_event_st {	/*
 /* -------------- */
     pseudo_bit_t	reserved1[0x000a0];
 /* -------------- */
-}; 
+};
 
 /* Event Queue Entry */
 
@@ -3065,7 +3065,7 @@ struct arbelprm_event_queue_entry_st {	/
                                                  1 HW */
     pseudo_bit_t	reserved3[0x00018];
 /* -------------- */
-}; 
+};
 
 /* QP/EE State Transitions Command Parameters */
 
@@ -3078,7 +3078,7 @@ struct arbelprm_qp_ee_state_transitions_
 /* -------------- */
     pseudo_bit_t	reserved1[0x009c0];
 /* -------------- */
-}; 
+};
 
 /* Completion Queue Entry Format */
 
@@ -3131,7 +3131,7 @@ struct arbelprm_completion_queue_entry_s
                                                  0xFE - For completion with error on Receive Queues
                                                  0xFF - For completion with error on Send Queues */
 /* -------------- */
-}; 
+};
 
 /*  */
 
@@ -3152,7 +3152,7 @@ struct arbelprm_ecc_detect_event_data_st
     pseudo_bit_t	err_ra[0x00010];
     pseudo_bit_t	err_ca[0x00010];
 /* -------------- */
-}; 
+};
 
 /* Event_data Field - ECC Detection Event */
 
@@ -3177,7 +3177,7 @@ struct arbelprm_scrubbing_event_st {	/*
     pseudo_bit_t	err_ra[0x00010];       /* Error row address */
     pseudo_bit_t	err_ca[0x00010];       /* Error column address */
 /* -------------- */
-}; 
+};
 
 /* Miscellaneous Counters */
 
@@ -3186,28 +3186,28 @@ struct arbelprm_misc_counters_st {	/* Li
 /* -------------- */
     pseudo_bit_t	reserved0[0x007e0];
 /* -------------- */
-}; 
+};
 
 /* LAM_EN Output Parameter */
 
 struct arbelprm_lam_en_out_param_st {	/* Little Endian */
     pseudo_bit_t	reserved0[0x00040];
 /* -------------- */
-}; 
+};
 
 /* Extended_Completion_Queue_Entry */
 
 struct arbelprm_extended_completion_queue_entry_st {	/* Little Endian */
     pseudo_bit_t	reserved0[0x00020];
 /* -------------- */
-}; 
+};
 
 /*  */
 
 struct arbelprm_eq_cmd_doorbell_st {	/* Little Endian */
     pseudo_bit_t	reserved0[0x00020];
 /* -------------- */
-}; 
+};
 
 /* 0 */
 
@@ -3456,5 +3456,5 @@ struct arbelprm_arbel_prm_st {	/* Little
 /* -------------- */
     pseudo_bit_t	reserved59[0xffcfc0];
 /* -------------- */
-}; 
+};
 #endif /* H_prefix_arbelprm_bits_fixnames_MT25218_PRM_csp_H */
diff -pruN 1.0.0+git-20190125.36a4c85-5.1/src/drivers/infiniband/MT25408_PRM.h 1.21.1+git-20220113.fbbdc3926-0ubuntu1/src/drivers/infiniband/MT25408_PRM.h
--- 1.0.0+git-20190125.36a4c85-5.1/src/drivers/infiniband/MT25408_PRM.h	2019-02-09 16:03:59.000000000 +0000
+++ 1.21.1+git-20220113.fbbdc3926-0ubuntu1/src/drivers/infiniband/MT25408_PRM.h	2022-01-13 13:43:08.000000000 +0000
@@ -47,7 +47,7 @@ struct hermonprm_ud_address_vector_st {
     pseudo_bit_t	reserved1[0x00008];
 /* -------------- */
     pseudo_bit_t	hop_limit[0x00008];    /* IPv6 hop limit */
-    pseudo_bit_t	max_stat_rate[0x00004];/* Maximum static rate control. 
+    pseudo_bit_t	max_stat_rate[0x00004];/* Maximum static rate control.
                                                  0 - 4X injection rate
                                                  1 - 1X injection rate
                                                  other - reserved
@@ -72,7 +72,7 @@ struct hermonprm_ud_address_vector_st {
 /* -------------- */
     pseudo_bit_t	rgid_31_0[0x00020];    /* Remote GID[31:0] if G bit is set. Must be set to 0x2 if G bit is cleared. */
 /* -------------- */
-}; 
+};
 
 /* Send doorbell */
 
@@ -87,7 +87,7 @@ struct hermonprm_send_doorbell_st {	/* L
     pseudo_bit_t	reserved1[0x00002];
     pseudo_bit_t	qpn[0x00018];          /* QP number this doorbell is rung on */
 /* -------------- */
-}; 
+};
 
 /* Send wqe segment data inline */
 
@@ -101,7 +101,7 @@ struct hermonprm_wqe_segment_data_inline
 /* -------------- */
     pseudo_bit_t	reserved2[0x00040];
 /* -------------- */
-}; 
+};
 
 /* Send wqe segment data ptr */
 
@@ -115,7 +115,7 @@ struct hermonprm_wqe_segment_data_ptr_st
 /* -------------- */
     pseudo_bit_t	local_address_l[0x00020];
 /* -------------- */
-}; 
+};
 
 /* Send wqe segment rd */
 
@@ -127,7 +127,7 @@ struct hermonprm_local_invalidate_segmen
 /* -------------- */
     pseudo_bit_t	reserved2[0x000a0];
 /* -------------- */
-}; 
+};
 
 /* Fast_Registration_Segment   ####michal - doesn't match PRM (fields were added, see below) new table size in bytes -  0x30 */
 
@@ -157,7 +157,7 @@ struct hermonprm_fast_registration_segme
 /* -------------- */
     pseudo_bit_t	reg_len_l[0x00020];    /* Region Length[31:0] */
 /* -------------- */
-}; 
+};
 
 /* Send wqe segment atomic */
 
@@ -170,7 +170,7 @@ struct hermonprm_wqe_segment_atomic_st {
 /* -------------- */
     pseudo_bit_t	compare_l[0x00020];
 /* -------------- */
-}; 
+};
 
 /* Send wqe segment remote address */
 
@@ -183,7 +183,7 @@ struct hermonprm_wqe_segment_remote_addr
 /* -------------- */
     pseudo_bit_t	reserved0[0x00020];
 /* -------------- */
-}; 
+};
 
 /* end wqe segment bind */
 
@@ -213,7 +213,7 @@ struct hermonprm_wqe_segment_bind_st {	/
 /* -------------- */
     pseudo_bit_t	length_l[0x00020];
 /* -------------- */
-}; 
+};
 
 /* Send wqe segment ud */
 
@@ -227,7 +227,7 @@ struct hermonprm_wqe_segment_ud_st {	/*
 /* -------------- */
     pseudo_bit_t	reserved1[0x00040];
 /* -------------- */
-}; 
+};
 
 /* Send wqe segment rd */
 
@@ -239,7 +239,7 @@ struct hermonprm_wqe_segment_rd_st {	/*
 /* -------------- */
     pseudo_bit_t	reserved1[0x00040];
 /* -------------- */
-}; 
+};
 
 /* Send wqe segment ctrl */
 
@@ -263,7 +263,7 @@ struct hermonprm_wqe_segment_ctrl_send_s
 /* -------------- */
     pseudo_bit_t	immediate[0x00020];    /* If the OpCode encodes an operation with Immediate (RDMA-write/SEND), This field will hold the Immediate data to be sent. If the OpCode encodes send and invalidate operations, this field holds the Invalidation key to be inserted into the packet; otherwise, this field is reserved. */
 /* -------------- */
-}; 
+};
 
 /* Address Path	# ###michal - match to PRM */
 
@@ -280,19 +280,19 @@ struct hermonprm_address_path_st {	/* Li
     pseudo_bit_t	reserved1[0x00008];
 /* -------------- */
     pseudo_bit_t	hop_limit[0x00008];    /* IPv6 hop limit */
-    pseudo_bit_t	max_stat_rate[0x00004];/* Maximum static rate control. 
-                                                 0 - 100% injection rate 
+    pseudo_bit_t	max_stat_rate[0x00004];/* Maximum static rate control.
+                                                 0 - 100% injection rate
                                                  1 - 25% injection rate
                                                  2 - 12.5% injection rate
                                                  3 - 50% injection rate
-                                                 7: 2.5 Gb/s. 
-                                                 8: 10 Gb/s. 
-                                                 9: 30 Gb/s. 
-                                                 10: 5 Gb/s. 
+                                                 7: 2.5 Gb/s.
+                                                 8: 10 Gb/s.
+                                                 9: 30 Gb/s.
+                                                 10: 5 Gb/s.
                                                  11: 20 Gb/s.
-                                                 12: 40 Gb/s. 
-                                                 13: 60 Gb/s. 
-                                                 14: 80 Gb/s. 
+                                                 12: 40 Gb/s.
+                                                 13: 60 Gb/s.
+                                                 14: 80 Gb/s.
                                                  15: 120 Gb/s. */
     pseudo_bit_t	reserved2[0x00004];
     pseudo_bit_t	mgid_index[0x00007];   /* Index to port GID table */
@@ -328,7 +328,7 @@ struct hermonprm_address_path_st {	/* Li
 /* -------------- */
     pseudo_bit_t	dmac_31_0[0x00020];
 /* -------------- */
-}; 
+};
 
 /* HCA Command Register (HCR)    #### michal - match PRM */
 
@@ -359,7 +359,7 @@ struct hermonprm_hca_command_register_st
     pseudo_bit_t	status[0x00008];       /* Command execution status report. Valid only if command interface in under SW ownership (Go bit is cleared)
                                                  0 - command completed without error. If different than zero, command execution completed with error. Syndrom encoding is depended on command executed and is defined for each command */
 /* -------------- */
-}; 
+};
 
 /* CQ Doorbell */
 
@@ -373,14 +373,14 @@ struct hermonprm_cq_cmd_doorbell_st {	/*
                                                  Other - Reserved */
     pseudo_bit_t	reserved0[0x00001];
     pseudo_bit_t	cmd_sn[0x00002];       /* Command Sequence Number - This field should be incremented upon receiving completion notification of the respective CQ.
-                                                 This transition is done by ringing Request notification for next Solicited, Request notification for next Solicited or Unsolicited 
+                                                 This transition is done by ringing Request notification for next Solicited, Request notification for next Solicited or Unsolicited
                                                  completion or Request notification for multiple completions doorbells after receiving completion notification.
                                                  This field is initialized to Zero */
     pseudo_bit_t	reserved1[0x00002];
 /* -------------- */
     pseudo_bit_t	cq_param[0x00020];     /* parameter to be used by CQ command */
 /* -------------- */
-}; 
+};
 
 /* RD-send doorbell */
 
@@ -394,7 +394,7 @@ struct hermonprm_rd_send_doorbell_st {	/
 /* -------------- */
     struct hermonprm_send_doorbell_st	send_doorbell;/* Send Parameters */
 /* -------------- */
-}; 
+};
 
 /* Multicast Group Member QP   #### michal - match PRM */
 
@@ -404,7 +404,7 @@ struct hermonprm_mgmqp_st {	/* Little En
     pseudo_bit_t	blck_lb[0x00001];      /* Block self-loopback messages arriving to this qp */
     pseudo_bit_t	qi[0x00001];           /* Qi: QPN_i is valid */
 /* -------------- */
-}; 
+};
 
 /* vsd */
 
@@ -521,7 +521,7 @@ struct hermonprm_vsd_st {	/* Little Endi
 /* -------------- */
     pseudo_bit_t	vsd_dw55[0x00020];
 /* -------------- */
-}; 
+};
 
 /* UAR Parameters */
 
@@ -535,7 +535,7 @@ struct hermonprm_uar_params_st {	/* Litt
 /* -------------- */
     pseudo_bit_t	reserved2[0x000a0];
 /* -------------- */
-}; 
+};
 
 /* Translation and Protection Tables Parameters */
 
@@ -552,7 +552,7 @@ struct hermonprm_tptparams_st {	/* Littl
 /* -------------- */
     pseudo_bit_t	log_dmpt_sz[0x00006];  /* Log (base 2) of the number of region/windows entries in the dMPT table. */
     pseudo_bit_t	reserved0[0x00002];
-    pseudo_bit_t	pfto[0x00005];         /* Page Fault RNR Timeout - 
+    pseudo_bit_t	pfto[0x00005];         /* Page Fault RNR Timeout -
                                                  The field returned in RNR Naks generated when a page fault is detected.
                                                  It has no effect when on-demand-paging is not used. */
     pseudo_bit_t	reserved1[0x00013];
@@ -575,7 +575,7 @@ struct hermonprm_tptparams_st {	/* Littl
                                                  Entry size is 64 bytes.
                                                  Table must be aligned to its size. */
 /* -------------- */
-}; 
+};
 
 /* Multicast Support Parameters   #### michal - match PRM */
 
@@ -584,14 +584,14 @@ struct hermonprm_multicastparam_st {	/*
                                                  The base address must be aligned to the entry size.
                                                  Address may be set to 0xFFFFFFFF if multicast is not supported. */
 /* -------------- */
-    pseudo_bit_t	mc_base_addr_l[0x00020];/* Base Address of the Multicast Table [31:0]. 
+    pseudo_bit_t	mc_base_addr_l[0x00020];/* Base Address of the Multicast Table [31:0].
                                                  The base address must be aligned to the entry size.
                                                  Address may be set to 0xFFFFFFFF if multicast is not supported. */
 /* -------------- */
     pseudo_bit_t	reserved0[0x00040];
 /* -------------- */
     pseudo_bit_t	log_mc_table_entry_sz[0x00005];/* Log2 of the Size of multicast group member (MGM) entry.
-                                                 Must be greater than 5 (to allow CTRL and GID sections). 
+                                                 Must be greater than 5 (to allow CTRL and GID sections).
                                                  That implies the number of QPs per MC table entry. */
     pseudo_bit_t	reserved1[0x0000b];
     pseudo_bit_t	reserved2[0x00010];
@@ -611,7 +611,7 @@ struct hermonprm_multicastparam_st {	/*
 /* -------------- */
     pseudo_bit_t	reserved6[0x00020];
 /* -------------- */
-}; 
+};
 
 /* QPC/EEC/CQC/EQC/RDB Parameters   #### michal - doesn't match PRM (field name are differs. see below) */
 
@@ -679,12 +679,12 @@ struct hermonprm_qpcbaseaddr_st {	/* Lit
 /* -------------- */
     pseudo_bit_t	log_num_rd[0x00003];   /* Log (base 2) of the maximum number of RdmaRdC entries per QP. This denotes the maximum number of outstanding reads/atomics as a responder. */
     pseudo_bit_t	reserved7[0x00002];
-    pseudo_bit_t	rdmardc_base_addr_l[0x0001b];/* rdmardc_base_addr_l: Base address of table that holds remote read and remote atomic requests [31:0]. 
+    pseudo_bit_t	rdmardc_base_addr_l[0x0001b];/* rdmardc_base_addr_l: Base address of table that holds remote read and remote atomic requests [31:0].
                                                  Table must be aligned to RDB entry size (32 bytes). */
 /* -------------- */
     pseudo_bit_t	reserved8[0x00040];
 /* -------------- */
-}; 
+};
 
 /* Header_Log_Register */
 
@@ -693,7 +693,7 @@ struct hermonprm_header_log_register_st
 /* -------------- */
     pseudo_bit_t	reserved0[0x00060];
 /* -------------- */
-}; 
+};
 
 /* Performance Monitors */
 
@@ -725,7 +725,7 @@ struct hermonprm_performance_monitors_st
 /* -------------- */
     pseudo_bit_t	event_counter2[0x00020];/* Read/write event counter, counting events specified by EvCntl and EvCnt2 fields repsectively. When the event counter reaches is maximum value of 0xFFFFFF, the next event will cause it to roll over to zero, set F1 or F2 bit respectively and generate interrupt by I1 I2 bit respectively. */
 /* -------------- */
-}; 
+};
 
 /* MLX WQE segment format */
 
@@ -751,7 +751,7 @@ struct hermonprm_wqe_segment_ctrl_mlx_st
     pseudo_bit_t	reserved5[0x00010];
     pseudo_bit_t	rlid[0x00010];         /* Destination LID (must match given headers) */
 /* -------------- */
-}; 
+};
 
 /* Send WQE segment format */
 
@@ -780,7 +780,7 @@ struct hermonprm_send_wqe_segment_st {	/
 /* -------------- */
     pseudo_bit_t	reserved1[0x00200];
 /* -------------- */
-}; 
+};
 
 /* QP and EE Context Entry */
 
@@ -833,7 +833,7 @@ struct hermonprm_queue_pair_ee_context_e
                                                  0x3 - 1024
                                                  0x4 - 2048
                                                  other - reserved
-                                                 
+
                                                  Should be configured to 0x4 for UD and MLX QPs. */
 /* -------------- */
     pseudo_bit_t	usr_page[0x00018];     /* UAR number to ring doorbells for this QP (aliased to doorbell and Blue Flame pages) */
@@ -883,7 +883,7 @@ struct hermonprm_queue_pair_ee_context_e
     pseudo_bit_t	reserved24[0x00008];
 /* -------------- */
     pseudo_bit_t	reserved25[0x00004];
-    pseudo_bit_t	ric[0x00001];          /* Invalid Credits. 
+    pseudo_bit_t	ric[0x00001];          /* Invalid Credits.
                                                  1 - place "Invalid Credits" to ACKs sent from this queue.
                                                  0 - ACKs report the actual number of end to end credits on the connection.
                                                  Not valid (reserved) in EE context.
@@ -895,12 +895,12 @@ struct hermonprm_queue_pair_ee_context_e
     pseudo_bit_t	rwe[0x00001];          /* If set - RDMA - write enabled on receive queue. Not valid (reserved) in EE context. */
     pseudo_bit_t	rre[0x00001];          /* If set - RDMA - read enabled on receive queue. Not valid (reserved) in EE context. */
     pseudo_bit_t	reserved28[0x00005];
-    pseudo_bit_t	rra_max[0x00003];      /* Maximum number of outstanding RDMA-read/Atomic operations allowed on receive queue is 2^RRA_Max. 
+    pseudo_bit_t	rra_max[0x00003];      /* Maximum number of outstanding RDMA-read/Atomic operations allowed on receive queue is 2^RRA_Max.
                                                  Must be 0 for EE context. */
     pseudo_bit_t	physical_function[0x00008];
 /* -------------- */
     pseudo_bit_t	next_rcv_psn[0x00018]; /* Next (expected) PSN on receive */
-    pseudo_bit_t	min_rnr_nak[0x00005];  /* Minimum RNR NAK timer value (TTTTT field encoding according to the IB spec Vol1 9.7.5.2.8). 
+    pseudo_bit_t	min_rnr_nak[0x00005];  /* Minimum RNR NAK timer value (TTTTT field encoding according to the IB spec Vol1 9.7.5.2.8).
                                                  Not valid (reserved) in EE context. */
     pseudo_bit_t	reserved30[0x00003];
 /* -------------- */
@@ -919,7 +919,7 @@ struct hermonprm_queue_pair_ee_context_e
                                                  On send datagrams, if Q_Key[31] specified in the WQE is set, then this Q_Key will be transmitted in the outgoing message.
                                                  Not valid (reserved) in EE context. */
 /* -------------- */
-    pseudo_bit_t	srqn[0x00018];         /* SRQN - Shared Receive Queue Number - specifies the SRQ number from which the QP dequeues receive descriptors. 
+    pseudo_bit_t	srqn[0x00018];         /* SRQN - Shared Receive Queue Number - specifies the SRQ number from which the QP dequeues receive descriptors.
                                                  SRQN is valid only if SRQ bit is set. Not valid (reserved) in EE context. */
     pseudo_bit_t	srq[0x00001];          /* SRQ - Shared Receive Queue. If this bit is set, then the QP is associated with a SRQ. Not valid (reserved) in EE context. */
     pseudo_bit_t	reserved34[0x00007];
@@ -983,7 +983,7 @@ struct hermonprm_queue_pair_ee_context_e
 /* -------------- */
     pseudo_bit_t	reserved48[0x000c0];
 /* -------------- */
-}; 
+};
 
 /*  */
 
@@ -993,21 +993,21 @@ struct hermonprm_mcg_qp_dw_st {	/* Littl
     pseudo_bit_t	blck_lb[0x00001];
     pseudo_bit_t	reserved1[0x00001];
 /* -------------- */
-}; 
+};
 
 /* Clear Interrupt [63:0]              #### michal - match to PRM */
 
 struct hermonprm_clr_int_st {	/* Little Endian */
     pseudo_bit_t	clr_int_h[0x00020];    /* Clear Interrupt [63:32]
-                                                 Write transactions to this register will clear (de-assert) the virtual interrupt output pins of InfiniHost-III-EX. The value to be written in this register is obtained by executing QUERY_ADAPTER command on command interface after system boot. 
+                                                 Write transactions to this register will clear (de-assert) the virtual interrupt output pins of InfiniHost-III-EX. The value to be written in this register is obtained by executing QUERY_ADAPTER command on command interface after system boot.
                                                  This register is write-only. Reading from this register will cause undefined result
                                                   */
 /* -------------- */
     pseudo_bit_t	clr_int_l[0x00020];    /* Clear Interrupt [31:0]
-                                                 Write transactions to this register will clear (de-assert) the virtual interrupt output pins of InfiniHost-III-EX. The value to be written in this register is obtained by executing QUERY_ADAPTER command on command interface after system boot. 
+                                                 Write transactions to this register will clear (de-assert) the virtual interrupt output pins of InfiniHost-III-EX. The value to be written in this register is obtained by executing QUERY_ADAPTER command on command interface after system boot.
                                                  This register is write-only. Reading from this register will cause undefined result */
 /* -------------- */
-}; 
+};
 
 /* EQ Set CI DBs Table */
 
@@ -1268,7 +1268,7 @@ struct hermonprm_eq_set_ci_table_st {	/*
 /* -------------- */
     pseudo_bit_t	reserved63[0x00020];
 /* -------------- */
-}; 
+};
 
 /* InfiniHost-III-EX Configuration Registers     #### michal - match to PRM */
 
@@ -1279,7 +1279,7 @@ struct hermonprm_configuration_registers
 /* -------------- */
     pseudo_bit_t	reserved1[0x3fcb20];
 /* -------------- */
-}; 
+};
 
 /* QP_DB_Record         ### michal = gdror fixed */
 
@@ -1287,7 +1287,7 @@ struct hermonprm_qp_db_record_st {	/* Li
     pseudo_bit_t	receive_wqe_counter[0x00010];/* Modulo-64K counter of WQEs posted to the QP since its creation. Should be initialized to zero. */
     pseudo_bit_t	reserved0[0x00010];
 /* -------------- */
-}; 
+};
 
 /* CQ_ARM_DB_Record */
 
@@ -1303,7 +1303,7 @@ struct hermonprm_cq_arm_db_record_st {	/
     pseudo_bit_t	res[0x00003];          /* Must be 0x2 */
     pseudo_bit_t	cq_number[0x00018];    /* CQ number */
 /* -------------- */
-}; 
+};
 
 /* CQ_CI_DB_Record */
 
@@ -1314,7 +1314,7 @@ struct hermonprm_cq_ci_db_record_st {	/*
     pseudo_bit_t	res[0x00003];          /* Must be 0x1 */
     pseudo_bit_t	cq_number[0x00018];    /* CQ number */
 /* -------------- */
-}; 
+};
 
 /* Virtual_Physical_Mapping */
 
@@ -1330,7 +1330,7 @@ struct hermonprm_virtual_physical_mappin
     pseudo_bit_t	reserved1[0x00006];
     pseudo_bit_t	pa_l[0x00014];         /* Physical Address[31:12] */
 /* -------------- */
-}; 
+};
 
 /* MOD_STAT_CFG            #### michal - gdror fix */
 
@@ -1518,7 +1518,7 @@ struct hermonprm_srq_context_st {	/* Lit
     pseudo_bit_t	reserved10[0x00002];
     pseudo_bit_t	db_record_addr_l[0x0001e];/* SRQ DB Record physical address [31:2] */
 /* -------------- */
-}; 
+};
 
 /* PBL */
 
@@ -1539,7 +1539,7 @@ struct hermonprm_pbl_st {	/* Little Endi
 /* -------------- */
     pseudo_bit_t	mtt_3_l[0x00020];      /* Fourth MTT[31:0] */
 /* -------------- */
-}; 
+};
 
 /* Performance Counters   #### michal - gdror fixed */
 
@@ -1554,7 +1554,7 @@ struct hermonprm_performance_counters_st
 /* -------------- */
     pseudo_bit_t	reserved4[0x00620];
 /* -------------- */
-}; 
+};
 
 /* Transport and CI Error Counters */
 
@@ -1575,10 +1575,10 @@ struct hermonprm_transport_and_ci_error_
 /* -------------- */
     pseudo_bit_t	sq_num_lpe[0x00020];   /* Requester - number of local protection errors */
 /* -------------- */
-    pseudo_bit_t	rq_num_wrfe[0x00020];  /* Responder - number of CQEs with error. 
+    pseudo_bit_t	rq_num_wrfe[0x00020];  /* Responder - number of CQEs with error.
                                                  Incremented each time a CQE with error is generated */
 /* -------------- */
-    pseudo_bit_t	sq_num_wrfe[0x00020];  /* Requester - number of CQEs with error. 
+    pseudo_bit_t	sq_num_wrfe[0x00020];  /* Requester - number of CQEs with error.
                                                  Incremented each time a CQE with error is generated */
 /* -------------- */
     pseudo_bit_t	reserved0[0x00020];
@@ -1698,7 +1698,7 @@ struct hermonprm_transport_and_ci_error_
 /* -------------- */
     pseudo_bit_t	reserved12[0x002a0];
 /* -------------- */
-}; 
+};
 
 /* Event_data Field - HCR Completion Event   #### michal - match PRM */
 
@@ -1717,7 +1717,7 @@ struct hermonprm_hcr_completion_event_st
 /* -------------- */
     pseudo_bit_t	reserved3[0x00020];
 /* -------------- */
-}; 
+};
 
 /* Completion with Error CQE             #### michal - gdror fixed */
 
@@ -1732,7 +1732,7 @@ struct hermonprm_completion_with_error_s
                                                          0x02 - Local QP Operation Error
                                                          0x03 - Local EE Context Operation Error
                                                          0x04 - Local Protection Error
-                                                         0x05 - Work Request Flushed Error 
+                                                         0x05 - Work Request Flushed Error
                                                          0x06 - Memory Window Bind Error
                                                          0x10 - Bad Response Error
                                                          0x11 - Local Access Error
@@ -1752,7 +1752,7 @@ struct hermonprm_completion_with_error_s
     pseudo_bit_t	wqe_counter[0x00010];
 /* -------------- */
     pseudo_bit_t	opcode[0x00005];       /* The opcode of WQE completion is reported for.
-                                                 
+
                                                  The following values are reported in case of completion with error:
                                                  0xFE - For completion with error on Receive Queues
                                                  0xFF - For completion with error on Send Queues */
@@ -1761,7 +1761,7 @@ struct hermonprm_completion_with_error_s
     pseudo_bit_t	owner[0x00001];        /* HW Flips this bit for every CQ warp around. Initialized to Zero. */
     pseudo_bit_t	reserved3[0x00018];
 /* -------------- */
-}; 
+};
 
 /* Resize CQ Input Mailbox */
 
@@ -1790,7 +1790,7 @@ struct hermonprm_resize_cq_st {	/* Littl
 /* -------------- */
     pseudo_bit_t	reserved10[0x00100];
 /* -------------- */
-}; 
+};
 
 /* MAD_IFC Input Modifier */
 
@@ -1802,14 +1802,14 @@ struct hermonprm_mad_ifc_input_modifier_
     pseudo_bit_t	rlid[0x00010];         /* Remote (source) LID  from the received MAD.
                                                  This field is required for trap generation upon MKey/BKey validation. */
 /* -------------- */
-}; 
+};
 
 /* MAD_IFC Input Mailbox     ###michal -gdror fixed */
 
 struct hermonprm_mad_ifc_st {	/* Little Endian */
     pseudo_bit_t	request_mad_packet[64][0x00020];/* Request MAD Packet (256bytes) */
 /* -------------- */
-    pseudo_bit_t	my_qpn[0x00018];       /* Destination QP number from the received MAD. 
+    pseudo_bit_t	my_qpn[0x00018];       /* Destination QP number from the received MAD.
                                                  This field is reserved if Mad_extended_info indication in the input modifier is clear. */
     pseudo_bit_t	reserved0[0x00008];
 /* -------------- */
@@ -1822,25 +1822,25 @@ struct hermonprm_mad_ifc_st {	/* Little
     pseudo_bit_t	reserved3[0x00010];
     pseudo_bit_t	ml_path[0x00007];      /* My (destination) LID path bits  from the received MAD.
                                                  This field is reserved if Mad_extended_info indication in the input modifier is clear. */
-    pseudo_bit_t	g[0x00001];            /* If set, the GRH field in valid. 
+    pseudo_bit_t	g[0x00001];            /* If set, the GRH field in valid.
                                                  This field is reserved if Mad_extended_info indication in the input modifier is clear. */
     pseudo_bit_t	reserved4[0x00004];
     pseudo_bit_t	sl[0x00004];           /* Service Level of the received MAD.
                                                  This field is reserved if Mad_extended_info indication in the input modifier is clear. */
 /* -------------- */
-    pseudo_bit_t	pkey_indx[0x00010];    /* Index in PKey table that matches PKey of the received MAD. 
+    pseudo_bit_t	pkey_indx[0x00010];    /* Index in PKey table that matches PKey of the received MAD.
                                                  This field is reserved if Mad_extended_info indication in the input modifier is clear. */
     pseudo_bit_t	reserved5[0x00010];
 /* -------------- */
     pseudo_bit_t	reserved6[0x00160];
 /* -------------- */
-    pseudo_bit_t	grh[10][0x00020];      /* The GRH field of the MAD packet that was scattered to the first 40 bytes pointed to by the scatter list. 
-                                                 Valid if Mad_extended_info bit (in the input modifier) and g bit are set. 
+    pseudo_bit_t	grh[10][0x00020];      /* The GRH field of the MAD packet that was scattered to the first 40 bytes pointed to by the scatter list.
+                                                 Valid if Mad_extended_info bit (in the input modifier) and g bit are set.
                                                  Otherwise this field is reserved. */
 /* -------------- */
     pseudo_bit_t	reserved7[0x004c0];
 /* -------------- */
-}; 
+};
 
 /* Query Debug Message     #### michal - gdror fixed */
 
@@ -1899,7 +1899,7 @@ struct hermonprm_query_debug_msg_st {	/*
 /* -------------- */
     pseudo_bit_t	reserved4[0x003c0];
 /* -------------- */
-}; 
+};
 
 /* User Access Region */
 
@@ -1914,7 +1914,7 @@ struct hermonprm_uar_st {	/* Little Endi
 /* -------------- */
     pseudo_bit_t	reserved1[0x03ec0];
 /* -------------- */
-}; 
+};
 
 /* Receive doorbell */
 
@@ -1928,7 +1928,7 @@ struct hermonprm_receive_doorbell_st {	/
     pseudo_bit_t	reserved3[0x00002];
     pseudo_bit_t	qpn[0x00018];          /* QP number or SRQ number this doorbell is rung on */
 /* -------------- */
-}; 
+};
 
 /* SET_IB Parameters */
 
@@ -1949,7 +1949,7 @@ struct hermonprm_set_ib_st {	/* Little E
 /* -------------- */
     pseudo_bit_t	reserved2[0x00180];
 /* -------------- */
-}; 
+};
 
 /* Multicast Group Member    #### michal - gdror fixed */
 
@@ -1989,7 +1989,7 @@ struct hermonprm_mgm_entry_st {	/* Littl
 /* -------------- */
     struct hermonprm_mgmqp_st	mgmqp_7;   /* Multicast Group Member QP */
 /* -------------- */
-}; 
+};
 
 /* INIT_PORT Parameters    #### michal - match PRM */
 
@@ -2041,7 +2041,7 @@ struct hermonprm_init_port_st {	/* Littl
 /* -------------- */
     pseudo_bit_t	reserved5[0x006c0];
 /* -------------- */
-}; 
+};
 
 /* Query Device Capablities     #### michal - gdror fixed */
 
@@ -2267,7 +2267,7 @@ struct hermonprm_query_dev_cap_st {	/* L
 /* -------------- */
     pseudo_bit_t	reserved46[0x002c0];
 /* -------------- */
-}; 
+};
 
 /* QUERY_ADAPTER Parameters Block    #### michal - gdror fixed */
 
@@ -2281,7 +2281,7 @@ struct hermonprm_query_adapter_st {	/* L
 /* -------------- */
     struct hermonprm_vsd_st	vsd;         /* ###michal- this field was replaced by 2 fields : vsd .1664; vsd(continued/psid .128; */
 /* -------------- */
-}; 
+};
 
 /* QUERY_FW Parameters Block      #### michal - doesn't match PRM */
 
@@ -2298,7 +2298,7 @@ struct hermonprm_query_fw_st {	/* Little
     pseudo_bit_t	log_max_outstanding_cmd[0x00008];/* Log2 of the maximum number of commands the HCR can support simultaneously */
     pseudo_bit_t	reserved1[0x00017];
     pseudo_bit_t	dt[0x00001];           /* Debug Trace Support
-                                                 0 - Debug trace is not supported 
+                                                 0 - Debug trace is not supported
                                                  1 - Debug trace is supported */
 /* -------------- */
     pseudo_bit_t	reserved2[0x00001];
@@ -2346,7 +2346,7 @@ struct hermonprm_query_fw_st {	/* Little
 /* -------------- */
     pseudo_bit_t	reserved8[0x00600];
 /* -------------- */
-}; 
+};
 
 /* Memory Access Parameters for UD Address Vector Table */
 
@@ -2358,7 +2358,7 @@ struct hermonprm_udavtable_memory_parame
     pseudo_bit_t	xlation_en[0x00001];   /* When cleared, address is physical address and no translation will be done. When set, address is virtual. */
     pseudo_bit_t	reserved1[0x00002];
 /* -------------- */
-}; 
+};
 
 /* INIT_HCA & QUERY_HCA Parameters Block ####michal-doesn't match PRM (see differs below) new size in bytes:0x300 */
 
@@ -2407,7 +2407,7 @@ struct hermonprm_init_hca_st {	/* Little
 /* -------------- */
     pseudo_bit_t	reserved10[0x00600];
 /* -------------- */
-}; 
+};
 
 /* Event Queue Context Table Entry     #### michal - gdror fixed */
 
@@ -2454,19 +2454,19 @@ struct hermonprm_eqc_st {	/* Little Endi
 /* -------------- */
     pseudo_bit_t	reserved12[0x00040];
 /* -------------- */
-    pseudo_bit_t	consumer_counter[0x00018];/* Consumer counter. The counter is incremented for each EQE polled from the EQ. 
-                                                  Must be 0x0 in EQ initialization. 
+    pseudo_bit_t	consumer_counter[0x00018];/* Consumer counter. The counter is incremented for each EQE polled from the EQ.
+                                                  Must be 0x0 in EQ initialization.
                                                   Maintained by HW (valid for the QUERY_EQ command only). */
     pseudo_bit_t	reserved13[0x00008];
 /* -------------- */
-    pseudo_bit_t	producer_counter[0x00018];/* Producer Coutner. The counter is incremented for each EQE that is written by the HW to the EQ. 
+    pseudo_bit_t	producer_counter[0x00018];/* Producer Coutner. The counter is incremented for each EQE that is written by the HW to the EQ.
                                                   EQ overrun is reported if Producer_counter + 1 equals to Consumer_counter and a EQE needs to be added.
                                                   Maintained by HW (valid for the QUERY_EQ command only) */
     pseudo_bit_t	reserved14[0x00008];
 /* -------------- */
     pseudo_bit_t	reserved15[0x00080];
 /* -------------- */
-}; 
+};
 
 /* Memory Translation Table (MTT) Entry     #### michal - match to PRM */
 
@@ -2477,7 +2477,7 @@ struct hermonprm_mtt_st {	/* Little Endi
     pseudo_bit_t	reserved0[0x00002];
     pseudo_bit_t	ptag_l[0x0001d];       /* Low-order bits of Physical tag. The size of the field depends on the page size of the region. Maximum PTAG size is 52 bits. */
 /* -------------- */
-}; 
+};
 
 /* Memory Protection Table (MPT) Entry   ### doesn't match PRM (new fields were added). new size in bytes : 0x54 */
 
@@ -2547,7 +2547,7 @@ struct hermonprm_mpt_st {	/* Little Endi
     pseudo_bit_t	mtt_fbo[0x00015];      /* First byte offset in the zero-based region - the first byte within the first block/page start address refers to. When mtt_rep is being used, fbo points within the replicated block (i.e. block-size x 2^mtt_rep) */
     pseudo_bit_t	reserved10[0x0000b];
 /* -------------- */
-}; 
+};
 
 /* Completion Queue Context Table Entry	#### michal - match PRM */
 
@@ -2559,7 +2559,7 @@ struct hermonprm_completion_queue_contex
                                                  0x6 - ARMED SOLICITED (Request Solicited Notification)
                                                  0xA - FIRED
                                                  other - reserved
-                                                 
+
                                                  Must be 0x0 in CQ initialization.
                                                  Valid for the QUERY_CQ and HW2SW_CQ commands only. */
     pseudo_bit_t	reserved1[0x00005];
@@ -2605,7 +2605,7 @@ struct hermonprm_completion_queue_contex
     pseudo_bit_t	reserved11[0x00008];
 /* -------------- */
     pseudo_bit_t	solicit_producer_indx[0x00018];/* Maintained by HW.
-                                                 Valid for QUERY_CQ and HW2SW_CQ commands only. 
+                                                 Valid for QUERY_CQ and HW2SW_CQ commands only.
                                                   */
     pseudo_bit_t	reserved12[0x00008];
 /* -------------- */
@@ -2627,7 +2627,7 @@ struct hermonprm_completion_queue_contex
     pseudo_bit_t	reserved17[0x00003];
     pseudo_bit_t	db_record_addr_l[0x0001d];/* CQ DB Record physical address [31:3] */
 /* -------------- */
-}; 
+};
 
 /* GPIO_event_data   #### michal - gdror fixed */
 
@@ -2640,7 +2640,7 @@ struct hermonprm_gpio_event_data_st {	/*
 /* -------------- */
     pseudo_bit_t	reserved1[0x00020];
 /* -------------- */
-}; 
+};
 
 /* Event_data Field - QP/EE Events     #### michal - doesn't match PRM */
 
@@ -2657,7 +2657,7 @@ struct hermonprm_qp_ee_event_st {	/* Lit
 /* -------------- */
     pseudo_bit_t	reserved4[0x00060];
 /* -------------- */
-}; 
+};
 
 /* InfiniHost-III-EX Type0 Configuration Header   ####michal - doesn't match PRM (new fields added, see below) */
 
@@ -2803,19 +2803,19 @@ struct hermonprm_mt25208_type0_st {	/* L
 /* -------------- */
     pseudo_bit_t	uncorrectable_error_status_register[0x00020];/* 0 Training Error Status
                                                  4 Data Link Protocol Error Status
-                                                 12 Poisoned TLP Status 
-                                                 13 Flow Control Protocol Error Status 
-                                                 14 Completion Timeout Status 
-                                                 15 Completer Abort Status 
-                                                 16 Unexpected Completion Status 
-                                                 17 Receiver Overflow Status 
-                                                 18 Malformed TLP Status 
-                                                 19 ECRC Error Status 
+                                                 12 Poisoned TLP Status
+                                                 13 Flow Control Protocol Error Status
+                                                 14 Completion Timeout Status
+                                                 15 Completer Abort Status
+                                                 16 Unexpected Completion Status
+                                                 17 Receiver Overflow Status
+                                                 18 Malformed TLP Status
+                                                 19 ECRC Error Status
                                                  20 Unsupported Request Error Status */
 /* -------------- */
     pseudo_bit_t	uncorrectable_error_mask_register[0x00020];/* 0 Training Error Mask
                                                  4 Data Link Protocol Error Mask
-                                                 12 Poisoned TLP Mask 
+                                                 12 Poisoned TLP Mask
                                                  13 Flow Control Protocol Error Mask
                                                  14 Completion Timeout Mask
                                                  15 Completer Abort Mask
@@ -2855,7 +2855,7 @@ struct hermonprm_mt25208_type0_st {	/* L
 /* -------------- */
     pseudo_bit_t	reserved13[0x006a0];
 /* -------------- */
-}; 
+};
 
 /* Event Data Field - Performance Monitor */
 
@@ -2873,7 +2873,7 @@ struct hermonprm_performance_monitor_eve
 /* -------------- */
     pseudo_bit_t	reserved1[0x00040];
 /* -------------- */
-}; 
+};
 
 /* Event_data Field - Page Faults */
 
@@ -2897,7 +2897,7 @@ struct hermonprm_page_fault_event_data_s
 /* -------------- */
     pseudo_bit_t	prefetch_len[0x00020]; /* Indicates how many subsequent pages in the same memory region/window will be accessed by the following transaction after this page fault is resolved. measured in bytes. SW can use this information in order to page-in the subsequent pages if they are not present. */
 /* -------------- */
-}; 
+};
 
 /* WQE segments format */
 
@@ -2914,7 +2914,7 @@ struct hermonprm_wqe_segment_st {	/* Lit
 /* -------------- */
     pseudo_bit_t	reserved2[0x00080];
 /* -------------- */
-}; 
+};
 
 /* Event_data Field - Port State Change   #### michal - match PRM */
 
@@ -2927,7 +2927,7 @@ struct hermonprm_port_state_change_st {
 /* -------------- */
     pseudo_bit_t	reserved3[0x00060];
 /* -------------- */
-}; 
+};
 
 /* Event_data Field - Completion Queue Error     #### michal - match PRM */
 
@@ -2944,7 +2944,7 @@ struct hermonprm_completion_queue_error_
 /* -------------- */
     pseudo_bit_t	reserved3[0x00060];
 /* -------------- */
-}; 
+};
 
 /* Event_data Field - Completion Event	#### michal - match PRM */
 
@@ -2954,12 +2954,12 @@ struct hermonprm_completion_event_st {	/
 /* -------------- */
     pseudo_bit_t	reserved1[0x000a0];
 /* -------------- */
-}; 
+};
 
 /* Event Queue Entry         #### michal - match to PRM */
 
 struct hermonprm_event_queue_entry_st {	/* Little Endian */
-    pseudo_bit_t	event_sub_type[0x00008];/* Event Sub Type. 
+    pseudo_bit_t	event_sub_type[0x00008];/* Event Sub Type.
                                                  Defined for events which have sub types, zero elsewhere. */
     pseudo_bit_t	reserved0[0x00008];
     pseudo_bit_t	event_type[0x00008];   /* Event Type */
@@ -2968,12 +2968,12 @@ struct hermonprm_event_queue_entry_st {
     pseudo_bit_t	event_data[6][0x00020];/* Delivers auxilary data to handle event. */
 /* -------------- */
     pseudo_bit_t	reserved2[0x00007];
-    pseudo_bit_t	owner[0x00001];        /* Owner of the entry 
-                                                 0 SW 
+    pseudo_bit_t	owner[0x00001];        /* Owner of the entry
+                                                 0 SW
                                                  1 HW */
     pseudo_bit_t	reserved3[0x00018];
 /* -------------- */
-}; 
+};
 
 /* QP/EE State Transitions Command Parameters  ###michal - doesn't match PRM (field name changed) */
 
@@ -2986,7 +2986,7 @@ struct hermonprm_qp_ee_state_transitions
 /* -------------- */
     pseudo_bit_t	reserved1[0x00800];
 /* -------------- */
-}; 
+};
 
 /* Completion Queue Entry Format        #### michal - fixed by gdror */
 
@@ -3010,7 +3010,7 @@ struct hermonprm_completion_queue_entry_
                                                  For IPoIB (UD) and RawEth CQEs this field contains the RSS hash function value.
                                                  Otherwise, this field is reserved. */
 /* -------------- */
-    pseudo_bit_t	srq_rqpn[0x00018];     /* For Responder UD QPs, Remote (source) QP number. 
+    pseudo_bit_t	srq_rqpn[0x00018];     /* For Responder UD QPs, Remote (source) QP number.
                                                  For Responder SRC QPs, SRQ number.
                                                  Otherwise, this field is reserved. */
     pseudo_bit_t	ml_path_mac_index[0x00007];/* For responder UD over IB CQE: These are the lower LMC bits of the DLID in an incoming UD packet, higher bits of this field, that are not part of the LMC bits are zeroed by HW. Invalid if incoming message DLID is the permissive LID or incoming message is multicast.
@@ -3028,17 +3028,17 @@ struct hermonprm_completion_queue_entry_
                                                   For responder UD over Ethernet and RawEth - it is VLAN-header[15:12]
                                                   Otherwise, this field is reserved. */
 /* -------------- */
-    pseudo_bit_t	smac31_0_rawether_ipoib_status[0x00020];/* For responder UD over Ethernet - source MAC[31:0] of the packet. 
-                                                  For responder RawEth and UD over IB - RawEth-IPoIB status {3 reserved, ipok,udp,tcp,ipv4opt,ipv6,ipv4vf,ipv4,rht(6),ipv6extmask(6),reserved(2),l2am,reserved(2),bfcs,reserved(2),enc} 
+    pseudo_bit_t	smac31_0_rawether_ipoib_status[0x00020];/* For responder UD over Ethernet - source MAC[31:0] of the packet.
+                                                  For responder RawEth and UD over IB - RawEth-IPoIB status {3 reserved, ipok,udp,tcp,ipv4opt,ipv6,ipv4vf,ipv4,rht(6),ipv6extmask(6),reserved(2),l2am,reserved(2),bfcs,reserved(2),enc}
                                                   Otherwise, this field is reserved. */
 /* -------------- */
-    pseudo_bit_t	byte_cnt[0x00020];     /* Byte count of data transferred. Applicable for RDMA-read, Atomic and all receive operations. completions. 
+    pseudo_bit_t	byte_cnt[0x00020];     /* Byte count of data transferred. Applicable for RDMA-read, Atomic and all receive operations. completions.
                                                  For Receive Queue that is subject for headers. separation, byte_cnt[31:24] specify number of bytes scattered to the first scatter entry (headers. length). Byte_cnt[23:0] specify total byte count received (including headers). */
 /* -------------- */
     pseudo_bit_t	checksum[0x00010];     /* Valid for RawEth and IPoIB only. */
     pseudo_bit_t	wqe_counter[0x00010];
 /* -------------- */
-    pseudo_bit_t	opcode[0x00005];       /* Send completions - same encoding as WQE. 
+    pseudo_bit_t	opcode[0x00005];       /* Send completions - same encoding as WQE.
                                                   Error coding is 0x1F
                                                   Receive:
                                                   0x0 - RDMA-Write with Immediate
@@ -3052,14 +3052,14 @@ struct hermonprm_completion_queue_entry_
     pseudo_bit_t	reserved1[0x00010];
     pseudo_bit_t	reserved2[0x00008];
 /* -------------- */
-}; 
+};
 
 /*  */
 
 struct hermonprm_mcg_qps_st {	/* Little Endian */
     struct hermonprm_mcg_qp_dw_st	dw[128];
 /* -------------- */
-}; 
+};
 
 /*  */
 
@@ -3084,7 +3084,7 @@ struct hermonprm_mcg_hdr_st {	/* Little
 /* -------------- */
     pseudo_bit_t	gid0[0x00020];
 /* -------------- */
-}; 
+};
 
 /*  */
 
@@ -3096,7 +3096,7 @@ struct hermonprm_sched_queue_context_st
     pseudo_bit_t	reserved0[0x00006];
     pseudo_bit_t	weight[0x00010];       /* Weight of this SchQ */
 /* -------------- */
-}; 
+};
 
 /*  */
 
@@ -3117,7 +3117,7 @@ struct hermonprm_ecc_detect_event_data_s
     pseudo_bit_t	err_ra[0x00010];
     pseudo_bit_t	err_ca[0x00010];
 /* -------------- */
-}; 
+};
 
 /* Event_data Field - ECC Detection Event */
 
@@ -3142,14 +3142,14 @@ struct hermonprm_scrubbing_event_st {	/*
     pseudo_bit_t	err_ra[0x00010];       /* Error row address */
     pseudo_bit_t	err_ca[0x00010];       /* Error column address */
 /* -------------- */
-}; 
+};
 
 /*  */
 
 struct hermonprm_eq_cmd_doorbell_st {	/* Little Endian */
     pseudo_bit_t	reserved0[0x00020];
 /* -------------- */
-}; 
+};
 
 /* 0 */
 
@@ -3400,5 +3400,5 @@ struct hermonprm_hermon_prm_st {	/* Litt
 /* -------------- */
     pseudo_bit_t	reserved64[0xffcfc0];
 /* -------------- */
-}; 
+};
 #endif /* H_prefix_hermonprm_bits_fixnames_MT25408_PRM_csp_H */
diff -pruN 1.0.0+git-20190125.36a4c85-5.1/src/drivers/infiniband/nodnic_prm.h 1.21.1+git-20220113.fbbdc3926-0ubuntu1/src/drivers/infiniband/nodnic_prm.h
--- 1.0.0+git-20190125.36a4c85-5.1/src/drivers/infiniband/nodnic_prm.h	2019-02-09 16:03:59.000000000 +0000
+++ 1.21.1+git-20220113.fbbdc3926-0ubuntu1/src/drivers/infiniband/nodnic_prm.h	2022-01-13 13:43:08.000000000 +0000
@@ -38,10 +38,10 @@ struct nodnic_wqe_segment_data_ptr_st {
 
 struct MLX_DECLARE_STRUCT ( nodnic_wqe_segment_data_ptr );
 
-#define HERMON_MAX_SCATTER 1
+#define NODNIC_MAX_SCATTER 1
 
 struct nodnic_recv_wqe {
-	struct nodnic_wqe_segment_data_ptr data[HERMON_MAX_SCATTER];
+	struct nodnic_wqe_segment_data_ptr data[NODNIC_MAX_SCATTER];
 } __attribute__ (( packed ));
 
 #endif /* SRC_DRIVERS_INFINIBAND_MLX_NODNIC_INCLUDE_PRM_NODNIC_PRM_H_ */
diff -pruN 1.0.0+git-20190125.36a4c85-5.1/src/drivers/infiniband/qib7322.c 1.21.1+git-20220113.fbbdc3926-0ubuntu1/src/drivers/infiniband/qib7322.c
--- 1.0.0+git-20190125.36a4c85-5.1/src/drivers/infiniband/qib7322.c	2019-02-09 16:03:59.000000000 +0000
+++ 1.21.1+git-20220113.fbbdc3926-0ubuntu1/src/drivers/infiniband/qib7322.c	2022-01-13 13:43:08.000000000 +0000
@@ -669,8 +669,8 @@ static int qib7322_init_send ( struct qi
 	}
 
 	/* Allocate space for the SendBufAvail array */
-	qib7322->sendbufavail = malloc_dma ( sizeof ( *qib7322->sendbufavail ),
-					     QIB7322_SENDBUFAVAIL_ALIGN );
+	qib7322->sendbufavail = malloc_phys ( sizeof ( *qib7322->sendbufavail ),
+					      QIB7322_SENDBUFAVAIL_ALIGN );
 	if ( ! qib7322->sendbufavail ) {
 		rc = -ENOMEM;
 		goto err_alloc_sendbufavail;
@@ -697,7 +697,7 @@ static int qib7322_init_send ( struct qi
 
 	return 0;
 
-	free_dma ( qib7322->sendbufavail, sizeof ( *qib7322->sendbufavail ) );
+	free_phys ( qib7322->sendbufavail, sizeof ( *qib7322->sendbufavail ) );
  err_alloc_sendbufavail:
 	qib7322_destroy_send_bufs ( qib7322, qib7322->send_bufs_vl15_port1 );
  err_create_send_bufs_vl15_port1:
@@ -724,7 +724,7 @@ static void qib7322_fini_send ( struct q
 	/* Ensure hardware has seen this disable */
 	qib7322_readq ( qib7322, &sendctrl, QIB_7322_SendCtrl_offset );
 
-	free_dma ( qib7322->sendbufavail, sizeof ( *qib7322->sendbufavail ) );
+	free_phys ( qib7322->sendbufavail, sizeof ( *qib7322->sendbufavail ) );
 	qib7322_destroy_send_bufs ( qib7322, qib7322->send_bufs_vl15_port1 );
 	qib7322_destroy_send_bufs ( qib7322, qib7322->send_bufs_vl15_port0 );
 	qib7322_destroy_send_bufs ( qib7322, qib7322->send_bufs_small );
@@ -767,8 +767,8 @@ static int qib7322_create_recv_wq ( stru
 	qib7322_wq->eager_cons = 0;
 
 	/* Allocate receive header buffer */
-	qib7322_wq->header = malloc_dma ( QIB7322_RECV_HEADERS_SIZE,
-					  QIB7322_RECV_HEADERS_ALIGN );
+	qib7322_wq->header = malloc_phys ( QIB7322_RECV_HEADERS_SIZE,
+					   QIB7322_RECV_HEADERS_ALIGN );
 	if ( ! qib7322_wq->header ) {
 		rc = -ENOMEM;
 		goto err_alloc_header;
@@ -810,7 +810,7 @@ static int qib7322_create_recv_wq ( stru
 	       virt_to_bus ( &qib7322_wq->header_prod ) );
 	return 0;
 
-	free_dma ( qib7322_wq->header, QIB7322_RECV_HEADERS_SIZE );
+	free_phys ( qib7322_wq->header, QIB7322_RECV_HEADERS_SIZE );
  err_alloc_header:
 	return rc;
 }
@@ -846,7 +846,7 @@ static void qib7322_destroy_recv_wq ( st
 	mb();
 
 	/* Free headers ring */
-	free_dma ( qib7322_wq->header, QIB7322_RECV_HEADERS_SIZE );
+	free_phys ( qib7322_wq->header, QIB7322_RECV_HEADERS_SIZE );
 }
 
 /**
@@ -2297,7 +2297,7 @@ static int qib7322_probe ( struct pci_de
 	adjust_pci_device ( pci );
 
 	/* Map PCI BARs */
-	qib7322->regs = ioremap ( pci->membase, QIB7322_BAR0_SIZE );
+	qib7322->regs = pci_ioremap ( pci, pci->membase, QIB7322_BAR0_SIZE );
 	DBGC2 ( qib7322, "QIB7322 %p has BAR at %08lx\n",
 		qib7322, pci->membase );
 
@@ -2348,6 +2348,7 @@ static int qib7322_probe ( struct pci_de
 		ibdev->dev = &pci->dev;
 		ibdev->op = &qib7322_ib_operations;
 		ibdev->port = ( QIB7322_PORT_BASE + i );
+		ibdev->ports = QIB7322_MAX_PORTS;
 		ibdev->link_width_enabled = ibdev->link_width_supported =
 			IB_LINK_WIDTH_4X; /* 1x does not work */
 		ibdev->link_speed_enabled = ibdev->link_speed_supported =
diff -pruN 1.0.0+git-20190125.36a4c85-5.1/src/drivers/linux/af_packet.c 1.21.1+git-20220113.fbbdc3926-0ubuntu1/src/drivers/linux/af_packet.c
--- 1.0.0+git-20190125.36a4c85-5.1/src/drivers/linux/af_packet.c	2019-02-09 16:03:59.000000000 +0000
+++ 1.21.1+git-20220113.fbbdc3926-0ubuntu1/src/drivers/linux/af_packet.c	2022-01-13 13:43:08.000000000 +0000
@@ -19,7 +19,7 @@
 #include <errno.h>
 #include <string.h>
 #include <stdio.h>
-#include <linux_api.h>
+#include <ipxe/linux_api.h>
 #include <ipxe/list.h>
 #include <ipxe/linux.h>
 #include <ipxe/malloc.h>
diff -pruN 1.0.0+git-20190125.36a4c85-5.1/src/drivers/linux/linux.c 1.21.1+git-20220113.fbbdc3926-0ubuntu1/src/drivers/linux/linux.c
--- 1.0.0+git-20190125.36a4c85-5.1/src/drivers/linux/linux.c	2019-02-09 16:03:59.000000000 +0000
+++ 1.21.1+git-20220113.fbbdc3926-0ubuntu1/src/drivers/linux/linux.c	2022-01-13 13:43:08.000000000 +0000
@@ -130,24 +130,48 @@ struct linux_setting *linux_find_setting
 	return result;
 }
 
-void linux_apply_settings(struct list_head *new_settings, struct settings *settings_block)
-{
-	struct linux_setting *setting;
+/**
+ * Apply Linux command-line settings
+ *
+ * @v list		List of command-line settings
+ * @v settings		Settings block
+ */
+void linux_apply_settings ( struct list_head *list,
+			    struct settings *settings ) {
+	struct linux_setting *lsetting;
+	struct settings *ignore;
+	struct setting setting;
 	int rc;
 
-	list_for_each_entry(setting, new_settings, list) {
+	list_for_each_entry ( lsetting, list, list ) {
+
 		/* Skip already applied settings */
-		if (setting->applied)
+		if ( lsetting->applied )
 			continue;
 
-		struct setting *s = find_setting(setting->name);
-		if (s) {
-			rc = storef_setting(settings_block, find_setting(setting->name), setting->value);
-			if (rc != 0)
-				DBG("linux storing setting '%s' = '%s' failed\n", setting->name, setting->value);
-			setting->applied = 1;
-		} else {
-			DBG("linux unknown setting '%s'\n", setting->name);
+		/* Parse setting name */
+		if ( ( rc = parse_setting_name ( lsetting->name,
+						 find_child_settings, &ignore,
+						 &setting ) ) != 0 ) {
+			DBGC ( settings, "Linux cannot parse %s: %s\n",
+			       lsetting->name, strerror ( rc ) );
+			continue;
 		}
+
+		/* Apply default type if not specified */
+		if ( ! setting.type )
+			setting.type = &setting_type_string;
+
+		/* Store setting */
+		if ( ( rc = storef_setting ( settings, &setting,
+					     lsetting->value ) ) != 0 ) {
+			DBGC ( settings, "Linux cannot set %s=\"%s\": %s\n",
+			       lsetting->name, lsetting->value,
+			       strerror ( rc ) );
+			continue;
+		}
+
+		/* Mark setting as applied */
+		lsetting->applied = 1;
 	}
 }
diff -pruN 1.0.0+git-20190125.36a4c85-5.1/src/drivers/linux/slirp.c 1.21.1+git-20220113.fbbdc3926-0ubuntu1/src/drivers/linux/slirp.c
--- 1.0.0+git-20190125.36a4c85-5.1/src/drivers/linux/slirp.c	1970-01-01 00:00:00.000000000 +0000
+++ 1.21.1+git-20220113.fbbdc3926-0ubuntu1/src/drivers/linux/slirp.c	2022-01-13 13:43:08.000000000 +0000
@@ -0,0 +1,552 @@
+/*
+ * Copyright (C) 2021 Michael Brown <mbrown@fensystems.co.uk>.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of the
+ * License, or any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+ * 02110-1301, USA.
+ */
+
+#include <stdio.h>
+#include <errno.h>
+#include <ipxe/netdevice.h>
+#include <ipxe/ethernet.h>
+#include <ipxe/if_ether.h>
+#include <ipxe/in.h>
+#include <ipxe/timer.h>
+#include <ipxe/retry.h>
+#include <ipxe/linux.h>
+#include <ipxe/linux_api.h>
+#include <ipxe/slirp.h>
+
+/** @file
+ *
+ * Linux Slirp network driver
+ *
+ */
+
+/** Maximum number of open file descriptors */
+#define SLIRP_MAX_FDS 128
+
+/** A Slirp network interface */
+struct slirp_nic {
+	/** The libslirp device object */
+	struct Slirp *slirp;
+	/** Polling file descriptor list */
+	struct pollfd pollfds[SLIRP_MAX_FDS];
+	/** Number of file descriptors */
+	unsigned int numfds;
+};
+
+/** A Slirp alarm timer */
+struct slirp_alarm {
+	/** Slirp network interface */
+	struct slirp_nic *slirp;
+	/** Retry timer */
+	struct retry_timer timer;
+	/** Callback function */
+	void ( __asmcall * callback ) ( void *opaque );
+	/** Opaque value for callback function */
+	void *opaque;
+};
+
+/** Default MAC address */
+static const uint8_t slirp_default_mac[ETH_ALEN] =
+	{ 0x52, 0x54, 0x00, 0x12, 0x34, 0x56 };
+
+/******************************************************************************
+ *
+ * Slirp interface
+ *
+ ******************************************************************************
+ */
+
+/**
+ * Send packet
+ *
+ * @v buf		Data buffer
+ * @v len		Length of data
+ * @v device		Device opaque pointer
+ * @ret len		Consumed length (or negative on error)
+ */
+static ssize_t __asmcall slirp_send_packet ( const void *buf, size_t len,
+					     void *device ) {
+	struct net_device *netdev = device;
+	struct io_buffer *iobuf;
+
+	/* Allocate I/O buffer */
+	iobuf = alloc_iob ( len );
+	if ( ! iobuf )
+		return -1;
+
+	/* Populate I/O buffer */
+	memcpy ( iob_put ( iobuf, len ), buf, len );
+
+	/* Hand off to network stack */
+	netdev_rx ( netdev, iobuf );
+
+	return len;
+}
+
+/**
+ * Print an error message
+ *
+ * @v msg		Error message
+ * @v device		Device opaque pointer
+ */
+static void __asmcall slirp_guest_error ( const char *msg, void *device ) {
+	struct net_device *netdev = device;
+	struct slirp_nic *slirp = netdev->priv;
+
+	DBGC ( slirp, "SLIRP %p error: %s\n", slirp, msg );
+}
+
+/**
+ * Get virtual clock
+ *
+ * @v device		Device opaque pointer
+ * @ret clock_ns	Clock time in nanoseconds
+ */
+static int64_t __asmcall slirp_clock_get_ns ( void *device __unused ) {
+	int64_t time;
+
+	time = currticks();
+	return ( time * ( 1000000 / TICKS_PER_MS ) );
+}
+
+/**
+ * Handle timer expiry
+ *
+ * @v timer		Retry timer
+ * @v over		Failure indicator
+ */
+static void slirp_expired ( struct retry_timer *timer, int over __unused ) {
+	struct slirp_alarm *alarm =
+		container_of ( timer, struct slirp_alarm, timer );
+	struct slirp_nic *slirp = alarm->slirp;
+
+	/* Notify callback */
+	DBGC ( slirp, "SLIRP %p timer fired\n", slirp );
+	alarm->callback ( alarm->opaque );
+}
+
+/**
+ * Create a new timer
+ *
+ * @v callback		Timer callback
+ * @v opaque		Timer opaque pointer
+ * @v device		Device opaque pointer
+ * @ret timer		Timer
+ */
+static void * __asmcall
+slirp_timer_new ( void ( __asmcall * callback ) ( void *opaque ),
+		  void *opaque, void *device ) {
+	struct net_device *netdev = device;
+	struct slirp_nic *slirp = netdev->priv;
+	struct slirp_alarm *alarm;
+
+	/* Allocate timer */
+	alarm = malloc ( sizeof ( *alarm ) );
+	if ( ! alarm ) {
+		DBGC ( slirp, "SLIRP %p could not allocate timer\n", slirp );
+		return NULL;
+	}
+
+	/* Initialise timer */
+	memset ( alarm, 0, sizeof ( *alarm ) );
+	alarm->slirp = slirp;
+	timer_init ( &alarm->timer, slirp_expired, NULL );
+	alarm->callback = callback;
+	alarm->opaque = opaque;
+	DBGC ( slirp, "SLIRP %p timer %p has callback %p (%p)\n",
+	       slirp, alarm, alarm->callback, alarm->opaque );
+
+	return alarm;
+}
+
+/**
+ * Delete a timer
+ *
+ * @v timer		Timer
+ * @v device		Device opaque pointer
+ */
+static void __asmcall slirp_timer_free ( void *timer, void *device ) {
+	struct net_device *netdev = device;
+	struct slirp_nic *slirp = netdev->priv;
+	struct slirp_alarm *alarm = timer;
+
+	/* Ignore timers that failed to allocate */
+	if ( ! alarm )
+		return;
+
+	/* Stop timer */
+	stop_timer ( &alarm->timer );
+
+	/* Free timer */
+	free ( alarm );
+	DBGC ( slirp, "SLIRP %p timer %p freed\n", slirp, alarm );
+}
+
+/**
+ * Set timer expiry time
+ *
+ * @v timer		Timer
+ * @v expire		Expiry time
+ * @v device		Device opaque pointer
+ */
+static void __asmcall slirp_timer_mod ( void *timer, int64_t expire,
+					void *device ) {
+	struct net_device *netdev = device;
+	struct slirp_nic *slirp = netdev->priv;
+	struct slirp_alarm *alarm = timer;
+	int64_t timeout_ms;
+	unsigned long timeout;
+
+	/* Ignore timers that failed to allocate */
+	if ( ! alarm )
+		return;
+
+	/* (Re)start timer */
+	timeout_ms = ( expire - ( currticks() / TICKS_PER_MS ) );
+	if ( timeout_ms < 0 )
+		timeout_ms = 0;
+	timeout = ( timeout_ms * TICKS_PER_MS );
+	start_timer_fixed ( &alarm->timer, timeout );
+	DBGC ( slirp, "SLIRP %p timer %p set for %ld ticks\n",
+	       slirp, alarm, timeout );
+}
+
+/**
+ * Register file descriptor for polling
+ *
+ * @v fd		File descriptor
+ * @v device		Device opaque pointer
+ */
+static void __asmcall slirp_register_poll_fd ( int fd, void *device ) {
+	struct net_device *netdev = device;
+	struct slirp_nic *slirp = netdev->priv;
+
+	DBGC ( slirp, "SLIRP %p registered FD %d\n", slirp, fd );
+}
+
+/**
+ * Unregister file descriptor
+ *
+ * @v fd		File descriptor
+ * @v device		Device opaque pointer
+ */
+static void __asmcall slirp_unregister_poll_fd ( int fd, void *device ) {
+	struct net_device *netdev = device;
+	struct slirp_nic *slirp = netdev->priv;
+
+	DBGC ( slirp, "SLIRP %p unregistered FD %d\n", slirp, fd );
+}
+
+/**
+ * Notify that new events are ready
+ *
+ * @v device		Device opaque pointer
+ */
+static void __asmcall slirp_notify ( void *device ) {
+	struct net_device *netdev = device;
+	struct slirp_nic *slirp = netdev->priv;
+
+	DBGC2 ( slirp, "SLIRP %p notified\n", slirp );
+}
+
+/** Slirp callbacks */
+static struct slirp_callbacks slirp_callbacks = {
+	.send_packet		= slirp_send_packet,
+	.guest_error		= slirp_guest_error,
+	.clock_get_ns		= slirp_clock_get_ns,
+	.timer_new		= slirp_timer_new,
+	.timer_free		= slirp_timer_free,
+	.timer_mod		= slirp_timer_mod,
+	.register_poll_fd	= slirp_register_poll_fd,
+	.unregister_poll_fd	= slirp_unregister_poll_fd,
+	.notify			= slirp_notify,
+};
+
+/******************************************************************************
+ *
+ * Network device interface
+ *
+ ******************************************************************************
+ */
+
+/**
+ * Open network device
+ *
+ * @v netdev		Network device
+ * @ret rc		Return status code
+ */
+static int slirp_open ( struct net_device *netdev ) {
+	struct slirp_nic *slirp = netdev->priv;
+
+	/* Nothing to do */
+	DBGC ( slirp, "SLIRP %p opened\n", slirp );
+
+	return 0;
+}
+
+/**
+ * Close network device
+ *
+ * @v netdev		Network device
+ */
+static void slirp_close ( struct net_device *netdev ) {
+	struct slirp_nic *slirp = netdev->priv;
+
+	/* Nothing to do */
+	DBGC ( slirp, "SLIRP %p closed\n", slirp );
+}
+
+/**
+ * Transmit packet
+ *
+ * @v netdev		Network device
+ * @v iobuf		I/O buffer
+ * @ret rc		Return status code
+ */
+static int slirp_transmit ( struct net_device *netdev,
+			    struct io_buffer *iobuf ) {
+	struct slirp_nic *slirp = netdev->priv;
+
+	/* Transmit packet */
+	linux_slirp_input ( slirp->slirp, iobuf->data, iob_len ( iobuf ) );
+	netdev_tx_complete ( netdev, iobuf );
+
+	return 0;
+}
+
+/**
+ * Add polling file descriptor
+ *
+ * @v fd		File descriptor
+ * @v events		Events of interest
+ * @v device		Device opaque pointer
+ * @ret index		File descriptor index
+ */
+static int __asmcall slirp_add_poll ( int fd, int events, void *device ) {
+	struct net_device *netdev = device;
+	struct slirp_nic *slirp = netdev->priv;
+	struct pollfd *pollfd;
+	unsigned int index;
+
+	/* Fail if too many descriptors are registered */
+	if ( slirp->numfds >= SLIRP_MAX_FDS ) {
+		DBGC ( slirp, "SLIRP %p too many file descriptors\n", slirp );
+		return -1;
+	}
+
+	/* Populate polling file descriptor */
+	index = slirp->numfds++;
+	pollfd = &slirp->pollfds[index];
+	pollfd->fd = fd;
+	pollfd->events = 0;
+	if ( events & SLIRP_EVENT_IN )
+		pollfd->events |= POLLIN;
+	if ( events & SLIRP_EVENT_OUT )
+		pollfd->events |= POLLOUT;
+	if ( events & SLIRP_EVENT_PRI )
+		pollfd->events |= POLLPRI;
+	if ( events & SLIRP_EVENT_ERR )
+		pollfd->events |= POLLERR;
+	if ( events & SLIRP_EVENT_HUP )
+		pollfd->events |= ( POLLHUP | POLLRDHUP );
+	DBGCP ( slirp, "SLIRP %p polling FD %d event mask %#04x(%#04x)\n",
+		slirp, fd, events, pollfd->events );
+
+	return index;
+}
+
+/**
+ * Get returned events for a file descriptor
+ *
+ * @v index		File descriptor index
+ * @v device		Device opaque pointer
+ * @ret events		Returned events
+ */
+static int __asmcall slirp_get_revents ( int index, void *device ) {
+	struct net_device *netdev = device;
+	struct slirp_nic *slirp = netdev->priv;
+	int revents;
+	int events;
+
+	/* Ignore failed descriptors */
+	if ( index < 0 )
+		return 0;
+
+	/* Collect events */
+	revents = slirp->pollfds[index].revents;
+	events = 0;
+	if ( revents & POLLIN )
+		events |= SLIRP_EVENT_IN;
+	if ( revents & POLLOUT )
+		events |= SLIRP_EVENT_OUT;
+	if ( revents & POLLPRI )
+		events |= SLIRP_EVENT_PRI;
+	if ( revents & POLLERR )
+		events |= SLIRP_EVENT_ERR;
+	if ( revents & ( POLLHUP | POLLRDHUP ) )
+		events |= SLIRP_EVENT_HUP;
+	if ( events ) {
+		DBGC2 ( slirp, "SLIRP %p polled FD %d events %#04x(%#04x)\n",
+			slirp, slirp->pollfds[index].fd, events, revents );
+	}
+
+	return events;
+}
+
+/**
+ * Poll for completed and received packets
+ *
+ * @v netdev		Network device
+ */
+static void slirp_poll ( struct net_device *netdev ) {
+	struct slirp_nic *slirp = netdev->priv;
+	uint32_t timeout = 0;
+	int ready;
+	int error;
+
+	/* Rebuild polling file descriptor list */
+	slirp->numfds = 0;
+	linux_slirp_pollfds_fill ( slirp->slirp, &timeout,
+				   slirp_add_poll, netdev );
+
+	/* Poll descriptors */
+	ready = linux_poll ( slirp->pollfds, slirp->numfds, 0 );
+	error = ( ready == -1 );
+	linux_slirp_pollfds_poll ( slirp->slirp, error, slirp_get_revents,
+				   netdev );
+
+	/* Record polling errors */
+	if ( error ) {
+		DBGC ( slirp, "SLIRP %p poll failed: %s\n",
+		       slirp, linux_strerror ( linux_errno ) );
+		netdev_rx_err ( netdev, NULL, -ELINUX ( linux_errno ) );
+	}
+}
+
+/** Network device operations */
+static struct net_device_operations slirp_operations = {
+	.open		= slirp_open,
+	.close		= slirp_close,
+	.transmit	= slirp_transmit,
+	.poll		= slirp_poll,
+};
+
+/******************************************************************************
+ *
+ * Linux driver interface
+ *
+ ******************************************************************************
+ */
+
+/**
+ * Probe device
+ *
+ * @v linux		Linux device
+ * @v request		Device creation request
+ * @ret rc		Return status code
+ */
+static int slirp_probe ( struct linux_device *linux,
+			 struct linux_device_request *request ) {
+	struct net_device *netdev;
+	struct slirp_nic *slirp;
+	struct slirp_config config;
+	int rc;
+
+	/* Allocate device */
+	netdev = alloc_etherdev ( sizeof ( *slirp ) );
+	if ( ! netdev ) {
+		rc = -ENOMEM;
+		goto err_alloc;
+	}
+	netdev_init ( netdev, &slirp_operations );
+	linux_set_drvdata ( linux, netdev );
+	snprintf ( linux->dev.name, sizeof ( linux->dev.name ), "host" );
+	netdev->dev = &linux->dev;
+	memcpy ( netdev->hw_addr, slirp_default_mac, ETH_ALEN );
+	slirp = netdev->priv;
+	memset ( slirp, 0, sizeof ( *slirp ) );
+
+	/* Apply requested settings */
+	linux_apply_settings ( &request->settings,
+			       netdev_settings ( netdev ) );
+
+	/* Initialise default configuration (matching qemu) */
+	memset ( &config, 0, sizeof ( config ) );
+	config.version = 1;
+	config.in_enabled = true;
+	config.vnetwork.s_addr = htonl ( 0x0a000200 ); /* 10.0.2.0 */
+	config.vnetmask.s_addr = htonl ( 0xffffff00 ); /* 255.255.255.0 */
+	config.vhost.s_addr = htonl ( 0x0a000202 ); /* 10.0.2.2 */
+	config.in6_enabled = true;
+	config.vdhcp_start.s_addr = htonl ( 0x0a00020f ); /* 10.0.2.15 */
+	config.vnameserver.s_addr = htonl ( 0x0a000203 ); /* 10.0.2.3 */
+
+	/* Instantiate device */
+	slirp->slirp = linux_slirp_new ( &config, &slirp_callbacks, netdev );
+	if ( ! slirp->slirp ) {
+		DBGC ( slirp, "SLIRP could not instantiate\n" );
+		rc = -ENODEV;
+		goto err_new;
+	}
+
+	/* Register network device */
+	if ( ( rc = register_netdev ( netdev ) ) != 0 )
+		goto err_register;
+
+	/* Set link up since there is no concept of link state */
+	netdev_link_up ( netdev );
+
+	return 0;
+
+	unregister_netdev ( netdev );
+ err_register:
+	linux_slirp_cleanup ( slirp->slirp );
+ err_new:
+	netdev_nullify ( netdev );
+	netdev_put ( netdev );
+ err_alloc:
+	return rc;
+}
+
+/**
+ * Remove device
+ *
+ * @v linux		Linux device
+ */
+static void slirp_remove ( struct linux_device *linux ) {
+	struct net_device *netdev = linux_get_drvdata ( linux );
+	struct slirp_nic *slirp = netdev->priv;
+
+	/* Unregister network device */
+	unregister_netdev ( netdev );
+
+	/* Shut down device */
+	linux_slirp_cleanup ( slirp->slirp );
+
+	/* Free network device */
+	netdev_nullify ( netdev );
+	netdev_put ( netdev );
+}
+
+/** Slirp driver */
+struct linux_driver slirp_driver __linux_driver = {
+	.name = "slirp",
+	.probe = slirp_probe,
+	.remove = slirp_remove,
+	.can_probe = 1,
+};
diff -pruN 1.0.0+git-20190125.36a4c85-5.1/src/drivers/linux/tap.c 1.21.1+git-20220113.fbbdc3926-0ubuntu1/src/drivers/linux/tap.c
--- 1.0.0+git-20190125.36a4c85-5.1/src/drivers/linux/tap.c	2019-02-09 16:03:59.000000000 +0000
+++ 1.21.1+git-20220113.fbbdc3926-0ubuntu1/src/drivers/linux/tap.c	2022-01-13 13:43:08.000000000 +0000
@@ -19,7 +19,7 @@
 #include <errno.h>
 #include <string.h>
 #include <stdio.h>
-#include <linux_api.h>
+#include <ipxe/linux_api.h>
 #include <ipxe/list.h>
 #include <ipxe/linux.h>
 #include <ipxe/malloc.h>
diff -pruN 1.0.0+git-20190125.36a4c85-5.1/src/drivers/net/3c90x.c 1.21.1+git-20220113.fbbdc3926-0ubuntu1/src/drivers/net/3c90x.c
--- 1.0.0+git-20190125.36a4c85-5.1/src/drivers/net/3c90x.c	2019-02-09 16:03:59.000000000 +0000
+++ 1.21.1+git-20220113.fbbdc3926-0ubuntu1/src/drivers/net/3c90x.c	2022-01-13 13:43:08.000000000 +0000
@@ -249,7 +249,7 @@ static int a3c90x_setup_tx_ring(struct I
 {
 	DBGP("a3c90x_setup_tx_ring\n");
 	p->tx_ring =
-	    malloc_dma(TX_RING_SIZE * sizeof(struct TXD), TX_RING_ALIGN);
+	    malloc_phys(TX_RING_SIZE * sizeof(struct TXD), TX_RING_ALIGN);
 
 	if (!p->tx_ring) {
 		DBG("Could not allocate TX-ring\n");
@@ -304,7 +304,7 @@ static void a3c90x_free_tx_ring(struct I
 {
 	DBGP("a3c90x_free_tx_ring\n");
 
-	free_dma(p->tx_ring, TX_RING_SIZE * sizeof(struct TXD));
+	free_phys(p->tx_ring, TX_RING_SIZE * sizeof(struct TXD));
 	p->tx_ring = NULL;
 	/* io_buffers are free()ed by netdev_tx_complete[,_err]() */
 }
@@ -461,7 +461,7 @@ static int a3c90x_setup_rx_ring(struct I
 	DBGP("a3c90x_setup_rx_ring\n");
 
 	p->rx_ring =
-	    malloc_dma(RX_RING_SIZE * sizeof(struct RXD), RX_RING_ALIGN);
+	    malloc_phys(RX_RING_SIZE * sizeof(struct RXD), RX_RING_ALIGN);
 
 	if (!p->rx_ring) {
 		DBG("Could not allocate RX-ring\n");
@@ -491,7 +491,7 @@ static void a3c90x_free_rx_ring(struct I
 {
 	DBGP("a3c90x_free_rx_ring\n");
 
-	free_dma(p->rx_ring, RX_RING_SIZE * sizeof(struct RXD));
+	free_phys(p->rx_ring, RX_RING_SIZE * sizeof(struct RXD));
 	p->rx_ring = NULL;
 }
 
diff -pruN 1.0.0+git-20190125.36a4c85-5.1/src/drivers/net/amd8111e.c 1.21.1+git-20220113.fbbdc3926-0ubuntu1/src/drivers/net/amd8111e.c
--- 1.0.0+git-20190125.36a4c85-5.1/src/drivers/net/amd8111e.c	2019-02-09 16:03:59.000000000 +0000
+++ 1.21.1+git-20220113.fbbdc3926-0ubuntu1/src/drivers/net/amd8111e.c	2022-01-13 13:43:08.000000000 +0000
@@ -664,7 +664,7 @@ static int amd8111e_probe(struct nic *ni
 	memset(lp, 0, sizeof(*lp));
 	lp->pdev = pdev;
 	lp->nic = nic;
-	lp->mmio = ioremap(mmio_start, mmio_len);
+	lp->mmio = pci_ioremap(pdev, mmio_start, mmio_len);
 	lp->opened = 1;
 	adjust_pci_device(pdev);
 
diff -pruN 1.0.0+git-20190125.36a4c85-5.1/src/drivers/net/ath/ath5k/ath5k.c 1.21.1+git-20220113.fbbdc3926-0ubuntu1/src/drivers/net/ath/ath5k/ath5k.c
--- 1.0.0+git-20190125.36a4c85-5.1/src/drivers/net/ath/ath5k/ath5k.c	2019-02-09 16:03:59.000000000 +0000
+++ 1.21.1+git-20220113.fbbdc3926-0ubuntu1/src/drivers/net/ath/ath5k/ath5k.c	2022-01-13 13:43:08.000000000 +0000
@@ -280,7 +280,7 @@ static int ath5k_probe(struct pci_device
 	 */
 	pci_write_config_byte(pdev, 0x41, 0);
 
-	mem = ioremap(pdev->membase, 0x10000);
+	mem = pci_ioremap(pdev, pdev->membase, 0x10000);
 	if (!mem) {
 		DBG("ath5k: cannot remap PCI memory region\n");
 		ret = -EIO;
@@ -877,7 +877,7 @@ ath5k_desc_alloc(struct ath5k_softc *sc)
 
 	/* allocate descriptors */
 	sc->desc_len = sizeof(struct ath5k_desc) * (ATH_TXBUF + ATH_RXBUF + 1);
-	sc->desc = malloc_dma(sc->desc_len, ATH5K_DESC_ALIGN);
+	sc->desc = malloc_phys(sc->desc_len, ATH5K_DESC_ALIGN);
 	if (sc->desc == NULL) {
 		DBG("ath5k: can't allocate descriptors\n");
 		ret = -ENOMEM;
@@ -915,7 +915,7 @@ ath5k_desc_alloc(struct ath5k_softc *sc)
 	return 0;
 
 err_free:
-	free_dma(sc->desc, sc->desc_len);
+	free_phys(sc->desc, sc->desc_len);
 err:
 	sc->desc = NULL;
 	return ret;
@@ -932,7 +932,7 @@ ath5k_desc_free(struct ath5k_softc *sc)
 		ath5k_rxbuf_free(sc, bf);
 
 	/* Free memory associated with all descriptors */
-	free_dma(sc->desc, sc->desc_len);
+	free_phys(sc->desc, sc->desc_len);
 
 	free(sc->bufptr);
 	sc->bufptr = NULL;
diff -pruN 1.0.0+git-20190125.36a4c85-5.1/src/drivers/net/ath/ath5k/ath5k_eeprom.c 1.21.1+git-20220113.fbbdc3926-0ubuntu1/src/drivers/net/ath/ath5k/ath5k_eeprom.c
--- 1.0.0+git-20190125.36a4c85-5.1/src/drivers/net/ath/ath5k/ath5k_eeprom.c	2019-02-09 16:03:59.000000000 +0000
+++ 1.21.1+git-20220113.fbbdc3926-0ubuntu1/src/drivers/net/ath/ath5k/ath5k_eeprom.c	2022-01-13 13:43:08.000000000 +0000
@@ -39,6 +39,9 @@ static int ath5k_hw_eeprom_read(struct a
 {
 	u32 status, timeout;
 
+	/* Avoid returning uninitialised data on error */
+	*data = 0xffff;
+
 	/*
 	 * Initialize EEPROM access
 	 */
@@ -416,6 +419,7 @@ ath5k_eeprom_read_turbo_modes(struct ath
 	if (ee->ee_version < AR5K_EEPROM_VERSION_5_0)
 		return 0;
 
+	AR5K_EEPROM_READ(o++, val);
 	switch (mode){
 	case AR5K_EEPROM_MODE_11A:
 		ee->ee_switch_settling_turbo[mode] = (val >> 6) & 0x7f;
diff -pruN 1.0.0+git-20190125.36a4c85-5.1/src/drivers/net/ath/ath9k/ath9k.c 1.21.1+git-20220113.fbbdc3926-0ubuntu1/src/drivers/net/ath/ath9k/ath9k.c
--- 1.0.0+git-20190125.36a4c85-5.1/src/drivers/net/ath/ath9k/ath9k.c	2019-02-09 16:03:59.000000000 +0000
+++ 1.21.1+git-20220113.fbbdc3926-0ubuntu1/src/drivers/net/ath/ath9k/ath9k.c	2022-01-13 13:43:08.000000000 +0000
@@ -138,7 +138,7 @@ static int ath_pci_probe(struct pci_devi
 	if ((val & 0x0000ff00) != 0)
 		pci_write_config_dword(pdev, 0x40, val & 0xffff00ff);
 
-	mem = ioremap(pdev->membase, 0x10000);
+	mem = pci_ioremap(pdev, pdev->membase, 0x10000);
 	if (!mem) {
 		DBG("ath9K: PCI memory map error\n") ;
 		ret = -EIO;
diff -pruN 1.0.0+git-20190125.36a4c85-5.1/src/drivers/net/ath/ath9k/ath9k_init.c 1.21.1+git-20220113.fbbdc3926-0ubuntu1/src/drivers/net/ath/ath9k/ath9k_init.c
--- 1.0.0+git-20190125.36a4c85-5.1/src/drivers/net/ath/ath9k/ath9k_init.c	2019-02-09 16:03:59.000000000 +0000
+++ 1.21.1+git-20220113.fbbdc3926-0ubuntu1/src/drivers/net/ath/ath9k/ath9k_init.c	2022-01-13 13:43:08.000000000 +0000
@@ -223,7 +223,7 @@ int ath_descdma_setup(struct ath_softc *
 	}
 
 	/* allocate descriptors */
-	dd->dd_desc = malloc_dma(dd->dd_desc_len, 16);
+	dd->dd_desc = malloc_phys(dd->dd_desc_len, 16);
 	if (dd->dd_desc == NULL) {
 		error = -ENOMEM;
 		goto fail;
@@ -264,7 +264,7 @@ int ath_descdma_setup(struct ath_softc *
 	}
 	return 0;
 fail2:
-	free_dma(dd->dd_desc, dd->dd_desc_len);
+	free_phys(dd->dd_desc, dd->dd_desc_len);
 fail:
 	memset(dd, 0, sizeof(*dd));
 	return error;
@@ -588,7 +588,7 @@ void ath_descdma_cleanup(struct ath_soft
 			 struct ath_descdma *dd,
 			 struct list_head *head)
 {
-	free_dma(dd->dd_desc, dd->dd_desc_len);
+	free_phys(dd->dd_desc, dd->dd_desc_len);
 
 	INIT_LIST_HEAD(head);
 	free(dd->dd_bufptr);
diff -pruN 1.0.0+git-20190125.36a4c85-5.1/src/drivers/net/atl1e.c 1.21.1+git-20220113.fbbdc3926-0ubuntu1/src/drivers/net/atl1e.c
--- 1.0.0+git-20190125.36a4c85-5.1/src/drivers/net/atl1e.c	2019-02-09 16:03:59.000000000 +0000
+++ 1.21.1+git-20220113.fbbdc3926-0ubuntu1/src/drivers/net/atl1e.c	2022-01-13 13:43:08.000000000 +0000
@@ -370,7 +370,7 @@ static void atl1e_free_ring_resources(st
 	atl1e_clean_rx_ring(adapter);
 
 	if (adapter->ring_vir_addr) {
-		free_dma(adapter->ring_vir_addr, adapter->ring_size);
+		free_phys(adapter->ring_vir_addr, adapter->ring_size);
 		adapter->ring_vir_addr = NULL;
 		adapter->ring_dma = 0;
 	}
@@ -405,7 +405,7 @@ static int atl1e_setup_ring_resources(st
 	/* real ring DMA buffer */
 
 	size = adapter->ring_size;
-	adapter->ring_vir_addr = malloc_dma(adapter->ring_size, 32);
+	adapter->ring_vir_addr = malloc_phys(adapter->ring_size, 32);
 
 	if (adapter->ring_vir_addr == NULL) {
 		DBG("atl1e: out of memory allocating %d bytes for %s ring\n",
diff -pruN 1.0.0+git-20190125.36a4c85-5.1/src/drivers/net/axge.c 1.21.1+git-20220113.fbbdc3926-0ubuntu1/src/drivers/net/axge.c
--- 1.0.0+git-20190125.36a4c85-5.1/src/drivers/net/axge.c	2019-02-09 16:03:59.000000000 +0000
+++ 1.21.1+git-20220113.fbbdc3926-0ubuntu1/src/drivers/net/axge.c	2022-01-13 13:43:08.000000000 +0000
@@ -213,6 +213,7 @@ static inline int axge_write_dword ( str
 static int axge_check_link ( struct axge_device *axge ) {
 	struct net_device *netdev = axge->netdev;
 	uint8_t plsr;
+	uint16_t msr;
 	int rc;
 
 	/* Read physical link status register */
@@ -222,12 +223,28 @@ static int axge_check_link ( struct axge
 		return rc;
 	}
 
+	/* Write medium status register */
+	msr = cpu_to_le16 ( AXGE_MSR_FD | AXGE_MSR_RFC | AXGE_MSR_TFC |
+			    AXGE_MSR_RE );
+	if ( plsr & AXGE_PLSR_EPHY_1000 ) {
+		msr |= cpu_to_le16 ( AXGE_MSR_GM );
+	} else if ( plsr & AXGE_PLSR_EPHY_100 ) {
+		msr |= cpu_to_le16 ( AXGE_MSR_PS );
+	}
+	if ( ( rc = axge_write_word ( axge, AXGE_MSR, msr ) ) != 0 ) {
+		DBGC ( axge, "AXGE %p could not write MSR: %s\n",
+		       axge, strerror ( rc ) );
+		return rc;
+	}
+
 	/* Update link status */
 	if ( plsr & AXGE_PLSR_EPHY_ANY ) {
-		DBGC ( axge, "AXGE %p link up (PLSR %02x)\n", axge, plsr );
+		DBGC ( axge, "AXGE %p link up (PLSR %02x MSR %04x)\n",
+		       axge, plsr, msr );
 		netdev_link_up ( netdev );
 	} else {
-		DBGC ( axge, "AXGE %p link down (PLSR %02x)\n", axge, plsr );
+		DBGC ( axge, "AXGE %p link down (PLSR %02x MSR %04x)\n",
+		       axge, plsr, msr );
 		netdev_link_down ( netdev );
 	}
 
@@ -291,13 +308,8 @@ static void axge_intr_complete ( struct
 
 	/* Extract link status */
 	link_ok = ( intr->link & cpu_to_le16 ( AXGE_INTR_LINK_PPLS ) );
-	if ( link_ok && ! netdev_link_ok ( netdev ) ) {
-		DBGC ( axge, "AXGE %p link up\n", axge );
-		netdev_link_up ( netdev );
-	} else if ( netdev_link_ok ( netdev ) && ! link_ok ) {
-		DBGC ( axge, "AXGE %p link down\n", axge );
-		netdev_link_down ( netdev );
-	}
+	if ( ( !! link_ok ) ^ ( !! netdev_link_ok ( netdev ) ) )
+		axge->check_link = 1;
 
 	/* Free I/O buffer */
 	free_iob ( iobuf );
@@ -519,6 +531,13 @@ static int axge_open ( struct net_device
 	uint16_t rcr;
 	int rc;
 
+	/* Reapply device configuration to avoid transaction errors */
+	if ( ( rc = usb_set_configuration ( axge->usb, axge->config ) ) != 0 ) {
+		DBGC ( axge, "AXGE %p could not set configuration: %s\n",
+		       axge, strerror ( rc ) );
+		goto err_set_configuration;
+	}
+
 	/* Open USB network device */
 	if ( ( rc = usbnet_open ( &axge->usbnet ) ) != 0 ) {
 		DBGC ( axge, "AXGE %p could not open: %s\n",
@@ -544,15 +563,18 @@ static int axge_open ( struct net_device
 	}
 
 	/* Update link status */
-	axge_check_link ( axge );
+	if ( ( rc = axge_check_link ( axge ) ) != 0 )
+		goto err_check_link;
 
 	return 0;
 
+ err_check_link:
 	axge_write_word ( axge, AXGE_RCR, 0 );
  err_write_rcr:
  err_write_mac:
 	usbnet_close ( &axge->usbnet );
  err_open:
+ err_set_configuration:
 	return rc;
 }
 
@@ -605,6 +627,15 @@ static void axge_poll ( struct net_devic
 	/* Refill endpoints */
 	if ( ( rc = usbnet_refill ( &axge->usbnet ) ) != 0 )
 		netdev_rx_err ( netdev, NULL, rc );
+
+	/* Update link state, if applicable */
+	if ( axge->check_link ) {
+		if ( ( rc = axge_check_link ( axge ) ) == 0 ) {
+			axge->check_link = 0;
+		} else {
+			netdev_rx_err ( netdev, NULL, rc );
+		}
+	}
 }
 
 /** AXGE network device operations */
@@ -635,7 +666,6 @@ static int axge_probe ( struct usb_funct
 	struct net_device *netdev;
 	struct axge_device *axge;
 	uint16_t epprcr;
-	uint16_t msr;
 	uint8_t csr;
 	int rc;
 
@@ -652,6 +682,7 @@ static int axge_probe ( struct usb_funct
 	axge->usb = usb;
 	axge->bus = usb->port->hub->bus;
 	axge->netdev = netdev;
+	axge->config = config->config;
 	usbnet_init ( &axge->usbnet, func, &axge_intr_operations,
 		      &axge_in_operations, &axge_out_operations );
 	usb_refill_init ( &axge->usbnet.intr, 0, 0, AXGE_INTR_MAX_FILL );
@@ -705,28 +736,20 @@ static int axge_probe ( struct usb_funct
 		goto err_write_bicr;
 	}
 
-	/* Set medium status */
-	msr = cpu_to_le16 ( AXGE_MSR_GM | AXGE_MSR_FD | AXGE_MSR_RFC |
-			    AXGE_MSR_TFC | AXGE_MSR_RE );
-	if ( ( rc = axge_write_word ( axge, AXGE_MSR, msr ) ) != 0 ) {
-		DBGC ( axge, "AXGE %p could not write MSR: %s\n",
-		       axge, strerror ( rc ) );
-		goto err_write_msr;
-	}
-
 	/* Register network device */
 	if ( ( rc = register_netdev ( netdev ) ) != 0 )
 		goto err_register;
 
 	/* Update link status */
-	axge_check_link ( axge );
+	if ( ( rc = axge_check_link ( axge ) ) != 0 )
+		goto err_check_link;
 
 	usb_func_set_drvdata ( func, axge );
 	return 0;
 
+ err_check_link:
 	unregister_netdev ( netdev );
  err_register:
- err_write_msr:
  err_write_bicr:
  err_write_csr:
  err_write_epprcr_on:
diff -pruN 1.0.0+git-20190125.36a4c85-5.1/src/drivers/net/axge.h 1.21.1+git-20220113.fbbdc3926-0ubuntu1/src/drivers/net/axge.h
--- 1.0.0+git-20190125.36a4c85-5.1/src/drivers/net/axge.h	2019-02-09 16:03:59.000000000 +0000
+++ 1.21.1+git-20220113.fbbdc3926-0ubuntu1/src/drivers/net/axge.h	2022-01-13 13:43:08.000000000 +0000
@@ -49,6 +49,7 @@ FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
 #define AXGE_MSR_RFC			0x0010	/**< RX flow control enable */
 #define AXGE_MSR_TFC			0x0020	/**< TX flow control enable */
 #define AXGE_MSR_RE			0x0100	/**< Receive enable */
+#define AXGE_MSR_PS			0x0200	/**< 100Mbps port speed */
 
 /** Ethernet PHY Power and Reset Control Register */
 #define AXGE_EPPRCR 0x26
@@ -144,6 +145,10 @@ struct axge_device {
 	struct net_device *netdev;
 	/** USB network device */
 	struct usbnet_device usbnet;
+	/** Device configuration */
+	unsigned int config;
+	/** Link state has changed */
+	int check_link;
 };
 
 /** Interrupt maximum fill level
diff -pruN 1.0.0+git-20190125.36a4c85-5.1/src/drivers/net/b44.c 1.21.1+git-20220113.fbbdc3926-0ubuntu1/src/drivers/net/b44.c
--- 1.0.0+git-20190125.36a4c85-5.1/src/drivers/net/b44.c	2019-02-09 16:03:59.000000000 +0000
+++ 1.21.1+git-20220113.fbbdc3926-0ubuntu1/src/drivers/net/b44.c	2022-01-13 13:43:08.000000000 +0000
@@ -436,7 +436,7 @@ static void b44_free_rx_ring(struct b44_
 			free_iob(bp->rx_iobuf[i]);
 			bp->rx_iobuf[i] = NULL;
 		}
-		free_dma(bp->rx, B44_RX_RING_LEN_BYTES);
+		free_phys(bp->rx, B44_RX_RING_LEN_BYTES);
 		bp->rx = NULL;
 	}
 }
@@ -446,11 +446,11 @@ static int b44_init_rx_ring(struct b44_p
 {
 	b44_free_rx_ring(bp);
 
-	bp->rx = malloc_dma(B44_RX_RING_LEN_BYTES, B44_DMA_ALIGNMENT);
+	bp->rx = malloc_phys(B44_RX_RING_LEN_BYTES, B44_DMA_ALIGNMENT);
 	if (!bp->rx)
 		return -ENOMEM;
 	if (!b44_address_ok(bp->rx)) {
-		free_dma(bp->rx, B44_RX_RING_LEN_BYTES);
+		free_phys(bp->rx, B44_RX_RING_LEN_BYTES);
 		return -ENOTSUP;
 	}
 
@@ -468,7 +468,7 @@ static int b44_init_rx_ring(struct b44_p
 static void b44_free_tx_ring(struct b44_private *bp)
 {
 	if (bp->tx) {
-		free_dma(bp->tx, B44_TX_RING_LEN_BYTES);
+		free_phys(bp->tx, B44_TX_RING_LEN_BYTES);
 		bp->tx = NULL;
 	}
 }
@@ -478,11 +478,11 @@ static int b44_init_tx_ring(struct b44_p
 {
 	b44_free_tx_ring(bp);
 
-	bp->tx = malloc_dma(B44_TX_RING_LEN_BYTES, B44_DMA_ALIGNMENT);
+	bp->tx = malloc_phys(B44_TX_RING_LEN_BYTES, B44_DMA_ALIGNMENT);
 	if (!bp->tx)
 		return -ENOMEM;
 	if (!b44_address_ok(bp->tx)) {
-		free_dma(bp->tx, B44_TX_RING_LEN_BYTES);
+		free_phys(bp->tx, B44_TX_RING_LEN_BYTES);
 		return -ENOTSUP;
 	}
 
@@ -673,7 +673,7 @@ static int b44_probe(struct pci_device *
 	bp->pci = pci;
 
 	/* Map device registers */
-	bp->regs = ioremap(pci->membase, B44_REGS_SIZE);
+	bp->regs = pci_ioremap(pci, pci->membase, B44_REGS_SIZE);
 	if (!bp->regs) {
 		netdev_put(netdev);
 		return -ENOMEM;
diff -pruN 1.0.0+git-20190125.36a4c85-5.1/src/drivers/net/bnx2.c 1.21.1+git-20220113.fbbdc3926-0ubuntu1/src/drivers/net/bnx2.c
--- 1.0.0+git-20190125.36a4c85-5.1/src/drivers/net/bnx2.c	1970-01-01 00:00:00.000000000 +0000
+++ 1.21.1+git-20220113.fbbdc3926-0ubuntu1/src/drivers/net/bnx2.c	2022-01-13 13:43:08.000000000 +0000
@@ -0,0 +1,2694 @@
+/* bnx2.c: Broadcom NX2 network driver.
+ *
+ * Copyright (c) 2004, 2005, 2006 Broadcom Corporation
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation.
+ *
+ * Written by: Michael Chan  (mchan@broadcom.com)
+ *
+ * Etherboot port by Ryan Jackson (rjackson@lnxi.com), based on driver
+ * version 1.4.40 from linux 2.6.17
+ */
+
+FILE_LICENCE ( GPL_ANY );
+
+#include "etherboot.h"
+#include "nic.h"
+#include <errno.h>
+#include <ipxe/pci.h>
+#include <ipxe/ethernet.h>
+#include "string.h"
+#include <mii.h>
+#include "bnx2.h"
+#include "bnx2_fw.h"
+
+#if 0
+/* Dummy defines for error handling */
+#define EBUSY  1
+#define ENODEV 2
+#define EINVAL 3
+#define ENOMEM 4
+#define EIO    5
+#endif
+
+/* The bnx2 seems to be picky about the alignment of the receive buffers
+ * and possibly the status block.
+ */
+static struct bss {
+	struct tx_bd tx_desc_ring[TX_DESC_CNT];
+	struct rx_bd rx_desc_ring[RX_DESC_CNT];
+	unsigned char rx_buf[RX_BUF_CNT][RX_BUF_SIZE];
+	struct status_block status_blk;
+	struct statistics_block stats_blk;
+} bnx2_bss;
+
+static struct bnx2 bnx2;
+
+static struct flash_spec flash_table[] =
+{
+	/* Slow EEPROM */
+	{0x00000000, 0x40830380, 0x009f0081, 0xa184a053, 0xaf000400,
+	 1, SEEPROM_PAGE_BITS, SEEPROM_PAGE_SIZE,
+	 SEEPROM_BYTE_ADDR_MASK, SEEPROM_TOTAL_SIZE,
+	 "EEPROM - slow"},
+	/* Expansion entry 0001 */
+	{0x08000002, 0x4b808201, 0x00050081, 0x03840253, 0xaf020406,
+	 0, SAIFUN_FLASH_PAGE_BITS, SAIFUN_FLASH_PAGE_SIZE,
+	 SAIFUN_FLASH_BYTE_ADDR_MASK, 0,
+	 "Entry 0001"},
+	/* Saifun SA25F010 (non-buffered flash) */
+	/* strap, cfg1, & write1 need updates */
+	{0x04000001, 0x47808201, 0x00050081, 0x03840253, 0xaf020406,
+	 0, SAIFUN_FLASH_PAGE_BITS, SAIFUN_FLASH_PAGE_SIZE,
+	 SAIFUN_FLASH_BYTE_ADDR_MASK, SAIFUN_FLASH_BASE_TOTAL_SIZE*2,
+	 "Non-buffered flash (128kB)"},
+	/* Saifun SA25F020 (non-buffered flash) */
+	/* strap, cfg1, & write1 need updates */
+	{0x0c000003, 0x4f808201, 0x00050081, 0x03840253, 0xaf020406,
+	 0, SAIFUN_FLASH_PAGE_BITS, SAIFUN_FLASH_PAGE_SIZE,
+	 SAIFUN_FLASH_BYTE_ADDR_MASK, SAIFUN_FLASH_BASE_TOTAL_SIZE*4,
+	 "Non-buffered flash (256kB)"},
+	/* Expansion entry 0100 */
+	{0x11000000, 0x53808201, 0x00050081, 0x03840253, 0xaf020406,
+	 0, SAIFUN_FLASH_PAGE_BITS, SAIFUN_FLASH_PAGE_SIZE,
+	 SAIFUN_FLASH_BYTE_ADDR_MASK, 0,
+	 "Entry 0100"},
+	/* Entry 0101: ST M45PE10 (non-buffered flash, TetonII B0) */
+	{0x19000002, 0x5b808201, 0x000500db, 0x03840253, 0xaf020406,        
+	 0, ST_MICRO_FLASH_PAGE_BITS, ST_MICRO_FLASH_PAGE_SIZE,
+	 ST_MICRO_FLASH_BYTE_ADDR_MASK, ST_MICRO_FLASH_BASE_TOTAL_SIZE*2,
+	 "Entry 0101: ST M45PE10 (128kB non-bufferred)"},
+	/* Entry 0110: ST M45PE20 (non-buffered flash)*/
+	{0x15000001, 0x57808201, 0x000500db, 0x03840253, 0xaf020406,
+	 0, ST_MICRO_FLASH_PAGE_BITS, ST_MICRO_FLASH_PAGE_SIZE,
+	 ST_MICRO_FLASH_BYTE_ADDR_MASK, ST_MICRO_FLASH_BASE_TOTAL_SIZE*4,
+	 "Entry 0110: ST M45PE20 (256kB non-bufferred)"},
+	/* Saifun SA25F005 (non-buffered flash) */
+	/* strap, cfg1, & write1 need updates */
+	{0x1d000003, 0x5f808201, 0x00050081, 0x03840253, 0xaf020406,
+	 0, SAIFUN_FLASH_PAGE_BITS, SAIFUN_FLASH_PAGE_SIZE,
+	 SAIFUN_FLASH_BYTE_ADDR_MASK, SAIFUN_FLASH_BASE_TOTAL_SIZE,
+	 "Non-buffered flash (64kB)"},
+	/* Fast EEPROM */
+	{0x22000000, 0x62808380, 0x009f0081, 0xa184a053, 0xaf000400,
+	 1, SEEPROM_PAGE_BITS, SEEPROM_PAGE_SIZE,
+	 SEEPROM_BYTE_ADDR_MASK, SEEPROM_TOTAL_SIZE,
+	 "EEPROM - fast"},
+	/* Expansion entry 1001 */
+	{0x2a000002, 0x6b808201, 0x00050081, 0x03840253, 0xaf020406,
+	 0, SAIFUN_FLASH_PAGE_BITS, SAIFUN_FLASH_PAGE_SIZE,
+	 SAIFUN_FLASH_BYTE_ADDR_MASK, 0,
+	 "Entry 1001"},
+	/* Expansion entry 1010 */
+	{0x26000001, 0x67808201, 0x00050081, 0x03840253, 0xaf020406,
+	 0, SAIFUN_FLASH_PAGE_BITS, SAIFUN_FLASH_PAGE_SIZE,
+	 SAIFUN_FLASH_BYTE_ADDR_MASK, 0,
+	 "Entry 1010"},
+	/* ATMEL AT45DB011B (buffered flash) */
+	{0x2e000003, 0x6e808273, 0x00570081, 0x68848353, 0xaf000400,
+	 1, BUFFERED_FLASH_PAGE_BITS, BUFFERED_FLASH_PAGE_SIZE,
+	 BUFFERED_FLASH_BYTE_ADDR_MASK, BUFFERED_FLASH_TOTAL_SIZE,
+	 "Buffered flash (128kB)"},
+	/* Expansion entry 1100 */
+	{0x33000000, 0x73808201, 0x00050081, 0x03840253, 0xaf020406,
+	 0, SAIFUN_FLASH_PAGE_BITS, SAIFUN_FLASH_PAGE_SIZE,
+	 SAIFUN_FLASH_BYTE_ADDR_MASK, 0,
+	 "Entry 1100"},
+	/* Expansion entry 1101 */
+	{0x3b000002, 0x7b808201, 0x00050081, 0x03840253, 0xaf020406,
+	 0, SAIFUN_FLASH_PAGE_BITS, SAIFUN_FLASH_PAGE_SIZE,
+	 SAIFUN_FLASH_BYTE_ADDR_MASK, 0,
+	 "Entry 1101"},
+	/* Ateml Expansion entry 1110 */
+	{0x37000001, 0x76808273, 0x00570081, 0x68848353, 0xaf000400,
+	 1, BUFFERED_FLASH_PAGE_BITS, BUFFERED_FLASH_PAGE_SIZE,
+	 BUFFERED_FLASH_BYTE_ADDR_MASK, 0,
+	 "Entry 1110 (Atmel)"},
+	/* ATMEL AT45DB021B (buffered flash) */
+	{0x3f000003, 0x7e808273, 0x00570081, 0x68848353, 0xaf000400,
+	 1, BUFFERED_FLASH_PAGE_BITS, BUFFERED_FLASH_PAGE_SIZE,
+	 BUFFERED_FLASH_BYTE_ADDR_MASK, BUFFERED_FLASH_TOTAL_SIZE*2,
+	 "Buffered flash (256kB)"},
+};
+
+static u32
+bnx2_reg_rd_ind(struct bnx2 *bp, u32 offset)
+{
+	REG_WR(bp, BNX2_PCICFG_REG_WINDOW_ADDRESS, offset);
+	return (REG_RD(bp, BNX2_PCICFG_REG_WINDOW));
+}
+
+static void
+bnx2_reg_wr_ind(struct bnx2 *bp, u32 offset, u32 val)
+{
+	REG_WR(bp, BNX2_PCICFG_REG_WINDOW_ADDRESS, offset);
+	REG_WR(bp, BNX2_PCICFG_REG_WINDOW, val);
+}
+
+static void
+bnx2_ctx_wr(struct bnx2 *bp, u32 cid_addr, u32 offset, u32 val)
+{
+	offset += cid_addr;
+	REG_WR(bp, BNX2_CTX_DATA_ADR, offset);
+	REG_WR(bp, BNX2_CTX_DATA, val);
+}
+
+static int
+bnx2_read_phy(struct bnx2 *bp, u32 reg, u32 *val)
+{
+	u32 val1;
+	int i, ret;
+
+	if (bp->phy_flags & PHY_INT_MODE_AUTO_POLLING_FLAG) {
+		val1 = REG_RD(bp, BNX2_EMAC_MDIO_MODE);
+		val1 &= ~BNX2_EMAC_MDIO_MODE_AUTO_POLL;
+
+		REG_WR(bp, BNX2_EMAC_MDIO_MODE, val1);
+		REG_RD(bp, BNX2_EMAC_MDIO_MODE);
+
+		udelay(40);
+	}
+
+	val1 = (bp->phy_addr << 21) | (reg << 16) |
+		BNX2_EMAC_MDIO_COMM_COMMAND_READ | BNX2_EMAC_MDIO_COMM_DISEXT |
+		BNX2_EMAC_MDIO_COMM_START_BUSY;
+	REG_WR(bp, BNX2_EMAC_MDIO_COMM, val1);
+
+	for (i = 0; i < 50; i++) {
+		udelay(10);
+
+		val1 = REG_RD(bp, BNX2_EMAC_MDIO_COMM);
+		if (!(val1 & BNX2_EMAC_MDIO_COMM_START_BUSY)) {
+			udelay(5);
+
+			val1 = REG_RD(bp, BNX2_EMAC_MDIO_COMM);
+			val1 &= BNX2_EMAC_MDIO_COMM_DATA;
+
+			break;
+		}
+	}
+
+	if (val1 & BNX2_EMAC_MDIO_COMM_START_BUSY) {
+		*val = 0x0;
+		ret = -EBUSY;
+	}
+	else {
+		*val = val1;
+		ret = 0;
+	}
+
+	if (bp->phy_flags & PHY_INT_MODE_AUTO_POLLING_FLAG) {
+		val1 = REG_RD(bp, BNX2_EMAC_MDIO_MODE);
+		val1 |= BNX2_EMAC_MDIO_MODE_AUTO_POLL;
+
+		REG_WR(bp, BNX2_EMAC_MDIO_MODE, val1);
+		REG_RD(bp, BNX2_EMAC_MDIO_MODE);
+
+		udelay(40);
+	}
+
+	return ret;
+}
+
+static int
+bnx2_write_phy(struct bnx2 *bp, u32 reg, u32 val)
+{
+	u32 val1;
+	int i, ret;
+
+	if (bp->phy_flags & PHY_INT_MODE_AUTO_POLLING_FLAG) {
+		val1 = REG_RD(bp, BNX2_EMAC_MDIO_MODE);
+		val1 &= ~BNX2_EMAC_MDIO_MODE_AUTO_POLL;
+
+		REG_WR(bp, BNX2_EMAC_MDIO_MODE, val1);
+		REG_RD(bp, BNX2_EMAC_MDIO_MODE);
+
+		udelay(40);
+	}
+
+	val1 = (bp->phy_addr << 21) | (reg << 16) | val |
+		BNX2_EMAC_MDIO_COMM_COMMAND_WRITE |
+		BNX2_EMAC_MDIO_COMM_START_BUSY | BNX2_EMAC_MDIO_COMM_DISEXT;
+	REG_WR(bp, BNX2_EMAC_MDIO_COMM, val1);
+    
+	for (i = 0; i < 50; i++) {
+		udelay(10);
+
+		val1 = REG_RD(bp, BNX2_EMAC_MDIO_COMM);
+		if (!(val1 & BNX2_EMAC_MDIO_COMM_START_BUSY)) {
+			udelay(5);
+			break;
+		}
+	}
+
+	if (val1 & BNX2_EMAC_MDIO_COMM_START_BUSY)
+        	ret = -EBUSY;
+	else
+		ret = 0;
+
+	if (bp->phy_flags & PHY_INT_MODE_AUTO_POLLING_FLAG) {
+		val1 = REG_RD(bp, BNX2_EMAC_MDIO_MODE);
+		val1 |= BNX2_EMAC_MDIO_MODE_AUTO_POLL;
+
+		REG_WR(bp, BNX2_EMAC_MDIO_MODE, val1);
+		REG_RD(bp, BNX2_EMAC_MDIO_MODE);
+
+		udelay(40);
+	}
+
+	return ret;
+}
+
+static void
+bnx2_disable_int(struct bnx2 *bp)
+{
+	REG_WR(bp, BNX2_PCICFG_INT_ACK_CMD,
+	       BNX2_PCICFG_INT_ACK_CMD_MASK_INT);
+	REG_RD(bp, BNX2_PCICFG_INT_ACK_CMD);
+
+}
+
+static int
+bnx2_alloc_mem(struct bnx2 *bp)
+{
+	bp->tx_desc_ring = bnx2_bss.tx_desc_ring;
+	bp->tx_desc_mapping = virt_to_bus(bp->tx_desc_ring);
+
+	bp->rx_desc_ring = bnx2_bss.rx_desc_ring;
+	memset(bp->rx_desc_ring, 0, sizeof(struct rx_bd) * RX_DESC_CNT);
+	bp->rx_desc_mapping = virt_to_bus(bp->rx_desc_ring);
+
+	memset(&bnx2_bss.status_blk, 0, sizeof(struct status_block));
+	bp->status_blk = &bnx2_bss.status_blk;
+	bp->status_blk_mapping = virt_to_bus(&bnx2_bss.status_blk);
+
+	bp->stats_blk = &bnx2_bss.stats_blk;
+	memset(&bnx2_bss.stats_blk, 0, sizeof(struct statistics_block));
+	bp->stats_blk_mapping = virt_to_bus(&bnx2_bss.stats_blk);
+
+	return 0;
+}
+
+static void
+bnx2_report_fw_link(struct bnx2 *bp)
+{
+	u32 fw_link_status = 0;
+
+	if (bp->link_up) {
+		u32 bmsr;
+
+		switch (bp->line_speed) {
+		case SPEED_10:
+			if (bp->duplex == DUPLEX_HALF)
+				fw_link_status = BNX2_LINK_STATUS_10HALF;
+			else
+				fw_link_status = BNX2_LINK_STATUS_10FULL;
+			break;
+		case SPEED_100:
+			if (bp->duplex == DUPLEX_HALF)
+				fw_link_status = BNX2_LINK_STATUS_100HALF;
+			else
+				fw_link_status = BNX2_LINK_STATUS_100FULL;
+			break;
+		case SPEED_1000:
+			if (bp->duplex == DUPLEX_HALF)
+				fw_link_status = BNX2_LINK_STATUS_1000HALF;
+			else
+				fw_link_status = BNX2_LINK_STATUS_1000FULL;
+			break;
+		case SPEED_2500:
+			if (bp->duplex == DUPLEX_HALF)
+				fw_link_status = BNX2_LINK_STATUS_2500HALF;
+			else
+				fw_link_status = BNX2_LINK_STATUS_2500FULL;
+			break;
+		}
+
+		fw_link_status |= BNX2_LINK_STATUS_LINK_UP;
+
+		if (bp->autoneg) {
+			fw_link_status |= BNX2_LINK_STATUS_AN_ENABLED;
+
+			bnx2_read_phy(bp, MII_BMSR, &bmsr);
+			bnx2_read_phy(bp, MII_BMSR, &bmsr);
+
+			if (!(bmsr & BMSR_ANEGCOMPLETE) ||
+			    bp->phy_flags & PHY_PARALLEL_DETECT_FLAG)
+				fw_link_status |= BNX2_LINK_STATUS_PARALLEL_DET;
+			else
+				fw_link_status |= BNX2_LINK_STATUS_AN_COMPLETE;
+		}
+	}
+	else
+		fw_link_status = BNX2_LINK_STATUS_LINK_DOWN;
+
+	REG_WR_IND(bp, bp->shmem_base + BNX2_LINK_STATUS, fw_link_status);
+}
+
+static void
+bnx2_report_link(struct bnx2 *bp)
+{
+	if (bp->link_up) {
+		printf("NIC Link is Up, ");
+
+		printf("%d Mbps ", bp->line_speed);
+
+		if (bp->duplex == DUPLEX_FULL)
+			printf("full duplex");
+		else
+			printf("half duplex");
+
+		if (bp->flow_ctrl) {
+			if (bp->flow_ctrl & FLOW_CTRL_RX) {
+				printf(", receive ");
+				if (bp->flow_ctrl & FLOW_CTRL_TX)
+					printf("& transmit ");
+			}
+			else {
+				printf(", transmit ");
+			}
+			printf("flow control ON");
+		}
+		printf("\n");
+	}
+	else {
+		printf("NIC Link is Down\n");
+	}
+
+	bnx2_report_fw_link(bp);
+}
+
+static void
+bnx2_resolve_flow_ctrl(struct bnx2 *bp)
+{
+	u32 local_adv, remote_adv;
+
+	bp->flow_ctrl = 0;
+	if ((bp->autoneg & (AUTONEG_SPEED | AUTONEG_FLOW_CTRL)) != 
+		(AUTONEG_SPEED | AUTONEG_FLOW_CTRL)) {
+
+		if (bp->duplex == DUPLEX_FULL) {
+			bp->flow_ctrl = bp->req_flow_ctrl;
+		}
+		return;
+	}
+
+	if (bp->duplex != DUPLEX_FULL) {
+		return;
+	}
+
+	if ((bp->phy_flags & PHY_SERDES_FLAG) &&
+	    (CHIP_NUM(bp) == CHIP_NUM_5708)) {
+		u32 val;
+
+		bnx2_read_phy(bp, BCM5708S_1000X_STAT1, &val);
+		if (val & BCM5708S_1000X_STAT1_TX_PAUSE)
+			bp->flow_ctrl |= FLOW_CTRL_TX;
+		if (val & BCM5708S_1000X_STAT1_RX_PAUSE)
+			bp->flow_ctrl |= FLOW_CTRL_RX;
+		return;
+	}
+
+	bnx2_read_phy(bp, MII_ADVERTISE, &local_adv);
+	bnx2_read_phy(bp, MII_LPA, &remote_adv);
+
+	if (bp->phy_flags & PHY_SERDES_FLAG) {
+		u32 new_local_adv = 0;
+		u32 new_remote_adv = 0;
+
+		if (local_adv & ADVERTISE_1000XPAUSE)
+			new_local_adv |= ADVERTISE_PAUSE_CAP;
+		if (local_adv & ADVERTISE_1000XPSE_ASYM)
+			new_local_adv |= ADVERTISE_PAUSE_ASYM;
+		if (remote_adv & ADVERTISE_1000XPAUSE)
+			new_remote_adv |= ADVERTISE_PAUSE_CAP;
+		if (remote_adv & ADVERTISE_1000XPSE_ASYM)
+			new_remote_adv |= ADVERTISE_PAUSE_ASYM;
+
+		local_adv = new_local_adv;
+		remote_adv = new_remote_adv;
+	}
+
+	/* See Table 28B-3 of 802.3ab-1999 spec. */
+	if (local_adv & ADVERTISE_PAUSE_CAP) {
+		if(local_adv & ADVERTISE_PAUSE_ASYM) {
+	                if (remote_adv & ADVERTISE_PAUSE_CAP) {
+				bp->flow_ctrl = FLOW_CTRL_TX | FLOW_CTRL_RX;
+			}
+			else if (remote_adv & ADVERTISE_PAUSE_ASYM) {
+				bp->flow_ctrl = FLOW_CTRL_RX;
+			}
+		}
+		else {
+			if (remote_adv & ADVERTISE_PAUSE_CAP) {
+				bp->flow_ctrl = FLOW_CTRL_TX | FLOW_CTRL_RX;
+			}
+		}
+	}
+	else if (local_adv & ADVERTISE_PAUSE_ASYM) {
+		if ((remote_adv & ADVERTISE_PAUSE_CAP) &&
+			(remote_adv & ADVERTISE_PAUSE_ASYM)) {
+
+			bp->flow_ctrl = FLOW_CTRL_TX;
+		}
+	}
+}
+
+static int
+bnx2_5708s_linkup(struct bnx2 *bp)
+{
+	u32 val;
+
+	bp->link_up = 1;
+	bnx2_read_phy(bp, BCM5708S_1000X_STAT1, &val);
+	switch (val & BCM5708S_1000X_STAT1_SPEED_MASK) {
+		case BCM5708S_1000X_STAT1_SPEED_10:
+			bp->line_speed = SPEED_10;
+			break;
+		case BCM5708S_1000X_STAT1_SPEED_100:
+			bp->line_speed = SPEED_100;
+			break;
+		case BCM5708S_1000X_STAT1_SPEED_1G:
+			bp->line_speed = SPEED_1000;
+			break;
+		case BCM5708S_1000X_STAT1_SPEED_2G5:
+			bp->line_speed = SPEED_2500;
+			break;
+	}
+	if (val & BCM5708S_1000X_STAT1_FD)
+		bp->duplex = DUPLEX_FULL;
+	else
+		bp->duplex = DUPLEX_HALF;
+
+	return 0;
+}
+
+static int
+bnx2_5706s_linkup(struct bnx2 *bp)
+{
+	u32 bmcr, local_adv, remote_adv, common;
+
+	bp->link_up = 1;
+	bp->line_speed = SPEED_1000;
+
+	bnx2_read_phy(bp, MII_BMCR, &bmcr);
+	if (bmcr & BMCR_FULLDPLX) {
+		bp->duplex = DUPLEX_FULL;
+	}
+	else {
+		bp->duplex = DUPLEX_HALF;
+	}
+
+	if (!(bmcr & BMCR_ANENABLE)) {
+		return 0;
+	}
+
+	bnx2_read_phy(bp, MII_ADVERTISE, &local_adv);
+	bnx2_read_phy(bp, MII_LPA, &remote_adv);
+
+	common = local_adv & remote_adv;
+	if (common & (ADVERTISE_1000XHALF | ADVERTISE_1000XFULL)) {
+
+		if (common & ADVERTISE_1000XFULL) {
+			bp->duplex = DUPLEX_FULL;
+		}
+		else {
+			bp->duplex = DUPLEX_HALF;
+		}
+	}
+
+	return 0;
+}
+
+static int
+bnx2_copper_linkup(struct bnx2 *bp)
+{
+	u32 bmcr;
+
+	bnx2_read_phy(bp, MII_BMCR, &bmcr);
+	if (bmcr & BMCR_ANENABLE) {
+		u32 local_adv, remote_adv, common;
+
+		bnx2_read_phy(bp, MII_CTRL1000, &local_adv);
+		bnx2_read_phy(bp, MII_STAT1000, &remote_adv);
+
+		common = local_adv & (remote_adv >> 2);
+		if (common & ADVERTISE_1000FULL) {
+			bp->line_speed = SPEED_1000;
+			bp->duplex = DUPLEX_FULL;
+		}
+		else if (common & ADVERTISE_1000HALF) {
+			bp->line_speed = SPEED_1000;
+			bp->duplex = DUPLEX_HALF;
+		}
+		else {
+			bnx2_read_phy(bp, MII_ADVERTISE, &local_adv);
+			bnx2_read_phy(bp, MII_LPA, &remote_adv);
+
+			common = local_adv & remote_adv;
+			if (common & ADVERTISE_100FULL) {
+				bp->line_speed = SPEED_100;
+				bp->duplex = DUPLEX_FULL;
+			}
+			else if (common & ADVERTISE_100HALF) {
+				bp->line_speed = SPEED_100;
+				bp->duplex = DUPLEX_HALF;
+			}
+			else if (common & ADVERTISE_10FULL) {
+				bp->line_speed = SPEED_10;
+				bp->duplex = DUPLEX_FULL;
+			}
+			else if (common & ADVERTISE_10HALF) {
+				bp->line_speed = SPEED_10;
+				bp->duplex = DUPLEX_HALF;
+			}
+			else {
+				bp->line_speed = 0;
+				bp->link_up = 0;
+			}
+		}
+	}
+	else {
+		if (bmcr & BMCR_SPEED100) {
+			bp->line_speed = SPEED_100;
+		}
+		else {
+			bp->line_speed = SPEED_10;
+		}
+		if (bmcr & BMCR_FULLDPLX) {
+			bp->duplex = DUPLEX_FULL;
+		}
+		else {
+			bp->duplex = DUPLEX_HALF;
+		}
+	}
+
+	return 0;
+}
+
+static int
+bnx2_set_mac_link(struct bnx2 *bp)
+{
+	u32 val;
+
+	REG_WR(bp, BNX2_EMAC_TX_LENGTHS, 0x2620);
+	if (bp->link_up && (bp->line_speed == SPEED_1000) &&
+		(bp->duplex == DUPLEX_HALF)) {
+		REG_WR(bp, BNX2_EMAC_TX_LENGTHS, 0x26ff);
+	}
+
+	/* Configure the EMAC mode register. */
+	val = REG_RD(bp, BNX2_EMAC_MODE);
+
+	val &= ~(BNX2_EMAC_MODE_PORT | BNX2_EMAC_MODE_HALF_DUPLEX |
+		BNX2_EMAC_MODE_MAC_LOOP | BNX2_EMAC_MODE_FORCE_LINK |
+		BNX2_EMAC_MODE_25G);
+
+	if (bp->link_up) {
+		switch (bp->line_speed) {
+			case SPEED_10:
+				if (CHIP_NUM(bp) == CHIP_NUM_5708) {
+					val |= BNX2_EMAC_MODE_PORT_MII_10;
+					break;
+				}
+				/* fall through */
+			case SPEED_100:
+				val |= BNX2_EMAC_MODE_PORT_MII;
+				break;
+			case SPEED_2500:
+				val |= BNX2_EMAC_MODE_25G;
+				/* fall through */
+			case SPEED_1000:
+				val |= BNX2_EMAC_MODE_PORT_GMII;
+				break;
+		}
+	}
+	else {
+		val |= BNX2_EMAC_MODE_PORT_GMII;
+	}
+
+	/* Set the MAC to operate in the appropriate duplex mode. */
+	if (bp->duplex == DUPLEX_HALF)
+		val |= BNX2_EMAC_MODE_HALF_DUPLEX;
+	REG_WR(bp, BNX2_EMAC_MODE, val);
+
+	/* Enable/disable rx PAUSE. */
+	bp->rx_mode &= ~BNX2_EMAC_RX_MODE_FLOW_EN;
+
+	if (bp->flow_ctrl & FLOW_CTRL_RX)
+		bp->rx_mode |= BNX2_EMAC_RX_MODE_FLOW_EN;
+	REG_WR(bp, BNX2_EMAC_RX_MODE, bp->rx_mode);
+
+	/* Enable/disable tx PAUSE. */
+	val = REG_RD(bp, BNX2_EMAC_TX_MODE);
+	val &= ~BNX2_EMAC_TX_MODE_FLOW_EN;
+
+	if (bp->flow_ctrl & FLOW_CTRL_TX)
+		val |= BNX2_EMAC_TX_MODE_FLOW_EN;
+	REG_WR(bp, BNX2_EMAC_TX_MODE, val);
+
+	/* Acknowledge the interrupt. */
+	REG_WR(bp, BNX2_EMAC_STATUS, BNX2_EMAC_STATUS_LINK_CHANGE);
+
+	return 0;
+}
+
+static int
+bnx2_set_link(struct bnx2 *bp)
+{
+	u32 bmsr;
+	u8 link_up;
+
+	if (bp->loopback == MAC_LOOPBACK) {
+		bp->link_up = 1;
+		return 0;
+	}
+
+	link_up = bp->link_up;
+
+	bnx2_read_phy(bp, MII_BMSR, &bmsr);
+	bnx2_read_phy(bp, MII_BMSR, &bmsr);
+
+	if ((bp->phy_flags & PHY_SERDES_FLAG) &&
+	    (CHIP_NUM(bp) == CHIP_NUM_5706)) {
+		u32 val;
+
+		val = REG_RD(bp, BNX2_EMAC_STATUS);
+		if (val & BNX2_EMAC_STATUS_LINK)
+			bmsr |= BMSR_LSTATUS;
+		else
+			bmsr &= ~BMSR_LSTATUS;
+	}
+
+	if (bmsr & BMSR_LSTATUS) {
+		bp->link_up = 1;
+
+		if (bp->phy_flags & PHY_SERDES_FLAG) {
+			if (CHIP_NUM(bp) == CHIP_NUM_5706)
+				bnx2_5706s_linkup(bp);
+			else if (CHIP_NUM(bp) == CHIP_NUM_5708)
+				bnx2_5708s_linkup(bp);
+		}
+		else {
+			bnx2_copper_linkup(bp);
+		}
+		bnx2_resolve_flow_ctrl(bp);
+	}
+	else {
+		if ((bp->phy_flags & PHY_SERDES_FLAG) &&
+			(bp->autoneg & AUTONEG_SPEED)) {
+
+			u32 bmcr;
+
+			bnx2_read_phy(bp, MII_BMCR, &bmcr);
+			if (!(bmcr & BMCR_ANENABLE)) {
+				bnx2_write_phy(bp, MII_BMCR, bmcr |
+					BMCR_ANENABLE);
+			}
+		}
+		bp->phy_flags &= ~PHY_PARALLEL_DETECT_FLAG;
+		bp->link_up = 0;
+	}
+
+	if (bp->link_up != link_up) {
+		bnx2_report_link(bp);
+	}
+
+	bnx2_set_mac_link(bp);
+
+	return 0;
+}
+
+static int
+bnx2_reset_phy(struct bnx2 *bp)
+{
+	int i;
+	u32 reg;
+
+        bnx2_write_phy(bp, MII_BMCR, BMCR_RESET);
+
+#define PHY_RESET_MAX_WAIT 100
+	for (i = 0; i < PHY_RESET_MAX_WAIT; i++) {
+		udelay(10);
+
+		bnx2_read_phy(bp, MII_BMCR, &reg);
+		if (!(reg & BMCR_RESET)) {
+			udelay(20);
+			break;
+		}
+	}
+	if (i == PHY_RESET_MAX_WAIT) {
+		return -EBUSY;
+	}
+	return 0;
+}
+
+static u32
+bnx2_phy_get_pause_adv(struct bnx2 *bp)
+{
+	u32 adv = 0;
+
+	if ((bp->req_flow_ctrl & (FLOW_CTRL_RX | FLOW_CTRL_TX)) ==
+		(FLOW_CTRL_RX | FLOW_CTRL_TX)) {
+
+		if (bp->phy_flags & PHY_SERDES_FLAG) {
+			adv = ADVERTISE_1000XPAUSE;
+		}
+		else {
+			adv = ADVERTISE_PAUSE_CAP;
+		}
+	}
+	else if (bp->req_flow_ctrl & FLOW_CTRL_TX) {
+		if (bp->phy_flags & PHY_SERDES_FLAG) {
+			adv = ADVERTISE_1000XPSE_ASYM;
+		}
+		else {
+			adv = ADVERTISE_PAUSE_ASYM;
+		}
+	}
+	else if (bp->req_flow_ctrl & FLOW_CTRL_RX) {
+		if (bp->phy_flags & PHY_SERDES_FLAG) {
+			adv = ADVERTISE_1000XPAUSE | ADVERTISE_1000XPSE_ASYM;
+		}
+		else {
+			adv = ADVERTISE_PAUSE_CAP | ADVERTISE_PAUSE_ASYM;
+		}
+	}
+	return adv;
+}
+
+static int
+bnx2_setup_serdes_phy(struct bnx2 *bp)
+{
+	u32 adv, bmcr, up1;
+	u32 new_adv = 0;
+
+	if (!(bp->autoneg & AUTONEG_SPEED)) {
+		u32 new_bmcr;
+		int force_link_down = 0;
+
+		if (CHIP_NUM(bp) == CHIP_NUM_5708) {
+			bnx2_read_phy(bp, BCM5708S_UP1, &up1);
+			if (up1 & BCM5708S_UP1_2G5) {
+				up1 &= ~BCM5708S_UP1_2G5;
+				bnx2_write_phy(bp, BCM5708S_UP1, up1);
+				force_link_down = 1;
+			}
+		}
+
+		bnx2_read_phy(bp, MII_ADVERTISE, &adv);
+		adv &= ~(ADVERTISE_1000XFULL | ADVERTISE_1000XHALF);
+
+		bnx2_read_phy(bp, MII_BMCR, &bmcr);
+		new_bmcr = bmcr & ~BMCR_ANENABLE;
+		new_bmcr |= BMCR_SPEED1000;
+		if (bp->req_duplex == DUPLEX_FULL) {
+			adv |= ADVERTISE_1000XFULL;
+			new_bmcr |= BMCR_FULLDPLX;
+		}
+		else {
+			adv |= ADVERTISE_1000XHALF;
+			new_bmcr &= ~BMCR_FULLDPLX;
+		}
+		if ((new_bmcr != bmcr) || (force_link_down)) {
+			/* Force a link down visible on the other side */
+			if (bp->link_up) {
+				bnx2_write_phy(bp, MII_ADVERTISE, adv &
+					       ~(ADVERTISE_1000XFULL |
+						 ADVERTISE_1000XHALF));
+				bnx2_write_phy(bp, MII_BMCR, bmcr |
+					BMCR_ANRESTART | BMCR_ANENABLE);
+
+				bp->link_up = 0;
+				bnx2_write_phy(bp, MII_BMCR, new_bmcr);
+			}
+			bnx2_write_phy(bp, MII_ADVERTISE, adv);
+			bnx2_write_phy(bp, MII_BMCR, new_bmcr);
+		}
+		return 0;
+	}
+
+	if (bp->phy_flags & PHY_2_5G_CAPABLE_FLAG) {
+		bnx2_read_phy(bp, BCM5708S_UP1, &up1);
+		up1 |= BCM5708S_UP1_2G5;
+		bnx2_write_phy(bp, BCM5708S_UP1, up1);
+	}
+
+	if (bp->advertising & ADVERTISED_1000baseT_Full)
+		new_adv |= ADVERTISE_1000XFULL;
+
+	new_adv |= bnx2_phy_get_pause_adv(bp);
+
+	bnx2_read_phy(bp, MII_ADVERTISE, &adv);
+	bnx2_read_phy(bp, MII_BMCR, &bmcr);
+
+	bp->serdes_an_pending = 0;
+	if ((adv != new_adv) || ((bmcr & BMCR_ANENABLE) == 0)) {
+		/* Force a link down visible on the other side */
+		if (bp->link_up) {
+			int i;
+
+			bnx2_write_phy(bp, MII_BMCR, BMCR_LOOPBACK);
+			for (i = 0; i < 110; i++) {
+				udelay(100);
+			}
+		}
+
+		bnx2_write_phy(bp, MII_ADVERTISE, new_adv);
+		bnx2_write_phy(bp, MII_BMCR, bmcr | BMCR_ANRESTART |
+			BMCR_ANENABLE);
+#if 0
+		if (CHIP_NUM(bp) == CHIP_NUM_5706) {
+			/* Speed up link-up time when the link partner
+			 * does not autonegotiate which is very common
+			 * in blade servers. Some blade servers use
+			 * IPMI for kerboard input and it's important
+			 * to minimize link disruptions. Autoneg. involves
+			 * exchanging base pages plus 3 next pages and
+			 * normally completes in about 120 msec.
+			 */
+			bp->current_interval = SERDES_AN_TIMEOUT;
+			bp->serdes_an_pending = 1;
+			mod_timer(&bp->timer, jiffies + bp->current_interval);
+		}
+#endif
+	}
+
+	return 0;
+}
+
+#define ETHTOOL_ALL_FIBRE_SPEED						\
+	(ADVERTISED_1000baseT_Full)
+
+#define ETHTOOL_ALL_COPPER_SPEED					\
+	(ADVERTISED_10baseT_Half | ADVERTISED_10baseT_Full |		\
+	ADVERTISED_100baseT_Half | ADVERTISED_100baseT_Full |		\
+	ADVERTISED_1000baseT_Full)
+
+#define PHY_ALL_10_100_SPEED (ADVERTISE_10HALF | ADVERTISE_10FULL | \
+	ADVERTISE_100HALF | ADVERTISE_100FULL | ADVERTISE_CSMA)
+	
+#define PHY_ALL_1000_SPEED (ADVERTISE_1000HALF | ADVERTISE_1000FULL)
+
+static int
+bnx2_setup_copper_phy(struct bnx2 *bp)
+{
+	u32 bmcr;
+	u32 new_bmcr;
+
+	bnx2_read_phy(bp, MII_BMCR, &bmcr);
+
+	if (bp->autoneg & AUTONEG_SPEED) {
+		u32 adv_reg, adv1000_reg;
+		u32 new_adv_reg = 0;
+		u32 new_adv1000_reg = 0;
+
+		bnx2_read_phy(bp, MII_ADVERTISE, &adv_reg);
+		adv_reg &= (PHY_ALL_10_100_SPEED | ADVERTISE_PAUSE_CAP |
+			ADVERTISE_PAUSE_ASYM);
+
+		bnx2_read_phy(bp, MII_CTRL1000, &adv1000_reg);
+		adv1000_reg &= PHY_ALL_1000_SPEED;
+
+		if (bp->advertising & ADVERTISED_10baseT_Half)
+			new_adv_reg |= ADVERTISE_10HALF;
+		if (bp->advertising & ADVERTISED_10baseT_Full)
+			new_adv_reg |= ADVERTISE_10FULL;
+		if (bp->advertising & ADVERTISED_100baseT_Half)
+			new_adv_reg |= ADVERTISE_100HALF;
+		if (bp->advertising & ADVERTISED_100baseT_Full)
+			new_adv_reg |= ADVERTISE_100FULL;
+		if (bp->advertising & ADVERTISED_1000baseT_Full)
+			new_adv1000_reg |= ADVERTISE_1000FULL;
+		
+		new_adv_reg |= ADVERTISE_CSMA;
+
+		new_adv_reg |= bnx2_phy_get_pause_adv(bp);
+
+		if ((adv1000_reg != new_adv1000_reg) ||
+			(adv_reg != new_adv_reg) ||
+			((bmcr & BMCR_ANENABLE) == 0)) {
+
+			bnx2_write_phy(bp, MII_ADVERTISE, new_adv_reg);
+			bnx2_write_phy(bp, MII_CTRL1000, new_adv1000_reg);
+			bnx2_write_phy(bp, MII_BMCR, BMCR_ANRESTART |
+				BMCR_ANENABLE);
+		}
+		else if (bp->link_up) {
+			/* Flow ctrl may have changed from auto to forced */
+			/* or vice-versa. */
+
+			bnx2_resolve_flow_ctrl(bp);
+			bnx2_set_mac_link(bp);
+		}
+		return 0;
+	}
+
+	new_bmcr = 0;
+	if (bp->req_line_speed == SPEED_100) {
+		new_bmcr |= BMCR_SPEED100;
+	}
+	if (bp->req_duplex == DUPLEX_FULL) {
+		new_bmcr |= BMCR_FULLDPLX;
+	}
+	if (new_bmcr != bmcr) {
+		u32 bmsr;
+		int i = 0;
+
+		bnx2_read_phy(bp, MII_BMSR, &bmsr);
+		bnx2_read_phy(bp, MII_BMSR, &bmsr);
+		
+		if (bmsr & BMSR_LSTATUS) {
+			/* Force link down */
+			bnx2_write_phy(bp, MII_BMCR, BMCR_LOOPBACK);
+			do {
+				udelay(100);
+				bnx2_read_phy(bp, MII_BMSR, &bmsr);
+				bnx2_read_phy(bp, MII_BMSR, &bmsr);
+				i++;
+			} while ((bmsr & BMSR_LSTATUS) && (i < 620));
+		}
+
+		bnx2_write_phy(bp, MII_BMCR, new_bmcr);
+
+		/* Normally, the new speed is setup after the link has
+		 * gone down and up again. In some cases, link will not go
+		 * down so we need to set up the new speed here.
+		 */
+		if (bmsr & BMSR_LSTATUS) {
+			bp->line_speed = bp->req_line_speed;
+			bp->duplex = bp->req_duplex;
+			bnx2_resolve_flow_ctrl(bp);
+			bnx2_set_mac_link(bp);
+		}
+	}
+	return 0;
+}
+
+static int
+bnx2_setup_phy(struct bnx2 *bp)
+{
+	if (bp->loopback == MAC_LOOPBACK)
+		return 0;
+
+	if (bp->phy_flags & PHY_SERDES_FLAG) {
+		return (bnx2_setup_serdes_phy(bp));
+	}
+	else {
+		return (bnx2_setup_copper_phy(bp));
+	}
+}
+
+static int
+bnx2_init_5708s_phy(struct bnx2 *bp)
+{
+	u32 val;
+
+	bnx2_write_phy(bp, BCM5708S_BLK_ADDR, BCM5708S_BLK_ADDR_DIG3);
+	bnx2_write_phy(bp, BCM5708S_DIG_3_0, BCM5708S_DIG_3_0_USE_IEEE);
+	bnx2_write_phy(bp, BCM5708S_BLK_ADDR, BCM5708S_BLK_ADDR_DIG);
+
+	bnx2_read_phy(bp, BCM5708S_1000X_CTL1, &val);
+	val |= BCM5708S_1000X_CTL1_FIBER_MODE | BCM5708S_1000X_CTL1_AUTODET_EN;
+	bnx2_write_phy(bp, BCM5708S_1000X_CTL1, val);
+
+	bnx2_read_phy(bp, BCM5708S_1000X_CTL2, &val);
+	val |= BCM5708S_1000X_CTL2_PLLEL_DET_EN;
+	bnx2_write_phy(bp, BCM5708S_1000X_CTL2, val);
+
+	if (bp->phy_flags & PHY_2_5G_CAPABLE_FLAG) {
+		bnx2_read_phy(bp, BCM5708S_UP1, &val);
+		val |= BCM5708S_UP1_2G5;
+		bnx2_write_phy(bp, BCM5708S_UP1, val);
+	}
+
+	if ((CHIP_ID(bp) == CHIP_ID_5708_A0) ||
+	    (CHIP_ID(bp) == CHIP_ID_5708_B0) ||
+	    (CHIP_ID(bp) == CHIP_ID_5708_B1)) {
+		/* increase tx signal amplitude */
+		bnx2_write_phy(bp, BCM5708S_BLK_ADDR,
+			       BCM5708S_BLK_ADDR_TX_MISC);
+		bnx2_read_phy(bp, BCM5708S_TX_ACTL1, &val);
+		val &= ~BCM5708S_TX_ACTL1_DRIVER_VCM;
+		bnx2_write_phy(bp, BCM5708S_TX_ACTL1, val);
+		bnx2_write_phy(bp, BCM5708S_BLK_ADDR, BCM5708S_BLK_ADDR_DIG);
+	}
+
+	val = REG_RD_IND(bp, bp->shmem_base + BNX2_PORT_HW_CFG_CONFIG) &
+	      BNX2_PORT_HW_CFG_CFG_TXCTL3_MASK;
+
+	if (val) {
+		u32 is_backplane;
+
+		is_backplane = REG_RD_IND(bp, bp->shmem_base +
+					  BNX2_SHARED_HW_CFG_CONFIG);
+		if (is_backplane & BNX2_SHARED_HW_CFG_PHY_BACKPLANE) {
+			bnx2_write_phy(bp, BCM5708S_BLK_ADDR,
+				       BCM5708S_BLK_ADDR_TX_MISC);
+			bnx2_write_phy(bp, BCM5708S_TX_ACTL3, val);
+			bnx2_write_phy(bp, BCM5708S_BLK_ADDR,
+				       BCM5708S_BLK_ADDR_DIG);
+		}
+	}
+	return 0;
+}
+
+static int
+bnx2_init_5706s_phy(struct bnx2 *bp)
+{
+	u32 val;
+
+	bp->phy_flags &= ~PHY_PARALLEL_DETECT_FLAG;
+
+	if (CHIP_NUM(bp) == CHIP_NUM_5706) {
+        	REG_WR(bp, BNX2_MISC_UNUSED0, 0x300);
+	}
+
+
+	bnx2_write_phy(bp, 0x18, 0x7);
+	bnx2_read_phy(bp, 0x18, &val);
+	bnx2_write_phy(bp, 0x18, val & ~0x4007);
+
+	bnx2_write_phy(bp, 0x1c, 0x6c00);
+	bnx2_read_phy(bp, 0x1c, &val);
+	bnx2_write_phy(bp, 0x1c, (val & 0x3fd) | 0xec00);
+
+	return 0;
+}
+
+static int
+bnx2_init_copper_phy(struct bnx2 *bp)
+{
+	u32 val;
+
+	bp->phy_flags |= PHY_CRC_FIX_FLAG;
+
+	if (bp->phy_flags & PHY_CRC_FIX_FLAG) {
+		bnx2_write_phy(bp, 0x18, 0x0c00);
+		bnx2_write_phy(bp, 0x17, 0x000a);
+		bnx2_write_phy(bp, 0x15, 0x310b);
+		bnx2_write_phy(bp, 0x17, 0x201f);
+		bnx2_write_phy(bp, 0x15, 0x9506);
+		bnx2_write_phy(bp, 0x17, 0x401f);
+		bnx2_write_phy(bp, 0x15, 0x14e2);
+		bnx2_write_phy(bp, 0x18, 0x0400);
+	}
+
+	bnx2_write_phy(bp, 0x18, 0x7);
+	bnx2_read_phy(bp, 0x18, &val);
+	bnx2_write_phy(bp, 0x18, val & ~0x4007);
+
+	bnx2_read_phy(bp, 0x10, &val);
+	bnx2_write_phy(bp, 0x10, val & ~0x1);
+
+	/* ethernet@wirespeed */
+	bnx2_write_phy(bp, 0x18, 0x7007);
+	bnx2_read_phy(bp, 0x18, &val);
+	bnx2_write_phy(bp, 0x18, val | (1 << 15) | (1 << 4));
+	return 0;
+}
+
+static int
+bnx2_init_phy(struct bnx2 *bp)
+{
+	u32 val;
+	int rc = 0;
+
+	bp->phy_flags &= ~PHY_INT_MODE_MASK_FLAG;
+	bp->phy_flags |= PHY_INT_MODE_LINK_READY_FLAG;
+
+        REG_WR(bp, BNX2_EMAC_ATTENTION_ENA, BNX2_EMAC_ATTENTION_ENA_LINK);
+
+	bnx2_reset_phy(bp);
+
+	bnx2_read_phy(bp, MII_PHYSID1, &val);
+	bp->phy_id = val << 16;
+	bnx2_read_phy(bp, MII_PHYSID2, &val);
+	bp->phy_id |= val & 0xffff;
+
+	if (bp->phy_flags & PHY_SERDES_FLAG) {
+		if (CHIP_NUM(bp) == CHIP_NUM_5706)
+			rc = bnx2_init_5706s_phy(bp);
+		else if (CHIP_NUM(bp) == CHIP_NUM_5708)
+			rc = bnx2_init_5708s_phy(bp);
+	}
+	else {
+		rc = bnx2_init_copper_phy(bp);
+	}
+
+	bnx2_setup_phy(bp);
+
+	return rc;
+}
+
+static int
+bnx2_fw_sync(struct bnx2 *bp, u32 msg_data, int silent)
+{
+	int i;
+	u32 val;
+
+	bp->fw_wr_seq++;
+	msg_data |= bp->fw_wr_seq;
+
+	REG_WR_IND(bp, bp->shmem_base + BNX2_DRV_MB, msg_data);
+
+	/* wait for an acknowledgement. */
+	for (i = 0; i < (FW_ACK_TIME_OUT_MS / 50); i++) {
+		mdelay(50);
+
+		val = REG_RD_IND(bp, bp->shmem_base + BNX2_FW_MB);
+
+		if ((val & BNX2_FW_MSG_ACK) == (msg_data & BNX2_DRV_MSG_SEQ))
+			break;
+	}
+	if ((msg_data & BNX2_DRV_MSG_DATA) == BNX2_DRV_MSG_DATA_WAIT0)
+		return 0;
+
+	/* If we timed out, inform the firmware that this is the case. */
+	if ((val & BNX2_FW_MSG_ACK) != (msg_data & BNX2_DRV_MSG_SEQ)) {
+		if (!silent)
+		  printf("fw sync timeout, reset code = %x\n", (unsigned int) msg_data);
+
+		msg_data &= ~BNX2_DRV_MSG_CODE;
+		msg_data |= BNX2_DRV_MSG_CODE_FW_TIMEOUT;
+
+		REG_WR_IND(bp, bp->shmem_base + BNX2_DRV_MB, msg_data);
+
+		return -EBUSY;
+	}
+
+	if ((val & BNX2_FW_MSG_STATUS_MASK) != BNX2_FW_MSG_STATUS_OK)
+		return -EIO;
+
+	return 0;
+}
+
+static void
+bnx2_init_context(struct bnx2 *bp)
+{
+	u32 vcid;
+
+	vcid = 96;
+	while (vcid) {
+		u32 vcid_addr, pcid_addr, offset;
+
+		vcid--;
+
+		if (CHIP_ID(bp) == CHIP_ID_5706_A0) {
+			u32 new_vcid;
+
+			vcid_addr = GET_PCID_ADDR(vcid);
+			if (vcid & 0x8) {
+				new_vcid = 0x60 + (vcid & 0xf0) + (vcid & 0x7);
+			}
+			else {
+				new_vcid = vcid;
+			}
+			pcid_addr = GET_PCID_ADDR(new_vcid);
+		}
+		else {
+	    		vcid_addr = GET_CID_ADDR(vcid);
+			pcid_addr = vcid_addr;
+		}
+
+		REG_WR(bp, BNX2_CTX_VIRT_ADDR, 0x00);
+		REG_WR(bp, BNX2_CTX_PAGE_TBL, pcid_addr);
+
+		/* Zero out the context. */
+		for (offset = 0; offset < PHY_CTX_SIZE; offset += 4) {
+			CTX_WR(bp, 0x00, offset, 0);
+		}
+
+		REG_WR(bp, BNX2_CTX_VIRT_ADDR, vcid_addr);
+		REG_WR(bp, BNX2_CTX_PAGE_TBL, pcid_addr);
+	}
+}
+
+static int
+bnx2_alloc_bad_rbuf(struct bnx2 *bp)
+{
+	u16 good_mbuf[512];
+	u32 good_mbuf_cnt;
+	u32 val;
+
+	REG_WR(bp, BNX2_MISC_ENABLE_SET_BITS,
+		BNX2_MISC_ENABLE_SET_BITS_RX_MBUF_ENABLE);
+
+	good_mbuf_cnt = 0;
+
+	/* Allocate a bunch of mbufs and save the good ones in an array. */
+	val = REG_RD_IND(bp, BNX2_RBUF_STATUS1);
+	while (val & BNX2_RBUF_STATUS1_FREE_COUNT) {
+		REG_WR_IND(bp, BNX2_RBUF_COMMAND, BNX2_RBUF_COMMAND_ALLOC_REQ);
+
+		val = REG_RD_IND(bp, BNX2_RBUF_FW_BUF_ALLOC);
+
+		val &= BNX2_RBUF_FW_BUF_ALLOC_VALUE;
+
+		/* The addresses with Bit 9 set are bad memory blocks. */
+		if (!(val & (1 << 9))) {
+			good_mbuf[good_mbuf_cnt] = (u16) val;
+			good_mbuf_cnt++;
+		}
+
+		val = REG_RD_IND(bp, BNX2_RBUF_STATUS1);
+	}
+
+	/* Free the good ones back to the mbuf pool thus discarding
+	 * all the bad ones. */
+	while (good_mbuf_cnt) {
+		good_mbuf_cnt--;
+
+		val = good_mbuf[good_mbuf_cnt];
+		val = (val << 9) | val | 1;
+
+		REG_WR_IND(bp, BNX2_RBUF_FW_BUF_FREE, val);
+	}
+	return 0;
+}
+
+static void
+bnx2_set_mac_addr(struct bnx2 *bp) 
+{
+	u32 val;
+	u8 *mac_addr = bp->nic->node_addr;
+
+	val = (mac_addr[0] << 8) | mac_addr[1];
+
+	REG_WR(bp, BNX2_EMAC_MAC_MATCH0, val);
+
+	val = (mac_addr[2] << 24) | (mac_addr[3] << 16) | 
+		(mac_addr[4] << 8) | mac_addr[5];
+
+	REG_WR(bp, BNX2_EMAC_MAC_MATCH1, val);
+}
+
+static void
+bnx2_set_rx_mode(struct nic *nic __unused)
+{
+	struct bnx2 *bp = &bnx2;
+	u32 rx_mode, sort_mode;
+	int i;
+
+	rx_mode = bp->rx_mode & ~(BNX2_EMAC_RX_MODE_PROMISCUOUS |
+				  BNX2_EMAC_RX_MODE_KEEP_VLAN_TAG);
+	sort_mode = 1 | BNX2_RPM_SORT_USER0_BC_EN;
+
+	if (!(bp->flags & ASF_ENABLE_FLAG)) {
+		rx_mode |= BNX2_EMAC_RX_MODE_KEEP_VLAN_TAG;
+	}
+
+	/* Accept all multicasts */
+	for (i = 0; i < NUM_MC_HASH_REGISTERS; i++) {
+		REG_WR(bp, BNX2_EMAC_MULTICAST_HASH0 + (i * 4),
+		       0xffffffff);
+       	}
+	sort_mode |= BNX2_RPM_SORT_USER0_MC_EN;
+
+	if (rx_mode != bp->rx_mode) {
+		bp->rx_mode = rx_mode;
+		REG_WR(bp, BNX2_EMAC_RX_MODE, rx_mode);
+	}
+
+	REG_WR(bp, BNX2_RPM_SORT_USER0, 0x0);
+	REG_WR(bp, BNX2_RPM_SORT_USER0, sort_mode);
+	REG_WR(bp, BNX2_RPM_SORT_USER0, sort_mode | BNX2_RPM_SORT_USER0_ENA);
+}
+
+static void
+load_rv2p_fw(struct bnx2 *bp, u32 *rv2p_code, u32 rv2p_code_len, u32 rv2p_proc)
+{
+	unsigned int i;
+	u32 val;
+
+
+	for (i = 0; i < rv2p_code_len; i += 8) {
+		REG_WR(bp, BNX2_RV2P_INSTR_HIGH, *rv2p_code);
+		rv2p_code++;
+		REG_WR(bp, BNX2_RV2P_INSTR_LOW, *rv2p_code);
+		rv2p_code++;
+
+		if (rv2p_proc == RV2P_PROC1) {
+			val = (i / 8) | BNX2_RV2P_PROC1_ADDR_CMD_RDWR;
+			REG_WR(bp, BNX2_RV2P_PROC1_ADDR_CMD, val);
+		}
+		else {
+			val = (i / 8) | BNX2_RV2P_PROC2_ADDR_CMD_RDWR;
+			REG_WR(bp, BNX2_RV2P_PROC2_ADDR_CMD, val);
+		}
+	}
+
+	/* Reset the processor, un-stall is done later. */
+	if (rv2p_proc == RV2P_PROC1) {
+		REG_WR(bp, BNX2_RV2P_COMMAND, BNX2_RV2P_COMMAND_PROC1_RESET);
+	}
+	else {
+		REG_WR(bp, BNX2_RV2P_COMMAND, BNX2_RV2P_COMMAND_PROC2_RESET);
+	}
+}
+
+static void
+load_cpu_fw(struct bnx2 *bp, struct cpu_reg *cpu_reg, struct fw_info *fw)
+{
+	u32 offset;
+	u32 val;
+
+	/* Halt the CPU. */
+	val = REG_RD_IND(bp, cpu_reg->mode);
+	val |= cpu_reg->mode_value_halt;
+	REG_WR_IND(bp, cpu_reg->mode, val);
+	REG_WR_IND(bp, cpu_reg->state, cpu_reg->state_value_clear);
+
+	/* Load the Text area. */
+	offset = cpu_reg->spad_base + (fw->text_addr - cpu_reg->mips_view_base);
+	if (fw->text) {
+		unsigned int j;
+
+		for (j = 0; j < (fw->text_len / 4); j++, offset += 4) {
+			REG_WR_IND(bp, offset, fw->text[j]);
+	        }
+	}
+
+	/* Load the Data area. */
+	offset = cpu_reg->spad_base + (fw->data_addr - cpu_reg->mips_view_base);
+	if (fw->data) {
+		unsigned int j;
+
+		for (j = 0; j < (fw->data_len / 4); j++, offset += 4) {
+			REG_WR_IND(bp, offset, fw->data[j]);
+		}
+	}
+
+	/* Load the SBSS area. */
+	offset = cpu_reg->spad_base + (fw->sbss_addr - cpu_reg->mips_view_base);
+	if (fw->sbss) {
+		unsigned int j;
+
+		for (j = 0; j < (fw->sbss_len / 4); j++, offset += 4) {
+			REG_WR_IND(bp, offset, fw->sbss[j]);
+		}
+	}
+
+	/* Load the BSS area. */
+	offset = cpu_reg->spad_base + (fw->bss_addr - cpu_reg->mips_view_base);
+	if (fw->bss) {
+		unsigned int j;
+
+		for (j = 0; j < (fw->bss_len/4); j++, offset += 4) {
+			REG_WR_IND(bp, offset, fw->bss[j]);
+		}
+	}
+
+	/* Load the Read-Only area. */
+	offset = cpu_reg->spad_base +
+		(fw->rodata_addr - cpu_reg->mips_view_base);
+	if (fw->rodata) {
+		unsigned int j;
+
+		for (j = 0; j < (fw->rodata_len / 4); j++, offset += 4) {
+			REG_WR_IND(bp, offset, fw->rodata[j]);
+		}
+	}
+
+	/* Clear the pre-fetch instruction. */
+	REG_WR_IND(bp, cpu_reg->inst, 0);
+	REG_WR_IND(bp, cpu_reg->pc, fw->start_addr);
+
+	/* Start the CPU. */
+	val = REG_RD_IND(bp, cpu_reg->mode);
+	val &= ~cpu_reg->mode_value_halt;
+	REG_WR_IND(bp, cpu_reg->state, cpu_reg->state_value_clear);
+	REG_WR_IND(bp, cpu_reg->mode, val);
+}
+
+static void
+bnx2_init_cpus(struct bnx2 *bp)
+{
+	struct cpu_reg cpu_reg;
+	struct fw_info fw;
+
+	/* Unfortunately, it looks like we need to load the firmware
+	 * before the card will work properly.  That means this driver
+	 * will be huge by Etherboot standards (approx. 50K compressed).
+	 */
+
+	/* Initialize the RV2P processor. */
+	load_rv2p_fw(bp, bnx2_rv2p_proc1, sizeof(bnx2_rv2p_proc1), RV2P_PROC1);
+	load_rv2p_fw(bp, bnx2_rv2p_proc2, sizeof(bnx2_rv2p_proc2), RV2P_PROC2);
+
+	/* Initialize the RX Processor. */
+	cpu_reg.mode = BNX2_RXP_CPU_MODE;
+	cpu_reg.mode_value_halt = BNX2_RXP_CPU_MODE_SOFT_HALT;
+	cpu_reg.mode_value_sstep = BNX2_RXP_CPU_MODE_STEP_ENA;
+	cpu_reg.state = BNX2_RXP_CPU_STATE;
+	cpu_reg.state_value_clear = 0xffffff;
+	cpu_reg.gpr0 = BNX2_RXP_CPU_REG_FILE;
+	cpu_reg.evmask = BNX2_RXP_CPU_EVENT_MASK;
+	cpu_reg.pc = BNX2_RXP_CPU_PROGRAM_COUNTER;
+	cpu_reg.inst = BNX2_RXP_CPU_INSTRUCTION;
+	cpu_reg.bp = BNX2_RXP_CPU_HW_BREAKPOINT;
+	cpu_reg.spad_base = BNX2_RXP_SCRATCH;
+	cpu_reg.mips_view_base = 0x8000000;
+
+	fw.ver_major = bnx2_RXP_b06FwReleaseMajor;
+	fw.ver_minor = bnx2_RXP_b06FwReleaseMinor;
+	fw.ver_fix = bnx2_RXP_b06FwReleaseFix;
+	fw.start_addr = bnx2_RXP_b06FwStartAddr;
+
+	fw.text_addr = bnx2_RXP_b06FwTextAddr;
+	fw.text_len = bnx2_RXP_b06FwTextLen;
+	fw.text_index = 0;
+	fw.text = bnx2_RXP_b06FwText;
+
+	fw.data_addr = bnx2_RXP_b06FwDataAddr;
+	fw.data_len = bnx2_RXP_b06FwDataLen;
+	fw.data_index = 0;
+	fw.data = bnx2_RXP_b06FwData;
+
+	fw.sbss_addr = bnx2_RXP_b06FwSbssAddr;
+	fw.sbss_len = bnx2_RXP_b06FwSbssLen;
+	fw.sbss_index = 0;
+	fw.sbss = bnx2_RXP_b06FwSbss;
+
+	fw.bss_addr = bnx2_RXP_b06FwBssAddr;
+	fw.bss_len = bnx2_RXP_b06FwBssLen;
+	fw.bss_index = 0;
+	fw.bss = bnx2_RXP_b06FwBss;
+
+	fw.rodata_addr = bnx2_RXP_b06FwRodataAddr;
+	fw.rodata_len = bnx2_RXP_b06FwRodataLen;
+	fw.rodata_index = 0;
+	fw.rodata = bnx2_RXP_b06FwRodata;
+
+	load_cpu_fw(bp, &cpu_reg, &fw);
+
+	/* Initialize the TX Processor. */
+	cpu_reg.mode = BNX2_TXP_CPU_MODE;
+	cpu_reg.mode_value_halt = BNX2_TXP_CPU_MODE_SOFT_HALT;
+	cpu_reg.mode_value_sstep = BNX2_TXP_CPU_MODE_STEP_ENA;
+	cpu_reg.state = BNX2_TXP_CPU_STATE;
+	cpu_reg.state_value_clear = 0xffffff;
+	cpu_reg.gpr0 = BNX2_TXP_CPU_REG_FILE;
+	cpu_reg.evmask = BNX2_TXP_CPU_EVENT_MASK;
+	cpu_reg.pc = BNX2_TXP_CPU_PROGRAM_COUNTER;
+	cpu_reg.inst = BNX2_TXP_CPU_INSTRUCTION;
+	cpu_reg.bp = BNX2_TXP_CPU_HW_BREAKPOINT;
+	cpu_reg.spad_base = BNX2_TXP_SCRATCH;
+	cpu_reg.mips_view_base = 0x8000000;
+    
+	fw.ver_major = bnx2_TXP_b06FwReleaseMajor;
+	fw.ver_minor = bnx2_TXP_b06FwReleaseMinor;
+	fw.ver_fix = bnx2_TXP_b06FwReleaseFix;
+	fw.start_addr = bnx2_TXP_b06FwStartAddr;
+
+	fw.text_addr = bnx2_TXP_b06FwTextAddr;
+	fw.text_len = bnx2_TXP_b06FwTextLen;
+	fw.text_index = 0;
+	fw.text = bnx2_TXP_b06FwText;
+
+	fw.data_addr = bnx2_TXP_b06FwDataAddr;
+	fw.data_len = bnx2_TXP_b06FwDataLen;
+	fw.data_index = 0;
+	fw.data = bnx2_TXP_b06FwData;
+
+	fw.sbss_addr = bnx2_TXP_b06FwSbssAddr;
+	fw.sbss_len = bnx2_TXP_b06FwSbssLen;
+	fw.sbss_index = 0;
+	fw.sbss = bnx2_TXP_b06FwSbss;
+
+	fw.bss_addr = bnx2_TXP_b06FwBssAddr;
+	fw.bss_len = bnx2_TXP_b06FwBssLen;
+	fw.bss_index = 0;
+	fw.bss = bnx2_TXP_b06FwBss;
+
+	fw.rodata_addr = bnx2_TXP_b06FwRodataAddr;
+	fw.rodata_len = bnx2_TXP_b06FwRodataLen;
+	fw.rodata_index = 0;
+	fw.rodata = bnx2_TXP_b06FwRodata;
+
+	load_cpu_fw(bp, &cpu_reg, &fw);
+
+	/* Initialize the TX Patch-up Processor. */
+	cpu_reg.mode = BNX2_TPAT_CPU_MODE;
+	cpu_reg.mode_value_halt = BNX2_TPAT_CPU_MODE_SOFT_HALT;
+	cpu_reg.mode_value_sstep = BNX2_TPAT_CPU_MODE_STEP_ENA;
+	cpu_reg.state = BNX2_TPAT_CPU_STATE;
+	cpu_reg.state_value_clear = 0xffffff;
+	cpu_reg.gpr0 = BNX2_TPAT_CPU_REG_FILE;
+	cpu_reg.evmask = BNX2_TPAT_CPU_EVENT_MASK;
+	cpu_reg.pc = BNX2_TPAT_CPU_PROGRAM_COUNTER;
+	cpu_reg.inst = BNX2_TPAT_CPU_INSTRUCTION;
+	cpu_reg.bp = BNX2_TPAT_CPU_HW_BREAKPOINT;
+	cpu_reg.spad_base = BNX2_TPAT_SCRATCH;
+	cpu_reg.mips_view_base = 0x8000000;
+    
+	fw.ver_major = bnx2_TPAT_b06FwReleaseMajor;
+	fw.ver_minor = bnx2_TPAT_b06FwReleaseMinor;
+	fw.ver_fix = bnx2_TPAT_b06FwReleaseFix;
+	fw.start_addr = bnx2_TPAT_b06FwStartAddr;
+
+	fw.text_addr = bnx2_TPAT_b06FwTextAddr;
+	fw.text_len = bnx2_TPAT_b06FwTextLen;
+	fw.text_index = 0;
+	fw.text = bnx2_TPAT_b06FwText;
+
+	fw.data_addr = bnx2_TPAT_b06FwDataAddr;
+	fw.data_len = bnx2_TPAT_b06FwDataLen;
+	fw.data_index = 0;
+	fw.data = bnx2_TPAT_b06FwData;
+
+	fw.sbss_addr = bnx2_TPAT_b06FwSbssAddr;
+	fw.sbss_len = bnx2_TPAT_b06FwSbssLen;
+	fw.sbss_index = 0;
+	fw.sbss = bnx2_TPAT_b06FwSbss;
+
+	fw.bss_addr = bnx2_TPAT_b06FwBssAddr;
+	fw.bss_len = bnx2_TPAT_b06FwBssLen;
+	fw.bss_index = 0;
+	fw.bss = bnx2_TPAT_b06FwBss;
+
+	fw.rodata_addr = bnx2_TPAT_b06FwRodataAddr;
+	fw.rodata_len = bnx2_TPAT_b06FwRodataLen;
+	fw.rodata_index = 0;
+	fw.rodata = bnx2_TPAT_b06FwRodata;
+
+	load_cpu_fw(bp, &cpu_reg, &fw);
+
+	/* Initialize the Completion Processor. */
+	cpu_reg.mode = BNX2_COM_CPU_MODE;
+	cpu_reg.mode_value_halt = BNX2_COM_CPU_MODE_SOFT_HALT;
+	cpu_reg.mode_value_sstep = BNX2_COM_CPU_MODE_STEP_ENA;
+	cpu_reg.state = BNX2_COM_CPU_STATE;
+	cpu_reg.state_value_clear = 0xffffff;
+	cpu_reg.gpr0 = BNX2_COM_CPU_REG_FILE;
+	cpu_reg.evmask = BNX2_COM_CPU_EVENT_MASK;
+	cpu_reg.pc = BNX2_COM_CPU_PROGRAM_COUNTER;
+	cpu_reg.inst = BNX2_COM_CPU_INSTRUCTION;
+	cpu_reg.bp = BNX2_COM_CPU_HW_BREAKPOINT;
+	cpu_reg.spad_base = BNX2_COM_SCRATCH;
+	cpu_reg.mips_view_base = 0x8000000;
+    
+	fw.ver_major = bnx2_COM_b06FwReleaseMajor;
+	fw.ver_minor = bnx2_COM_b06FwReleaseMinor;
+	fw.ver_fix = bnx2_COM_b06FwReleaseFix;
+	fw.start_addr = bnx2_COM_b06FwStartAddr;
+
+	fw.text_addr = bnx2_COM_b06FwTextAddr;
+	fw.text_len = bnx2_COM_b06FwTextLen;
+	fw.text_index = 0;
+	fw.text = bnx2_COM_b06FwText;
+
+	fw.data_addr = bnx2_COM_b06FwDataAddr;
+	fw.data_len = bnx2_COM_b06FwDataLen;
+	fw.data_index = 0;
+	fw.data = bnx2_COM_b06FwData;
+
+	fw.sbss_addr = bnx2_COM_b06FwSbssAddr;
+	fw.sbss_len = bnx2_COM_b06FwSbssLen;
+	fw.sbss_index = 0;
+	fw.sbss = bnx2_COM_b06FwSbss;
+
+	fw.bss_addr = bnx2_COM_b06FwBssAddr;
+	fw.bss_len = bnx2_COM_b06FwBssLen;
+	fw.bss_index = 0;
+	fw.bss = bnx2_COM_b06FwBss;
+
+	fw.rodata_addr = bnx2_COM_b06FwRodataAddr;
+	fw.rodata_len = bnx2_COM_b06FwRodataLen;
+	fw.rodata_index = 0;
+	fw.rodata = bnx2_COM_b06FwRodata;
+
+	load_cpu_fw(bp, &cpu_reg, &fw);
+
+}
+
+static int
+bnx2_set_power_state_0(struct bnx2 *bp)
+{
+	u16 pmcsr;
+	u32 val;
+
+	pci_read_config_word(bp->pdev, bp->pm_cap + PCI_PM_CTRL, &pmcsr);
+
+	pci_write_config_word(bp->pdev, bp->pm_cap + PCI_PM_CTRL,
+		(pmcsr & ~PCI_PM_CTRL_STATE_MASK) |
+		PCI_PM_CTRL_PME_STATUS);
+
+	if (pmcsr & PCI_PM_CTRL_STATE_MASK)
+		/* delay required during transition out of D3hot */
+		mdelay(20);
+
+	val = REG_RD(bp, BNX2_EMAC_MODE);
+	val |= BNX2_EMAC_MODE_MPKT_RCVD | BNX2_EMAC_MODE_ACPI_RCVD;
+	val &= ~BNX2_EMAC_MODE_MPKT;
+	REG_WR(bp, BNX2_EMAC_MODE, val);
+
+	val = REG_RD(bp, BNX2_RPM_CONFIG);
+	val &= ~BNX2_RPM_CONFIG_ACPI_ENA;
+	REG_WR(bp, BNX2_RPM_CONFIG, val);
+		
+	return 0;
+}
+
+static void
+bnx2_enable_nvram_access(struct bnx2 *bp)
+{
+	u32 val;
+
+	val = REG_RD(bp, BNX2_NVM_ACCESS_ENABLE);
+	/* Enable both bits, even on read. */
+	REG_WR(bp, BNX2_NVM_ACCESS_ENABLE, 
+	       val | BNX2_NVM_ACCESS_ENABLE_EN | BNX2_NVM_ACCESS_ENABLE_WR_EN);
+}
+
+static void
+bnx2_disable_nvram_access(struct bnx2 *bp)
+{
+	u32 val;
+
+	val = REG_RD(bp, BNX2_NVM_ACCESS_ENABLE);
+	/* Disable both bits, even after read. */
+	REG_WR(bp, BNX2_NVM_ACCESS_ENABLE, 
+		val & ~(BNX2_NVM_ACCESS_ENABLE_EN |
+			BNX2_NVM_ACCESS_ENABLE_WR_EN));
+}
+
+static int
+bnx2_init_nvram(struct bnx2 *bp)
+{
+	u32 val;
+	int j, entry_count, rc;
+	struct flash_spec *flash;
+
+	/* Determine the selected interface. */
+	val = REG_RD(bp, BNX2_NVM_CFG1);
+
+	entry_count = sizeof(flash_table) / sizeof(struct flash_spec);
+
+	rc = 0;
+	if (val & 0x40000000) {
+		/* Flash interface has been reconfigured */
+		for (j = 0, flash = &flash_table[0]; j < entry_count;
+		     j++, flash++) {
+			if ((val & FLASH_BACKUP_STRAP_MASK) ==
+			    (flash->config1 & FLASH_BACKUP_STRAP_MASK)) {
+				bp->flash_info = flash;
+				break;
+			}
+		}
+	}
+	else {
+		u32 mask;
+		/* Not yet been reconfigured */
+
+		if (val & (1 << 23))
+			mask = FLASH_BACKUP_STRAP_MASK;
+		else
+			mask = FLASH_STRAP_MASK;
+
+		for (j = 0, flash = &flash_table[0]; j < entry_count;
+			j++, flash++) {
+
+			if ((val & mask) == (flash->strapping & mask)) {
+				bp->flash_info = flash;
+
+				/* Enable access to flash interface */
+				bnx2_enable_nvram_access(bp);
+
+				/* Reconfigure the flash interface */
+				REG_WR(bp, BNX2_NVM_CFG1, flash->config1);
+				REG_WR(bp, BNX2_NVM_CFG2, flash->config2);
+				REG_WR(bp, BNX2_NVM_CFG3, flash->config3);
+				REG_WR(bp, BNX2_NVM_WRITE1, flash->write1);
+
+				/* Disable access to flash interface */
+				bnx2_disable_nvram_access(bp);
+
+				break;
+			}
+		}
+	} /* if (val & 0x40000000) */
+
+	if (j == entry_count) {
+		bp->flash_info = NULL;
+		printf("Unknown flash/EEPROM type.\n");
+		return -ENODEV;
+	}
+
+	val = REG_RD_IND(bp, bp->shmem_base + BNX2_SHARED_HW_CFG_CONFIG2);
+	val &= BNX2_SHARED_HW_CFG2_NVM_SIZE_MASK;
+	if (val) {
+		bp->flash_size = val;
+	}
+	else {
+		bp->flash_size = bp->flash_info->total_size;
+	}
+
+	return rc;
+}
+
+static int
+bnx2_reset_chip(struct bnx2 *bp, u32 reset_code)
+{
+	u32 val;
+	int i, rc = 0;
+
+	/* Wait for the current PCI transaction to complete before
+	 * issuing a reset. */
+	REG_WR(bp, BNX2_MISC_ENABLE_CLR_BITS,
+	       BNX2_MISC_ENABLE_CLR_BITS_TX_DMA_ENABLE |
+	       BNX2_MISC_ENABLE_CLR_BITS_DMA_ENGINE_ENABLE |
+	       BNX2_MISC_ENABLE_CLR_BITS_RX_DMA_ENABLE |
+	       BNX2_MISC_ENABLE_CLR_BITS_HOST_COALESCE_ENABLE);
+	val = REG_RD(bp, BNX2_MISC_ENABLE_CLR_BITS);
+	udelay(5);
+
+
+	/* Wait for the firmware to tell us it is ok to issue a reset. */
+	bnx2_fw_sync(bp, BNX2_DRV_MSG_DATA_WAIT0 | reset_code, 1);
+
+	/* Deposit a driver reset signature so the firmware knows that
+	 * this is a soft reset. */
+	REG_WR_IND(bp, bp->shmem_base + BNX2_DRV_RESET_SIGNATURE,
+		   BNX2_DRV_RESET_SIGNATURE_MAGIC);
+
+	/* Do a dummy read to force the chip to complete all current transaction
+	 * before we issue a reset. */
+	val = REG_RD(bp, BNX2_MISC_ID);
+
+	val = BNX2_PCICFG_MISC_CONFIG_CORE_RST_REQ |
+	      BNX2_PCICFG_MISC_CONFIG_REG_WINDOW_ENA |
+	      BNX2_PCICFG_MISC_CONFIG_TARGET_MB_WORD_SWAP;
+
+	/* Chip reset. */
+	REG_WR(bp, BNX2_PCICFG_MISC_CONFIG, val);
+
+	if ((CHIP_ID(bp) == CHIP_ID_5706_A0) ||
+	    (CHIP_ID(bp) == CHIP_ID_5706_A1))
+		mdelay(15);
+
+	/* Reset takes approximate 30 usec */
+	for (i = 0; i < 10; i++) {
+		val = REG_RD(bp, BNX2_PCICFG_MISC_CONFIG);
+		if ((val & (BNX2_PCICFG_MISC_CONFIG_CORE_RST_REQ |
+			    BNX2_PCICFG_MISC_CONFIG_CORE_RST_BSY)) == 0) {
+			break;
+		}
+		udelay(10);
+	}
+
+	if (val & (BNX2_PCICFG_MISC_CONFIG_CORE_RST_REQ |
+		   BNX2_PCICFG_MISC_CONFIG_CORE_RST_BSY)) {
+		printf("Chip reset did not complete\n");
+		return -EBUSY;
+	}
+
+	/* Make sure byte swapping is properly configured. */
+	val = REG_RD(bp, BNX2_PCI_SWAP_DIAG0);
+	if (val != 0x01020304) {
+		printf("Chip not in correct endian mode\n");
+		return -ENODEV;
+	}
+
+	/* Wait for the firmware to finish its initialization. */
+	rc = bnx2_fw_sync(bp, BNX2_DRV_MSG_DATA_WAIT1 | reset_code, 0);
+	if (rc) {
+		return rc;
+	}
+
+	if (CHIP_ID(bp) == CHIP_ID_5706_A0) {
+		/* Adjust the voltage regular to two steps lower.  The default
+		 * of this register is 0x0000000e. */
+		REG_WR(bp, BNX2_MISC_VREG_CONTROL, 0x000000fa);
+
+		/* Remove bad rbuf memory from the free pool. */
+		rc = bnx2_alloc_bad_rbuf(bp);
+	}
+
+	return rc;
+}
+
+static void
+bnx2_disable(struct nic *nic __unused)
+{
+	struct bnx2* bp = &bnx2;
+
+	if (bp->regview) {
+		bnx2_reset_chip(bp, BNX2_DRV_MSG_CODE_UNLOAD);
+		iounmap(bp->regview);
+	}
+}
+
+static int
+bnx2_init_chip(struct bnx2 *bp)
+{
+	u32 val;
+	int rc;
+
+	/* Make sure the interrupt is not active. */
+	REG_WR(bp, BNX2_PCICFG_INT_ACK_CMD, BNX2_PCICFG_INT_ACK_CMD_MASK_INT);
+
+	val = BNX2_DMA_CONFIG_DATA_BYTE_SWAP |
+	      BNX2_DMA_CONFIG_DATA_WORD_SWAP |
+#if __BYTE_ORDER ==  __BIG_ENDIAN
+	      BNX2_DMA_CONFIG_CNTL_BYTE_SWAP | 
+#endif
+	      BNX2_DMA_CONFIG_CNTL_WORD_SWAP | 
+	      DMA_READ_CHANS << 12 |
+	      DMA_WRITE_CHANS << 16;
+
+	val |= (0x2 << 20) | (1 << 11);
+
+	if ((bp->flags & PCIX_FLAG) && (bp->bus_speed_mhz == 133))
+		val |= (1 << 23);
+
+	if ((CHIP_NUM(bp) == CHIP_NUM_5706) &&
+	    (CHIP_ID(bp) != CHIP_ID_5706_A0) && !(bp->flags & PCIX_FLAG))
+		val |= BNX2_DMA_CONFIG_CNTL_PING_PONG_DMA;
+
+	REG_WR(bp, BNX2_DMA_CONFIG, val);
+
+	if (CHIP_ID(bp) == CHIP_ID_5706_A0) {
+		val = REG_RD(bp, BNX2_TDMA_CONFIG);
+		val |= BNX2_TDMA_CONFIG_ONE_DMA;
+		REG_WR(bp, BNX2_TDMA_CONFIG, val);
+	}
+
+	if (bp->flags & PCIX_FLAG) {
+		u16 val16;
+
+		pci_read_config_word(bp->pdev, bp->pcix_cap + PCI_X_CMD,
+				     &val16);
+		pci_write_config_word(bp->pdev, bp->pcix_cap + PCI_X_CMD,
+				      val16 & ~PCI_X_CMD_ERO);
+	}
+
+	REG_WR(bp, BNX2_MISC_ENABLE_SET_BITS,
+	       BNX2_MISC_ENABLE_SET_BITS_HOST_COALESCE_ENABLE |
+	       BNX2_MISC_ENABLE_STATUS_BITS_RX_V2P_ENABLE |
+	       BNX2_MISC_ENABLE_STATUS_BITS_CONTEXT_ENABLE);
+
+	/* Initialize context mapping and zero out the quick contexts.  The
+	 * context block must have already been enabled. */
+	bnx2_init_context(bp);
+
+	bnx2_init_nvram(bp);
+	bnx2_init_cpus(bp);
+
+	bnx2_set_mac_addr(bp);
+
+	val = REG_RD(bp, BNX2_MQ_CONFIG);
+	val &= ~BNX2_MQ_CONFIG_KNL_BYP_BLK_SIZE;
+	val |= BNX2_MQ_CONFIG_KNL_BYP_BLK_SIZE_256;
+	REG_WR(bp, BNX2_MQ_CONFIG, val);
+
+	val = 0x10000 + (MAX_CID_CNT * MB_KERNEL_CTX_SIZE);
+	REG_WR(bp, BNX2_MQ_KNL_BYP_WIND_START, val);
+	REG_WR(bp, BNX2_MQ_KNL_WIND_END, val);
+
+	val = (BCM_PAGE_BITS - 8) << 24;
+	REG_WR(bp, BNX2_RV2P_CONFIG, val);
+
+	/* Configure page size. */
+	val = REG_RD(bp, BNX2_TBDR_CONFIG);
+	val &= ~BNX2_TBDR_CONFIG_PAGE_SIZE;
+	val |= (BCM_PAGE_BITS - 8) << 24 | 0x40;
+	REG_WR(bp, BNX2_TBDR_CONFIG, val);
+
+	val = bp->mac_addr[0] +
+	      (bp->mac_addr[1] << 8) +
+	      (bp->mac_addr[2] << 16) +
+	      bp->mac_addr[3] +
+	      (bp->mac_addr[4] << 8) +
+	      (bp->mac_addr[5] << 16);
+	REG_WR(bp, BNX2_EMAC_BACKOFF_SEED, val);
+
+	/* Program the MTU.  Also include 4 bytes for CRC32. */
+	val = ETH_MAX_MTU + ETH_HLEN + 4;
+	if (val > (MAX_ETHERNET_PACKET_SIZE + 4))
+		val |= BNX2_EMAC_RX_MTU_SIZE_JUMBO_ENA;
+	REG_WR(bp, BNX2_EMAC_RX_MTU_SIZE, val);
+
+	bp->last_status_idx = 0;
+	bp->rx_mode = BNX2_EMAC_RX_MODE_SORT_MODE;
+
+	/* Set up how to generate a link change interrupt. */
+	REG_WR(bp, BNX2_EMAC_ATTENTION_ENA, BNX2_EMAC_ATTENTION_ENA_LINK);
+
+	REG_WR(bp, BNX2_HC_STATUS_ADDR_L,
+	       (u64) bp->status_blk_mapping & 0xffffffff);
+	REG_WR(bp, BNX2_HC_STATUS_ADDR_H, (u64) bp->status_blk_mapping >> 32);
+
+	REG_WR(bp, BNX2_HC_STATISTICS_ADDR_L,
+	       (u64) bp->stats_blk_mapping & 0xffffffff);
+	REG_WR(bp, BNX2_HC_STATISTICS_ADDR_H,
+	       (u64) bp->stats_blk_mapping >> 32);
+
+	REG_WR(bp, BNX2_HC_TX_QUICK_CONS_TRIP, 
+	       (bp->tx_quick_cons_trip_int << 16) | bp->tx_quick_cons_trip);
+
+	REG_WR(bp, BNX2_HC_RX_QUICK_CONS_TRIP,
+	       (bp->rx_quick_cons_trip_int << 16) | bp->rx_quick_cons_trip);
+
+	REG_WR(bp, BNX2_HC_COMP_PROD_TRIP,
+	       (bp->comp_prod_trip_int << 16) | bp->comp_prod_trip);
+
+	REG_WR(bp, BNX2_HC_TX_TICKS, (bp->tx_ticks_int << 16) | bp->tx_ticks);
+
+	REG_WR(bp, BNX2_HC_RX_TICKS, (bp->rx_ticks_int << 16) | bp->rx_ticks);
+
+	REG_WR(bp, BNX2_HC_COM_TICKS,
+	       (bp->com_ticks_int << 16) | bp->com_ticks);
+
+	REG_WR(bp, BNX2_HC_CMD_TICKS,
+	       (bp->cmd_ticks_int << 16) | bp->cmd_ticks);
+
+	REG_WR(bp, BNX2_HC_STATS_TICKS, bp->stats_ticks & 0xffff00);
+	REG_WR(bp, BNX2_HC_STAT_COLLECT_TICKS, 0xbb8);  /* 3ms */
+
+	if (CHIP_ID(bp) == CHIP_ID_5706_A1)
+		REG_WR(bp, BNX2_HC_CONFIG, BNX2_HC_CONFIG_COLLECT_STATS);
+	else {
+		REG_WR(bp, BNX2_HC_CONFIG, BNX2_HC_CONFIG_RX_TMR_MODE |
+		       BNX2_HC_CONFIG_TX_TMR_MODE |
+		       BNX2_HC_CONFIG_COLLECT_STATS);
+	}
+
+	/* Clear internal stats counters. */
+	REG_WR(bp, BNX2_HC_COMMAND, BNX2_HC_COMMAND_CLR_STAT_NOW);
+
+	REG_WR(bp, BNX2_HC_ATTN_BITS_ENABLE, STATUS_ATTN_BITS_LINK_STATE);
+
+	if (REG_RD_IND(bp, bp->shmem_base + BNX2_PORT_FEATURE) &
+	    BNX2_PORT_FEATURE_ASF_ENABLED)
+		bp->flags |= ASF_ENABLE_FLAG;
+
+	/* Initialize the receive filter. */
+	bnx2_set_rx_mode(bp->nic);
+
+	rc = bnx2_fw_sync(bp, BNX2_DRV_MSG_DATA_WAIT2 | BNX2_DRV_MSG_CODE_RESET,
+			  0);
+
+	REG_WR(bp, BNX2_MISC_ENABLE_SET_BITS, 0x5ffffff);
+	REG_RD(bp, BNX2_MISC_ENABLE_SET_BITS);
+
+	udelay(20);
+
+	bp->hc_cmd = REG_RD(bp, BNX2_HC_COMMAND);
+
+	return rc;
+}
+
+static void
+bnx2_init_tx_ring(struct bnx2 *bp)
+{
+	struct tx_bd *txbd;
+	u32 val;
+
+	txbd = &bp->tx_desc_ring[MAX_TX_DESC_CNT];
+		
+	/* Etherboot lives below 4GB, so hi is always 0 */
+	txbd->tx_bd_haddr_hi = 0;
+	txbd->tx_bd_haddr_lo = bp->tx_desc_mapping;
+
+	bp->tx_prod = 0;
+	bp->tx_cons = 0;
+	bp->hw_tx_cons = 0;
+	bp->tx_prod_bseq = 0;
+	
+	val = BNX2_L2CTX_TYPE_TYPE_L2;
+	val |= BNX2_L2CTX_TYPE_SIZE_L2;
+	CTX_WR(bp, GET_CID_ADDR(TX_CID), BNX2_L2CTX_TYPE, val);
+
+	val = BNX2_L2CTX_CMD_TYPE_TYPE_L2;
+	val |= 8 << 16;
+	CTX_WR(bp, GET_CID_ADDR(TX_CID), BNX2_L2CTX_CMD_TYPE, val);
+
+	/* Etherboot lives below 4GB, so hi is always 0 */
+	CTX_WR(bp, GET_CID_ADDR(TX_CID), BNX2_L2CTX_TBDR_BHADDR_HI, 0);
+
+	val = (u64) bp->tx_desc_mapping & 0xffffffff;
+	CTX_WR(bp, GET_CID_ADDR(TX_CID), BNX2_L2CTX_TBDR_BHADDR_LO, val);
+}
+
+static void
+bnx2_init_rx_ring(struct bnx2 *bp)
+{
+	struct rx_bd *rxbd;
+	unsigned int i;
+	u16 prod, ring_prod;
+	u32 val;
+
+	bp->rx_buf_use_size = RX_BUF_USE_SIZE;
+	bp->rx_buf_size = RX_BUF_SIZE;
+
+	ring_prod = prod = bp->rx_prod = 0;
+	bp->rx_cons = 0;
+	bp->hw_rx_cons = 0;
+	bp->rx_prod_bseq = 0;
+
+	memset(bnx2_bss.rx_buf, 0, sizeof(bnx2_bss.rx_buf));
+		
+	rxbd = &bp->rx_desc_ring[0];
+	for (i = 0; i < MAX_RX_DESC_CNT; i++, rxbd++) {
+		rxbd->rx_bd_len = bp->rx_buf_use_size;
+		rxbd->rx_bd_flags = RX_BD_FLAGS_START | RX_BD_FLAGS_END;
+	}
+	rxbd->rx_bd_haddr_hi = 0;
+	rxbd->rx_bd_haddr_lo = (u64) bp->rx_desc_mapping & 0xffffffff;
+
+	val = BNX2_L2CTX_CTX_TYPE_CTX_BD_CHN_TYPE_VALUE;
+	val |= BNX2_L2CTX_CTX_TYPE_SIZE_L2;
+	val |= 0x02 << 8;
+	CTX_WR(bp, GET_CID_ADDR(RX_CID), BNX2_L2CTX_CTX_TYPE, val);
+
+	/* Etherboot doesn't use memory above 4GB, so this is always 0 */
+	CTX_WR(bp, GET_CID_ADDR(RX_CID), BNX2_L2CTX_NX_BDHADDR_HI, 0);
+
+	val = bp->rx_desc_mapping & 0xffffffff;
+	CTX_WR(bp, GET_CID_ADDR(RX_CID), BNX2_L2CTX_NX_BDHADDR_LO, val);
+
+	for (i = 0; (int) i < bp->rx_ring_size; i++) {
+		rxbd = &bp->rx_desc_ring[RX_RING_IDX(ring_prod)];
+		rxbd->rx_bd_haddr_hi = 0;
+		rxbd->rx_bd_haddr_lo = virt_to_bus(&bnx2_bss.rx_buf[ring_prod][0]);
+		bp->rx_prod_bseq += bp->rx_buf_use_size;
+		prod = NEXT_RX_BD(prod);
+		ring_prod = RX_RING_IDX(prod);
+	}
+	bp->rx_prod = prod;
+
+	REG_WR16(bp, MB_RX_CID_ADDR + BNX2_L2CTX_HOST_BDIDX, bp->rx_prod);
+
+	REG_WR(bp, MB_RX_CID_ADDR + BNX2_L2CTX_HOST_BSEQ, bp->rx_prod_bseq);
+}
+
+static int
+bnx2_reset_nic(struct bnx2 *bp, u32 reset_code)
+{
+	int rc;
+
+	rc = bnx2_reset_chip(bp, reset_code);
+	if (rc) {
+		return rc;
+	}
+
+	bnx2_init_chip(bp);
+	bnx2_init_tx_ring(bp);
+	bnx2_init_rx_ring(bp);
+	return 0;
+}
+
+static int
+bnx2_init_nic(struct bnx2 *bp)
+{
+	int rc;
+
+	if ((rc = bnx2_reset_nic(bp, BNX2_DRV_MSG_CODE_RESET)) != 0)
+		return rc;
+
+	bnx2_init_phy(bp);
+	bnx2_set_link(bp);
+	return 0;
+}
+
+static int
+bnx2_init_board(struct pci_device *pdev, struct nic *nic)
+{
+	unsigned long bnx2reg_base, bnx2reg_len;
+	struct bnx2 *bp = &bnx2;
+	int rc;
+	u32 reg;
+
+	bp->flags = 0;
+	bp->phy_flags = 0;
+
+	/* enable device (incl. PCI PM wakeup), and bus-mastering */
+	adjust_pci_device(pdev);
+
+	nic->ioaddr = pdev->ioaddr & ~3;
+	nic->irqno = 0;
+
+	rc = 0;
+	bp->pm_cap = pci_find_capability(pdev, PCI_CAP_ID_PM);
+	if (bp->pm_cap == 0) {
+		printf("Cannot find power management capability, aborting.\n");
+		rc = -EIO;
+		goto err_out_disable;
+	}
+
+	bp->pcix_cap = pci_find_capability(pdev, PCI_CAP_ID_PCIX);
+	if (bp->pcix_cap == 0) {
+		printf("Cannot find PCIX capability, aborting.\n");
+		rc = -EIO;
+		goto err_out_disable;
+	}
+
+	bp->pdev = pdev;
+	bp->nic = nic;
+
+	bnx2reg_base = pci_bar_start(pdev, PCI_BASE_ADDRESS_0);
+	bnx2reg_len = MB_GET_CID_ADDR(17);
+
+	bp->regview = pci_ioremap(pdev, bnx2reg_base, bnx2reg_len);
+
+	if (!bp->regview) {
+		printf("Cannot map register space, aborting.\n");
+		rc = -EIO;
+		goto err_out_disable;
+	}
+
+	/* Configure byte swap and enable write to the reg_window registers.
+	 * Rely on CPU to do target byte swapping on big endian systems
+	 * The chip's target access swapping will not swap all accesses
+	 */
+	pci_write_config_dword(bp->pdev, BNX2_PCICFG_MISC_CONFIG,
+			       BNX2_PCICFG_MISC_CONFIG_REG_WINDOW_ENA |
+			       BNX2_PCICFG_MISC_CONFIG_TARGET_MB_WORD_SWAP);
+
+	bnx2_set_power_state_0(bp);
+
+	bp->chip_id = REG_RD(bp, BNX2_MISC_ID);
+
+	/* Get bus information. */
+	reg = REG_RD(bp, BNX2_PCICFG_MISC_STATUS);
+	if (reg & BNX2_PCICFG_MISC_STATUS_PCIX_DET) {
+		u32 clkreg;
+
+		bp->flags |= PCIX_FLAG;
+
+		clkreg = REG_RD(bp, BNX2_PCICFG_PCI_CLOCK_CONTROL_BITS);
+		
+		clkreg &= BNX2_PCICFG_PCI_CLOCK_CONTROL_BITS_PCI_CLK_SPD_DET;
+		switch (clkreg) {
+		case BNX2_PCICFG_PCI_CLOCK_CONTROL_BITS_PCI_CLK_SPD_DET_133MHZ:
+			bp->bus_speed_mhz = 133;
+			break;
+
+		case BNX2_PCICFG_PCI_CLOCK_CONTROL_BITS_PCI_CLK_SPD_DET_95MHZ:
+			bp->bus_speed_mhz = 100;
+			break;
+
+		case BNX2_PCICFG_PCI_CLOCK_CONTROL_BITS_PCI_CLK_SPD_DET_66MHZ:
+		case BNX2_PCICFG_PCI_CLOCK_CONTROL_BITS_PCI_CLK_SPD_DET_80MHZ:
+			bp->bus_speed_mhz = 66;
+			break;
+
+		case BNX2_PCICFG_PCI_CLOCK_CONTROL_BITS_PCI_CLK_SPD_DET_48MHZ:
+		case BNX2_PCICFG_PCI_CLOCK_CONTROL_BITS_PCI_CLK_SPD_DET_55MHZ:
+			bp->bus_speed_mhz = 50;
+			break;
+
+		case BNX2_PCICFG_PCI_CLOCK_CONTROL_BITS_PCI_CLK_SPD_DET_LOW:
+		case BNX2_PCICFG_PCI_CLOCK_CONTROL_BITS_PCI_CLK_SPD_DET_32MHZ:
+		case BNX2_PCICFG_PCI_CLOCK_CONTROL_BITS_PCI_CLK_SPD_DET_38MHZ:
+			bp->bus_speed_mhz = 33;
+			break;
+		}
+	}
+	else {
+		if (reg & BNX2_PCICFG_MISC_STATUS_M66EN)
+			bp->bus_speed_mhz = 66;
+		else
+			bp->bus_speed_mhz = 33;
+	}
+
+	if (reg & BNX2_PCICFG_MISC_STATUS_32BIT_DET)
+		bp->flags |= PCI_32BIT_FLAG;
+
+	/* 5706A0 may falsely detect SERR and PERR. */
+	if (CHIP_ID(bp) == CHIP_ID_5706_A0) {
+		reg = REG_RD(bp, PCI_COMMAND);
+		reg &= ~(PCI_COMMAND_SERR | PCI_COMMAND_PARITY);
+		REG_WR(bp, PCI_COMMAND, reg);
+	}
+	else if ((CHIP_ID(bp) == CHIP_ID_5706_A1) &&
+		!(bp->flags & PCIX_FLAG)) {
+
+		printf("5706 A1 can only be used in a PCIX bus, aborting.\n");
+		goto err_out_disable;
+	}
+
+	bnx2_init_nvram(bp);
+
+	reg = REG_RD_IND(bp, BNX2_SHM_HDR_SIGNATURE);
+
+	if ((reg & BNX2_SHM_HDR_SIGNATURE_SIG_MASK) ==
+	    BNX2_SHM_HDR_SIGNATURE_SIG)
+		bp->shmem_base = REG_RD_IND(bp, BNX2_SHM_HDR_ADDR_0);
+	else
+		bp->shmem_base = HOST_VIEW_SHMEM_BASE;
+
+	/* Get the permanent MAC address.  First we need to make sure the
+	 * firmware is actually running.
+	 */
+	reg = REG_RD_IND(bp, bp->shmem_base + BNX2_DEV_INFO_SIGNATURE);
+
+	if ((reg & BNX2_DEV_INFO_SIGNATURE_MAGIC_MASK) !=
+	    BNX2_DEV_INFO_SIGNATURE_MAGIC) {
+		printf("Firmware not running, aborting.\n");
+		rc = -ENODEV;
+		goto err_out_disable;
+	}
+
+	bp->fw_ver = REG_RD_IND(bp, bp->shmem_base + BNX2_DEV_INFO_BC_REV);
+
+	reg = REG_RD_IND(bp, bp->shmem_base + BNX2_PORT_HW_CFG_MAC_UPPER);
+	bp->mac_addr[0] = (u8) (reg >> 8);
+	bp->mac_addr[1] = (u8) reg;
+
+	reg = REG_RD_IND(bp, bp->shmem_base + BNX2_PORT_HW_CFG_MAC_LOWER);
+	bp->mac_addr[2] = (u8) (reg >> 24);
+	bp->mac_addr[3] = (u8) (reg >> 16);
+	bp->mac_addr[4] = (u8) (reg >> 8);
+	bp->mac_addr[5] = (u8) reg;
+
+	bp->tx_ring_size = MAX_TX_DESC_CNT;
+	bp->rx_ring_size = RX_BUF_CNT;
+	bp->rx_max_ring_idx = MAX_RX_DESC_CNT;
+
+	bp->rx_offset = RX_OFFSET;
+
+	bp->tx_quick_cons_trip_int = 20;
+	bp->tx_quick_cons_trip = 20;
+	bp->tx_ticks_int = 80;
+	bp->tx_ticks = 80;
+		
+	bp->rx_quick_cons_trip_int = 6;
+	bp->rx_quick_cons_trip = 6;
+	bp->rx_ticks_int = 18;
+	bp->rx_ticks = 18;
+
+	bp->stats_ticks = 1000000 & 0xffff00;
+
+	bp->phy_addr = 1;
+
+	/* No need for WOL support in Etherboot */
+	bp->flags |= NO_WOL_FLAG;
+
+	/* Disable WOL support if we are running on a SERDES chip. */
+	if (CHIP_BOND_ID(bp) & CHIP_BOND_ID_SERDES_BIT) {
+		bp->phy_flags |= PHY_SERDES_FLAG;
+		if (CHIP_NUM(bp) == CHIP_NUM_5708) {
+			bp->phy_addr = 2;
+			reg = REG_RD_IND(bp, bp->shmem_base +
+					 BNX2_SHARED_HW_CFG_CONFIG);
+			if (reg & BNX2_SHARED_HW_CFG_PHY_2_5G)
+				bp->phy_flags |= PHY_2_5G_CAPABLE_FLAG;
+		}
+	}
+
+	if (CHIP_ID(bp) == CHIP_ID_5706_A0) {
+		bp->tx_quick_cons_trip_int =
+			bp->tx_quick_cons_trip;
+		bp->tx_ticks_int = bp->tx_ticks;
+		bp->rx_quick_cons_trip_int =
+			bp->rx_quick_cons_trip;
+		bp->rx_ticks_int = bp->rx_ticks;
+		bp->comp_prod_trip_int = bp->comp_prod_trip;
+		bp->com_ticks_int = bp->com_ticks;
+		bp->cmd_ticks_int = bp->cmd_ticks;
+	}
+
+	bp->autoneg = AUTONEG_SPEED | AUTONEG_FLOW_CTRL;
+	bp->req_line_speed = 0;
+	if (bp->phy_flags & PHY_SERDES_FLAG) {
+		bp->advertising = ETHTOOL_ALL_FIBRE_SPEED | ADVERTISED_Autoneg;
+
+		reg = REG_RD_IND(bp, bp->shmem_base + BNX2_PORT_HW_CFG_CONFIG);
+		reg &= BNX2_PORT_HW_CFG_CFG_DFLT_LINK_MASK;
+		if (reg == BNX2_PORT_HW_CFG_CFG_DFLT_LINK_1G) {
+			bp->autoneg = 0;
+			bp->req_line_speed = bp->line_speed = SPEED_1000;
+			bp->req_duplex = DUPLEX_FULL;
+		}
+	}
+	else {
+		bp->advertising = ETHTOOL_ALL_COPPER_SPEED | ADVERTISED_Autoneg;
+	}
+
+	bp->req_flow_ctrl = FLOW_CTRL_RX | FLOW_CTRL_TX;
+
+	/* Disable driver heartbeat checking */
+	REG_WR_IND(bp, bp->shmem_base + BNX2_DRV_PULSE_MB,
+			BNX2_DRV_MSG_DATA_PULSE_CODE_ALWAYS_ALIVE);
+	REG_RD_IND(bp, bp->shmem_base + BNX2_DRV_PULSE_MB);
+
+	return 0;
+
+err_out_disable:
+	bnx2_disable(nic);
+
+	return rc;
+}
+
+static void
+bnx2_transmit(struct nic *nic, const char *dst_addr,
+		unsigned int type, unsigned int size, const char *packet)
+{
+	/* Sometimes the nic will be behind by a frame.  Using two transmit
+	 * buffers prevents us from timing out in that case.
+	 */
+	static struct eth_frame {
+		uint8_t  dst_addr[ETH_ALEN];
+		uint8_t  src_addr[ETH_ALEN];
+		uint16_t type;
+		uint8_t  data [ETH_FRAME_LEN - ETH_HLEN];
+	} frame[2];
+	static int frame_idx = 0;
+	
+	/* send the packet to destination */
+	struct tx_bd *txbd;
+	struct bnx2 *bp = &bnx2;
+	u16 prod, ring_prod;
+	u16 hw_cons;
+	int i = 0;
+
+	prod = bp->tx_prod;
+	ring_prod = TX_RING_IDX(prod);
+	hw_cons = bp->status_blk->status_tx_quick_consumer_index0;
+	if ((hw_cons & MAX_TX_DESC_CNT) == MAX_TX_DESC_CNT) {
+		hw_cons++;
+	}
+
+	while((hw_cons != prod) && (hw_cons != (PREV_TX_BD(prod)))) {
+		mdelay(10);	/* give the nic a chance */
+		//poll_interruptions();
+		if (++i > 500) { /* timeout 5s for transmit */
+			printf("transmit timed out\n");
+			bnx2_disable(bp->nic);
+			bnx2_init_board(bp->pdev, bp->nic);
+			return;
+		}
+	}
+	if (i != 0) {
+		printf("#");
+	}
+
+	/* Copy the packet to the our local buffer */
+	memcpy(&frame[frame_idx].dst_addr, dst_addr, ETH_ALEN);
+	memcpy(&frame[frame_idx].src_addr, nic->node_addr, ETH_ALEN);
+	frame[frame_idx].type = htons(type);
+	memset(&frame[frame_idx].data, 0, sizeof(frame[frame_idx].data));
+	memcpy(&frame[frame_idx].data, packet, size);
+
+	/* Setup the ring buffer entry to transmit */
+	txbd = &bp->tx_desc_ring[ring_prod];
+	txbd->tx_bd_haddr_hi = 0; /* Etherboot runs under 4GB */
+	txbd->tx_bd_haddr_lo = virt_to_bus(&frame[frame_idx]);
+	txbd->tx_bd_mss_nbytes = (size + ETH_HLEN);
+	txbd->tx_bd_vlan_tag_flags = TX_BD_FLAGS_START | TX_BD_FLAGS_END;
+
+	/* Advance to the next entry */
+	prod = NEXT_TX_BD(prod);
+	frame_idx ^= 1;
+
+	bp->tx_prod_bseq += (size + ETH_HLEN);
+
+	REG_WR16(bp, MB_TX_CID_ADDR + BNX2_L2CTX_TX_HOST_BIDX, prod);
+	REG_WR(bp, MB_TX_CID_ADDR + BNX2_L2CTX_TX_HOST_BSEQ, bp->tx_prod_bseq);
+
+	wmb();
+
+	bp->tx_prod = prod;
+}
+
+static int
+bnx2_poll_link(struct bnx2 *bp)
+{
+	u32 new_link_state, old_link_state, emac_status;
+
+	new_link_state = bp->status_blk->status_attn_bits &
+		STATUS_ATTN_BITS_LINK_STATE;
+
+	old_link_state = bp->status_blk->status_attn_bits_ack &
+		STATUS_ATTN_BITS_LINK_STATE;
+
+	if (!new_link_state && !old_link_state) {
+		/* For some reason the card doesn't always update the link
+		 * status bits properly.  Kick the stupid thing and try again.
+		 */
+		u32 bmsr;
+
+		bnx2_read_phy(bp, MII_BMSR, &bmsr);
+		bnx2_read_phy(bp, MII_BMSR, &bmsr);
+
+		if ((bp->phy_flags & PHY_SERDES_FLAG) &&
+		    (CHIP_NUM(bp) == CHIP_NUM_5706)) {
+			REG_RD(bp, BNX2_EMAC_STATUS);
+		}
+
+		new_link_state = bp->status_blk->status_attn_bits &
+			STATUS_ATTN_BITS_LINK_STATE;
+
+		old_link_state = bp->status_blk->status_attn_bits_ack &
+			STATUS_ATTN_BITS_LINK_STATE;
+
+		/* Okay, for some reason the above doesn't work with some
+		 * switches (like HP ProCurve). If the above doesn't work,
+		 * check the MAC directly to see if we have a link.  Perhaps we
+		 * should always check the MAC instead probing the MII.
+		 */
+		if (!new_link_state && !old_link_state) {
+			emac_status = REG_RD(bp, BNX2_EMAC_STATUS);
+			if (emac_status & BNX2_EMAC_STATUS_LINK_CHANGE) {
+				/* Acknowledge the link change */
+				REG_WR(bp, BNX2_EMAC_STATUS, BNX2_EMAC_STATUS_LINK_CHANGE);
+			} else if (emac_status & BNX2_EMAC_STATUS_LINK) {
+				new_link_state = !old_link_state;
+			}
+		}
+
+	}
+
+	if (new_link_state != old_link_state) {
+		if (new_link_state) {
+			REG_WR(bp, BNX2_PCICFG_STATUS_BIT_SET_CMD,
+				STATUS_ATTN_BITS_LINK_STATE);
+		}
+		else {
+			REG_WR(bp, BNX2_PCICFG_STATUS_BIT_CLEAR_CMD,
+				STATUS_ATTN_BITS_LINK_STATE);
+		}
+
+		bnx2_set_link(bp);
+
+		/* This is needed to take care of transient status
+		 * during link changes.
+		 */
+
+		REG_WR(bp, BNX2_HC_COMMAND,
+		       bp->hc_cmd | BNX2_HC_COMMAND_COAL_NOW_WO_INT);
+		REG_RD(bp, BNX2_HC_COMMAND);
+
+	}
+
+	return bp->link_up;
+}
+
+static int
+bnx2_poll(struct nic* nic, int retrieve)
+{
+	struct bnx2 *bp = &bnx2;
+	struct rx_bd *cons_bd, *prod_bd;
+	u16 hw_cons, sw_cons, sw_ring_cons, sw_prod, sw_ring_prod;
+	struct l2_fhdr *rx_hdr;
+	int result = 0;
+	unsigned int len;
+	unsigned char *data;
+	u32 status;
+	
+#if 0
+	if ((bp->status_blk->status_idx == bp->last_status_idx) &&
+	    (REG_RD(bp, BNX2_PCICFG_MISC_STATUS) &
+	     BNX2_PCICFG_MISC_STATUS_INTA_VALUE)) {
+
+		bp->last_status_idx = bp->status_blk->status_idx;
+		REG_WR(bp, BNX2_PCICFG_INT_ACK_CMD,
+	       BNX2_PCICFG_INT_ACK_CMD_INDEX_VALID |
+	       BNX2_PCICFG_INT_ACK_CMD_MASK_INT |
+	       bp->last_status_idx);
+		return 0;
+	}
+#endif
+
+	if ((bp->status_blk->status_rx_quick_consumer_index0 != bp->rx_cons) && !retrieve)
+		return 1;
+
+	if (bp->status_blk->status_rx_quick_consumer_index0 != bp->rx_cons) {
+
+		hw_cons = bp->hw_rx_cons = bp->status_blk->status_rx_quick_consumer_index0;
+		if ((hw_cons & MAX_RX_DESC_CNT) == MAX_RX_DESC_CNT) {
+			hw_cons++;
+		}
+		sw_cons = bp->rx_cons;
+		sw_prod = bp->rx_prod;
+
+		rmb();
+		if (sw_cons != hw_cons) {
+
+			sw_ring_cons = RX_RING_IDX(sw_cons);
+			sw_ring_prod = RX_RING_IDX(sw_prod);
+
+			data = bus_to_virt(bp->rx_desc_ring[sw_ring_cons].rx_bd_haddr_lo);
+
+			rx_hdr = (struct l2_fhdr *)data;
+			len = rx_hdr->l2_fhdr_pkt_len - 4;
+			if ((len > (ETH_MAX_MTU + ETH_HLEN)) ||
+				((status = rx_hdr->l2_fhdr_status) &
+				(L2_FHDR_ERRORS_BAD_CRC |
+				L2_FHDR_ERRORS_PHY_DECODE |
+				L2_FHDR_ERRORS_ALIGNMENT |
+				L2_FHDR_ERRORS_TOO_SHORT |
+				L2_FHDR_ERRORS_GIANT_FRAME))) {
+				result = 0;
+			}
+			else
+			{
+				nic->packetlen = len;
+				memcpy(nic->packet, data + bp->rx_offset, len);
+				result = 1;
+			}
+
+			/* Reuse the buffer */
+			bp->rx_prod_bseq += bp->rx_buf_use_size;
+			if (sw_cons != sw_prod) {
+				cons_bd = &bp->rx_desc_ring[sw_ring_cons];
+				prod_bd = &bp->rx_desc_ring[sw_ring_prod];
+				prod_bd->rx_bd_haddr_hi = 0; /* Etherboot runs under 4GB */
+				prod_bd->rx_bd_haddr_lo = cons_bd->rx_bd_haddr_lo;
+			}
+
+			sw_cons = NEXT_RX_BD(sw_cons);
+			sw_prod = NEXT_RX_BD(sw_prod);
+
+		}
+
+		bp->rx_cons = sw_cons;
+		bp->rx_prod = sw_prod;
+
+		REG_WR16(bp, MB_RX_CID_ADDR + BNX2_L2CTX_HOST_BDIDX, bp->rx_prod);
+
+		REG_WR(bp, MB_RX_CID_ADDR + BNX2_L2CTX_HOST_BSEQ, bp->rx_prod_bseq);
+
+		wmb();
+
+	}
+
+	bnx2_poll_link(bp);
+
+#if 0
+	bp->last_status_idx = bp->status_blk->status_idx;
+	rmb();
+
+	REG_WR(bp, BNX2_PCICFG_INT_ACK_CMD,
+	       BNX2_PCICFG_INT_ACK_CMD_INDEX_VALID |
+	       BNX2_PCICFG_INT_ACK_CMD_MASK_INT |
+	       bp->last_status_idx);
+
+	REG_WR(bp, BNX2_HC_COMMAND, bp->hc_cmd | BNX2_HC_COMMAND_COAL_NOW_WO_INT);
+#endif
+
+	return result;
+}
+
+static void
+bnx2_irq(struct nic *nic __unused, irq_action_t action __unused)
+{
+	switch ( action ) {
+		case DISABLE: break;
+		case ENABLE: break;
+		case FORCE: break;
+	}
+}
+
+static struct nic_operations bnx2_operations = {
+	.connect	= dummy_connect,
+	.poll		= bnx2_poll,
+	.transmit	= bnx2_transmit,
+	.irq		= bnx2_irq,
+};
+
+static int
+bnx2_probe(struct nic *nic, struct pci_device *pdev)
+{
+	struct bnx2 *bp = &bnx2;
+	int i, rc;
+
+	memset(bp, 0, sizeof(*bp));
+
+	rc = bnx2_init_board(pdev, nic);
+	if (rc < 0) {
+		return 0;
+	}
+
+	/*
+	nic->disable = bnx2_disable;
+	nic->transmit = bnx2_transmit;
+	nic->poll = bnx2_poll;
+	nic->irq = bnx2_irq;
+	*/
+	
+	nic->nic_op	= &bnx2_operations;
+
+	memcpy(nic->node_addr, bp->mac_addr, ETH_ALEN);
+	printf("Ethernet addr: %s\n", eth_ntoa( nic->node_addr ) );
+	printf("Broadcom NetXtreme II (%c%d) PCI%s %s %dMHz\n",
+	        (int) ((CHIP_ID(bp) & 0xf000) >> 12) + 'A',
+	        (int) ((CHIP_ID(bp) & 0x0ff0) >> 4),
+		((bp->flags & PCIX_FLAG) ? "-X" : ""),
+		((bp->flags & PCI_32BIT_FLAG) ? "32-bit" : "64-bit"),
+		bp->bus_speed_mhz);
+
+	bnx2_set_power_state_0(bp);
+	bnx2_disable_int(bp);
+
+	bnx2_alloc_mem(bp);
+
+	rc = bnx2_init_nic(bp);
+	if (rc) {
+		return 0;
+	}
+
+	bnx2_poll_link(bp);
+	for(i = 0; !bp->link_up && (i < VALID_LINK_TIMEOUT*100); i++) {
+		mdelay(1);
+		bnx2_poll_link(bp);
+	}
+#if 1
+	if (!bp->link_up){
+		printf("Valid link not established\n");
+		goto err_out_disable;
+	}
+#endif
+	
+	return 1;
+
+err_out_disable:
+	bnx2_disable(nic);
+	return 0;
+}
+
+static struct pci_device_id bnx2_nics[] = {
+	PCI_ROM(0x14e4, 0x164a, "bnx2-5706",        "Broadcom NetXtreme II BCM5706", 0),
+	PCI_ROM(0x14e4, 0x164c, "bnx2-5708",        "Broadcom NetXtreme II BCM5708", 0),
+	PCI_ROM(0x14e4, 0x16aa, "bnx2-5706S",       "Broadcom NetXtreme II BCM5706S", 0),
+	PCI_ROM(0x14e4, 0x16ac, "bnx2-5708S",       "Broadcom NetXtreme II BCM5708S", 0),
+};
+
+PCI_DRIVER ( bnx2_driver, bnx2_nics, PCI_NO_CLASS );
+
+DRIVER ( "BNX2", nic_driver, pci_driver, bnx2_driver, bnx2_probe, bnx2_disable );
+
+/*
+static struct pci_driver bnx2_driver __pci_driver = {
+	.type     = NIC_DRIVER,
+	.name     = "BNX2",              
+	.probe    = bnx2_probe,
+	.ids      = bnx2_nics,                  
+	.id_count = sizeof(bnx2_nics)/sizeof(bnx2_nics[0]), 
+	.class    = 0,    
+};
+*/
diff -pruN 1.0.0+git-20190125.36a4c85-5.1/src/drivers/net/bnx2_fw.h 1.21.1+git-20220113.fbbdc3926-0ubuntu1/src/drivers/net/bnx2_fw.h
--- 1.0.0+git-20190125.36a4c85-5.1/src/drivers/net/bnx2_fw.h	1970-01-01 00:00:00.000000000 +0000
+++ 1.21.1+git-20220113.fbbdc3926-0ubuntu1/src/drivers/net/bnx2_fw.h	2022-01-13 13:43:08.000000000 +0000
@@ -0,0 +1,3494 @@
+/* bnx2_fw.h: Broadcom NX2 network driver.
+ *
+ * Copyright (c) 2004, 2005, 2006 Broadcom Corporation
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, except as noted below.
+ *
+ * This file contains firmware data derived from proprietary unpublished
+ * source code, Copyright (c) 2004, 2005 Broadcom Corporation.
+ *
+ * Permission is hereby granted for the distribution of this firmware data
+ * in hexadecimal or equivalent format, provided this copyright notice is
+ * accompanying it.
+ */
+
+static const int bnx2_COM_b06FwReleaseMajor = 0x1;
+static const int bnx2_COM_b06FwReleaseMinor = 0x0;
+static const int bnx2_COM_b06FwReleaseFix = 0x0;
+static const u32 bnx2_COM_b06FwStartAddr = 0x080008b4;
+static const u32 bnx2_COM_b06FwTextAddr = 0x08000000;
+static const int bnx2_COM_b06FwTextLen = 0x57bc;
+static const u32 bnx2_COM_b06FwDataAddr = 0x08005840;
+static const int bnx2_COM_b06FwDataLen = 0x0;
+static const u32 bnx2_COM_b06FwRodataAddr = 0x080057c0;
+static const int bnx2_COM_b06FwRodataLen = 0x58;
+static const u32 bnx2_COM_b06FwBssAddr = 0x08005860;
+static const int bnx2_COM_b06FwBssLen = 0x88;
+static const u32 bnx2_COM_b06FwSbssAddr = 0x08005840;
+static const int bnx2_COM_b06FwSbssLen = 0x1c;
+static u32 bnx2_COM_b06FwText[(0x57bc/4) + 1] = {
+	0x0a00022d, 0x00000000, 0x00000000, 0x0000000d, 0x636f6d20, 0x322e352e,
+	0x38000000, 0x02050802, 0x00000000, 0x00000003, 0x00000014, 0x00000032,
+	0x00000003, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000010, 0x000003e8, 0x0000ea60, 0x00000001, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x0000ffff, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000002, 0x00000020, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x10000003, 0x00000000, 0x0000000d, 0x0000000d, 0x3c020800, 0x24425840,
+	0x3c030800, 0x246358e8, 0xac400000, 0x0043202b, 0x1480fffd, 0x24420004,
+	0x3c1d0800, 0x37bd7ffc, 0x03a0f021, 0x3c100800, 0x261008b4, 0x3c1c0800,
+	0x279c5840, 0x0e0002f7, 0x00000000, 0x0000000d, 0x27bdffe8, 0x3c1a8000,
+	0x3c020008, 0x0342d825, 0x3c036010, 0xafbf0010, 0x8c655000, 0x3c020800,
+	0x24470f30, 0x3c040800, 0x24865860, 0x2402ff7f, 0x00a22824, 0x34a5380c,
+	0xac655000, 0x00002821, 0x24020037, 0x24030c80, 0xaf420008, 0xaf430024,
+	0xacc70000, 0x24a50001, 0x2ca20016, 0x1440fffc, 0x24c60004, 0x24845860,
+	0x3c020800, 0x24420f3c, 0x3c030800, 0x24630e2c, 0xac820004, 0x3c020800,
+	0x24420a2c, 0x3c050800, 0x24a51268, 0xac82000c, 0x3c020800, 0x244243dc,
+	0xac830008, 0x3c030800, 0x24633698, 0xac820014, 0x3c020800, 0x24423c24,
+	0xac830018, 0xac83001c, 0x3c030800, 0x24630f44, 0xac820024, 0x3c020800,
+	0x244243ac, 0xac83002c, 0x3c030800, 0x246343cc, 0xac820030, 0x3c020800,
+	0x244242f0, 0xac830034, 0x3c030800, 0x24633d78, 0xac82003c, 0x3c020800,
+	0x24420fd4, 0xac850010, 0xac850020, 0xac830040, 0x0e0010b7, 0xac820050,
+	0x8fbf0010, 0x03e00008, 0x27bd0018, 0x27bdffe0, 0xafb00010, 0x27500100,
+	0xafbf0018, 0xafb10014, 0x9203000b, 0x24020003, 0x1462005b, 0x96110008,
+	0x32220001, 0x10400009, 0x27430080, 0x8e020000, 0x96040014, 0x000211c2,
+	0x00021040, 0x00621821, 0xa4640000, 0x0a0002d0, 0x3c020800, 0x3c020800,
+	0x8c430020, 0x1060002a, 0x3c030800, 0x0e00148e, 0x00000000, 0x97420108,
+	0x8f850018, 0x9743010c, 0x3042003e, 0x00021400, 0x00621825, 0xaca30000,
+	0x8f840018, 0x8f420100, 0xac820004, 0x97430116, 0x9742010e, 0x8f840018,
+	0x00031c00, 0x00431025, 0xac820008, 0x97430110, 0x97440112, 0x8f850018,
+	0x00031c00, 0x00832025, 0xaca4000c, 0x97420114, 0x8f840018, 0x3042ffff,
+	0xac820010, 0x8f830018, 0xac600014, 0x8f820018, 0x3c030800, 0xac400018,
+	0x946258ce, 0x8f840018, 0x3c032000, 0x00431025, 0xac82001c, 0x0e0014cc,
+	0x24040001, 0x3c030800, 0x8c620040, 0x24420001, 0xac620040, 0x3c020800,
+	0x8c430044, 0x32240004, 0x24630001, 0x10800017, 0xac430044, 0x8f4202b8,
+	0x04430007, 0x8e020020, 0x3c040800, 0x8c830060, 0x24020001, 0x24630001,
+	0x0a0002f2, 0xac830060, 0x3c060800, 0x8cc4005c, 0xaf420280, 0x96030016,
+	0x00001021, 0xa7430284, 0x8e050004, 0x24840001, 0x3c031000, 0xaf450288,
+	0xaf4302b8, 0x0a0002f2, 0xacc4005c, 0x32220002, 0x0a0002f2, 0x0002102b,
+	0x3c026000, 0xac400808, 0x0000000d, 0x00001021, 0x8fbf0018, 0x8fb10014,
+	0x8fb00010, 0x03e00008, 0x27bd0020, 0x27bdffc8, 0xafbf0034, 0xafbe0030,
+	0xafb7002c, 0xafb60028, 0xafb50024, 0xafb40020, 0xafb3001c, 0xafb20018,
+	0xafb10014, 0x0e000244, 0xafb00010, 0x3c170800, 0x3c160800, 0x24110020,
+	0x24150030, 0x2794000c, 0x27930008, 0x3c124000, 0x3c1e0800, 0x8f820004,
+	0x3c040800, 0x8c830020, 0x10430005, 0x8ee200a4, 0xaf830004, 0x0e001593,
+	0x00000000, 0x8ee200a4, 0x8ec300a0, 0x10430004, 0x26c400a0, 0x94820002,
+	0xa742009e, 0xaee300a4, 0x8f500000, 0x32020007, 0x1040ffee, 0x32020001,
+	0x1040002c, 0x32020002, 0x8f420100, 0xaf420020, 0x8f430104, 0xaf4300a8,
+	0x9342010b, 0x93630000, 0x306300ff, 0x10710005, 0x304400ff, 0x10750006,
+	0x2c820016, 0x0a000333, 0x00000000, 0xaf940000, 0x0a000334, 0x2c820016,
+	0xaf930000, 0x0a000334, 0x00000000, 0xaf800000, 0x14400005, 0x00041880,
+	0x0e0003cc, 0x00000000, 0x0a000340, 0x00000000, 0x3c020800, 0x24425860,
+	0x00621821, 0x8c620000, 0x0040f809, 0x00000000, 0x10400005, 0x3c030800,
+	0x8f420104, 0x3c016020, 0xac220014, 0x3c030800, 0x8c620034, 0xaf520138,
+	0x24420001, 0xac620034, 0x32020002, 0x1040001a, 0x32020004, 0x8f420140,
+	0xaf420020, 0x93630000, 0x306300ff, 0x10710005, 0x00000000, 0x10750006,
+	0x00000000, 0x0a00035d, 0x00000000, 0xaf940000, 0x0a00035e, 0x00000000,
+	0xaf930000, 0x0a00035e, 0x00000000, 0xaf800000, 0x0e000c7b, 0x00000000,
+	0x3c040800, 0x8c820038, 0xaf520178, 0x24420001, 0xac820038, 0x32020004,
+	0x1040ffa4, 0x00000000, 0x8f420180, 0xaf420020, 0x93630000, 0x306300ff,
+	0x10710005, 0x00000000, 0x10750006, 0x00000000, 0x0a000378, 0x00000000,
+	0xaf940000, 0x0a000379, 0x00000000, 0xaf930000, 0x0a000379, 0x00000000,
+	0xaf800000, 0x8f430180, 0x24020f00, 0x14620005, 0x00000000, 0x8f420188,
+	0xa742009c, 0x0a000387, 0x8fc2003c, 0x93620000, 0x14510004, 0x8fc2003c,
+	0x0e000bad, 0x00000000, 0x8fc2003c, 0xaf5201b8, 0x24420001, 0x0a00030b,
+	0xafc2003c, 0x27bdffe8, 0xafbf0010, 0x97420108, 0x24033000, 0x30447000,
+	0x10830016, 0x28823001, 0x10400007, 0x24024000, 0x1080000b, 0x24022000,
+	0x1082000c, 0x00000000, 0x0a0003b3, 0x00000000, 0x10820010, 0x24025000,
+	0x10820012, 0x00000000, 0x0a0003b3, 0x00000000, 0x0000000d, 0x0a0003b5,
+	0x00001021, 0x0e000442, 0x00000000, 0x0a0003b6, 0x8fbf0010, 0x0e00041a,
+	0x00000000, 0x0a0003b5, 0x00001021, 0x0e000669, 0x00000000, 0x0a0003b5,
+	0x00001021, 0x0e001467, 0x00000000, 0x0a0003b5, 0x00001021, 0x0000000d,
+	0x00001021, 0x8fbf0010, 0x03e00008, 0x27bd0018, 0x93620000, 0x24030020,
+	0x304400ff, 0x10830005, 0x24020030, 0x10820007, 0x00000000, 0x0a0003c9,
+	0x00000000, 0x2782000c, 0xaf820000, 0x03e00008, 0x00000000, 0x27820008,
+	0xaf820000, 0x03e00008, 0x00000000, 0xaf800000, 0x03e00008, 0x00000000,
+	0x0000000d, 0x03e00008, 0x00001021, 0x03e00008, 0x00001021, 0x27440100,
+	0x94830008, 0x30620004, 0x10400017, 0x30620002, 0x8f4202b8, 0x04430007,
+	0x8c820020, 0x3c040800, 0x8c830060, 0x24020001, 0x24630001, 0x03e00008,
+	0xac830060, 0xaf420280, 0x94830016, 0x3c060800, 0xa7430284, 0x8c850004,
+	0x8cc4005c, 0x00001021, 0x3c031000, 0x24840001, 0xaf450288, 0xaf4302b8,
+	0x03e00008, 0xacc4005c, 0x14400003, 0x3c040800, 0x03e00008, 0x00001021,
+	0x8c830084, 0x24020001, 0x24630001, 0x03e00008, 0xac830084, 0x27450100,
+	0x3c040800, 0x8c820088, 0x94a3000c, 0x24420001, 0x007a1821, 0xac820088,
+	0x8ca40018, 0x90664000, 0xaf440038, 0x8ca2001c, 0x2403fff8, 0x00063600,
+	0x00431024, 0x34420004, 0x3c030005, 0xaf42003c, 0xaf430030, 0x00000000,
+	0x00000000, 0x00000000, 0xaf460404, 0x00000000, 0x00000000, 0x00000000,
+	0x3c020006, 0x34420001, 0xaf420030, 0x00000000, 0x00000000, 0x00000000,
+	0x8f420000, 0x30420010, 0x1040fffd, 0x00001021, 0x03e00008, 0x00000000,
+	0x3c020800, 0x8c430020, 0x27bdffe8, 0xafb00010, 0x27500100, 0x1060001e,
+	0xafbf0014, 0x0e00148e, 0x00000000, 0x8f830018, 0x8e020018, 0xac620000,
+	0x8f840018, 0x9602000c, 0xac820004, 0x8f830018, 0xac600008, 0x8f820018,
+	0xac40000c, 0x8f830018, 0xac600010, 0x8f820018, 0xac400014, 0x8f840018,
+	0x3c026000, 0x8c434448, 0xac830018, 0x96020008, 0x3c030800, 0x946458ce,
+	0x8f850018, 0x00021400, 0x00441025, 0x24040001, 0x0e0014cc, 0xaca2001c,
+	0x8fbf0014, 0x8fb00010, 0x03e00008, 0x27bd0018, 0x27bdffe8, 0xafb00010,
+	0x27500100, 0xafbf0014, 0x92020009, 0x14400003, 0x3c020800, 0x0a00046c,
+	0x24020001, 0x8c430020, 0x1060001f, 0x00001021, 0x0e00148e, 0x00000000,
+	0x8f830018, 0x8e020018, 0xac620000, 0x8f840018, 0x9602000c, 0xac820004,
+	0x8f830018, 0xac600008, 0x8f820018, 0xac40000c, 0x8f830018, 0xac600010,
+	0x8f820018, 0xac400014, 0x8f840018, 0x3c026000, 0x8c434448, 0xac830018,
+	0x96020008, 0x3c030800, 0x946458ce, 0x8f850018, 0x00021400, 0x00441025,
+	0x24040001, 0x0e0014cc, 0xaca2001c, 0x00001021, 0x8fbf0014, 0x8fb00010,
+	0x03e00008, 0x27bd0018, 0x3c0b0800, 0x8d6808b0, 0x3c070800, 0x24e700b0,
+	0x00084900, 0x01271821, 0xac640000, 0x93620005, 0x97660008, 0x00e95021,
+	0x93630023, 0x9364003f, 0x25080001, 0x00021600, 0x00063400, 0x00461025,
+	0x00031a00, 0x00431025, 0x00822025, 0xad440004, 0x9362007e, 0x9366007f,
+	0x8f630178, 0x9364007a, 0x00021600, 0x00063400, 0x00461025, 0x00031a00,
+	0x00431025, 0x00822025, 0xad440008, 0x93620080, 0x9363007d, 0x3108007f,
+	0x01403821, 0xad6808b0, 0x00021600, 0x00031c00, 0x00431025, 0x00451025,
+	0x03e00008, 0xace2000c, 0x27bdffb8, 0xafb3002c, 0x00009821, 0xafbe0040,
+	0x0000f021, 0xafb50034, 0x27550100, 0xafbf0044, 0xafb7003c, 0xafb60038,
+	0xafb40030, 0xafb20028, 0xafb10024, 0xafb00020, 0xafa00010, 0xafa00014,
+	0x96a20008, 0x8f540100, 0x8eb10018, 0x30420001, 0x10400037, 0x02a0b821,
+	0x8f630054, 0x2622ffff, 0x00431023, 0x18400006, 0x00000000, 0x0000000d,
+	0x00000000, 0x2400015c, 0x0a0004e5, 0x00002021, 0x8f62004c, 0x02221023,
+	0x18400028, 0x00002021, 0x93650120, 0x93640121, 0x3c030800, 0x8c62008c,
+	0x308400ff, 0x24420001, 0x30a500ff, 0x00803821, 0x1485000b, 0xac62008c,
+	0x3c040800, 0x8c830090, 0x24630001, 0xac830090, 0x93620122, 0x30420001,
+	0x00021023, 0x30420005, 0x0a0004e5, 0x34440004, 0x27660100, 0x00041080,
+	0x00c21021, 0x8c430000, 0x02231823, 0x04600004, 0x24820001, 0x30440007,
+	0x1485fff9, 0x00041080, 0x10870007, 0x3c030800, 0xa3640121, 0x8c620094,
+	0x24040005, 0x24420001, 0x0a0004e5, 0xac620094, 0x24040004, 0x00809821,
+	0x9362003f, 0x304400ff, 0x38830016, 0x2c630001, 0x38820010, 0x2c420001,
+	0x00621825, 0x1460000c, 0x24020001, 0x38830008, 0x2c630001, 0x38820014,
+	0x2c420001, 0x00621825, 0x14600005, 0x24020001, 0x24020012, 0x14820002,
+	0x00001021, 0x24020001, 0x10400009, 0x00000000, 0x8ea20020, 0x8f630040,
+	0x0040b021, 0x00431023, 0x5c400010, 0x8f760040, 0x0a000511, 0x00000000,
+	0x9343010b, 0x24020004, 0x1462000a, 0x8eb60020, 0x8f630040, 0x3c021000,
+	0x00761823, 0x0043102a, 0x10400004, 0x00000000, 0x0000000d, 0x00000000,
+	0x240002fa, 0x9343010b, 0x24020004, 0x5462000b, 0x96a20008, 0x24020001,
+	0xafa20010, 0x96a20008, 0x24030001, 0xafa30018, 0x8eb2001c, 0x36730002,
+	0x30420020, 0x0a000526, 0xafa20014, 0x36730080, 0x30420002, 0x10400003,
+	0xafa00018, 0x0a000526, 0x8eb2001c, 0x8eb20014, 0x2402fffb, 0x02628024,
+	0x1200002a, 0x3c030800, 0x8c620030, 0x02021024, 0x10400026, 0x3c020800,
+	0x8c430020, 0x10600024, 0x32620004, 0x0e00148e, 0x00000000, 0x8f830018,
+	0x8f420100, 0xac620000, 0x8f840018, 0x02401821, 0x32620002, 0xac900004,
+	0x8f840018, 0x54400001, 0x02c01821, 0xac830008, 0x8f830018, 0x8ee20020,
+	0xac62000c, 0x8f840018, 0x8f620040, 0xac820010, 0x8f830018, 0x8ee20018,
+	0xac620014, 0x8f850018, 0x3c026000, 0x8c434448, 0x24040001, 0x3c020800,
+	0xaca30018, 0x944358ce, 0x8f850018, 0x3c024010, 0x00621825, 0x0e0014cc,
+	0xaca3001c, 0x32620004, 0x10400063, 0x00003821, 0x3c029000, 0x34420001,
+	0x3c038000, 0x02821025, 0xa360007c, 0xaf420020, 0x8f420020, 0x00431024,
+	0x1440fffd, 0x00000000, 0x93620023, 0x30420080, 0x10400011, 0x00000000,
+	0x8f65005c, 0x8f63004c, 0x9764003c, 0x8f620064, 0x00a32823, 0x00852821,
+	0x00a2102b, 0x54400006, 0x3c023fff, 0x93620023, 0x3042007f, 0xa3620023,
+	0xaf710064, 0x3c023fff, 0x0a000580, 0x3442ffff, 0x8f62005c, 0x02221023,
+	0x04400011, 0x00000000, 0x8f65005c, 0x8f630064, 0x9764003c, 0x3c023fff,
+	0x3442ffff, 0xaf710064, 0x00a32823, 0x00852821, 0x0045102b, 0x10400004,
+	0x02251021, 0x3c053fff, 0x34a5ffff, 0x02251021, 0xaf62005c, 0x24070001,
+	0xaf71004c, 0x8f620054, 0x16220005, 0x00000000, 0x93620023, 0x30420040,
+	0x10400017, 0x24020001, 0x9762006a, 0x00022880, 0x50a00001, 0x24050001,
+	0x97630068, 0x93640081, 0x3c020800, 0x8c46004c, 0x00652821, 0x00852804,
+	0x00c5102b, 0x54400001, 0x00a03021, 0x3c020800, 0x8c440050, 0x00c4182b,
+	0x54600001, 0x00c02021, 0x8f420074, 0x2403fffe, 0x00832824, 0x00a21021,
+	0xaf62000c, 0x93620082, 0x30420080, 0x50400001, 0xa3600081, 0x3c028000,
+	0x34420001, 0x02821025, 0xaf420020, 0x9363007e, 0x9362007a, 0x10620004,
+	0x00000000, 0x0e0013c4, 0x00000000, 0x00403821, 0x54e00001, 0x241e0001,
+	0x8f700040, 0x8f620040, 0x14520003, 0x00521023, 0x0a0005bf, 0x00001021,
+	0x28420001, 0x10400041, 0x8fa20010, 0x0e000fae, 0x02402021, 0xaf720040,
+	0x9362003e, 0x30420001, 0x1440000b, 0x3c029000, 0x93620022, 0x24420001,
+	0xa3620022, 0x93630022, 0x3c020800, 0x8c440098, 0x0064182b, 0x14600027,
+	0x3c020800, 0x3c029000, 0x34420001, 0x02821025, 0xaf420020, 0x3c038000,
+	0x8f420020, 0x00431024, 0x1440fffd, 0x00000000, 0x9362007d, 0x3c038000,
+	0x34420001, 0xa362007d, 0x8f640074, 0x34630001, 0x02831825, 0xaf430020,
+	0x04810006, 0x3c038000, 0x02802021, 0x0e000470, 0x24050273, 0x0a0005f2,
+	0x24050001, 0x8f4201f8, 0x00431024, 0x1440fffd, 0x24020002, 0x3c031000,
+	0xaf5401c0, 0xa34201c4, 0xaf4301f8, 0x24050001, 0x24020001, 0xa7620012,
+	0xa3600022, 0x0a0005fe, 0x2ca20001, 0x9743007a, 0x9444002a, 0x00002821,
+	0x00641821, 0x3063fffe, 0xa7630012, 0x2ca20001, 0x00021023, 0x03c2f024,
+	0x8fa20010, 0x10400004, 0x8fa30014, 0x0e0013c1, 0x00000000, 0x8fa30014,
+	0x10600003, 0x00000000, 0x0e0010eb, 0x00000000, 0x13c0001f, 0x3c029000,
+	0x34420001, 0x02821025, 0xaf420020, 0x3c038000, 0x8f420020, 0x00431024,
+	0x1440fffd, 0x00000000, 0x9362007d, 0x3c038000, 0xa362007d, 0x8f640074,
+	0x34630001, 0x02831825, 0xaf430020, 0x04810006, 0x3c038000, 0x02802021,
+	0x0e000470, 0x2405036c, 0x0a00062b, 0x8fa20018, 0x8f4201f8, 0x00431024,
+	0x1440fffd, 0x24020002, 0x3c031000, 0xaf5401c0, 0xa34201c4, 0xaf4301f8,
+	0x8fa20018, 0x5040002f, 0x96a20008, 0x8f620048, 0x8f630024, 0x00761821,
+	0xaf630048, 0x9764003c, 0x00501023, 0x0044102b, 0x10400025, 0x3c029000,
+	0x34420001, 0x3c040800, 0x8c830080, 0x8f450100, 0x3c068000, 0x24630001,
+	0x00a21025, 0xac830080, 0xaf420020, 0x8f420020, 0x00461024, 0x1440fffd,
+	0x00000000, 0x9362007d, 0x3c038000, 0x34420004, 0xa362007d, 0x8f640074,
+	0x34630001, 0x00a31825, 0xaf430020, 0x04810006, 0x3c038000, 0x00a02021,
+	0x0e000470, 0x2405038a, 0x0a00065b, 0x96a20008, 0x8f4201f8, 0x00431024,
+	0x1440fffd, 0x24020002, 0x3c031000, 0xaf4501c0, 0xa34201c4, 0xaf4301f8,
+	0x96a20008, 0x8fbf0044, 0x8fbe0040, 0x8fb7003c, 0x8fb60038, 0x8fb50034,
+	0x8fb40030, 0x8fb3002c, 0x8fb20028, 0x8fb10024, 0x8fb00020, 0x00021042,
+	0x30420001, 0x03e00008, 0x27bd0048, 0x27bdffe0, 0xafbf0018, 0x97420108,
+	0x24030019, 0x304400ff, 0x10830065, 0x2882001a, 0x1040001a, 0x2882000a,
+	0x1040000f, 0x28820008, 0x10400040, 0x24020001, 0x1082003a, 0x28820002,
+	0x50400005, 0x24020006, 0x10800032, 0x3c026000, 0x0a0006fb, 0x00000000,
+	0x1082003d, 0x00000000, 0x0a0006fb, 0x00000000, 0x2402000b, 0x10820044,
+	0x2882000b, 0x1440004b, 0x2402000e, 0x10820045, 0x00000000, 0x0a0006fb,
+	0x00000000, 0x24020020, 0x10820062, 0x28820021, 0x1040000e, 0x2402001c,
+	0x1082004c, 0x2882001d, 0x10400005, 0x2402001b, 0x10820043, 0x00000000,
+	0x0a0006fb, 0x00000000, 0x2402001f, 0x10820050, 0x00000000, 0x0a0006fb,
+	0x00000000, 0x240200c1, 0x10820042, 0x288200c2, 0x10400005, 0x24020080,
+	0x10820021, 0x00000000, 0x0a0006fb, 0x00000000, 0x240200c2, 0x1082003d,
+	0x240200c9, 0x50820049, 0xafa00010, 0x0a0006fb, 0x00000000, 0x0e001163,
+	0xac400808, 0x0a0006fd, 0x8fbf0018, 0x3c026000, 0x8c444448, 0x3c030800,
+	0xac640064, 0x0e001163, 0x00000000, 0x3c026000, 0x8c444448, 0x3c030800,
+	0x0a0006fc, 0xac640068, 0x8f440100, 0x0e0006ff, 0x00000000, 0x3c026000,
+	0x8c444448, 0x3c030800, 0x0a0006fc, 0xac64006c, 0x0e001191, 0x00000000,
+	0x0a0006fd, 0x8fbf0018, 0x8f440100, 0x0e0011bb, 0x00000000, 0x0a0006fd,
+	0x8fbf0018, 0x0e001202, 0x00000000, 0x0a0006fd, 0x8fbf0018, 0x0000000d,
+	0x0a0006fd, 0x8fbf0018, 0x0e000826, 0x00000000, 0x0a0006fd, 0x8fbf0018,
+	0x8f440100, 0x0e001264, 0x00000000, 0x0a0006fd, 0x8fbf0018, 0x0e00134e,
+	0x00000000, 0x0a0006fd, 0x8fbf0018, 0x0e00087c, 0x27440100, 0x0a0006fd,
+	0x8fbf0018, 0x8f640040, 0x0e000fae, 0x00000000, 0x0a0006fd, 0x8fbf0018,
+	0x8f440100, 0x0e001059, 0x00000000, 0x0a0006fd, 0x8fbf0018, 0x0e001417,
+	0x00000000, 0x0a0006fd, 0x8fbf0018, 0xafa00014, 0x8f440100, 0x8f450118,
+	0x8f46011c, 0x0e001439, 0x8f470120, 0x0a0006fd, 0x8fbf0018, 0x0000000d,
+	0x8fbf0018, 0x03e00008, 0x27bd0020, 0x27bdffe8, 0xafbf0010, 0x9742010c,
+	0x1440005e, 0x00803821, 0x3c029000, 0x34420001, 0x00e21025, 0xaf420020,
+	0x3c038000, 0x8f420020, 0x00431024, 0x1440fffd, 0x00000000, 0x93620023,
+	0x30420010, 0x14400026, 0x3c030800, 0x8f630074, 0x3c027fff, 0x3442ffff,
+	0x00621824, 0xaf630074, 0x93620005, 0x34420001, 0xa3620005, 0x8f63004c,
+	0x8f620054, 0x10620021, 0x24040001, 0x9762006a, 0x00022880, 0x50a00001,
+	0x24050001, 0x97630068, 0x93640081, 0x3c020800, 0x8c46004c, 0x00652821,
+	0x00852804, 0x00c5102b, 0x54400001, 0x00a03021, 0x3c020800, 0x8c440050,
+	0x00c4182b, 0x54600001, 0x00c02021, 0x8f420074, 0x2403fffe, 0x00832824,
+	0x00a21021, 0xaf62000c, 0x0a00073d, 0x24040001, 0x8c6200a8, 0x00002021,
+	0x24420001, 0xac6200a8, 0x0000000d, 0x00000000, 0x2400044d, 0x3c028000,
+	0x34420001, 0x00e21025, 0xaf420020, 0x1080001f, 0x3c029000, 0x34420001,
+	0x00e21025, 0xaf420020, 0x3c038000, 0x8f420020, 0x00431024, 0x1440fffd,
+	0x00000000, 0x9362007d, 0x3c038000, 0xa362007d, 0x8f640074, 0x34630001,
+	0x00e31825, 0xaf430020, 0x04810006, 0x3c038000, 0x00e02021, 0x0e000470,
+	0x24050455, 0x0a000761, 0x00000000, 0x8f4201f8, 0x00431024, 0x1440fffd,
+	0x24020002, 0x3c031000, 0xaf4701c0, 0xa34201c4, 0xaf4301f8, 0x0e001163,
+	0x00000000, 0x8fbf0010, 0x03e00008, 0x27bd0018, 0x27bdffd8, 0xafbf0024,
+	0xafb40020, 0xafb3001c, 0xafb20018, 0xafb10014, 0xafb00010, 0x93630005,
+	0x00809821, 0x24020030, 0x30630030, 0x146200ac, 0x00a0a021, 0x3c020800,
+	0x8c430020, 0x106000a6, 0x00000000, 0x0e00148e, 0x00000000, 0x8f830018,
+	0xac730000, 0x936200c4, 0x30420002, 0x10400004, 0x24020001, 0x8f830018,
+	0x0a000784, 0x00000000, 0x8f830018, 0x24020003, 0xac620004, 0x8f6200dc,
+	0x8f630040, 0x00431023, 0x18400004, 0x00000000, 0x0000000d, 0x00000000,
+	0x24000509, 0x8f840018, 0x8f6200dc, 0xac820008, 0x8f830018, 0xac60000c,
+	0x8f820018, 0xac400010, 0x8f830018, 0x8f62004c, 0x3c100800, 0xac620014,
+	0x8f850018, 0x3c026000, 0x8c434448, 0x261258c0, 0x00002021, 0xaca30018,
+	0x9642000e, 0x8f850018, 0x3c034010, 0x00431025, 0x0e0014cc, 0xaca2001c,
+	0x8f830018, 0xac730000, 0x9362003e, 0x9363003f, 0x8f840018, 0x00021200,
+	0x00621825, 0xac830004, 0x93620081, 0x93630082, 0x8f840018, 0x00021600,
+	0x00031c00, 0x00431025, 0xac820008, 0x8f830018, 0x8f620040, 0xac62000c,
+	0x8f840018, 0x8f620048, 0xac820010, 0x8f71004c, 0x8f820018, 0xac510014,
+	0x8f620050, 0x8f850018, 0x00401821, 0x02221023, 0x5c400001, 0x02201821,
+	0x00002021, 0xaca30018, 0x9642000e, 0x8f850018, 0x3c03c00b, 0x00431025,
+	0x0e0014cc, 0xaca2001c, 0x8f620054, 0x8f840018, 0x00401821, 0x02221023,
+	0x5c400001, 0x02201821, 0xac830000, 0x8f840018, 0x8f630058, 0xac830004,
+	0x93620023, 0x30420010, 0x10400004, 0x00000000, 0x8f830018, 0x0a0007dd,
+	0x8f620148, 0x8f830018, 0x8f62005c, 0xac620008, 0x8f830018, 0x8f620060,
+	0xac62000c, 0x8f840018, 0x8f620064, 0xac820010, 0x97630068, 0x9762006a,
+	0x8f840018, 0x00031c00, 0x00431025, 0xac820014, 0x8f850018, 0x00002021,
+	0x2402ffff, 0x260358c0, 0xaca20018, 0x9462000e, 0x8f850018, 0x3c03c00c,
+	0x00431025, 0x0e0014cc, 0xaca2001c, 0x8f840018, 0x8f630018, 0xac830000,
+	0x936200c4, 0x30420002, 0x10400006, 0x00000000, 0x976200c8, 0x8f830018,
+	0x3042ffff, 0x0a000803, 0xac620004, 0x8f820018, 0xac400004, 0x8f830018,
+	0x8f62006c, 0xac620008, 0x8f840018, 0x8f6200dc, 0xac82000c, 0x8f830018,
+	0xac600010, 0x93620005, 0x8f830018, 0x00021600, 0x00541025, 0xac620014,
+	0x8f850018, 0x3c026000, 0x8c434448, 0x24040001, 0x260258c0, 0xaca30018,
+	0x9443000e, 0x8f850018, 0x3c02400d, 0x00621825, 0x0e0014cc, 0xaca3001c,
+	0x0e00122e, 0x02602021, 0x8fbf0024, 0x8fb40020, 0x8fb3001c, 0x8fb20018,
+	0x8fb10014, 0x8fb00010, 0x03e00008, 0x27bd0028, 0x27bdffe0, 0xafb00010,
+	0x27500100, 0xafbf0018, 0xafb10014, 0x9603000c, 0x240200c1, 0x54620024,
+	0x8e040000, 0x3c029000, 0x8f450100, 0x34420001, 0x3c038000, 0x00a21025,
+	0xaf420020, 0x8f420020, 0x00431024, 0x1440fffd, 0x00000000, 0x9362007d,
+	0x3c038000, 0x34420004, 0xa362007d, 0x8f640074, 0x34630001, 0x00a31825,
+	0xaf430020, 0x04810006, 0x3c038000, 0x00a02021, 0x0e000470, 0x240505b2,
+	0x0a000878, 0x8fbf0018, 0x8f4201f8, 0x00431024, 0x1440fffd, 0x24020002,
+	0x3c031000, 0xaf4501c0, 0xa34201c4, 0xaf4301f8, 0x0a000878, 0x8fbf0018,
+	0x8f65004c, 0x24060001, 0x0e0012a3, 0x240705be, 0x3c020800, 0x8c430020,
+	0x9611000c, 0x1060001d, 0x8e100000, 0x0e00148e, 0x00000000, 0x8f820018,
+	0xac500000, 0x8f840018, 0x00111400, 0xac820004, 0x8f830018, 0xac600008,
+	0x8f820018, 0xac40000c, 0x8f830018, 0xac600010, 0x8f840018, 0x240205c1,
+	0xac820014, 0x8f850018, 0x3c026000, 0x8c434448, 0x24040001, 0x3c020800,
+	0xaca30018, 0x944358ce, 0x8f850018, 0x3c024019, 0x00621825, 0x0e0014cc,
+	0xaca3001c, 0x8fbf0018, 0x8fb10014, 0x8fb00010, 0x03e00008, 0x27bd0020,
+	0x27bdffb0, 0xafb5003c, 0x0000a821, 0xafbe0048, 0x0000f021, 0xafb70044,
+	0x0000b821, 0xafb30034, 0x00009821, 0xafb60040, 0x0080b021, 0xafbf004c,
+	0xafb40038, 0xafb20030, 0xafb1002c, 0xafb00028, 0xafa00010, 0x8f620040,
+	0x8ec30014, 0x96d1000c, 0x00431023, 0x04410025, 0x8ed40000, 0x32220401,
+	0x1040030c, 0x3c029000, 0x34420001, 0x02821025, 0xaf420020, 0x3c038000,
+	0x8f420020, 0x00431024, 0x1440fffd, 0x00000000, 0x9362007d, 0x3c038000,
+	0x34420004, 0xa362007d, 0x8f640074, 0x34630001, 0x02831825, 0xaf430020,
+	0x04810006, 0x3c038000, 0x02802021, 0x0e000470, 0x24050664, 0x0a000ba2,
+	0x8fbf004c, 0x8f4201f8, 0x00431024, 0x1440fffd, 0x24020002, 0x3c031000,
+	0xaf5401c0, 0xa34201c4, 0xaf4301f8, 0x0a000ba2, 0x8fbf004c, 0x32220010,
+	0x1040006b, 0x00003021, 0x9362003f, 0x92c6000f, 0x304500ff, 0x24c3fff8,
+	0x2c62000f, 0x10400057, 0x3c020800, 0x244257c0, 0x00031880, 0x00621821,
+	0x8c640000, 0x00800008, 0x00000000, 0x38a20012, 0x0a000924, 0x0002a82b,
+	0x2402000e, 0x14a20004, 0x2402000c, 0x24150001, 0x0a000924, 0x24060010,
+	0x10a20049, 0x38a30010, 0x2c630001, 0x38a20016, 0x2c420001, 0x00621825,
+	0x1460004d, 0x0000a821, 0x24020014, 0x10a2004a, 0x00000000, 0x0000000d,
+	0x00000000, 0x2400069c, 0x0a000924, 0x0000a821, 0x24020016, 0x14a20005,
+	0x2402000c, 0x24150001, 0x24060010, 0x0a000924, 0x3231fffd, 0x10a20032,
+	0x38a30010, 0x2c630001, 0x38a2000e, 0x2c420001, 0x00621825, 0x14600036,
+	0x0000a821, 0x24020014, 0x14a20003, 0x24150001, 0x0a000924, 0x24060012,
+	0x0000000d, 0x00000000, 0x240006bc, 0x0a000924, 0x0000a821, 0x2402000e,
+	0x14a20004, 0x24020016, 0x24150001, 0x0a000924, 0x3231fffb, 0x14a20004,
+	0x24020014, 0x24150001, 0x0a000924, 0x3231fffd, 0x54a20013, 0x92c2000e,
+	0x24150001, 0x24060012, 0x0a000924, 0x3231fffd, 0x2402000c, 0x54a2000c,
+	0x92c2000e, 0x92c3000e, 0x2402000a, 0x10620005, 0x24150001, 0x0000000d,
+	0x00000000, 0x240006e8, 0x24150001, 0x0a000924, 0x24060014, 0x92c2000e,
+	0x14a20003, 0x00000000, 0x0a000924, 0x24150001, 0x10a6ffc1, 0x24020012,
+	0x10a20005, 0x0000a821, 0x0000000d, 0x00000000, 0x24000704, 0x0000a821,
+	0x12a00022, 0x32220004, 0x10400002, 0x24020001, 0xafa20010, 0x32230102,
+	0x24020002, 0x1462000f, 0x00000000, 0x92c2000a, 0x30420020, 0x1440000b,
+	0x00000000, 0x8f630048, 0x8f620040, 0x14620004, 0x00000000, 0x8f620048,
+	0x24420001, 0xaf620048, 0x8f620040, 0x24420001, 0xaf620040, 0xa366003f,
+	0x38c30012, 0x2c630001, 0x38c20010, 0x2c420001, 0x00621825, 0x10600005,
+	0x3c030800, 0x8c620074, 0x24420001, 0x0e00140d, 0xac620074, 0x32220040,
+	0x32230020, 0xafa30020, 0x32230080, 0xafa30024, 0x32230001, 0xafa30018,
+	0x32230008, 0xafa3001c, 0x32230100, 0x104000c4, 0xafa30014, 0x8ec60010,
+	0x8f630054, 0x24c2ffff, 0x00431023, 0x18400006, 0x00000000, 0x0000000d,
+	0x00000000, 0x2400015c, 0x0a000989, 0x00009021, 0x8f62004c, 0x00c21023,
+	0x18400028, 0x00009021, 0x93650120, 0x93640121, 0x3c030800, 0x8c62008c,
+	0x308400ff, 0x24420001, 0x30a500ff, 0x00804021, 0x1485000b, 0xac62008c,
+	0x3c040800, 0x8c830090, 0x24630001, 0xac830090, 0x93620122, 0x30420001,
+	0x00021023, 0x30420005, 0x0a000989, 0x34520004, 0x27670100, 0x00041080,
+	0x00e21021, 0x8c430000, 0x00c31823, 0x04600004, 0x24820001, 0x30440007,
+	0x1485fff9, 0x00041080, 0x10880007, 0x3c030800, 0xa3640121, 0x8c620094,
+	0x24120005, 0x24420001, 0x0a000989, 0xac620094, 0x24120004, 0x32420001,
+	0x10400021, 0x3c020800, 0x8c430020, 0x8ed00000, 0x1060001c, 0x8ed30010,
+	0x0e00148e, 0x00000000, 0x8f820018, 0xac500000, 0x8f840018, 0x24020001,
+	0xac820004, 0x8f830018, 0xac600008, 0x8f820018, 0xac40000c, 0x8f830018,
+	0xac600010, 0x8f820018, 0xac530014, 0x8f850018, 0x3c026000, 0x8c434448,
+	0x24040001, 0x3c020800, 0xaca30018, 0x944358ce, 0x8f850018, 0x3c024010,
+	0x00621825, 0x0e0014cc, 0xaca3001c, 0x24130001, 0x32420004, 0x10400068,
+	0x00003821, 0x3c029000, 0x8ec60010, 0x34420001, 0x3c038000, 0x02821025,
+	0xa360007c, 0xaf420020, 0x8f420020, 0x00431024, 0x1440fffd, 0x00000000,
+	0x93620023, 0x30420080, 0x10400011, 0x00000000, 0x8f65005c, 0x8f63004c,
+	0x9764003c, 0x8f620064, 0x00a32823, 0x00852821, 0x00a2102b, 0x54400006,
+	0x3c023fff, 0x93620023, 0x3042007f, 0xa3620023, 0xaf660064, 0x3c023fff,
+	0x0a0009da, 0x3442ffff, 0x8f62005c, 0x00c21023, 0x04400011, 0x00000000,
+	0x8f65005c, 0x8f630064, 0x9764003c, 0x3c023fff, 0x3442ffff, 0xaf660064,
+	0x00a32823, 0x00852821, 0x0045102b, 0x10400004, 0x00c51021, 0x3c053fff,
+	0x34a5ffff, 0x00c51021, 0xaf62005c, 0x24070001, 0xaf66004c, 0x8fa20010,
+	0x10400003, 0x00000000, 0xaf660050, 0xaf660054, 0x8f620054, 0x14c20005,
+	0x00000000, 0x93620023, 0x30420040, 0x10400017, 0x24020001, 0x9762006a,
+	0x00022880, 0x50a00001, 0x24050001, 0x97630068, 0x93640081, 0x3c020800,
+	0x8c46004c, 0x00652821, 0x00852804, 0x00c5102b, 0x54400001, 0x00a03021,
+	0x3c020800, 0x8c440050, 0x00c4182b, 0x54600001, 0x00c02021, 0x8f420074,
+	0x2403fffe, 0x00832824, 0x00a21021, 0xaf62000c, 0x93620082, 0x30420080,
+	0x50400001, 0xa3600081, 0x3c028000, 0x34420001, 0x02821025, 0xaf420020,
+	0x9363007e, 0x9362007a, 0x10620005, 0x00e0b821, 0x0e0013c4, 0x00000000,
+	0x00403821, 0x00e0b821, 0x8fa30020, 0x10600009, 0x8fa20010, 0x8ec20018,
+	0xaf620018, 0x8ec3001c, 0xaf63001c, 0x8ec20020, 0x24170001, 0xaf620058,
+	0x8fa20010, 0x10400057, 0x8fa30024, 0x93620023, 0x30420040, 0x10400053,
+	0x00000000, 0x16600021, 0x3c120800, 0x8e420020, 0x8f70004c, 0x1040001e,
+	0x24130001, 0x0e00148e, 0x00000000, 0x8f820018, 0xac540000, 0x8f840018,
+	0x24020001, 0xac820004, 0x8f830018, 0xac600008, 0x8f820018, 0xac40000c,
+	0x8f830018, 0xac600010, 0x8f820018, 0xac500014, 0x8f850018, 0x3c026000,
+	0x8c434448, 0x24040001, 0x3c020800, 0xaca30018, 0x944358ce, 0x8f850018,
+	0x3c024010, 0x00621825, 0xaca3001c, 0x0e0014cc, 0x24130001, 0x8e420020,
+	0x1040001c, 0x8ed00000, 0x0e00148e, 0x00000000, 0x8f820018, 0xac500000,
+	0x8f830018, 0xac600004, 0x8f820018, 0xac400008, 0x8f830018, 0xac60000c,
+	0x8f820018, 0xac400010, 0x8f830018, 0x24020798, 0xac620014, 0x8f850018,
+	0x3c026000, 0x8c434448, 0x24040001, 0x3c020800, 0xaca30018, 0x944358ce,
+	0x8f850018, 0x3c024019, 0x00621825, 0x0e0014cc, 0xaca3001c, 0x3c029000,
+	0x34420001, 0x02821025, 0xaf420020, 0x3c038000, 0x8f420020, 0x00431024,
+	0x1440fffd, 0x24020001, 0xaf62000c, 0x93630023, 0x3c028000, 0x34420001,
+	0x02821025, 0x306300bf, 0xa3630023, 0xaf420020, 0x8fa30024, 0x10600012,
+	0x8fa30018, 0x9362007c, 0x24420001, 0xa362007c, 0x9363007e, 0x9362007a,
+	0x1462000b, 0x8fa30018, 0x9362007c, 0x3c030800, 0x8c640024, 0x0044102b,
+	0x14400005, 0x8fa30018, 0x0e0013c4, 0x00000000, 0x02e2b825, 0x8fa30018,
+	0x3062ffff, 0x10400003, 0x32220200, 0x0a000a94, 0x241e0004, 0x10400003,
+	0x00000000, 0x241e0040, 0x24170001, 0x12a000d0, 0x32220002, 0x104000cf,
+	0x8fa2001c, 0x92c2000a, 0x30420002, 0x5040003b, 0x92c2000a, 0x93620023,
+	0x30420008, 0x54400037, 0x92c2000a, 0x3c020800, 0x8c430020, 0x10600023,
+	0x3c029000, 0x0e00148e, 0x00000000, 0x8f840018, 0x8ec30000, 0xac830000,
+	0x92c2000a, 0x8f830018, 0x00021600, 0xac620004, 0x8f840018, 0x8f620040,
+	0xac820008, 0x8f850018, 0x8f63004c, 0xaca3000c, 0x9362003f, 0x8f840018,
+	0x304200ff, 0xac820010, 0x8f830018, 0x3c026000, 0xac600014, 0x8f850018,
+	0x8c434448, 0x24040001, 0x3c020800, 0xaca30018, 0x944358ce, 0x8f850018,
+	0x3c02401a, 0x00621825, 0x0e0014cc, 0xaca3001c, 0x3c029000, 0x34420001,
+	0x02821025, 0xaf420020, 0x3c038000, 0x8f420020, 0x00431024, 0x1440fffd,
+	0x00000000, 0x93630023, 0x3c028000, 0x34420001, 0x02821025, 0x34630008,
+	0xa3630023, 0xaf420020, 0x92c2000a, 0x30420020, 0x1040008e, 0x8fa2001c,
+	0x93620023, 0x30420001, 0x14400035, 0x3c020800, 0x8c430020, 0x10600023,
+	0x3c029000, 0x0e00148e, 0x00000000, 0x8f840018, 0x8ec30000, 0xac830000,
+	0x92c2000a, 0x8f830018, 0x00021600, 0xac620004, 0x8f840018, 0x8f620040,
+	0xac820008, 0x8f850018, 0x8f63004c, 0xaca3000c, 0x9362003f, 0x8f840018,
+	0x304200ff, 0xac820010, 0x8f830018, 0x3c026000, 0xac600014, 0x8f850018,
+	0x8c434448, 0x24040001, 0x3c020800, 0xaca30018, 0x944358ce, 0x8f850018,
+	0x3c02401a, 0x00621825, 0x0e0014cc, 0xaca3001c, 0x3c029000, 0x34420001,
+	0x02821025, 0xaf420020, 0x3c038000, 0x8f420020, 0x00431024, 0x1440fffd,
+	0x00000000, 0x93630023, 0x3c028000, 0x34420001, 0x02821025, 0x34630001,
+	0xa3630023, 0xaf420020, 0x93620023, 0x30420040, 0x10400052, 0x8fa2001c,
+	0x16600020, 0x3c120800, 0x8e420020, 0x8f70004c, 0x1040003c, 0x3c029000,
+	0x0e00148e, 0x00000000, 0x8f820018, 0xac540000, 0x8f840018, 0x24020001,
+	0xac820004, 0x8f830018, 0xac600008, 0x8f820018, 0xac40000c, 0x8f830018,
+	0xac600010, 0x8f820018, 0xac500014, 0x8f850018, 0x3c026000, 0x8c434448,
+	0x24040001, 0x3c020800, 0xaca30018, 0x944358ce, 0x8f850018, 0x3c024010,
+	0x00621825, 0x0e0014cc, 0xaca3001c, 0x8e420020, 0x1040001e, 0x3c029000,
+	0x0e00148e, 0x00000000, 0x8f820018, 0xac540000, 0x8f840018, 0x3c02008d,
+	0xac820004, 0x8f830018, 0xac600008, 0x8f820018, 0xac40000c, 0x8f830018,
+	0xac600010, 0x8f840018, 0x240207ee, 0xac820014, 0x8f850018, 0x3c026000,
+	0x8c434448, 0x24040001, 0x3c020800, 0xaca30018, 0x944358ce, 0x8f850018,
+	0x3c024019, 0x00621825, 0x0e0014cc, 0xaca3001c, 0x3c029000, 0x34420001,
+	0x02821025, 0xaf420020, 0x3c038000, 0x8f420020, 0x00431024, 0x1440fffd,
+	0x00000000, 0x93630023, 0x3c028000, 0x34420001, 0x02821025, 0x306300bf,
+	0xa3630023, 0xaf420020, 0x8fa2001c, 0x1040000e, 0x8fa20014, 0x92c2000a,
+	0xa3620082, 0x57c00005, 0x37de0008, 0x8fa30014, 0x10600004, 0x00000000,
+	0x37de0008, 0x0a000b75, 0x24170001, 0x0e0012cf, 0x02802021, 0x8fa20014,
+	0x10400003, 0x00000000, 0x37de0010, 0x24170001, 0x12e00020, 0x3c029000,
+	0x34420001, 0x02821025, 0xaf420020, 0x3c038000, 0x8f420020, 0x00431024,
+	0x1440fffd, 0x00000000, 0x9362007d, 0x3c038000, 0x03c21025, 0xa362007d,
+	0x8f640074, 0x34630001, 0x02831825, 0xaf430020, 0x04810006, 0x3c038000,
+	0x02802021, 0x0e000470, 0x2405082a, 0x0a000b9b, 0x00000000, 0x8f4201f8,
+	0x00431024, 0x1440fffd, 0x24020002, 0x3c031000, 0xaf5401c0, 0xa34201c4,
+	0xaf4301f8, 0x9363003f, 0x24020012, 0x14620004, 0x8fbf004c, 0x0e00140d,
+	0x00000000, 0x8fbf004c, 0x8fbe0048, 0x8fb70044, 0x8fb60040, 0x8fb5003c,
+	0x8fb40038, 0x8fb30034, 0x8fb20030, 0x8fb1002c, 0x8fb00028, 0x03e00008,
+	0x27bd0050, 0x27bdffe8, 0xafbf0014, 0xafb00010, 0x8f500180, 0x97420184,
+	0x30420200, 0x14400015, 0x00000000, 0x8f430188, 0x3c02ff00, 0x00621824,
+	0x3c020200, 0x10620031, 0x0043102b, 0x14400007, 0x3c020300, 0x1060000b,
+	0x3c020100, 0x1062000d, 0x00000000, 0x0a000c2c, 0x00000000, 0x10620027,
+	0x3c020400, 0x1062003e, 0x02002021, 0x0a000c2c, 0x00000000, 0x0e000c31,
+	0x02002021, 0x0a000c2e, 0x8fbf0014, 0x93620005, 0x30420020, 0x1440005e,
+	0x8fbf0014, 0x3c029000, 0x34420001, 0x02021025, 0xaf420020, 0x3c038000,
+	0x8f420020, 0x00431024, 0x1440fffd, 0x00000000, 0x93620005, 0x3c038000,
+	0x34630001, 0x02031825, 0x34420020, 0xa3620005, 0xaf430020, 0x93620005,
+	0x30420020, 0x14400003, 0x02002021, 0x0000000d, 0x02002021, 0x0e000766,
+	0x24055854, 0x0a000c2e, 0x8fbf0014, 0x93620005, 0x30420001, 0x1040003f,
+	0x3c029000, 0x34420001, 0x02021025, 0xaf420020, 0x3c038000, 0x8f420020,
+	0x00431024, 0x1440fffd, 0x00000000, 0x93620023, 0x34420004, 0xa3620023,
+	0x93630005, 0x3c048000, 0x3c020800, 0x306300fe, 0xa3630005, 0x8c430020,
+	0x34840001, 0x02042025, 0x0a000c0a, 0xaf440020, 0x00002821, 0x00003021,
+	0x0e000fb1, 0x240708d9, 0x3c020800, 0x8c430020, 0x10600023, 0x8fbf0014,
+	0x0e00148e, 0x00000000, 0x8f820018, 0xac500000, 0x93630082, 0x9362003f,
+	0x8f840018, 0x00031a00, 0x00431025, 0xac820004, 0x8f830018, 0xac600008,
+	0x8f820018, 0xac40000c, 0x8f830018, 0xac600010, 0x8f820018, 0xac400014,
+	0x8f850018, 0x3c026000, 0x8c434448, 0x24040001, 0x3c020800, 0xaca30018,
+	0x944358ce, 0x8f850018, 0x3c02400a, 0x00621825, 0x0e0014cc, 0xaca3001c,
+	0x0a000c2e, 0x8fbf0014, 0x0000000d, 0x8fbf0014, 0x8fb00010, 0x03e00008,
+	0x27bd0018, 0x27bdffe8, 0xafbf0010, 0x8f420188, 0x00803021, 0x93640000,
+	0x24030020, 0x00021402, 0x10830008, 0x304500ff, 0x3c036018, 0x8c625000,
+	0x34420400, 0xac625000, 0x0000000d, 0x00000000, 0x24000955, 0x9363003f,
+	0x24020012, 0x14620023, 0x3c029000, 0x34420001, 0x3c038000, 0x00c21025,
+	0xaf650178, 0xa365007a, 0xaf420020, 0x8f420020, 0x00431024, 0x1440fffd,
+	0x00000000, 0x9362007d, 0x3c038000, 0xa362007d, 0x8f640074, 0x34630001,
+	0x00c31825, 0xaf430020, 0x04810006, 0x3c038000, 0x00c02021, 0x0e000470,
+	0x24050963, 0x0a000c79, 0x8fbf0010, 0x8f4201f8, 0x00431024, 0x1440fffd,
+	0x24020002, 0x3c031000, 0xaf4601c0, 0xa34201c4, 0xaf4301f8, 0x0a000c79,
+	0x8fbf0010, 0x9362007e, 0x1445000e, 0x00000000, 0x8f620178, 0x1045000b,
+	0x00000000, 0x8f820000, 0xaf650178, 0x8f660178, 0x8f440180, 0x8f65004c,
+	0x8c430000, 0x0060f809, 0x30c600ff, 0x0a000c79, 0x8fbf0010, 0xaf650178,
+	0x8fbf0010, 0x03e00008, 0x27bd0018, 0x27bdffe8, 0xafbf0010, 0x93630000,
+	0x24020020, 0x10620005, 0x00000000, 0x93630000, 0x24020030, 0x1462004d,
+	0x8fbf0010, 0x93420148, 0x2444ffff, 0x2c830005, 0x10600047, 0x3c020800,
+	0x24425800, 0x00041880, 0x00621821, 0x8c640000, 0x00800008, 0x00000000,
+	0x8f430144, 0x8f62000c, 0x14620006, 0x24020001, 0xaf62000c, 0x0e000d59,
+	0x00000000, 0x0a000cd1, 0x8fbf0010, 0x8f62000c, 0x0a000cca, 0x00000000,
+	0x97630010, 0x8f420144, 0x14430006, 0x24020001, 0xa7620010, 0x0e00137a,
+	0x00000000, 0x0a000cd1, 0x8fbf0010, 0x97620010, 0x0a000cca, 0x00000000,
+	0x97630012, 0x8f420144, 0x14430006, 0x24020001, 0xa7620012, 0x0e001395,
+	0x00000000, 0x0a000cd1, 0x8fbf0010, 0x97620012, 0x0a000cca, 0x00000000,
+	0x97630014, 0x8f420144, 0x14430006, 0x24020001, 0xa7620014, 0x0e0013bb,
+	0x00000000, 0x0a000cd1, 0x8fbf0010, 0x97620014, 0x0a000cca, 0x00000000,
+	0x97630016, 0x8f420144, 0x14430006, 0x24020001, 0xa7620016, 0x0e0013be,
+	0x00000000, 0x0a000cd1, 0x8fbf0010, 0x97620016, 0x14400006, 0x8fbf0010,
+	0x3c030800, 0x8c620070, 0x24420001, 0xac620070, 0x8fbf0010, 0x03e00008,
+	0x27bd0018, 0x27bdffe0, 0x3c029000, 0xafbf001c, 0xafb20018, 0xafb10014,
+	0xafb00010, 0x8f500140, 0x34420001, 0x3c038000, 0x02021025, 0xaf420020,
+	0x8f420020, 0x00431024, 0x1440fffd, 0x24020012, 0x24030080, 0xa362003f,
+	0xa3630082, 0x93620023, 0x30420040, 0x10400007, 0x00008821, 0x93620023,
+	0x24110001, 0x304200bf, 0xa3620023, 0x0a000cf0, 0x3c028000, 0x3c028000,
+	0x34420001, 0x3c039000, 0x34630001, 0x3c048000, 0x02021025, 0x02031825,
+	0xaf420020, 0xaf430020, 0x8f420020, 0x00441024, 0x1440fffd, 0x00000000,
+	0x9362007d, 0x3c038000, 0x34420020, 0xa362007d, 0x8f640074, 0x34630001,
+	0x02031825, 0xaf430020, 0x04810006, 0x3c038000, 0x02002021, 0x0e000470,
+	0x24050a63, 0x0a000d13, 0x00000000, 0x8f4201f8, 0x00431024, 0x1440fffd,
+	0x24020002, 0x3c031000, 0xaf5001c0, 0xa34201c4, 0xaf4301f8, 0x1220003f,
+	0x3c120800, 0x8e420020, 0x8f71004c, 0x1040003c, 0x8fbf001c, 0x0e00148e,
+	0x00000000, 0x8f820018, 0xac500000, 0x8f840018, 0x24020001, 0xac820004,
+	0x8f830018, 0xac600008, 0x8f820018, 0xac40000c, 0x8f830018, 0xac600010,
+	0x8f820018, 0xac510014, 0x8f850018, 0x3c026000, 0x8c434448, 0x24040001,
+	0x3c020800, 0xaca30018, 0x944358ce, 0x8f850018, 0x3c024010, 0x00621825,
+	0x0e0014cc, 0xaca3001c, 0x8e420020, 0x1040001e, 0x8fbf001c, 0x0e00148e,
+	0x00000000, 0x8f820018, 0xac500000, 0x8f840018, 0x3c02008d, 0xac820004,
+	0x8f830018, 0xac600008, 0x8f820018, 0xac40000c, 0x8f830018, 0xac600010,
+	0x8f840018, 0x24020a6a, 0xac820014, 0x8f850018, 0x3c026000, 0x8c434448,
+	0x24040001, 0x3c020800, 0xaca30018, 0x944358ce, 0x8f850018, 0x3c024019,
+	0x00621825, 0x0e0014cc, 0xaca3001c, 0x8fbf001c, 0x8fb20018, 0x8fb10014,
+	0x8fb00010, 0x03e00008, 0x27bd0020, 0x27bdffe8, 0xafbf0010, 0x93620081,
+	0x3c030800, 0x8c640048, 0x0044102b, 0x14400005, 0x00000000, 0x0e000cd3,
+	0x00000000, 0x0a000da4, 0x8fbf0010, 0x93620081, 0x24420001, 0x0e0013c4,
+	0xa3620081, 0x9763006a, 0x00032880, 0x14a00002, 0x00403821, 0x24050001,
+	0x97630068, 0x93640081, 0x3c020800, 0x8c46004c, 0x00652821, 0x00852804,
+	0x00c5102b, 0x54400001, 0x00a03021, 0x3c020800, 0x8c440050, 0x00c4182b,
+	0x54600001, 0x00c02021, 0x8f420074, 0x2403fffe, 0x00832824, 0x00a21021,
+	0xaf62000c, 0x10e00021, 0x3c029000, 0x8f450140, 0x34420001, 0x3c038000,
+	0x00a21025, 0xaf420020, 0x8f420020, 0x00431024, 0x1440fffd, 0x00000000,
+	0x9362007d, 0x3c038000, 0x34420004, 0xa362007d, 0x8f640074, 0x34630001,
+	0x00a31825, 0xaf430020, 0x04810006, 0x3c038000, 0x00a02021, 0x0e000470,
+	0x24050a92, 0x0a000da4, 0x8fbf0010, 0x8f4201f8, 0x00431024, 0x1440fffd,
+	0x24020002, 0x3c031000, 0xaf4501c0, 0xa34201c4, 0xaf4301f8, 0x8fbf0010,
+	0x03e00008, 0x27bd0018, 0x27bdffd8, 0xafb3001c, 0x27530100, 0xafbf0024,
+	0xafb40020, 0xafb20018, 0xafb10014, 0xafb00010, 0x96620008, 0x3c140800,
+	0x8f520100, 0x30420001, 0x104000da, 0x00000000, 0x8e700018, 0x8f630054,
+	0x2602ffff, 0x00431023, 0x18400006, 0x00000000, 0x0000000d, 0x00000000,
+	0x2400015c, 0x0a000dea, 0x00008821, 0x8f62004c, 0x02021023, 0x18400028,
+	0x00008821, 0x93650120, 0x93640121, 0x3c030800, 0x8c62008c, 0x308400ff,
+	0x24420001, 0x30a500ff, 0x00803821, 0x1485000b, 0xac62008c, 0x3c040800,
+	0x8c830090, 0x24630001, 0xac830090, 0x93620122, 0x30420001, 0x00021023,
+	0x30420005, 0x0a000dea, 0x34510004, 0x27660100, 0x00041080, 0x00c21021,
+	0x8c430000, 0x02031823, 0x04600004, 0x24820001, 0x30440007, 0x1485fff9,
+	0x00041080, 0x10870007, 0x3c030800, 0xa3640121, 0x8c620094, 0x24110005,
+	0x24420001, 0x0a000dea, 0xac620094, 0x24110004, 0x32220001, 0x1040001e,
+	0x8e820020, 0x1040001d, 0x32220004, 0x0e00148e, 0x00000000, 0x8f820018,
+	0xac520000, 0x8f840018, 0x24020001, 0xac820004, 0x8f830018, 0xac600008,
+	0x8f820018, 0xac40000c, 0x8f830018, 0xac600010, 0x8f820018, 0xac500014,
+	0x8f850018, 0x3c026000, 0x8c434448, 0x24040001, 0x3c020800, 0xaca30018,
+	0x944358ce, 0x8f850018, 0x3c024010, 0x00621825, 0x0e0014cc, 0xaca3001c,
+	0x32220004, 0x10400081, 0x00003821, 0x3c029000, 0x34420001, 0x3c038000,
+	0x02421025, 0xa360007c, 0xaf420020, 0x8f420020, 0x00431024, 0x1440fffd,
+	0x00000000, 0x93620023, 0x30420080, 0x10400011, 0x00000000, 0x8f65005c,
+	0x8f63004c, 0x9764003c, 0x8f620064, 0x00a32823, 0x00852821, 0x00a2102b,
+	0x54400006, 0x3c023fff, 0x93620023, 0x3042007f, 0xa3620023, 0xaf700064,
+	0x3c023fff, 0x0a000e37, 0x3442ffff, 0x8f62005c, 0x02021023, 0x04400011,
+	0x00000000, 0x8f65005c, 0x8f630064, 0x9764003c, 0x3c023fff, 0x3442ffff,
+	0xaf700064, 0x00a32823, 0x00852821, 0x0045102b, 0x10400004, 0x02051021,
+	0x3c053fff, 0x34a5ffff, 0x02051021, 0xaf62005c, 0x24070001, 0xaf70004c,
+	0x8f620054, 0x16020005, 0x00000000, 0x93620023, 0x30420040, 0x10400017,
+	0x24020001, 0x9762006a, 0x00022880, 0x50a00001, 0x24050001, 0x97630068,
+	0x93640081, 0x3c020800, 0x8c46004c, 0x00652821, 0x00852804, 0x00c5102b,
+	0x54400001, 0x00a03021, 0x3c020800, 0x8c440050, 0x00c4182b, 0x54600001,
+	0x00c02021, 0x8f420074, 0x2403fffe, 0x00832824, 0x00a21021, 0xaf62000c,
+	0x93620082, 0x30420080, 0x50400001, 0xa3600081, 0x3c028000, 0x34420001,
+	0x02421025, 0xaf420020, 0x9363007e, 0x9362007a, 0x10620004, 0x00000000,
+	0x0e0013c4, 0x00000000, 0x00403821, 0x10e0001f, 0x3c029000, 0x34420001,
+	0x02421025, 0xaf420020, 0x3c038000, 0x8f420020, 0x00431024, 0x1440fffd,
+	0x00000000, 0x9362007d, 0x3c038000, 0xa362007d, 0x8f640074, 0x34630001,
+	0x02431825, 0xaf430020, 0x04810006, 0x3c038000, 0x02402021, 0x0e000470,
+	0x24050b3d, 0x0a000e8d, 0x00000000, 0x8f4201f8, 0x00431024, 0x1440fffd,
+	0x24020002, 0x3c031000, 0xaf5201c0, 0xa34201c4, 0xaf4301f8, 0x9342010b,
+	0x9343010b, 0x8e820020, 0x27500100, 0x38630006, 0x10400029, 0x2c710001,
+	0x0e00148e, 0x00000000, 0x8f830018, 0x8e020000, 0xac620000, 0x8f840018,
+	0x96020008, 0xac820004, 0x8f830018, 0x8e020014, 0xac620008, 0x8f850018,
+	0x3c026000, 0x8c434448, 0xaca3000c, 0x8f840018, 0x96020012, 0xac820010,
+	0x8f850018, 0x8e030020, 0xaca30014, 0x9602000c, 0x9603000e, 0x8f840018,
+	0x00021400, 0x00431025, 0xac820018, 0x12200005, 0x3c020800, 0x944358ce,
+	0x8f840018, 0x0a000eb8, 0x3c024013, 0x944358ce, 0x8f840018, 0x3c024014,
+	0x00621825, 0xac83001c, 0x0e0014cc, 0x24040001, 0x8e700014, 0x8f620040,
+	0x14500003, 0x00501023, 0x0a000ec3, 0x00001021, 0x28420001, 0x1040003a,
+	0x00000000, 0x0e000fae, 0x02002021, 0xaf700040, 0x9362003e, 0x30420001,
+	0x1440000b, 0x3c029000, 0x93620022, 0x24420001, 0xa3620022, 0x93630022,
+	0x3c020800, 0x8c440098, 0x0064182b, 0x14600025, 0x3c020800, 0x3c029000,
+	0x34420001, 0x02421025, 0xaf420020, 0x3c038000, 0x8f420020, 0x00431024,
+	0x1440fffd, 0x00000000, 0x9362007d, 0x3c038000, 0x34420001, 0xa362007d,
+	0x8f640074, 0x34630001, 0x02431825, 0xaf430020, 0x04810006, 0x3c038000,
+	0x02402021, 0x0e000470, 0x24050273, 0x0a000ef6, 0x24020001, 0x8f4201f8,
+	0x00431024, 0x1440fffd, 0x24020002, 0x3c031000, 0xaf5201c0, 0xa34201c4,
+	0xaf4301f8, 0x24020001, 0xa7620012, 0x0a000efe, 0xa3600022, 0x9743007a,
+	0x9444002a, 0x00641821, 0x3063fffe, 0xa7630012, 0x97420108, 0x8fbf0024,
+	0x8fb40020, 0x8fb3001c, 0x8fb20018, 0x8fb10014, 0x8fb00010, 0x00021042,
+	0x30420001, 0x03e00008, 0x27bd0028, 0x27bdffe0, 0xafb20018, 0x3c120800,
+	0x8e420020, 0xafb00010, 0x27500100, 0xafbf001c, 0x10400046, 0xafb10014,
+	0x0e00148e, 0x00000000, 0x8f840018, 0x8e020000, 0xac820000, 0x936300b1,
+	0x936200c5, 0x8f850018, 0x00031e00, 0x00021400, 0x34420100, 0x00621825,
+	0xaca30004, 0x8f840018, 0x8e02001c, 0xac820008, 0x8f830018, 0x8f620048,
+	0xac62000c, 0x8f840018, 0x96020012, 0xac820010, 0x8f830018, 0x8f620040,
+	0x24040001, 0xac620014, 0x8f850018, 0x3c026000, 0x8c434448, 0x3c020800,
+	0x245158c0, 0xaca30018, 0x9623000e, 0x8f850018, 0x3c024016, 0x00621825,
+	0x0e0014cc, 0xaca3001c, 0x96030008, 0x30630010, 0x1060001c, 0x8e420020,
+	0x1040001a, 0x8e100000, 0x0e00148e, 0x00000000, 0x8f820018, 0xac500000,
+	0x8f830018, 0xac600004, 0x8f820018, 0xac400008, 0x8f830018, 0xac60000c,
+	0x8f820018, 0xac400010, 0x8f830018, 0xac600014, 0x8f850018, 0x3c036000,
+	0x8c634448, 0x24040001, 0xaca30018, 0x9622000e, 0x8f850018, 0x3c034015,
+	0x00431025, 0x0e0014cc, 0xaca2001c, 0x00001021, 0x8fbf001c, 0x8fb20018,
+	0x8fb10014, 0x8fb00010, 0x03e00008, 0x27bd0020, 0x27bdffe0, 0xafb20018,
+	0x3c120800, 0x8e420020, 0xafb00010, 0x27500100, 0xafbf001c, 0x10400041,
+	0xafb10014, 0x0e00148e, 0x00000000, 0x8f830018, 0x8e020000, 0xac620000,
+	0x8f840018, 0x24020100, 0xac820004, 0x8f830018, 0x8e02001c, 0xac620008,
+	0x8f840018, 0x8e020018, 0xac82000c, 0x8f830018, 0x96020012, 0xac620010,
+	0x8f840018, 0x96020008, 0xac820014, 0x8f850018, 0x3c026000, 0x8c434448,
+	0x24040001, 0x3c020800, 0x245158c0, 0xaca30018, 0x9623000e, 0x8f850018,
+	0x3c024017, 0x00621825, 0x0e0014cc, 0xaca3001c, 0x96030008, 0x30630010,
+	0x1060001c, 0x8e420020, 0x1040001a, 0x8e100000, 0x0e00148e, 0x00000000,
+	0x8f820018, 0xac500000, 0x8f830018, 0xac600004, 0x8f820018, 0xac400008,
+	0x8f830018, 0xac60000c, 0x8f820018, 0xac400010, 0x8f830018, 0xac600014,
+	0x8f850018, 0x3c036000, 0x8c634448, 0x24040001, 0xaca30018, 0x9622000e,
+	0x8f850018, 0x3c034015, 0x00431025, 0x0e0014cc, 0xaca2001c, 0x00001021,
+	0x8fbf001c, 0x8fb20018, 0x8fb10014, 0x8fb00010, 0x03e00008, 0x27bd0020,
+	0x27bdfff0, 0x03e00008, 0x27bd0010, 0x27bdffd0, 0xafb10014, 0x00808821,
+	0xafb40020, 0x00c0a021, 0xafbf0028, 0xafb50024, 0xafb3001c, 0xafb20018,
+	0xafb00010, 0x93620023, 0x00e0a821, 0x30420040, 0x1040003e, 0x30b3ffff,
+	0x3c120800, 0x8e420020, 0x1040003a, 0x8f70004c, 0x0e00148e, 0x00000000,
+	0x8f820018, 0xac510000, 0x8f840018, 0x24020001, 0xac820004, 0x8f830018,
+	0xac600008, 0x8f820018, 0xac40000c, 0x8f830018, 0xac600010, 0x8f820018,
+	0x24040001, 0xac500014, 0x8f850018, 0x3c026000, 0x8c434448, 0x3c020800,
+	0x245058c0, 0xaca30018, 0x9603000e, 0x8f850018, 0x3c024010, 0x00621825,
+	0x0e0014cc, 0xaca3001c, 0x8e430020, 0x1060001b, 0x00000000, 0x0e00148e,
+	0x00000000, 0x8f820018, 0xac510000, 0x8f840018, 0x3c02008d, 0xac820004,
+	0x8f830018, 0xac600008, 0x8f820018, 0xac40000c, 0x8f830018, 0xac600010,
+	0x8f820018, 0xac550014, 0x8f850018, 0x3c036000, 0x8c634448, 0x24040001,
+	0xaca30018, 0x9602000e, 0x8f850018, 0x3c034019, 0x00431025, 0x0e0014cc,
+	0xaca2001c, 0x93620023, 0x30420020, 0x14400003, 0x3c120800, 0x1280003f,
+	0x3c029000, 0x8e420020, 0x8f70004c, 0x1040003b, 0x3c029000, 0x0e00148e,
+	0x00000000, 0x8f820018, 0xac510000, 0x8f840018, 0x24020001, 0xac820004,
+	0x8f830018, 0xac600008, 0x8f820018, 0xac40000c, 0x8f830018, 0xac600010,
+	0x8f820018, 0x24040001, 0xac500014, 0x8f850018, 0x3c026000, 0x8c434448,
+	0x3c020800, 0x245058c0, 0xaca30018, 0x9603000e, 0x8f850018, 0x3c024010,
+	0x00621825, 0x0e0014cc, 0xaca3001c, 0x8e430020, 0x1060001c, 0x3c029000,
+	0x0e00148e, 0x00000000, 0x8f820018, 0xac510000, 0x8f840018, 0x00131400,
+	0xac820004, 0x8f830018, 0xac750008, 0x8f820018, 0xac40000c, 0x8f830018,
+	0xac600010, 0x8f820018, 0xac400014, 0x8f850018, 0x3c036000, 0x8c634448,
+	0x24040001, 0xaca30018, 0x9602000e, 0x8f850018, 0x3c03401b, 0x00431025,
+	0x0e0014cc, 0xaca2001c, 0x3c029000, 0x34420001, 0x02221025, 0xaf420020,
+	0x3c038000, 0x8f420020, 0x00431024, 0x1440fffd, 0x00000000, 0x93630023,
+	0x3c028000, 0x34420001, 0x02221025, 0x8fbf0028, 0x8fb50024, 0x8fb40020,
+	0x8fb3001c, 0x8fb20018, 0x8fb10014, 0x8fb00010, 0x3063009f, 0xa3630023,
+	0xaf420020, 0x03e00008, 0x27bd0030, 0x27bdffe0, 0xafb10014, 0x27510100,
+	0x3c029000, 0x34420001, 0xafb00010, 0x00808021, 0x02021025, 0x3c038000,
+	0xafbf0018, 0xaf420020, 0x8f420020, 0x00431024, 0x1440fffd, 0x00000000,
+	0xa7600008, 0x8f63005c, 0x3c028000, 0x34420001, 0xaf630148, 0x8f640050,
+	0x02021025, 0x3c039000, 0xaf64017c, 0xaf420020, 0x8f450100, 0x34630001,
+	0x3c048000, 0x00a31825, 0xaf430020, 0x8f420020, 0x00441024, 0x1440fffd,
+	0x00000000, 0x9362007d, 0x3c038000, 0x34420001, 0xa362007d, 0x8f640074,
+	0x34630001, 0x00a31825, 0xaf430020, 0x04810006, 0x3c038000, 0x00a02021,
+	0x0e000470, 0x24050de5, 0x0a001093, 0x3c020800, 0x8f4201f8, 0x00431024,
+	0x1440fffd, 0x24020002, 0x3c031000, 0xaf4501c0, 0xa34201c4, 0xaf4301f8,
+	0x3c020800, 0x8c430020, 0x1060001e, 0x8fbf0018, 0x0e00148e, 0x00000000,
+	0x8f830018, 0xac700000, 0x9622000c, 0x8f840018, 0x00021400, 0xac820004,
+	0x8f830018, 0xac600008, 0x8f820018, 0xac40000c, 0x8f830018, 0xac600010,
+	0x8f820018, 0xac400014, 0x8f850018, 0x3c026000, 0x8c434448, 0x24040001,
+	0x3c020800, 0xaca30018, 0x944358ce, 0x8f850018, 0x3c02401f, 0x00621825,
+	0x0e0014cc, 0xaca3001c, 0x8fbf0018, 0x8fb10014, 0x8fb00010, 0x03e00008,
+	0x27bd0020, 0x3c020800, 0x24424c3c, 0xaf82000c, 0x03e00008, 0x00000000,
+	0x27bdffe8, 0xafb00010, 0x27500100, 0xafbf0014, 0x8e02001c, 0x14400003,
+	0x3c020800, 0x0000000d, 0x3c020800, 0x8c430020, 0x10600020, 0x00001021,
+	0x0e00148e, 0x00000000, 0x8f830018, 0x8e020000, 0xac620000, 0x8f840018,
+	0x8e02001c, 0xac820004, 0x8f830018, 0xac600008, 0x8f840018, 0x8e020018,
+	0xac82000c, 0x8f850018, 0x96020012, 0xaca20010, 0x8f830018, 0x3c026000,
+	0xac600014, 0x8f840018, 0x8c434448, 0x3c020800, 0xac830018, 0x944358ce,
+	0x8f840018, 0x3c024012, 0x00621825, 0xac83001c, 0x0e0014cc, 0x24040001,
+	0x00001021, 0x8fbf0014, 0x8fb00010, 0x03e00008, 0x27bd0018, 0x3c020800,
+	0x97430078, 0x9444002e, 0x00001021, 0x00641821, 0x3063fffe, 0x03e00008,
+	0xa7630010, 0x27bdfff0, 0x00001021, 0x03e00008, 0x27bd0010, 0x8f420100,
+	0x34420001, 0xaf4200a4, 0x03e00008, 0x00001021, 0x27bdffe0, 0xafbf0018,
+	0xafb10014, 0xafb00010, 0x9362007e, 0x30d000ff, 0x16020031, 0x00808821,
+	0x8f620178, 0x1602002e, 0x00000000, 0x9362007f, 0x1602002b, 0x00000000,
+	0x9362007a, 0x16020004, 0x00000000, 0x0000000d, 0x00000000, 0x240009d2,
+	0x0e0013e6, 0x00000000, 0x3c039000, 0x34630001, 0x3c048000, 0x02231825,
+	0xa370007a, 0xaf430020, 0x8f420020, 0x00441024, 0x1440fffd, 0x00000000,
+	0x9362007d, 0x3c038000, 0xa362007d, 0x8f640074, 0x34630001, 0x02231825,
+	0xaf430020, 0x04810006, 0x3c038000, 0x02202021, 0x0e000470, 0x240509dd,
+	0x0a001138, 0x8fbf0018, 0x8f4201f8, 0x00431024, 0x1440fffd, 0x24020002,
+	0x3c031000, 0xaf5101c0, 0xa34201c4, 0xaf4301f8, 0x0a001138, 0x8fbf0018,
+	0x0000000d, 0x00000000, 0x240009e2, 0x8fbf0018, 0x8fb10014, 0x8fb00010,
+	0x03e00008, 0x27bd0020, 0x27bdffe8, 0x30a500ff, 0x3c029000, 0x34420001,
+	0x00803821, 0x00e21025, 0x3c038000, 0xafbf0010, 0xaf420020, 0x8f420020,
+	0x00431024, 0x1440fffd, 0x00000000, 0x9362007d, 0x3c038000, 0x00a21025,
+	0xa362007d, 0x8f640074, 0x34630001, 0x00e31825, 0xaf430020, 0x04810006,
+	0x3c038000, 0x00e02021, 0x0e000470, 0x00c02821, 0x0a001161, 0x8fbf0010,
+	0x8f4201f8, 0x00431024, 0x1440fffd, 0x24020002, 0x3c031000, 0xaf4701c0,
+	0xa34201c4, 0xaf4301f8, 0x8fbf0010, 0x03e00008, 0x27bd0018, 0x3c020800,
+	0x8c430020, 0x27bdffe8, 0xafb00010, 0x27500100, 0x10600024, 0xafbf0014,
+	0x0e00148e, 0x00000000, 0x8f830018, 0x8e020000, 0xac620000, 0x8f840018,
+	0x8e020004, 0xac820004, 0x8f830018, 0x8e020018, 0xac620008, 0x8f840018,
+	0x8e03001c, 0xac83000c, 0x9602000c, 0x9203000a, 0x8f840018, 0x00021400,
+	0x00431025, 0xac820010, 0x8f830018, 0x3c026000, 0xac600014, 0x8f840018,
+	0x8c434448, 0xac830018, 0x96020008, 0x3c030800, 0x946458ce, 0x8f850018,
+	0x00021400, 0x00441025, 0x24040001, 0x0e0014cc, 0xaca2001c, 0x8fbf0014,
+	0x8fb00010, 0x03e00008, 0x27bd0018, 0x3c020800, 0x8c430020, 0x27bdffe8,
+	0xafb00010, 0x27500100, 0x10600020, 0xafbf0014, 0x0e00148e, 0x00000000,
+	0x8f820018, 0xac400000, 0x8f830018, 0xac600004, 0x8f820018, 0xac400008,
+	0x8f830018, 0xac60000c, 0x9602000c, 0x9603000e, 0x8f840018, 0x00021400,
+	0x00431025, 0xac820010, 0x8f830018, 0x3c026000, 0xac600014, 0x8f840018,
+	0x8c434448, 0xac830018, 0x96020008, 0x3c030800, 0x946458ce, 0x8f850018,
+	0x00021400, 0x00441025, 0x24040001, 0x0e0014cc, 0xaca2001c, 0x8fbf0014,
+	0x8fb00010, 0x03e00008, 0x27bd0018, 0x27bdffe8, 0xafb00010, 0x27500100,
+	0xafbf0014, 0x9602000c, 0x10400024, 0x00802821, 0x3c020800, 0x8c430020,
+	0x1060003a, 0x8fbf0014, 0x0e00148e, 0x00000000, 0x8f840018, 0x8e030000,
+	0xac830000, 0x9602000c, 0x8f840018, 0x00021400, 0xac820004, 0x8f830018,
+	0xac600008, 0x8f820018, 0xac40000c, 0x8f830018, 0xac600010, 0x8f820018,
+	0xac400014, 0x8f850018, 0x3c026000, 0x8c434448, 0x24040001, 0x3c020800,
+	0xaca30018, 0x944358ce, 0x8f850018, 0x3c02400b, 0x00621825, 0x0e0014cc,
+	0xaca3001c, 0x0a0011ff, 0x8fbf0014, 0x93620005, 0x30420010, 0x14400015,
+	0x3c029000, 0x34420001, 0x00a21025, 0xaf420020, 0x3c038000, 0x8f420020,
+	0x00431024, 0x1440fffd, 0x00000000, 0x3c038000, 0x93620005, 0x34630001,
+	0x00a02021, 0x00a31825, 0x24055852, 0x34420010, 0xa3620005, 0x0e000766,
+	0xaf430020, 0x0a0011ff, 0x8fbf0014, 0x0000000d, 0x8fbf0014, 0x8fb00010,
+	0x03e00008, 0x27bd0018, 0x3c020800, 0x8c430020, 0x27bdffe8, 0xafb00010,
+	0x27500100, 0x10600022, 0xafbf0014, 0x0e00148e, 0x00000000, 0x8f840018,
+	0x8e020004, 0xac820000, 0x9603000c, 0x9762002c, 0x8f840018, 0x00031c00,
+	0x00431025, 0xac820004, 0x8f830018, 0xac600008, 0x8f820018, 0xac40000c,
+	0x8f830018, 0xac600010, 0x8f820018, 0xac400014, 0x8f850018, 0x3c026000,
+	0x8c434448, 0x24040001, 0x3c020800, 0xaca30018, 0x944358ce, 0x8f850018,
+	0x3c02400e, 0x00621825, 0x0e0014cc, 0xaca3001c, 0x0e00122e, 0x8e040000,
+	0x8fbf0014, 0x8fb00010, 0x03e00008, 0x27bd0018, 0x3c038000, 0x8f420278,
+	0x00431024, 0x1440fffd, 0x24020002, 0x3c031000, 0xaf440240, 0xa3420244,
+	0x03e00008, 0xaf430278, 0x3c020800, 0x8c430020, 0x27bdffe0, 0xafb10014,
+	0x00808821, 0xafb20018, 0x00c09021, 0xafb00010, 0x30b0ffff, 0x1060001c,
+	0xafbf001c, 0x0e00148e, 0x00000000, 0x8f820018, 0xac510000, 0x8f840018,
+	0x00101400, 0xac820004, 0x8f830018, 0xac600008, 0x8f820018, 0xac40000c,
+	0x8f830018, 0xac600010, 0x8f820018, 0xac520014, 0x8f840018, 0x3c026000,
+	0x8c434448, 0x3c020800, 0xac830018, 0x944358ce, 0x8f840018, 0x3c024019,
+	0x00621825, 0xac83001c, 0x0e0014cc, 0x24040001, 0x8fbf001c, 0x8fb20018,
+	0x8fb10014, 0x8fb00010, 0x03e00008, 0x27bd0020, 0x27bdffe8, 0x27450100,
+	0xafbf0010, 0x94a3000c, 0x240200c1, 0x14620031, 0x00803021, 0x3c029000,
+	0x34420001, 0x00c21025, 0xaf420020, 0x3c038000, 0x8f420020, 0x00431024,
+	0x1440fffd, 0x3c028000, 0x34420001, 0x3c049000, 0x34840001, 0x3c058000,
+	0x24030012, 0x00c21025, 0x00c42025, 0xa363003f, 0xaf420020, 0xaf440020,
+	0x8f420020, 0x00451024, 0x1440fffd, 0x00000000, 0x9362007d, 0x3c038000,
+	0x34420020, 0xa362007d, 0x8f640074, 0x34630001, 0x00c31825, 0xaf430020,
+	0x04810006, 0x3c038000, 0x00c02021, 0x0e000470, 0x24050906, 0x0a0012a1,
+	0x8fbf0010, 0x8f4201f8, 0x00431024, 0x1440fffd, 0x24020002, 0x3c031000,
+	0xaf4601c0, 0xa34201c4, 0xaf4301f8, 0x0a0012a1, 0x8fbf0010, 0x00c02021,
+	0x94a5000c, 0x24060001, 0x0e000fb1, 0x2407090e, 0x8fbf0010, 0x03e00008,
+	0x27bd0018, 0x3c020800, 0x8c430020, 0x27bdffe0, 0xafb00010, 0x00808021,
+	0xafb20018, 0x00a09021, 0xafb10014, 0x30d100ff, 0x1060001c, 0xafbf001c,
+	0x0e00148e, 0x00000000, 0x8f820018, 0xac500000, 0x8f840018, 0x24020001,
+	0xac820004, 0x8f830018, 0xac600008, 0x8f820018, 0xac40000c, 0x8f830018,
+	0xac600010, 0x8f820018, 0xac520014, 0x8f840018, 0x3c026000, 0x8c434448,
+	0x3c020800, 0xac830018, 0x944358ce, 0x8f840018, 0x3c024010, 0x00621825,
+	0xac83001c, 0x0e0014cc, 0x02202021, 0x8fbf001c, 0x8fb20018, 0x8fb10014,
+	0x8fb00010, 0x03e00008, 0x27bd0020, 0x27bdffe8, 0xafbf0014, 0xafb00010,
+	0x93620005, 0x30420001, 0x10400036, 0x00808021, 0x3c029000, 0x34420001,
+	0x02021025, 0xaf420020, 0x3c038000, 0x8f420020, 0x00431024, 0x1440fffd,
+	0x00000000, 0x93620023, 0x34420004, 0xa3620023, 0x93630005, 0x3c048000,
+	0x3c020800, 0x306300fe, 0xa3630005, 0x8c430020, 0x34840001, 0x02042025,
+	0xaf440020, 0x10600020, 0x8fbf0014, 0x0e00148e, 0x00000000, 0x8f820018,
+	0xac500000, 0x93630082, 0x9362003f, 0x8f840018, 0x00031a00, 0x00431025,
+	0xac820004, 0x8f830018, 0xac600008, 0x8f820018, 0xac40000c, 0x8f830018,
+	0xac600010, 0x8f820018, 0xac400014, 0x8f840018, 0x3c026000, 0x8c434448,
+	0x3c020800, 0xac830018, 0x944358ce, 0x8f840018, 0x3c02400a, 0x00621825,
+	0xac83001c, 0x0e0014cc, 0x24040001, 0x8fbf0014, 0x8fb00010, 0x03e00008,
+	0x27bd0018, 0x3c020800, 0x8c430020, 0x27bdffe0, 0xafb10014, 0x00808821,
+	0xafb20018, 0x00a09021, 0xafb00010, 0x30d000ff, 0x1060002f, 0xafbf001c,
+	0x0e00148e, 0x00000000, 0x8f820018, 0xac510000, 0x8f830018, 0xac700004,
+	0x8f820018, 0xac520008, 0x8f830018, 0xac60000c, 0x8f820018, 0xac400010,
+	0x9763006a, 0x00032880, 0x50a00001, 0x24050001, 0x97630068, 0x93640081,
+	0x3c020800, 0x8c46004c, 0x00652821, 0x00852804, 0x00c5102b, 0x54400001,
+	0x00a03021, 0x3c020800, 0x8c440050, 0x00c4182b, 0x54600001, 0x00c02021,
+	0x8f830018, 0x2402fffe, 0x00822824, 0x3c026000, 0xac650014, 0x8f840018,
+	0x8c434448, 0x3c020800, 0xac830018, 0x944358ce, 0x8f840018, 0x3c024011,
+	0x00621825, 0xac83001c, 0x0e0014cc, 0x24040001, 0x8fbf001c, 0x8fb20018,
+	0x8fb10014, 0x8fb00010, 0x03e00008, 0x27bd0020, 0x27bdffe8, 0xafbf0014,
+	0xafb00010, 0x8f440100, 0x27500100, 0x8f650050, 0x0e0010fc, 0x9206001b,
+	0x3c020800, 0x8c430020, 0x1060001d, 0x8e100018, 0x0e00148e, 0x00000000,
+	0x8f840018, 0x8f420100, 0xac820000, 0x8f830018, 0xac700004, 0x8f840018,
+	0x8f620050, 0xac820008, 0x8f830018, 0xac60000c, 0x8f820018, 0xac400010,
+	0x8f830018, 0x3c026000, 0xac600014, 0x8f850018, 0x8c434448, 0x24040001,
+	0x3c020800, 0xaca30018, 0x944358ce, 0x8f850018, 0x3c02401c, 0x00621825,
+	0x0e0014cc, 0xaca3001c, 0x8fbf0014, 0x8fb00010, 0x03e00008, 0x27bd0018,
+	0x8f430238, 0x3c020800, 0x04610013, 0x8c44009c, 0x2406fffe, 0x3c050800,
+	0x3c038000, 0x2484ffff, 0x14800009, 0x00000000, 0x97420078, 0x8ca3007c,
+	0x24420001, 0x00461024, 0x24630001, 0xa7620010, 0x03e00008, 0xaca3007c,
+	0x8f420238, 0x00431024, 0x1440fff3, 0x2484ffff, 0x8f420140, 0x3c031000,
+	0xaf420200, 0x03e00008, 0xaf430238, 0x27bdffe8, 0x3c029000, 0xafbf0010,
+	0x8f450140, 0x34420001, 0x3c038000, 0x00a21025, 0xaf420020, 0x8f420020,
+	0x00431024, 0x1440fffd, 0x00000000, 0x9362007d, 0x3c038000, 0x34420001,
+	0xa362007d, 0x8f640074, 0x34630001, 0x00a31825, 0xaf430020, 0x04810006,
+	0x3c038000, 0x00a02021, 0x0e000470, 0x24050ac7, 0x0a0013b9, 0x8fbf0010,
+	0x8f4201f8, 0x00431024, 0x1440fffd, 0x24020002, 0x3c031000, 0xaf4501c0,
+	0xa34201c4, 0xaf4301f8, 0x8fbf0010, 0x03e00008, 0x27bd0018, 0x0000000d,
+	0x03e00008, 0x00000000, 0x0000000d, 0x03e00008, 0x00000000, 0x24020001,
+	0x03e00008, 0xa7620010, 0x9362003f, 0x304400ff, 0x3883000e, 0x2c630001,
+	0x38820010, 0x2c420001, 0x00621825, 0x14600003, 0x24020012, 0x14820003,
+	0x00000000, 0x03e00008, 0x00001021, 0x9363007e, 0x9362007a, 0x14620006,
+	0x00000000, 0x9363007e, 0x24020001, 0x24630001, 0x03e00008, 0xa363007e,
+	0x9362007e, 0x8f630178, 0x304200ff, 0x14430006, 0x00000000, 0x9363000b,
+	0x24020001, 0x24630001, 0x03e00008, 0xa363000b, 0x03e00008, 0x00001021,
+	0x9362000b, 0x10400023, 0x00001021, 0xa360000b, 0x9362003f, 0x304400ff,
+	0x3883000e, 0x2c630001, 0x38820010, 0x2c420001, 0x00621825, 0x14600017,
+	0x00001821, 0x24020012, 0x10820014, 0x00000000, 0x9363007e, 0x9362007a,
+	0x14620007, 0x00000000, 0x9362007e, 0x24030001, 0x24420001, 0xa362007e,
+	0x03e00008, 0x00601021, 0x9362007e, 0x8f630178, 0x304200ff, 0x14430005,
+	0x00001821, 0x9362000b, 0x24030001, 0x24420001, 0xa362000b, 0x03e00008,
+	0x00601021, 0x03e00008, 0x00000000, 0x24040001, 0xaf64000c, 0x8f6300dc,
+	0x8f6200cc, 0x50620001, 0xa7640010, 0xa7640012, 0xa7640014, 0x03e00008,
+	0xa7640016, 0x3c020800, 0x8c430020, 0x27bdffe8, 0x1060001b, 0xafbf0010,
+	0x0e00148e, 0x00000000, 0x8f820018, 0xac400000, 0x8f830018, 0xac600004,
+	0x8f820018, 0xac400008, 0x8f830018, 0xac60000c, 0x8f820018, 0xac400010,
+	0x8f830018, 0x3c026000, 0xac600014, 0x8f840018, 0x8c434448, 0x3c020800,
+	0xac830018, 0x944358ce, 0x8f840018, 0x3c024020, 0x00621825, 0xac83001c,
+	0x0e0014cc, 0x24040001, 0x8fbf0010, 0x03e00008, 0x27bd0018, 0x3c020800,
+	0x8c430020, 0x27bdffe0, 0xafb00010, 0x00a08021, 0xafb10014, 0x00c08821,
+	0xafb20018, 0x00e09021, 0x1060001e, 0xafbf001c, 0x0e00148e, 0x00000000,
+	0x8f840018, 0x8f420100, 0xac820000, 0x8f830018, 0xac700004, 0x8f820018,
+	0xac510008, 0x8f830018, 0xac72000c, 0x8f840018, 0x8fa20030, 0xac820010,
+	0x8f830018, 0x8fa20034, 0xac620014, 0x8f840018, 0x3c026000, 0x8c434448,
+	0x3c020800, 0xac830018, 0x944358ce, 0x8f840018, 0x3c0240c9, 0x00621825,
+	0xac83001c, 0x0e0014cc, 0x24040001, 0x8fbf001c, 0x8fb20018, 0x8fb10014,
+	0x8fb00010, 0x03e00008, 0x27bd0020, 0x3c020800, 0x8c430020, 0x27bdffe8,
+	0xafb00010, 0x27500100, 0x1060001d, 0xafbf0014, 0x0e00148e, 0x00000000,
+	0x8f830018, 0x8e020004, 0xac620000, 0x8f840018, 0x8e020018, 0xac820004,
+	0x8f850018, 0x8e020000, 0xaca20008, 0x8f830018, 0xac60000c, 0x8f820018,
+	0xac400010, 0x8f830018, 0xac600014, 0x8f820018, 0xac400018, 0x96030008,
+	0x3c020800, 0x944458ce, 0x8f850018, 0x00031c00, 0x00641825, 0x24040001,
+	0x0e0014cc, 0xaca3001c, 0x8fbf0014, 0x8fb00010, 0x03e00008, 0x27bd0018,
+	0x3c060800, 0x24c558c0, 0x3c02000a, 0x03421821, 0x94640006, 0x94a2000a,
+	0x00441023, 0x00021400, 0x00021c03, 0x04610006, 0xa4a40006, 0x0000000d,
+	0x00000000, 0x2400005a, 0x0a0014a3, 0x24020001, 0x8f820014, 0x0062102b,
+	0x14400002, 0x00001021, 0x24020001, 0x304200ff, 0x1040001c, 0x274a0400,
+	0x3c07000a, 0x3c020800, 0x244558c0, 0x94a9000a, 0x8f880014, 0x03471021,
+	0x94430006, 0x00402021, 0xa4a30006, 0x94820006, 0xa4a20006, 0x01221023,
+	0x00021400, 0x00021403, 0x04410006, 0x0048102b, 0x0000000d, 0x00000000,
+	0x2400005a, 0x0a0014be, 0x24020001, 0x14400002, 0x00001021, 0x24020001,
+	0x304200ff, 0x1440ffec, 0x03471021, 0x24c458c0, 0x8c820010, 0xaf420038,
+	0x8c830014, 0x3c020005, 0xaf43003c, 0xaf420030, 0xaf800010, 0xaf8a0018,
+	0x03e00008, 0x00000000, 0x27bdffe0, 0x8f820010, 0x8f850018, 0x3c070800,
+	0x24e858c0, 0xafbf001c, 0xafb20018, 0xafb10014, 0xafb00010, 0x9503000a,
+	0x8d060014, 0x00009021, 0x309000ff, 0x00e08821, 0x24420001, 0x24a50020,
+	0x24630001, 0xaf820010, 0xaf850018, 0xa503000a, 0x24c30020, 0x3c028000,
+	0x04c10007, 0xad030014, 0x00621024, 0x14400005, 0x262258c0, 0x8d020010,
+	0x24420001, 0xad020010, 0x262258c0, 0x9444000a, 0x94450018, 0x0010102b,
+	0x00a41826, 0x2c630001, 0x00621825, 0x1060001c, 0x3c030006, 0x8f820010,
+	0x24120001, 0x00021140, 0x00431025, 0xaf420030, 0x00000000, 0x00000000,
+	0x00000000, 0x27450400, 0x8f420000, 0x30420010, 0x1040fffd, 0x262258c0,
+	0x9444000a, 0x94430018, 0xaf800010, 0xaf850018, 0x14830012, 0x262758c0,
+	0x0e00155a, 0x00000000, 0x1600000e, 0x262758c0, 0x0e00148e, 0x00000000,
+	0x0a001517, 0x262758c0, 0x00041c00, 0x00031c03, 0x00051400, 0x00021403,
+	0x00621823, 0x18600002, 0x3c026000, 0xac400808, 0x262758c0, 0x94e2000e,
+	0x94e3000c, 0x24420001, 0xa4e2000e, 0x3042ffff, 0x50430001, 0xa4e0000e,
+	0x12000005, 0x3c02000a, 0x94e2000a, 0xa74200a2, 0x0a001554, 0x02401021,
+	0x03421821, 0x94640006, 0x94e2000a, 0x00441023, 0x00021400, 0x00021c03,
+	0x04610006, 0xa4e40006, 0x0000000d, 0x00000000, 0x2400005a, 0x0a001536,
+	0x24020001, 0x8f820014, 0x0062102b, 0x14400002, 0x00001021, 0x24020001,
+	0x304200ff, 0x1040001b, 0x3c020800, 0x3c06000a, 0x244558c0, 0x94a8000a,
+	0x8f870014, 0x03461021, 0x94430006, 0x00402021, 0xa4a30006, 0x94820006,
+	0xa4a20006, 0x01021023, 0x00021400, 0x00021403, 0x04410006, 0x0047102b,
+	0x0000000d, 0x00000000, 0x2400005a, 0x0a001550, 0x24020001, 0x14400002,
+	0x00001021, 0x24020001, 0x304200ff, 0x1440ffec, 0x03461021, 0x02401021,
+	0x8fbf001c, 0x8fb20018, 0x8fb10014, 0x8fb00010, 0x03e00008, 0x27bd0020,
+	0x3c020800, 0x244558c0, 0x94a3001a, 0x8ca40024, 0x00403021, 0x000318c0,
+	0x00832021, 0xaf44003c, 0x8ca20020, 0xaf420038, 0x3c020050, 0x34420008,
+	0xaf420030, 0x00000000, 0x00000000, 0x00000000, 0x8f420000, 0x30420020,
+	0x1040fffd, 0x00000000, 0x8f430400, 0x24c658c0, 0xacc30010, 0x8f420404,
+	0x3c030020, 0xacc20014, 0xaf430030, 0x94c40018, 0x94c3001c, 0x94c2001a,
+	0x94c5001e, 0x00832021, 0x24420001, 0xa4c2001a, 0x3042ffff, 0x14450002,
+	0xa4c40018, 0xa4c0001a, 0x03e00008, 0x00000000, 0x8f820010, 0x3c030006,
+	0x00021140, 0x00431025, 0xaf420030, 0x00000000, 0x00000000, 0x00000000,
+	0x27430400, 0x8f420000, 0x30420010, 0x1040fffd, 0x00000000, 0xaf800010,
+	0xaf830018, 0x03e00008, 0x00000000, 0x27bdffe8, 0xafb00010, 0x3c100800,
+	0x261058c0, 0x3c05000a, 0x02002021, 0x03452821, 0xafbf0014, 0x0e0015b0,
+	0x2406000a, 0x96020002, 0x9603001e, 0x3042000f, 0x24420003, 0x00431804,
+	0x24027fff, 0x0043102b, 0xaf830014, 0x10400004, 0x00000000, 0x0000000d,
+	0x00000000, 0x24000043, 0x0e00155a, 0x00000000, 0x8fbf0014, 0x8fb00010,
+	0x03e00008, 0x27bd0018, 0x10c00007, 0x00000000, 0x8ca20000, 0x24c6ffff,
+	0x24a50004, 0xac820000, 0x14c0fffb, 0x24840004, 0x03e00008, 0x00000000,
+	0x0a0015c1, 0x00a01021, 0xac860000, 0x00000000, 0x00000000, 0x24840004,
+	0x00a01021, 0x1440fffa, 0x24a5ffff, 0x03e00008, 0x00000000, 0x3c036000,
+	0x8c642b7c, 0x3c036010, 0x8c6553fc, 0x00041582, 0x00042302, 0x308403ff,
+	0x00052d82, 0x00441026, 0x0002102b, 0x0005282b, 0x00451025, 0x1440000d,
+	0x3c020050, 0x34420004, 0xaf400038, 0xaf40003c, 0xaf420030, 0x00000000,
+	0x00000000, 0x8f420000, 0x30420020, 0x1040fffd, 0x3c020020, 0xaf420030,
+	0x0000000d, 0x03e00008, 0x00000000, 0x3c020050, 0x34420004, 0xaf440038,
+	0xaf45003c, 0xaf420030, 0x00000000, 0x00000000, 0x8f420000, 0x30420020,
+	0x1040fffd, 0x3c020020, 0xaf420030, 0x03e00008, 0x00000000, 0x00000000};
+
+static u32 bnx2_COM_b06FwData[(0x0/4) + 1] = { 0x0 };
+static u32 bnx2_COM_b06FwRodata[(0x58/4) + 1] = {
+	0x08002428, 0x0800245c, 0x0800245c, 0x0800245c, 0x0800245c, 0x0800245c,
+	0x08002380, 0x0800245c, 0x080023e4, 0x0800245c, 0x0800231c, 0x0800245c,
+	0x0800245c, 0x0800245c, 0x08002328, 0x00000000, 0x08003240, 0x08003270,
+	0x080032a0, 0x080032d0, 0x08003300, 0x00000000, 0x00000000 };
+static u32 bnx2_COM_b06FwBss[(0x88/4) + 1] = { 0x0 };
+static u32 bnx2_COM_b06FwSbss[(0x1c/4) + 1] = { 0x0 };
+
+static int bnx2_RXP_b06FwReleaseMajor = 0x1;
+static int bnx2_RXP_b06FwReleaseMinor = 0x0;
+static int bnx2_RXP_b06FwReleaseFix = 0x0;
+static u32 bnx2_RXP_b06FwStartAddr = 0x08003184;
+static u32 bnx2_RXP_b06FwTextAddr = 0x08000000;
+static int bnx2_RXP_b06FwTextLen = 0x588c;
+static u32 bnx2_RXP_b06FwDataAddr = 0x080058e0;
+static int bnx2_RXP_b06FwDataLen = 0x0;
+static u32 bnx2_RXP_b06FwRodataAddr = 0x08005890;
+static int bnx2_RXP_b06FwRodataLen = 0x28;
+static u32 bnx2_RXP_b06FwBssAddr = 0x08005900;
+static int bnx2_RXP_b06FwBssLen = 0x13a4;
+static u32 bnx2_RXP_b06FwSbssAddr = 0x080058e0;
+static int bnx2_RXP_b06FwSbssLen = 0x1c;
+static u32 bnx2_RXP_b06FwText[(0x588c/4) + 1] = {
+	0x0a000c61, 0x00000000, 0x00000000, 0x0000000d, 0x72787020, 0x322e362e,
+	0x31000000, 0x02060103, 0x00000000, 0x0000000d, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x10000003, 0x00000000, 0x0000000d, 0x0000000d,
+	0x3c020800, 0x244258e0, 0x3c030800, 0x24636ca4, 0xac400000, 0x0043202b,
+	0x1480fffd, 0x24420004, 0x3c1d0800, 0x37bd7ffc, 0x03a0f021, 0x3c100800,
+	0x26103184, 0x3c1c0800, 0x279c58e0, 0x0e00104a, 0x00000000, 0x0000000d,
+	0x27bdffe8, 0xafb00010, 0xafbf0014, 0x0e000f1d, 0x00808021, 0x1440000d,
+	0x00000000, 0x8f820010, 0x10400005, 0x00000000, 0x9743011c, 0x9742011e,
+	0x0a000c89, 0x00021400, 0x9743011e, 0x9742011c, 0x00021400, 0x00621825,
+	0xaf830004, 0x8f840008, 0x3c020020, 0x34424000, 0x00821824, 0x54620004,
+	0x3c020020, 0x8f820014, 0x0a000c9a, 0x34421000, 0x34428000, 0x00821824,
+	0x14620004, 0x00000000, 0x8f820014, 0x34428000, 0xaf820014, 0x8f820008,
+	0x9743010c, 0x00403021, 0x30421000, 0x10400010, 0x3069ffff, 0x30c20020,
+	0x1440000e, 0x24070005, 0x3c021000, 0x00c21024, 0x10400009, 0x3c030dff,
+	0x3463ffff, 0x3c020e00, 0x00c21024, 0x0062182b, 0x50600004, 0x24070001,
+	0x0a000cb2, 0x3c020800, 0x24070001, 0x3c020800, 0x8c430034, 0x1460001d,
+	0x00405821, 0x8f820014, 0x30424000, 0x1440001a, 0x3c020001, 0x3c021f01,
+	0x00c24024, 0x3c031000, 0x15030015, 0x3c020001, 0x31220200, 0x14400012,
+	0x3c020001, 0x9744010e, 0x24020003, 0xa342018b, 0x97850016, 0x24020002,
+	0x34e30002, 0xaf400180, 0xa742018c, 0xa7430188, 0x24840004, 0x30a5bfff,
+	0xa744018e, 0xa74501a6, 0xaf4801b8, 0x0a000f19, 0x00001021, 0x3c020001,
+	0x00c21024, 0x1040002f, 0x00000000, 0x9742010e, 0x3c038000, 0x3046ffff,
+	0x8f4201b8, 0x00431024, 0x1440fffd, 0x24020003, 0xa342018b, 0x9784000a,
+	0x8f850004, 0x8f870014, 0x24020080, 0x24030002, 0xaf420180, 0x24020003,
+	0xa743018c, 0xa746018e, 0xa7420188, 0x30e28000, 0xa7440190, 0x1040000c,
+	0xaf4501a8, 0x93420116, 0x304200fc, 0x005a1021, 0x24424004, 0x8c430000,
+	0x3063ffff, 0x14600004, 0x3c02ffff, 0x34427fff, 0x00e21024, 0xaf820014,
+	0x97820016, 0x9743010c, 0x8f440104, 0x3042bfff, 0x00031c00, 0x3084ffff,
+	0x00641825, 0xa74201a6, 0xaf4301ac, 0x3c021000, 0xaf4201b8, 0x0a000f19,
+	0x00001021, 0x8f820014, 0x30434000, 0x10600016, 0x00404021, 0x3c020f00,
+	0x00c21024, 0x14400012, 0x00000000, 0x93420116, 0x34424000, 0x03421821,
+	0x94650002, 0x2ca21389, 0x1040000b, 0x3c020800, 0x24425900, 0x00051942,
+	0x00031880, 0x00621821, 0x30a5001f, 0x8c640000, 0x24020001, 0x00a21004,
+	0x00822024, 0x02048025, 0x12000030, 0x3c021000, 0x9742010e, 0x34e80002,
+	0x3c038000, 0x24420004, 0x3046ffff, 0x8f4201b8, 0x00431024, 0x1440fffd,
+	0x24020003, 0xa342018b, 0x9784000a, 0x8f850004, 0x8f870014, 0x24020180,
+	0x24030002, 0xaf420180, 0xa743018c, 0xa746018e, 0xa7480188, 0x30e28000,
+	0xa7440190, 0x1040000c, 0xaf4501a8, 0x93420116, 0x304200fc, 0x005a1021,
+	0x24424004, 0x8c430000, 0x3063ffff, 0x14600004, 0x3c02ffff, 0x34427fff,
+	0x00e21024, 0xaf820014, 0x97820016, 0x9743010c, 0x8f440104, 0x3042bfff,
+	0x00031c00, 0x3084ffff, 0x00641825, 0xa74201a6, 0xaf4301ac, 0x3c021000,
+	0xaf4201b8, 0x0a000f19, 0x00001021, 0x00c21024, 0x104000c0, 0x3c020800,
+	0x8c430030, 0x10600037, 0x31024000, 0x10400035, 0x3c030f00, 0x00c31824,
+	0x3c020100, 0x0043102b, 0x14400031, 0x3c030800, 0x9742010e, 0x34e80002,
+	0x3c038000, 0x24420004, 0x3046ffff, 0x8f4201b8, 0x00431024, 0x1440fffd,
+	0x24020003, 0xa342018b, 0x9784000a, 0x8f850004, 0x8f870014, 0x24020080,
+	0x24030002, 0xaf420180, 0xa743018c, 0xa746018e, 0xa7480188, 0x30e28000,
+	0xa7440190, 0x1040000c, 0xaf4501a8, 0x93420116, 0x304200fc, 0x005a1021,
+	0x24424004, 0x8c430000, 0x3063ffff, 0x14600004, 0x3c02ffff, 0x34427fff,
+	0x00e21024, 0xaf820014, 0x97820016, 0x9743010c, 0x8f440104, 0x3042bfff,
+	0x00031c00, 0x3084ffff, 0x00641825, 0xa74201a6, 0xaf4301ac, 0x3c021000,
+	0xaf4201b8, 0x0a000f19, 0x00001021, 0x3c030800, 0x8c620024, 0x30420008,
+	0x10400035, 0x34ea0002, 0x3c020f00, 0x00c21024, 0x14400032, 0x8d620034,
+	0x31220200, 0x1040002f, 0x8d620034, 0x9742010e, 0x30e8fffb, 0x3c038000,
+	0x24420004, 0x3046ffff, 0x8f4201b8, 0x00431024, 0x1440fffd, 0x24020003,
+	0xa342018b, 0x9784000a, 0x8f850004, 0x8f870014, 0x24020180, 0x24030002,
+	0xaf420180, 0xa743018c, 0xa746018e, 0xa7480188, 0x30e28000, 0xa7440190,
+	0x1040000c, 0xaf4501a8, 0x93420116, 0x304200fc, 0x005a1021, 0x24424004,
+	0x8c430000, 0x3063ffff, 0x14600004, 0x3c02ffff, 0x34427fff, 0x00e21024,
+	0xaf820014, 0x97820016, 0x9743010c, 0x8f440104, 0x3042bfff, 0x00031c00,
+	0x3084ffff, 0x00641825, 0xa74201a6, 0xaf4301ac, 0x3c021000, 0xaf4201b8,
+	0x8d620034, 0x8f860008, 0x10400012, 0x30c20100, 0x10400010, 0x3c020f00,
+	0x00c21024, 0x3c030200, 0x1043000c, 0x3c020800, 0x8c430038, 0x8f840004,
+	0x3c020800, 0x2442003c, 0x2463ffff, 0x00832024, 0x00822021, 0x90830000,
+	0x24630004, 0x0a000de1, 0x000329c0, 0x00000000, 0x00061602, 0x3042000f,
+	0x000229c0, 0x3c04fc00, 0x00441021, 0x3c030300, 0x0062182b, 0x50600001,
+	0x24050800, 0x9742010e, 0x3148ffff, 0x3c038000, 0x24420004, 0x3046ffff,
+	0x8f4201b8, 0x00431024, 0x1440fffd, 0x24020003, 0xa342018b, 0x9783000a,
+	0x8f840004, 0x8f870014, 0x24020002, 0xaf450180, 0xa742018c, 0xa746018e,
+	0xa7480188, 0x30e28000, 0xa7430190, 0x1040000c, 0xaf4401a8, 0x93420116,
+	0x304200fc, 0x005a1021, 0x24424004, 0x8c430000, 0x3063ffff, 0x14600004,
+	0x3c02ffff, 0x34427fff, 0x00e21024, 0xaf820014, 0x97820016, 0x9743010c,
+	0x8f440104, 0x3042bfff, 0x00031c00, 0x3084ffff, 0x00641825, 0xa74201a6,
+	0xaf4301ac, 0x3c021000, 0xaf4201b8, 0x0a000f19, 0x00001021, 0x8f424000,
+	0x30420100, 0x104000d5, 0x3c020800, 0x8c440024, 0x24030001, 0x1483002f,
+	0x00405021, 0x9742010e, 0x34e70002, 0x3c038000, 0x24420004, 0x3045ffff,
+	0x8f4201b8, 0x00431024, 0x1440fffd, 0x24020003, 0xa342018b, 0x9783000a,
+	0x8f840004, 0x8f860014, 0x24020002, 0xaf400180, 0xa742018c, 0xa745018e,
+	0xa7470188, 0x30c28000, 0xa7430190, 0x1040000c, 0xaf4401a8, 0x93420116,
+	0x304200fc, 0x005a1021, 0x24424004, 0x8c430000, 0x3063ffff, 0x14600004,
+	0x3c02ffff, 0x34427fff, 0x00c21024, 0xaf820014, 0x97820016, 0x9743010c,
+	0x8f440104, 0x3042bfff, 0x00031c00, 0x3084ffff, 0x00641825, 0xa74201a6,
+	0xaf4301ac, 0x3c021000, 0xaf4201b8, 0x0a000f19, 0x00001021, 0x30820001,
+	0x1040002e, 0x30eb0004, 0x9742010e, 0x30e9fffb, 0x3c038000, 0x24420004,
+	0x3045ffff, 0x8f4201b8, 0x00431024, 0x1440fffd, 0x24020003, 0xa342018b,
+	0x9783000a, 0x8f840004, 0x8f860014, 0x24020002, 0xaf400180, 0xa742018c,
+	0xa745018e, 0xa7470188, 0x30c28000, 0xa7430190, 0x1040000c, 0xaf4401a8,
+	0x93420116, 0x304200fc, 0x005a1021, 0x24424004, 0x8c430000, 0x3063ffff,
+	0x14600004, 0x3c02ffff, 0x34427fff, 0x00c21024, 0xaf820014, 0x97820016,
+	0x9743010c, 0x8f440104, 0x3042bfff, 0x00031c00, 0x3084ffff, 0x00641825,
+	0xa74201a6, 0xaf4301ac, 0x3c021000, 0xaf4201b8, 0x3127ffff, 0x8d420024,
+	0x30420004, 0x10400030, 0x8d420024, 0x9742010e, 0x30e9fffb, 0x3c038000,
+	0x24420004, 0x3046ffff, 0x8f4201b8, 0x00431024, 0x1440fffd, 0x24020003,
+	0xa342018b, 0x9784000a, 0x8f850004, 0x8f880014, 0x24020100, 0x24030002,
+	0xaf420180, 0xa743018c, 0xa746018e, 0xa7470188, 0x31028000, 0xa7440190,
+	0x1040000c, 0xaf4501a8, 0x93420116, 0x304200fc, 0x005a1021, 0x24424004,
+	0x8c430000, 0x3063ffff, 0x14600004, 0x3c02ffff, 0x34427fff, 0x01021024,
+	0xaf820014, 0x97820016, 0x9743010c, 0x8f440104, 0x3042bfff, 0x00031c00,
+	0x3084ffff, 0x00641825, 0xa74201a6, 0xaf4301ac, 0x3c021000, 0xaf4201b8,
+	0x3127ffff, 0x8d420024, 0x30420008, 0x1040002d, 0x00000000, 0x9742010e,
+	0x3c038000, 0x24420004, 0x3046ffff, 0x8f4201b8, 0x00431024, 0x1440fffd,
+	0x24020003, 0xa342018b, 0x9784000a, 0x8f850004, 0x8f880014, 0x24020180,
+	0x24030002, 0xaf420180, 0xa743018c, 0xa746018e, 0xa7470188, 0x31028000,
+	0xa7440190, 0x1040000c, 0xaf4501a8, 0x93420116, 0x304200fc, 0x005a1021,
+	0x24424004, 0x8c430000, 0x3063ffff, 0x14600004, 0x3c02ffff, 0x34427fff,
+	0x01021024, 0xaf820014, 0x97820016, 0x9743010c, 0x8f440104, 0x3042bfff,
+	0x00031c00, 0x3084ffff, 0x00641825, 0xa74201a6, 0xaf4301ac, 0x3c021000,
+	0xaf4201b8, 0x15600041, 0x00001021, 0x27440180, 0x3c038000, 0x8f4201b8,
+	0x00431024, 0x1440fffd, 0x24022000, 0x24030002, 0xa4820008, 0xa083000b,
+	0xa4800010, 0x3c021000, 0xaf4201b8, 0x0a000f19, 0x00001021, 0x3c030800,
+	0x8c620024, 0x30420001, 0x1040002e, 0x00001021, 0x9742010e, 0x34e70002,
+	0x3c038000, 0x24420004, 0x3045ffff, 0x8f4201b8, 0x00431024, 0x1440fffd,
+	0x24020003, 0xa342018b, 0x9783000a, 0x8f840004, 0x8f860014, 0x24020002,
+	0xaf400180, 0xa742018c, 0xa745018e, 0xa7470188, 0x30c28000, 0xa7430190,
+	0x1040000c, 0xaf4401a8, 0x93420116, 0x304200fc, 0x005a1021, 0x24424004,
+	0x8c430000, 0x3063ffff, 0x14600004, 0x3c02ffff, 0x34427fff, 0x00c21024,
+	0xaf820014, 0x97820016, 0x9743010c, 0x8f440104, 0x3042bfff, 0x00031c00,
+	0x3084ffff, 0x00641825, 0xa74201a6, 0xaf4301ac, 0x3c021000, 0xaf4201b8,
+	0x00001021, 0x8fbf0014, 0x8fb00010, 0x03e00008, 0x27bd0018, 0x8f4b0070,
+	0x93420112, 0x8f840008, 0x00022882, 0x30820100, 0x14400003, 0x24a30003,
+	0x03e00008, 0x00001021, 0x30824000, 0x10400010, 0x27424000, 0x00031880,
+	0x00431021, 0x8c470000, 0x24a30004, 0x00031880, 0x27424000, 0x00431021,
+	0x8c490000, 0x93430116, 0x27424000, 0x306300fc, 0x00431021, 0x8c4a0000,
+	0x0a000f45, 0x3c030800, 0x30822000, 0x1040ffea, 0x00031880, 0x27424000,
+	0x00431021, 0x8c470000, 0x24a30004, 0x00031880, 0x27424000, 0x00431021,
+	0x8c490000, 0x00005021, 0x3c030800, 0x24680100, 0x00071602, 0x00021080,
+	0x00481021, 0x8c460000, 0x00071b82, 0x306303fc, 0x01031821, 0x8c640400,
+	0x00071182, 0x304203fc, 0x01021021, 0x8c450800, 0x30e300ff, 0x00031880,
+	0x01031821, 0x00091602, 0x00021080, 0x01021021, 0x00c43026, 0x8c640c00,
+	0x8c431000, 0x00c53026, 0x00091382, 0x304203fc, 0x01021021, 0x8c451400,
+	0x312200ff, 0x00021080, 0x01021021, 0x00c43026, 0x00c33026, 0x00091982,
+	0x306303fc, 0x01031821, 0x8c641800, 0x8c431c00, 0x00c53026, 0x00c43026,
+	0x11400015, 0x00c33026, 0x000a1602, 0x00021080, 0x01021021, 0x8c432000,
+	0x000a1382, 0x304203fc, 0x01021021, 0x8c452400, 0x314200ff, 0x00021080,
+	0x01021021, 0x00c33026, 0x000a1982, 0x306303fc, 0x01031821, 0x8c642800,
+	0x8c432c00, 0x00c53026, 0x00c43026, 0x00c33026, 0x8f430070, 0x3c050800,
+	0x8ca43100, 0x2c820020, 0x10400008, 0x006b5823, 0x3c020800, 0x24423104,
+	0x00041880, 0x00621821, 0x24820001, 0xac6b0000, 0xaca23100, 0xaf860004,
+	0x03e00008, 0x24020001, 0x27bdffe8, 0xafbf0010, 0x8f460128, 0x8f840010,
+	0xaf460020, 0x8f450104, 0x8f420100, 0x24030800, 0xaf850008, 0xaf820014,
+	0xaf4301b8, 0x1080000a, 0x3c020800, 0x8c430034, 0x10600007, 0x30a22000,
+	0x10400005, 0x34a30100, 0x8f82000c, 0xaf830008, 0x24420001, 0xaf82000c,
+	0x3c020800, 0x8c4300c0, 0x10600006, 0x3c030800, 0x8c6200c4, 0x24040001,
+	0x24420001, 0x0a000fd5, 0xac6200c4, 0x8f820008, 0x3c030010, 0x00431024,
+	0x14400009, 0x3c02001f, 0x3c030800, 0x8c620020, 0x00002021, 0x24420001,
+	0x0e000c78, 0xac620020, 0x0a000fd5, 0x00402021, 0x3442ff00, 0x14c20009,
+	0x2403bfff, 0x3c030800, 0x8c620020, 0x24040001, 0x24420001, 0x0e000c78,
+	0xac620020, 0x0a000fd5, 0x00402021, 0x8f820014, 0x00431024, 0x14400006,
+	0x00000000, 0xaf400048, 0x0e0011a9, 0xaf400040, 0x0a000fd5, 0x00402021,
+	0x0e001563, 0x00000000, 0x00402021, 0x10800005, 0x3c024000, 0x8f430124,
+	0x3c026020, 0xac430014, 0x3c024000, 0xaf420138, 0x00000000, 0x8fbf0010,
+	0x03e00008, 0x27bd0018, 0x27bdffe0, 0xafbf0018, 0xafb10014, 0xafb00010,
+	0x8f420140, 0xaf420020, 0x8f430148, 0x3c027000, 0x00621824, 0x3c023000,
+	0x10620021, 0x0043102b, 0x14400006, 0x3c024000, 0x3c022000, 0x10620009,
+	0x3c024000, 0x0a001040, 0x00000000, 0x10620045, 0x3c025000, 0x10620047,
+	0x3c024000, 0x0a001040, 0x00000000, 0x27440180, 0x3c038000, 0x8f4201b8,
+	0x00431024, 0x1440fffd, 0x00000000, 0x8f420148, 0x24030002, 0xa083000b,
+	0x00021402, 0xa4820008, 0x8f430148, 0xa4830010, 0x8f420144, 0x3c031000,
+	0xac820024, 0xaf4301b8, 0x0a001040, 0x3c024000, 0x8f420148, 0x24030002,
+	0x3044ffff, 0x00021402, 0x305000ff, 0x1203000c, 0x27510180, 0x2a020003,
+	0x10400005, 0x24020003, 0x0600001d, 0x36053000, 0x0a001027, 0x3c038000,
+	0x12020007, 0x00000000, 0x0a001034, 0x00000000, 0x0e00112c, 0x00000000,
+	0x0a001025, 0x00402021, 0x0e00113e, 0x00000000, 0x00402021, 0x36053000,
+	0x3c038000, 0x8f4201b8, 0x00431024, 0x1440fffd, 0x24020002, 0xa6250008,
+	0xa222000b, 0xa6240010, 0x8f420144, 0x3c031000, 0xae220024, 0xaf4301b8,
+	0x0a001040, 0x3c024000, 0x0000000d, 0x00000000, 0x240002bf, 0x0a001040,
+	0x3c024000, 0x0e001441, 0x00000000, 0x0a001040, 0x3c024000, 0x0e0015ea,
+	0x00000000, 0x3c024000, 0xaf420178, 0x00000000, 0x8fbf0018, 0x8fb10014,
+	0x8fb00010, 0x03e00008, 0x27bd0020, 0x24020800, 0x03e00008, 0xaf4201b8,
+	0x27bdffe8, 0x3c04600c, 0xafbf0014, 0xafb00010, 0x8c825000, 0x3c1a8000,
+	0x2403ff7f, 0x3c106000, 0x00431024, 0x3442380c, 0x24030003, 0xac825000,
+	0x3c020008, 0xaf430008, 0x8e040808, 0x0342d825, 0x8e020808, 0x3c030800,
+	0xac600020, 0x3084fff0, 0x2c840001, 0x3042fff0, 0x38420010, 0x2c420001,
+	0xaf840010, 0xaf820000, 0x0e00160c, 0x00000000, 0x0e001561, 0x00000000,
+	0x3c020400, 0x3442000c, 0x3c03ffff, 0x34630806, 0xae021948, 0xae03194c,
+	0x8e021980, 0x34420200, 0xae021980, 0x8f500000, 0x32020003, 0x1040fffd,
+	0x32020001, 0x10400004, 0x32020002, 0x0e000f92, 0x00000000, 0x32020002,
+	0x1040fff6, 0x00000000, 0x0e000fe0, 0x00000000, 0x0a001071, 0x00000000,
+	0x27bdffe8, 0x3c04600c, 0xafbf0014, 0xafb00010, 0x8c825000, 0x3c1a8000,
+	0x2403ff7f, 0x3c106000, 0x00431024, 0x3442380c, 0x24030003, 0xac825000,
+	0x3c020008, 0xaf430008, 0x8e040808, 0x0342d825, 0x8e020808, 0x3c030800,
+	0xac600020, 0x3084fff0, 0x2c840001, 0x3042fff0, 0x38420010, 0x2c420001,
+	0xaf840010, 0xaf820000, 0x0e00160c, 0x00000000, 0x0e001561, 0x00000000,
+	0x3c020400, 0x3442000c, 0x3c03ffff, 0x34630806, 0xae021948, 0xae03194c,
+	0x8e021980, 0x8fbf0014, 0x34420200, 0xae021980, 0x8fb00010, 0x03e00008,
+	0x27bd0018, 0x00804821, 0x30a5ffff, 0x30c6ffff, 0x30e7ffff, 0x3c038000,
+	0x8f4201b8, 0x00431024, 0x1440fffd, 0x24020003, 0xa342018b, 0x9783000a,
+	0x8f840004, 0x8f880014, 0xaf490180, 0xa745018c, 0xa746018e, 0xa7470188,
+	0x31028000, 0xa7430190, 0x1040000c, 0xaf4401a8, 0x93420116, 0x304200fc,
+	0x005a1021, 0x24424004, 0x8c430000, 0x3063ffff, 0x14600004, 0x3c02ffff,
+	0x34427fff, 0x01021024, 0xaf820014, 0x97820016, 0x9743010c, 0x8f440104,
+	0x3042bfff, 0x00031c00, 0x3084ffff, 0x00641825, 0xa74201a6, 0xaf4301ac,
+	0x3c021000, 0xaf4201b8, 0x03e00008, 0x00000000, 0x27440180, 0x3c038000,
+	0x8f4201b8, 0x00431024, 0x1440fffd, 0x24022000, 0x24030002, 0xa4820008,
+	0xa083000b, 0xa4800010, 0x3c021000, 0xaf4201b8, 0x03e00008, 0x00000000,
+	0x27440180, 0x3c038000, 0x8f4201b8, 0x00431024, 0x1440fffd, 0x00000000,
+	0x8f420148, 0x24030002, 0xa083000b, 0x00021402, 0xa4820008, 0x8f430148,
+	0xa4830010, 0x8f420144, 0x3c031000, 0xac820024, 0x03e00008, 0xaf4301b8,
+	0x27bdffe0, 0xafbf0018, 0xafb10014, 0xafb00010, 0x8f420148, 0x24030002,
+	0x3044ffff, 0x00021402, 0x305000ff, 0x1203000c, 0x27510180, 0x2a020003,
+	0x10400005, 0x24020003, 0x0600001d, 0x36053000, 0x0a001117, 0x3c038000,
+	0x12020007, 0x00000000, 0x0a001124, 0x00000000, 0x0e00112c, 0x00000000,
+	0x0a001115, 0x00402021, 0x0e00113e, 0x00000000, 0x00402021, 0x36053000,
+	0x3c038000, 0x8f4201b8, 0x00431024, 0x1440fffd, 0x24020002, 0xa6250008,
+	0xa222000b, 0xa6240010, 0x8f420144, 0x3c031000, 0xae220024, 0xaf4301b8,
+	0x0a001128, 0x8fbf0018, 0x0000000d, 0x00000000, 0x240002bf, 0x8fbf0018,
+	0x8fb10014, 0x8fb00010, 0x03e00008, 0x27bd0020, 0x3084ffff, 0x2c821389,
+	0x1040000d, 0x00001021, 0x3c030800, 0x24635900, 0x00042942, 0x00052880,
+	0x00a32821, 0x3086001f, 0x8ca40000, 0x24030001, 0x00c31804, 0x00832025,
+	0x03e00008, 0xaca40000, 0x03e00008, 0x24020091, 0x3084ffff, 0x2c821389,
+	0x1040000e, 0x00001021, 0x3c030800, 0x24635900, 0x00042942, 0x00052880,
+	0x00a32821, 0x3086001f, 0x24030001, 0x8ca40000, 0x00c31804, 0x00031827,
+	0x00832024, 0x03e00008, 0xaca40000, 0x03e00008, 0x24020091, 0x9482000c,
+	0x24870014, 0x00021302, 0x00021080, 0x00824021, 0x00e8182b, 0x1060004f,
+	0x00000000, 0x90e30000, 0x2c620009, 0x10400047, 0x3c020800, 0x24425890,
+	0x00031880, 0x00621821, 0x8c640000, 0x00800008, 0x00000000, 0x0a0011a4,
+	0x24e70001, 0x90e30001, 0x2402000a, 0x54620024, 0x01003821, 0x01071023,
+	0x2c42000a, 0x54400020, 0x01003821, 0x3c050800, 0x8ca26c98, 0x24e70002,
+	0x34420100, 0xaca26c98, 0x90e30000, 0x90e20001, 0x90e40002, 0x90e60003,
+	0x24e70004, 0x24a56c98, 0x00031e00, 0x00021400, 0x00621825, 0x00042200,
+	0x00641825, 0x00661825, 0xaca30004, 0x90e20000, 0x90e30001, 0x90e40002,
+	0x90e60003, 0x24e70004, 0x00021600, 0x00031c00, 0x00431025, 0x00042200,
+	0x00441025, 0x00461025, 0x0a0011a4, 0xaca20008, 0x90e30001, 0x24020004,
+	0x1062000e, 0x00601021, 0x0a00119e, 0x01001021, 0x90e30001, 0x24020003,
+	0x10620008, 0x00601021, 0x0a00119e, 0x01001021, 0x90e30001, 0x24020002,
+	0x14620003, 0x01001021, 0x00601021, 0x00e21021, 0x0a0011a4, 0x00403821,
+	0x90e20001, 0x0a0011a4, 0x00e23821, 0x01003821, 0x00e8102b, 0x5440ffb4,
+	0x90e30000, 0x03e00008, 0x24020001, 0x27bdff90, 0x3c030800, 0xafbf006c,
+	0xafbe0068, 0xafb70064, 0xafb60060, 0xafb5005c, 0xafb40058, 0xafb30054,
+	0xafb20050, 0xafb1004c, 0xafb00048, 0xac606c98, 0x93620023, 0x30420010,
+	0x1440027c, 0x24020001, 0x93420116, 0x93630005, 0x34424000, 0x30630001,
+	0x14600005, 0x0342b021, 0x0e0015e0, 0x00000000, 0x0a001436, 0x8fbf006c,
+	0x93420112, 0x8f430104, 0x3c040020, 0x34424000, 0x00641824, 0x10600012,
+	0x03422821, 0x27450180, 0x3c038000, 0x8f4201b8, 0x00431024, 0x1440fffd,
+	0x00000000, 0x8f420128, 0xaca20000, 0x8f640040, 0x24030008, 0x240240c1,
+	0xa4a20008, 0x24020002, 0xa0a2000b, 0x3c021000, 0x0a0011f1, 0xa0a3000a,
+	0x8f420104, 0x3c030040, 0x00431024, 0x1040001d, 0x3c038000, 0x27450180,
+	0x8f4201b8, 0x00431024, 0x1440fffd, 0x00000000, 0x8f420128, 0xaca20000,
+	0x8f640040, 0x24030010, 0x240240c1, 0xa4a20008, 0x24020002, 0xa0a3000a,
+	0x24030008, 0xa0a2000b, 0x3c021000, 0xa4a30010, 0xa0a00012, 0xa0a00013,
+	0xaca00014, 0xaca00024, 0xaca00028, 0xaca0002c, 0xaca40018, 0x0e0015e0,
+	0xaf4201b8, 0x0a001436, 0x8fbf006c, 0x8f820000, 0x10400016, 0x00000000,
+	0x8f420104, 0x3c030001, 0x00431024, 0x10400011, 0x00000000, 0x8ca3000c,
+	0x8f620030, 0x1462022d, 0x24020001, 0x8ca30010, 0x8f62002c, 0x14620229,
+	0x24020001, 0x9763003a, 0x96c20000, 0x14430225, 0x24020001, 0x97630038,
+	0x96c20002, 0x14430221, 0x24020001, 0xaf400048, 0xaf400054, 0xaf400040,
+	0x8f740040, 0x8f650048, 0x00b43023, 0x04c10004, 0x00000000, 0x0000000d,
+	0x00000000, 0x240001af, 0x9742011a, 0x3052ffff, 0x12400004, 0x8ed30004,
+	0x02721021, 0x0a001228, 0x2451ffff, 0x02608821, 0x92d7000d, 0xa7a00020,
+	0xa3a0001a, 0xafa00028, 0x9362003f, 0x32e30004, 0x1060003a, 0x305000ff,
+	0x24040012, 0x16040006, 0x24020001, 0x3c040800, 0x8c830028, 0x24630001,
+	0x0a001328, 0xac830028, 0x8f620044, 0x16620010, 0x27a60010, 0x27450180,
+	0x3c038000, 0x2402001a, 0xa7a20020, 0x24020020, 0xafb40028, 0xa3b00022,
+	0xa3a40023, 0xa3a2001a, 0x8f4201b8, 0x00431024, 0x1440fffd, 0x00000000,
+	0x0a00130d, 0x00000000, 0x8f620044, 0x02621023, 0x0440001a, 0x02651023,
+	0x044100d9, 0x24020001, 0x3c020800, 0x8c4300d8, 0x10600004, 0x24020001,
+	0xa7a20020, 0x0a00125e, 0xafb40028, 0x2402001a, 0xa7a20020, 0x24020020,
+	0xafb40028, 0xa3b00022, 0xa3a40023, 0xa3a2001a, 0x27a60010, 0x27450180,
+	0x3c038000, 0x8f4201b8, 0x00431024, 0x1440fffd, 0x00000000, 0x0a00130d,
+	0x00000000, 0x0a001328, 0x24020001, 0x0293f023, 0x1bc00016, 0x025e102a,
+	0x54400007, 0x32f700fe, 0x57d2000f, 0x027e9821, 0x32e20001, 0x5440000c,
+	0x027e9821, 0x32f700fe, 0x0240f021, 0x3c040800, 0x8c8300c8, 0x00009021,
+	0x24020001, 0xa7a20020, 0xafb40028, 0x24630001, 0x0a001282, 0xac8300c8,
+	0x025e1023, 0x0a001282, 0x3052ffff, 0x0000f021, 0x24a2ffff, 0x02221823,
+	0x1860001f, 0x0072102a, 0x54400019, 0x00a08821, 0x97a20020, 0x3c040800,
+	0x8c8300cc, 0xafb40028, 0x34420001, 0x24630001, 0xa7a20020, 0x02741026,
+	0x2c420001, 0xac8300cc, 0x2cc30001, 0x00431024, 0x1440000a, 0x02401821,
+	0x27a60010, 0x27450180, 0x3c038000, 0x8f4201b8, 0x00431024, 0x1440fffd,
+	0x00000000, 0x0a00130d, 0x00000000, 0x00a08821, 0x02431023, 0x3052ffff,
+	0x0a0012ae, 0x32f700f6, 0x02741023, 0x18400008, 0x97a20020, 0x3c040800,
+	0x8c8300d4, 0xafb30028, 0x34420400, 0x24630001, 0xa7a20020, 0xac8300d4,
+	0x32e20002, 0x1040001c, 0x32e20010, 0x8f620044, 0x1662000d, 0x27a60010,
+	0x97a20020, 0x27450180, 0x3c038000, 0xafb40028, 0x34420001, 0xa7a20020,
+	0x8f4201b8, 0x00431024, 0x1440fffd, 0x00000000, 0x0a00130d, 0x00000000,
+	0x97a20020, 0x27450180, 0x3c038000, 0xafb40028, 0x34420001, 0xa7a20020,
+	0x8f4201b8, 0x00431024, 0x1440fffd, 0x00000000, 0x0a00130d, 0x00000000,
+	0x54400003, 0x8ed50008, 0x0a001328, 0x24020001, 0x8f630054, 0x26a2ffff,
+	0x00431023, 0x18400011, 0x27a60010, 0x97a20020, 0x3c040800, 0x8c8300d0,
+	0x27450180, 0x3c078000, 0xafb40028, 0x34420001, 0x24630001, 0xa7a20020,
+	0xac8300d0, 0x8f4201b8, 0x00471024, 0x1440fffd, 0x00000000, 0x0a00130d,
+	0x00000000, 0x32e20020, 0x10400011, 0x00000000, 0x96c20012, 0x0052102b,
+	0x10400008, 0x97a20020, 0x96d20012, 0x12400003, 0x02721021, 0x0a0012f2,
+	0x2451ffff, 0x02608821, 0x97a20020, 0x93a3001a, 0x34420008, 0x34630004,
+	0xa7a20020, 0xa3a3001a, 0x8f420104, 0x3c030080, 0x00431024, 0x10400037,
+	0x3a03000a, 0x0e001151, 0x02c02021, 0x24030002, 0x1443002b, 0x3c030800,
+	0x27a60010, 0x97a20020, 0x27450180, 0x3c038000, 0xafb40028, 0x34420001,
+	0xa7a20020, 0x8f4201b8, 0x00431024, 0x1440fffd, 0x00000000, 0x8f420128,
+	0xaca20000, 0x8cc30018, 0x240240c1, 0xa4a20008, 0xaca30018, 0x90c4000a,
+	0x24020002, 0xa0a2000b, 0xa0a4000a, 0x94c20010, 0xa4a20010, 0x90c30012,
+	0xa0a30012, 0x90c20013, 0xa0a20013, 0x8cc30014, 0xaca30014, 0x8cc20024,
+	0xaca20024, 0x8cc30028, 0xaca30028, 0x8cc4002c, 0x24020001, 0x3c031000,
+	0xaca4002c, 0xaf4301b8, 0xaf400044, 0xaf400050, 0x0a001436, 0x8fbf006c,
+	0x8c626c98, 0x30420100, 0x10400003, 0x24636c98, 0x8c620004, 0xaf62017c,
+	0x3a03000a, 0x2c630001, 0x3a02000c, 0x2c420001, 0x00621825, 0x14600003,
+	0x2402000e, 0x56020030, 0x00009021, 0x52400008, 0x96c4000e, 0x12400004,
+	0xa7b20040, 0x02721021, 0x0a001343, 0x2451ffff, 0x02608821, 0x96c4000e,
+	0x93630035, 0x8f62004c, 0x00642004, 0x00952021, 0x00821023, 0x18400015,
+	0x00000000, 0x8f620018, 0x02621023, 0x1c400015, 0x97a20020, 0x8f620018,
+	0x1662001c, 0x00000000, 0x8f62001c, 0x02a21023, 0x1c40000e, 0x97a20020,
+	0x8f62001c, 0x16a20015, 0x00000000, 0x8f620058, 0x00821023, 0x18400011,
+	0x97a20020, 0x0a001364, 0xafb10028, 0x8f620058, 0x00821023, 0x0441000b,
+	0x97a20020, 0xafb10028, 0xafb30034, 0xafb50038, 0xafa4003c, 0x34420020,
+	0x0a00136d, 0xa7a20020, 0x02809821, 0x02608821, 0x8f640058, 0x8f62004c,
+	0x02a21023, 0x18400009, 0x00000000, 0x8f620054, 0x02a21023, 0x1c400005,
+	0x97a20020, 0xafb10028, 0xafb50024, 0x0a001385, 0x34420040, 0x9742011a,
+	0x1440000c, 0x24020014, 0x8f620058, 0x14820009, 0x24020014, 0x8f63004c,
+	0x8f620054, 0x10620004, 0x97a20020, 0xafb10028, 0x34420080, 0xa7a20020,
+	0x24020014, 0x1202000a, 0x2a020015, 0x10400005, 0x2402000c, 0x12020006,
+	0x32e20001, 0x0a0013c6, 0x00000000, 0x24020016, 0x16020035, 0x32e20001,
+	0x8f620084, 0x24420001, 0x16a20031, 0x32e20001, 0x24020014, 0x12020021,
+	0x2a020015, 0x10400005, 0x2402000c, 0x12020008, 0x32e20001, 0x0a0013c6,
+	0x00000000, 0x24020016, 0x1202000c, 0x32e20001, 0x0a0013c6, 0x00000000,
+	0x97a30020, 0x2402000e, 0xafb10028, 0xa3b00022, 0xa3a20023, 0xafb50024,
+	0x34630054, 0x0a0013c5, 0xa7a30020, 0x97a20020, 0x93a4001a, 0x24030010,
+	0xafb10028, 0xa3b00022, 0xa3a30023, 0xafb50024, 0x3442005d, 0x34840002,
+	0xa7a20020, 0x0a0013c5, 0xa3a4001a, 0x97a20020, 0x24030012, 0xa3a30023,
+	0x93a3001a, 0xafb10028, 0xa3b00022, 0xafb50024, 0x3042fffe, 0x3442005c,
+	0x34630002, 0xa7a20020, 0xa3a3001a, 0x32e20001, 0x10400030, 0x2402000c,
+	0x12020013, 0x2a02000d, 0x10400005, 0x2402000a, 0x12020008, 0x97a20020,
+	0x0a0013f8, 0x32e20009, 0x2402000e, 0x1202001b, 0x32e20009, 0x0a0013f9,
+	0x0002102b, 0x93a4001a, 0x24030008, 0xafb10028, 0xa3b00022, 0xa3a30023,
+	0x0a0013f4, 0x34420013, 0x97a30020, 0x30620004, 0x14400005, 0x93a2001a,
+	0x3463001b, 0xa7a30020, 0x0a0013e7, 0x24030016, 0x3463001b, 0xa7a30020,
+	0x24030010, 0xafb10028, 0xa3b00022, 0xa3a30023, 0x34420002, 0x0a0013f7,
+	0xa3a2001a, 0x97a20020, 0x93a4001a, 0x24030010, 0xafb10028, 0xa3b00022,
+	0xa3a30023, 0x3442001b, 0x34840002, 0xa7a20020, 0xa3a4001a, 0x32e20009,
+	0x0002102b, 0x00021023, 0x30420007, 0x12400015, 0x34450003, 0x8f820018,
+	0x24030800, 0x27440180, 0x24420001, 0xaf820018, 0x24020004, 0xaf4301b8,
+	0xa4850008, 0xa082000b, 0x93430120, 0x00003021, 0x3c021000, 0xa492000e,
+	0xac950024, 0xac930028, 0x007e1821, 0xa483000c, 0xaf4201b8, 0x0a001413,
+	0x97a20020, 0x24060001, 0x97a20020, 0x10400020, 0x27450180, 0x3c038000,
+	0x8f4201b8, 0x00431024, 0x1440fffd, 0x00000000, 0x8f420128, 0xaca20000,
+	0x8fa30028, 0x240240c1, 0xa4a20008, 0xaca30018, 0x93a4001a, 0x24020002,
+	0xa0a2000b, 0xa0a4000a, 0x97a20020, 0xa4a20010, 0x93a30022, 0xa0a30012,
+	0x93a20023, 0xa0a20013, 0x8fa30024, 0xaca30014, 0x8fa20034, 0xaca20024,
+	0x8fa30038, 0xaca30028, 0x8fa2003c, 0x3c031000, 0xaca2002c, 0xaf4301b8,
+	0x00c01021, 0x8fbf006c, 0x8fbe0068, 0x8fb70064, 0x8fb60060, 0x8fb5005c,
+	0x8fb40058, 0x8fb30054, 0x8fb20050, 0x8fb1004c, 0x8fb00048, 0x03e00008,
+	0x27bd0070, 0x8f470140, 0x8f460148, 0x3c028000, 0x00c24024, 0x00062c02,
+	0x30a300ff, 0x24020019, 0x106200e7, 0x27440180, 0x2862001a, 0x1040001f,
+	0x24020008, 0x106200be, 0x28620009, 0x1040000d, 0x24020001, 0x10620046,
+	0x28620002, 0x50400005, 0x24020006, 0x1060002e, 0x00a01821, 0x0a00155e,
+	0x00000000, 0x1062005b, 0x00a01821, 0x0a00155e, 0x00000000, 0x2402000b,
+	0x10620084, 0x2862000c, 0x10400005, 0x24020009, 0x106200bc, 0x00061c02,
+	0x0a00155e, 0x00000000, 0x2402000e, 0x106200b7, 0x00061c02, 0x0a00155e,
+	0x00000000, 0x28620021, 0x10400009, 0x2862001f, 0x104000c1, 0x2402001b,
+	0x106200bf, 0x2402001c, 0x1062009a, 0x00061c02, 0x0a00155e, 0x00000000,
+	0x240200c2, 0x106200ca, 0x286200c3, 0x10400005, 0x24020080, 0x1062005a,
+	0x00a01821, 0x0a00155e, 0x00000000, 0x240200c9, 0x106200cd, 0x30c5ffff,
+	0x0a00155e, 0x00000000, 0x3c058000, 0x8f4201b8, 0x00451024, 0x1440fffd,
+	0x24020001, 0xa4830008, 0x24030002, 0xac870000, 0xac800004, 0xa082000a,
+	0xa083000b, 0xa4860010, 0x8f430144, 0x3c021000, 0xac800028, 0xac830024,
+	0x3c036000, 0xaf4201b8, 0x03e00008, 0xac600808, 0x11000009, 0x00a01821,
+	0x3c020800, 0x24030002, 0xa0436c88, 0x24426c88, 0xac470008, 0x8f430144,
+	0x03e00008, 0xac430004, 0x3c058000, 0x8f4201b8, 0x00451024, 0x1440fffd,
+	0x24020002, 0xac800000, 0xac870004, 0xa4830008, 0xa082000a, 0xa082000b,
+	0xa4860010, 0xac800024, 0x8f420144, 0x3c031000, 0xac820028, 0x3c026000,
+	0xaf4301b8, 0x03e00008, 0xac400808, 0x3c080800, 0x3c058000, 0x8f4201b8,
+	0x00451024, 0x1440fffd, 0x00000000, 0xac870000, 0x91026c88, 0x00002821,
+	0x10400002, 0x25076c88, 0x8ce50008, 0xac850004, 0xa4830008, 0x91036c88,
+	0x24020002, 0xa082000b, 0xa4860010, 0x34630001, 0xa083000a, 0x8f420144,
+	0xac820024, 0x91036c88, 0x10600002, 0x00001021, 0x8ce20004, 0xac820028,
+	0x3c021000, 0xaf4201b8, 0x3c026000, 0xa1006c88, 0x03e00008, 0xac400808,
+	0x3c058000, 0x8f4201b8, 0x00451024, 0x1440fffd, 0x24020002, 0xa082000b,
+	0xa4830008, 0xa4860010, 0x8f420144, 0x3c031000, 0xa4820012, 0x03e00008,
+	0xaf4301b8, 0x30c2ffff, 0x14400028, 0x00061c02, 0x93620005, 0x30420004,
+	0x14400020, 0x3c029000, 0x34420001, 0x00e21025, 0xaf420020, 0x3c038000,
+	0x8f420020, 0x00431024, 0x1440fffd, 0x00000000, 0x93620005, 0x3c038000,
+	0x34630001, 0x00e31825, 0x34420004, 0xa3620005, 0xaf430020, 0x93620005,
+	0x30420004, 0x14400003, 0x3c038000, 0x0000000d, 0x3c038000, 0x8f4201b8,
+	0x00431024, 0x1440fffd, 0x24020005, 0x3c031000, 0xac870000, 0xa082000b,
+	0xaf4301b8, 0x0a00150d, 0x00061c02, 0x0000000d, 0x03e00008, 0x00000000,
+	0x00061c02, 0x3c058000, 0x8f4201b8, 0x00451024, 0x1440fffd, 0x24020001,
+	0xa4830008, 0x24030002, 0xac870000, 0xac800004, 0xa082000a, 0xa083000b,
+	0xa4860010, 0x8f430144, 0x3c021000, 0xac800028, 0xac830024, 0x03e00008,
+	0xaf4201b8, 0x3c058000, 0x8f4201b8, 0x00451024, 0x1440fffd, 0x24020002,
+	0xac800000, 0xac870004, 0xa4830008, 0xa082000a, 0xa082000b, 0xa4860010,
+	0xac800024, 0x8f420144, 0x3c031000, 0xac820028, 0x03e00008, 0xaf4301b8,
+	0x00061c02, 0x3c058000, 0x8f4201b8, 0x00451024, 0x1440fffd, 0x24020001,
+	0xa4830008, 0x24030002, 0xa082000a, 0x3c021000, 0xac870000, 0xac800004,
+	0xa083000b, 0xa4860010, 0xac800024, 0xac800028, 0x03e00008, 0xaf4201b8,
+	0x00a01821, 0x3c058000, 0x8f4201b8, 0x00451024, 0x1440fffd, 0x24020002,
+	0xac870000, 0xac800004, 0xa4830008, 0xa080000a, 0x0a001518, 0xa082000b,
+	0x8f440144, 0x3c038000, 0x8f4201b8, 0x00431024, 0x1440fffd, 0x24020002,
+	0x240340c9, 0xaf470180, 0xa342018b, 0x3c021000, 0xa7430188, 0xaf4401a4,
+	0xaf4501a8, 0xaf4001ac, 0x03e00008, 0xaf4201b8, 0x0000000d, 0x03e00008,
+	0x00000000, 0x03e00008, 0x00000000, 0x8f420100, 0x3042003e, 0x14400011,
+	0x24020001, 0xaf400048, 0x8f420100, 0x304207c0, 0x10400005, 0x00000000,
+	0xaf40004c, 0xaf400050, 0x03e00008, 0x24020001, 0xaf400054, 0xaf400040,
+	0x8f420100, 0x30423800, 0x54400001, 0xaf400044, 0x24020001, 0x03e00008,
+	0x00000000, 0x3c038000, 0x8f4201b8, 0x00431024, 0x1440fffd, 0x24020002,
+	0x240340c9, 0xaf440180, 0xa342018b, 0x3c021000, 0xa7430188, 0xaf4501a4,
+	0xaf4601a8, 0xaf4701ac, 0x03e00008, 0xaf4201b8, 0x3c029000, 0x34420001,
+	0x00822025, 0xaf440020, 0x3c038000, 0x8f420020, 0x00431024, 0x1440fffd,
+	0x00000000, 0x03e00008, 0x00000000, 0x3c028000, 0x34420001, 0x00822025,
+	0x03e00008, 0xaf440020, 0x308600ff, 0x27450180, 0x3c038000, 0x8f4201b8,
+	0x00431024, 0x1440fffd, 0x00000000, 0x8f420128, 0xaca20000, 0x8f640040,
+	0x24030008, 0x240240c1, 0xa4a20008, 0x24020002, 0xa0a2000b, 0x3c021000,
+	0xa0a6000a, 0xa4a30010, 0xa0a00012, 0xa0a00013, 0xaca00014, 0xaca00024,
+	0xaca00028, 0xaca0002c, 0xaca40018, 0x03e00008, 0xaf4201b8, 0x24020001,
+	0xacc40000, 0x03e00008, 0xa4e50000, 0x24020001, 0xaf400044, 0x03e00008,
+	0xaf400050, 0x00803021, 0x27450180, 0x3c038000, 0x8f4201b8, 0x00431024,
+	0x1440fffd, 0x00000000, 0x8f420128, 0xaca20000, 0x8cc30018, 0x240240c1,
+	0xa4a20008, 0xaca30018, 0x90c4000a, 0x24020002, 0xa0a2000b, 0xa0a4000a,
+	0x94c20010, 0xa4a20010, 0x90c30012, 0xa0a30012, 0x90c20013, 0xa0a20013,
+	0x8cc30014, 0xaca30014, 0x8cc20024, 0xaca20024, 0x8cc30028, 0xaca30028,
+	0x8cc2002c, 0x3c031000, 0xaca2002c, 0x24020001, 0xaf4301b8, 0xaf400044,
+	0x03e00008, 0xaf400050, 0x27bdffe8, 0xafbf0010, 0x0e001047, 0x00000000,
+	0x00002021, 0x0e000c78, 0xaf400180, 0x8fbf0010, 0x03e00008, 0x27bd0018,
+	0x8f460148, 0x27450180, 0x3c038000, 0x00061402, 0x304700ff, 0x8f4201b8,
+	0x00431024, 0x1440fffd, 0x00000000, 0x8f440140, 0x00061202, 0x304200ff,
+	0x00061c02, 0xaca20004, 0x24020002, 0xa4a30008, 0x30c300ff, 0xa0a2000b,
+	0xaca30024, 0x10e0000a, 0xaca40000, 0x28e20004, 0x14400005, 0x24020001,
+	0x24020005, 0x54e20005, 0xa0a0000a, 0x24020001, 0x0a001609, 0xa0a2000a,
+	0xa0a0000a, 0x3c021000, 0x03e00008, 0xaf4201b8, 0x03e00008, 0x00001021,
+	0x10c00007, 0x00000000, 0x8ca20000, 0x24c6ffff, 0x24a50004, 0xac820000,
+	0x14c0fffb, 0x24840004, 0x03e00008, 0x00000000, 0x0a00161f, 0x00a01021,
+	0xac860000, 0x00000000, 0x00000000, 0x24840004, 0x00a01021, 0x1440fffa,
+	0x24a5ffff, 0x03e00008, 0x00000000, 0x00000000 }; 
+
+static u32 bnx2_RXP_b06FwData[(0x0/4) + 1] = { 0x0 };
+static u32 bnx2_RXP_b06FwRodata[(0x28/4) + 1] = {
+	0x0800468c, 0x0800458c, 0x08004630, 0x08004648, 0x08004660, 0x08004680,
+	0x0800468c, 0x0800468c, 0x08004594, 0x00000000, 0x00000000 };
+static u32 bnx2_RXP_b06FwBss[(0x13a4/4) + 1] = { 0x0 };
+static u32 bnx2_RXP_b06FwSbss[(0x1c/4) + 1] = { 0x0 };
+
+static u32 bnx2_rv2p_proc1[] = {
+	0x00000008, 0xac000001, 0x0000000c, 0x2f800001, 0x00000010, 0x213f0004,
+	0x00000010, 0x20bf002c, 0x00000010, 0x203f0143, 0x00000018, 0x8000fffd,
+	0x00000010, 0xb1b8b017, 0x0000000b, 0x2fdf0002, 0x00000000, 0x03d80000,
+	0x00000000, 0x2c380000, 0x00000008, 0x2c800000, 0x00000008, 0x2d000000,
+	0x00000010, 0x91d40000, 0x00000008, 0x2d800108, 0x00000008, 0x02000002,
+	0x00000010, 0x91de0000, 0x0000000f, 0x42e0001c, 0x00000010, 0x91840a08,
+	0x00000008, 0x2c8000b0, 0x00000008, 0x2d000008, 0x00000008, 0x2d800150,
+	0x00000000, 0x00000000, 0x00000010, 0x91de0000, 0x00000010, 0x2c620002,
+	0x00000018, 0x80000012, 0x0000000b, 0x2fdf0002, 0x0000000c, 0x1f800002,
+	0x00000000, 0x2c070000, 0x00000018, 0x8000ffe6, 0x00000008, 0x02000002,
+	0x0000000f, 0x42e0001c, 0x00000010, 0x91840a08, 0x00000008, 0x2c8000b0,
+	0x00000008, 0x2d000008, 0x00000010, 0x91d40000, 0x00000008, 0x2d800108,
+	0x00000000, 0x00000000, 0x00000010, 0x91de0000, 0x00000018, 0x80000004,
+	0x0000000c, 0x1f800002, 0x00000000, 0x00000000, 0x00000018, 0x8000ffd9,
+	0x0000000c, 0x29800002, 0x0000000c, 0x1f800002, 0x00000000, 0x2adf0000,
+	0x00000008, 0x2a000005, 0x00000018, 0x8000ffd4, 0x00000008, 0x02240030,
+	0x00000018, 0x00040000, 0x00000018, 0x80000015, 0x00000018, 0x80000017,
+	0x00000018, 0x8000001b, 0x00000018, 0x8000004c, 0x00000018, 0x8000008c,
+	0x00000018, 0x8000000f, 0x00000018, 0x8000000e, 0x00000018, 0x8000000d,
+	0x00000018, 0x8000000c, 0x00000018, 0x800000c2, 0x00000018, 0x8000000a,
+	0x00000018, 0x80000009, 0x00000018, 0x80000008, 0x00000018, 0x800000fd,
+	0x00000018, 0x80000006, 0x00000018, 0x80000005, 0x00000018, 0x800000ff,
+	0x00000018, 0x80000104, 0x00000018, 0x80000002, 0x00000018, 0x80000098,
+	0x00000018, 0x80000000, 0x0000000c, 0x1f800001, 0x00000000, 0x00000000,
+	0x00000018, 0x8000ffba, 0x00000010, 0x91d40000, 0x0000000c, 0x29800001,
+	0x0000000c, 0x1f800001, 0x00000008, 0x2a000002, 0x00000018, 0x8000ffb5,
+	0x00000010, 0xb1a0b012, 0x0000000b, 0x2fdf0002, 0x00000000, 0x2c200000,
+	0x00000008, 0x2c800000, 0x00000008, 0x2d000000, 0x00000010, 0x91d40000,
+	0x00000008, 0x2d80011c, 0x00000000, 0x00000000, 0x00000010, 0x91de0000,
+	0x0000000f, 0x47600008, 0x0000000f, 0x060e0001, 0x00000010, 0x001f0000,
+	0x00000000, 0x0f580000, 0x00000000, 0x0a640000, 0x00000000, 0x0ae50000,
+	0x00000000, 0x0b660000, 0x00000000, 0x0d610000, 0x00000018, 0x80000013,
+	0x0000000f, 0x47600008, 0x0000000b, 0x2fdf0002, 0x00000008, 0x2c800000,
+	0x00000008, 0x2d000000, 0x00000010, 0x91d40000, 0x00000008, 0x2d80011c,
+	0x0000000f, 0x060e0001, 0x00000010, 0x001f0000, 0x00000000, 0x0f580000,
+	0x00000010, 0x91de0000, 0x00000000, 0x0a640000, 0x00000000, 0x0ae50000,
+	0x00000000, 0x0b660000, 0x00000000, 0x0d610000, 0x00000000, 0x02620000,
+	0x0000000b, 0x2fdf0002, 0x00000000, 0x309a0000, 0x00000000, 0x31040000,
+	0x00000000, 0x0c961800, 0x00000009, 0x0c99ffff, 0x00000004, 0xcc993400,
+	0x00000010, 0xb1963202, 0x00000008, 0x0f800000, 0x0000000c, 0x29800001,
+	0x00000010, 0x00220002, 0x0000000c, 0x29520001, 0x0000000c, 0x29520000,
+	0x00000008, 0x22000001, 0x0000000c, 0x1f800001, 0x00000000, 0x2adf0000,
+	0x00000008, 0x2a000003, 0x00000018, 0x8000ff83, 0x00000010, 0xb1a0b01d,
+	0x0000000b, 0x2fdf0002, 0x00000000, 0x2c200000, 0x00000008, 0x2c8000b0,
+	0x00000008, 0x2d000008, 0x00000010, 0x91d40000, 0x00000008, 0x2d800150,
+	0x00000000, 0x00000000, 0x00000010, 0x205f0000, 0x00000008, 0x2c800000,
+	0x00000008, 0x2d000000, 0x00000008, 0x2d800108, 0x00000000, 0x00000000,
+	0x00000010, 0x91de0000, 0x0000000f, 0x47600008, 0x00000000, 0x060e0000,
+	0x00000010, 0x001f0000, 0x00000000, 0x0f580000, 0x00000010, 0x91de0000,
+	0x00000000, 0x0a640000, 0x00000000, 0x0ae50000, 0x00000000, 0x0b670000,
+	0x00000000, 0x0d620000, 0x00000000, 0x0ce71800, 0x00000009, 0x0c99ffff,
+	0x00000004, 0xcc993400, 0x00000010, 0xb1963220, 0x00000008, 0x0f800000,
+	0x00000018, 0x8000001e, 0x0000000f, 0x47600008, 0x0000000b, 0x2fdf0002,
+	0x00000008, 0x2c8000b0, 0x00000008, 0x2d000008, 0x00000010, 0x91d40000,
+	0x00000008, 0x2d80012c, 0x0000000f, 0x060e0001, 0x00000010, 0x001f0000,
+	0x00000000, 0x0f580000, 0x00000010, 0x91de0000, 0x00000000, 0x0a640000,
+	0x00000000, 0x0ae50000, 0x00000000, 0x0b670000, 0x00000000, 0x0d620000,
+	0x00000000, 0x02630000, 0x0000000f, 0x47620010, 0x00000000, 0x0ce71800,
+	0x0000000b, 0x2fdf0002, 0x00000000, 0x311a0000, 0x00000000, 0x31840000,
+	0x0000000b, 0xc20000ff, 0x00000002, 0x42040000, 0x00000001, 0x31620800,
+	0x0000000f, 0x020e0010, 0x00000002, 0x31620800, 0x00000009, 0x0c99ffff,
+	0x00000004, 0xcc993400, 0x00000010, 0xb1963202, 0x00000008, 0x0f800000,
+	0x0000000c, 0x29800001, 0x0000000c, 0x1f800001, 0x0000000c, 0x61420006,
+	0x00000008, 0x22000008, 0x00000000, 0x2adf0000, 0x00000008, 0x2a000004,
+	0x00000018, 0x8000ff42, 0x00000008, 0x2c8000b0, 0x00000008, 0x2d000008,
+	0x00000010, 0x91a0b008, 0x00000010, 0x91d40000, 0x0000000c, 0x31620018,
+	0x00000008, 0x2d800001, 0x00000000, 0x00000000, 0x00000010, 0x91de0000,
+	0x00000008, 0xac000001, 0x00000018, 0x8000000e, 0x00000000, 0x0380b000,
+	0x0000000b, 0x2fdf0002, 0x00000000, 0x2c004000, 0x00000010, 0x91d40000,
+	0x00000008, 0x2d800101, 0x00000000, 0x00000000, 0x00000010, 0x91de0000,
+	0x0000000c, 0x31620018, 0x00000008, 0x2d800001, 0x00000000, 0x00000000,
+	0x00000010, 0x91de0000, 0x0000000b, 0x2fdf0002, 0x00000000, 0x2c000e00,
+	0x0000000c, 0x29800001, 0x0000000c, 0x1f800001, 0x00000008, 0x2a000007,
+	0x00000018, 0x8000ff27, 0x00000010, 0xb1a0b016, 0x0000000b, 0x2fdf0002,
+	0x00000000, 0x03d80000, 0x00000000, 0x2c200000, 0x00000008, 0x2c8000b0,
+	0x00000008, 0x2d000008, 0x00000010, 0x91d40000, 0x00000008, 0x2d800150,
+	0x00000000, 0x00000000, 0x00000010, 0x205f0000, 0x00000008, 0x2c800000,
+	0x00000008, 0x2d000000, 0x00000008, 0x2d800108, 0x00000008, 0x07000001,
+	0x00000010, 0xb5de1c00, 0x00000010, 0x2c620002, 0x00000018, 0x8000000a,
+	0x0000000b, 0x2fdf0002, 0x00000000, 0x2c070000, 0x0000000c, 0x1f800001,
+	0x00000010, 0x91de0000, 0x00000018, 0x8000ff11, 0x00000008, 0x2c8000b0,
+	0x00000008, 0x2d000008, 0x00000010, 0x91d40000, 0x00000008, 0x2d800108,
+	0x0000000c, 0x29800001, 0x0000000c, 0x1f800001, 0x00000010, 0x91de0000,
+	0x00000000, 0x2adf0000, 0x00000008, 0x2a00000a, 0x00000018, 0x8000ff07,
+	0x00000000, 0x82265600, 0x0000000f, 0x47220008, 0x00000009, 0x070e000f,
+	0x00000008, 0x070e0008, 0x00000008, 0x02800001, 0x00000007, 0x02851c00,
+	0x00000008, 0x82850001, 0x00000000, 0x02840a00, 0x00000007, 0x42851c00,
+	0x00000003, 0xc3aa5200, 0x00000000, 0x03b10e00, 0x00000010, 0x001f0000,
+	0x0000000f, 0x0f280007, 0x00000007, 0x4b071c00, 0x00000000, 0x00000000,
+	0x0000000f, 0x0a960003, 0x00000000, 0x0a955c00, 0x00000000, 0x4a005a00,
+	0x00000000, 0x0c960a00, 0x00000009, 0x0c99ffff, 0x00000008, 0x0d00ffff,
+	0x00000010, 0xb1963202, 0x00000008, 0x0f800005, 0x00000010, 0x00220020,
+	0x00000000, 0x02a70000, 0x00000010, 0xb1850002, 0x00000008, 0x82850200,
+	0x00000000, 0x02000000, 0x00000000, 0x03a60000, 0x00000018, 0x8000004e,
+	0x00000000, 0x072b0000, 0x00000001, 0x878c1c00, 0x00000000, 0x870e1e00,
+	0x00000000, 0x860c1e00, 0x00000000, 0x03061e00, 0x00000010, 0xb18e0003,
+	0x00000018, 0x80000047, 0x00000018, 0x8000fffa, 0x00000010, 0x918c0003,
+	0x00000010, 0xb1870002, 0x00000018, 0x80000043, 0x00000010, 0x91d40000,
+	0x0000000c, 0x29800001, 0x00000000, 0x2a860000, 0x00000000, 0x230c0000,
+	0x00000000, 0x2b070000, 0x00000010, 0xb187000e, 0x00000008, 0x2a000008,
+	0x00000018, 0x8000003b, 0x00000010, 0x91d40000, 0x00000000, 0x28d18c00,
+	0x00000000, 0x2a860000, 0x00000000, 0x230c0000, 0x00000000, 0x2b070000,
+	0x00000018, 0x8000fff8, 0x00000010, 0x91d40000, 0x0000000c, 0x29800001,
+	0x00000000, 0x2aab0000, 0x00000000, 0xa3265600, 0x00000000, 0x2b000000,
+	0x0000000c, 0x1f800001, 0x00000008, 0x2a000008, 0x00000018, 0x8000fec8,
+	0x00000010, 0x91d40000, 0x0000000c, 0x29800001, 0x0000000c, 0x1f800001,
+	0x00000008, 0x2a000009, 0x00000018, 0x8000fec3, 0x00000010, 0x91d40000,
+	0x0000000c, 0x29800001, 0x0000000c, 0x1f800001, 0x00000000, 0x29420000,
+	0x00000008, 0x2a000002, 0x00000018, 0x8000febd, 0x00000018, 0x8000febc,
+	0x00000010, 0xb1bcb016, 0x0000000b, 0x2fdf0002, 0x00000000, 0x03d80000,
+	0x00000000, 0x2c3c0000, 0x00000008, 0x2c8000b0, 0x00000008, 0x2d000008,
+	0x00000010, 0x91d40000, 0x00000008, 0x2d800150, 0x00000000, 0x00000000,
+	0x00000010, 0x205f0000, 0x00000008, 0x2c800000, 0x00000008, 0x2d000000,
+	0x00000008, 0x2d800108, 0x00000008, 0x07000001, 0x00000010, 0xb5de1c00,
+	0x00000010, 0x2c620002, 0x00000018, 0x8000000a, 0x0000000b, 0x2fdf0002,
+	0x00000000, 0x2c070000, 0x0000000c, 0x1f800000, 0x00000010, 0x91de0000,
+	0x00000018, 0x8000fea6, 0x00000008, 0x2c8000b0, 0x00000008, 0x2d000008,
+	0x00000010, 0x91d40000, 0x00000008, 0x2d800108, 0x0000000c, 0x29800000,
+	0x0000000c, 0x1f800000, 0x00000010, 0x91de0000, 0x00000000, 0x2adf0000,
+	0x00000008, 0x2a000006, 0x00000018, 0x8000fe9c, 0x00000008, 0x03050004,
+	0x00000006, 0x83040c00, 0x00000008, 0x02850200, 0x00000000, 0x86050c00,
+	0x00000001, 0x860c0e00, 0x00000008, 0x02040004, 0x00000000, 0x02041800,
+	0x00000000, 0x83871800, 0x00000018, 0x00020000 };
+
+static u32 bnx2_rv2p_proc2[] = {
+	0x00000000, 0x2a000000, 0x00000010, 0xb1d40000, 0x00000008, 0x02540003,
+	0x00000018, 0x00040000, 0x00000018, 0x8000000a, 0x00000018, 0x8000000a,
+	0x00000018, 0x8000000e, 0x00000018, 0x80000056, 0x00000018, 0x800001b9,
+	0x00000018, 0x800001e1, 0x00000018, 0x8000019b, 0x00000018, 0x800001f9,
+	0x00000018, 0x8000019f, 0x00000018, 0x800001a6, 0x00000018, 0x80000000,
+	0x0000000c, 0x29800001, 0x00000000, 0x2a000000, 0x0000000c, 0x29800000,
+	0x00000010, 0x20530000, 0x00000018, 0x8000ffee, 0x0000000c, 0x29800001,
+	0x00000010, 0x91de0000, 0x00000010, 0x001f0000, 0x00000000, 0x2f80aa00,
+	0x00000000, 0x2a000000, 0x00000000, 0x0d610000, 0x00000000, 0x03620000,
+	0x00000000, 0x2c400000, 0x00000000, 0x02638c00, 0x00000000, 0x26460000,
+	0x00000010, 0x00420002, 0x00000008, 0x02040012, 0x00000010, 0xb9060836,
+	0x00000000, 0x0f580000, 0x00000000, 0x0a640000, 0x00000000, 0x0ae50000,
+	0x00000000, 0x0b660000, 0x00000000, 0x0c000000, 0x00000000, 0x0b800000,
+	0x00000010, 0x00420009, 0x00000008, 0x0cc60012, 0x00000008, 0x0f800003,
+	0x00000000, 0x00000000, 0x00000010, 0x009f0000, 0x00000008, 0x27110012,
+	0x00000000, 0x66900000, 0x00000008, 0xa31b0012, 0x00000018, 0x80000008,
+	0x00000000, 0x0cc60000, 0x00000008, 0x0f800003, 0x00000000, 0x00000000,
+	0x00000010, 0x009f0000, 0x00000000, 0x27110000, 0x00000000, 0x66900000,
+	0x00000000, 0x231b0000, 0x00000010, 0xb197320e, 0x00000000, 0x25960000,
+	0x00000000, 0x021b0000, 0x00000010, 0x001f0000, 0x00000008, 0x0f800003,
+	0x0000000c, 0x29800000, 0x00000010, 0x20530000, 0x00000000, 0x22c50800,
+	0x00000010, 0x009f0000, 0x00000000, 0x27002200, 0x00000000, 0x26802000,
+	0x00000000, 0x231b0000, 0x0000000c, 0x69520001, 0x00000018, 0x8000fff3,
+	0x00000010, 0x01130002, 0x00000010, 0xb1980003, 0x00000010, 0x001f0000,
+	0x00000008, 0x0f800004, 0x00000008, 0x22000003, 0x00000008, 0x2c80000c,
+	0x00000008, 0x2d00000c, 0x00000010, 0x009f0000, 0x00000000, 0x25960000,
+	0x0000000c, 0x29800000, 0x00000000, 0x32140000, 0x00000000, 0x32950000,
+	0x00000000, 0x33160000, 0x00000000, 0x31e32e00, 0x00000008, 0x2d800010,
+	0x00000010, 0x20530000, 0x00000018, 0x8000ffac, 0x00000000, 0x23000000,
+	0x00000000, 0x25e60000, 0x00000008, 0x2200000b, 0x0000000c, 0x69520000,
+	0x0000000c, 0x29800000, 0x00000010, 0x20530000, 0x00000018, 0x8000ffa5,
+	0x0000000c, 0x29800001, 0x00000010, 0x91de0000, 0x00000000, 0x2fd50000,
+	0x00000010, 0x001f0000, 0x00000000, 0x02700000, 0x00000000, 0x0d620000,
+	0x00000000, 0xbb630800, 0x00000000, 0x2a000000, 0x00000009, 0x076000ff,
+	0x0000000f, 0x2c0e0007, 0x00000008, 0x2c800000, 0x00000008, 0x2d000064,
+	0x00000008, 0x2d80011c, 0x00000009, 0x06420002, 0x0000000c, 0x61420001,
+	0x00000000, 0x0f400000, 0x00000000, 0x02d08c00, 0x00000000, 0x23000000,
+	0x00000004, 0x826da000, 0x00000000, 0x8304a000, 0x00000000, 0x22c50c00,
+	0x00000000, 0x03760000, 0x00000004, 0x83860a00, 0x00000000, 0x83870c00,
+	0x00000010, 0x91de0000, 0x00000000, 0x037c0000, 0x00000000, 0x837b0c00,
+	0x00000001, 0x83060e00, 0x00000000, 0x83870c00, 0x00000000, 0x82850e00,
+	0x00000010, 0xb1860016, 0x0000000f, 0x47610018, 0x00000000, 0x068e0000,
+	0x0000000f, 0x47670010, 0x0000000f, 0x47e20010, 0x00000000, 0x870e1e00,
+	0x00000010, 0xb70e1a10, 0x00000010, 0x0ce7000e, 0x00000008, 0x22000009,
+	0x00000000, 0x286d0000, 0x0000000f, 0x65680010, 0x00000003, 0xf66c9400,
+	0x00000010, 0xb972a003, 0x0000000c, 0x73e70019, 0x0000000c, 0x21420004,
+	0x00000018, 0x8000023f, 0x00000000, 0x37ed0000, 0x0000000c, 0x73e7001a,
+	0x00000010, 0x20530000, 0x00000008, 0x22000008, 0x0000000c, 0x61420004,
+	0x00000000, 0x02f60000, 0x00000004, 0x82840a00, 0x00000010, 0xb1840a2b,
+	0x00000010, 0x2d67000a, 0x00000010, 0xb96d0804, 0x00000004, 0xb6ed0a00,
+	0x00000000, 0x37ed0000, 0x00000018, 0x80000029, 0x0000000c, 0x61420000,
+	0x00000000, 0x37040000, 0x00000000, 0x37850000, 0x0000000c, 0x33e7001a,
+	0x00000018, 0x80000024, 0x00000010, 0xb96d0809, 0x00000004, 0xb6ed0a00,
+	0x00000000, 0x036d0000, 0x00000004, 0xb76e0c00, 0x00000010, 0x91ee0c1f,
+	0x0000000c, 0x73e7001a, 0x00000004, 0xb6ef0c00, 0x00000000, 0x37ed0000,
+	0x00000018, 0x8000001b, 0x0000000c, 0x61420000, 0x00000010, 0xb7ee0a05,
+	0x00000010, 0xb96f0815, 0x00000003, 0xb76e0800, 0x00000004, 0xb7ef0a00,
+	0x00000018, 0x80000015, 0x00000010, 0x0ce7000c, 0x00000008, 0x22000009,
+	0x00000000, 0x286d0000, 0x0000000f, 0x65680010, 0x00000003, 0xf66c9400,
+	0x00000010, 0xb972a003, 0x0000000c, 0x73e70019, 0x0000000c, 0x21420004,
+	0x00000018, 0x80000215, 0x00000010, 0x20530000, 0x00000008, 0x22000008,
+	0x0000000c, 0x61420004, 0x00000000, 0x37040000, 0x00000000, 0x37850000,
+	0x00000000, 0x036d0000, 0x00000003, 0xb8f10c00, 0x00000018, 0x80000004,
+	0x00000000, 0x02840000, 0x00000002, 0x21421800, 0x0000000c, 0x61420000,
+	0x00000000, 0x286d0000, 0x0000000f, 0x65ed0010, 0x00000009, 0x266dffff,
+	0x00000000, 0x23000000, 0x00000010, 0xb1840a3d, 0x00000010, 0x01420002,
+	0x00000004, 0xb8f10a00, 0x00000003, 0x83760a00, 0x00000010, 0xb8040c39,
+	0x00000010, 0xb7e6080a, 0x00000000, 0x0a640000, 0x00000000, 0x0ae50000,
+	0x00000009, 0x0c68ffff, 0x00000009, 0x0b67ffff, 0x00000000, 0x0be60000,
+	0x00000000, 0x0c840000, 0x00000010, 0xb197320c, 0x00000008, 0x0f800002,
+	0x00000018, 0x8000000a, 0x00000000, 0x0a6a0000, 0x00000000, 0x0aeb0000,
+	0x00000000, 0x0c000000, 0x00000009, 0x0b6cffff, 0x00000000, 0x0be90000,
+	0x00000000, 0x0c840000, 0x00000010, 0xb1973203, 0x00000008, 0x0f800002,
+	0x00000018, 0x80000001, 0x00000010, 0x001f0000, 0x00000000, 0x0c860000,
+	0x00000000, 0x06980000, 0x00000008, 0x0f800003, 0x00000000, 0x00000000,
+	0x00000010, 0x009f0000, 0x00000010, 0xb1973210, 0x00000000, 0x231b0000,
+	0x00000000, 0x02043600, 0x00000003, 0x8384a000, 0x0000000f, 0x65870010,
+	0x00000009, 0x2607ffff, 0x00000000, 0x27111a00, 0x00000000, 0x66900000,
+	0x0000000c, 0x29000000, 0x00000018, 0x800001de, 0x00000000, 0x06980000,
+	0x00000010, 0x20530000, 0x00000000, 0x22c58c00, 0x00000010, 0x001f0000,
+	0x00000008, 0x0f800003, 0x00000018, 0x8000fff0, 0x00000000, 0x02043600,
+	0x00000000, 0x231b0000, 0x00000003, 0x8384a000, 0x0000000f, 0x65870010,
+	0x00000009, 0x2607ffff, 0x00000000, 0x27111a00, 0x00000000, 0x66900000,
+	0x0000000c, 0x29000000, 0x00000010, 0x91840a02, 0x00000002, 0x21421800,
+	0x00000000, 0x32140000, 0x00000000, 0x32950000, 0x00000005, 0x73e72c00,
+	0x00000005, 0x74683000, 0x00000000, 0x33170000, 0x00000018, 0x80000138,
+	0x00000010, 0x91c60004, 0x00000008, 0x07000004, 0x00000010, 0xb1c41c02,
+	0x00000010, 0x91840a04, 0x00000018, 0x800001c3, 0x00000010, 0x20530000,
+	0x00000000, 0x22c58c00, 0x00000010, 0xb1840a8e, 0x0000000c, 0x21420006,
+	0x00000010, 0x0ce7001a, 0x0000000f, 0x43680010, 0x00000000, 0x03f30c00,
+	0x00000010, 0x91870850, 0x0000000f, 0x46ec0010, 0x00000010, 0xb68d0c4e,
+	0x00000000, 0x838d0c00, 0x00000000, 0xa3050800, 0x00000001, 0xa3460e00,
+	0x00000000, 0x02048c00, 0x00000010, 0x91840a02, 0x00000002, 0x21421800,
+	0x00000010, 0x001f0000, 0x00000008, 0x22000008, 0x00000003, 0x8384a000,
+	0x0000000f, 0x65870010, 0x00000009, 0x2607ffff, 0x00000000, 0x27750c00,
+	0x00000000, 0x66f40000, 0x0000000c, 0x29000000, 0x00000018, 0x800001aa,
+	0x00000000, 0x03068c00, 0x00000003, 0xf4680c00, 0x00000010, 0x20530000,
+	0x00000000, 0x22c58c00, 0x00000018, 0x8000ffe5, 0x00000000, 0x39760000,
+	0x00000000, 0x39840000, 0x0000000c, 0x33e70019, 0x00000010, 0x001f0000,
+	0x00000000, 0x031e0000, 0x00000000, 0x0760fe00, 0x0000000f, 0x0f0e0007,
+	0x00000000, 0x83850800, 0x00000000, 0x0a7d0000, 0x00000000, 0x0afe0000,
+	0x00000000, 0x0b7f0000, 0x00000000, 0x0d7a0000, 0x00000000, 0x0c000000,
+	0x00000000, 0x0bfc0000, 0x00000000, 0x0c970e00, 0x00000008, 0x0f800003,
+	0x0000000f, 0x47670010, 0x00000008, 0x070e0001, 0x0000000b, 0xc38000ff,
+	0x00000002, 0x43870000, 0x00000001, 0x33e70e00, 0x0000000f, 0x038e0010,
+	0x00000002, 0x33e70e00, 0x00000000, 0x28f30000, 0x00000010, 0x009f0000,
+	0x00000000, 0x02043600, 0x00000010, 0x91840a02, 0x00000002, 0x21421800,
+	0x00000008, 0x22000006, 0x00000000, 0x231b0000, 0x00000000, 0x23ff0000,
+	0x00000000, 0x241b0000, 0x00000003, 0x8384a000, 0x0000000f, 0x65870010,
+	0x00000009, 0x2607ffff, 0x00000000, 0x27110000, 0x00000000, 0x26900000,
+	0x0000000c, 0x29000000, 0x00000018, 0x8000017e, 0x00000003, 0xf4683600,
+	0x00000000, 0x3a100000, 0x00000000, 0x3a910000, 0x00000003, 0xf66c2400,
+	0x00000010, 0x001f0000, 0x00000010, 0xb1923604, 0x00000008, 0x0f800004,
+	0x00000000, 0x00000000, 0x00000010, 0x009f0000, 0x00000000, 0x3e170000,
+	0x00000000, 0x3e940000, 0x00000000, 0x3f150000, 0x00000000, 0x3f960000,
+	0x00000010, 0x001f0000, 0x00000000, 0x0f060000, 0x00000010, 0x20530000,
+	0x00000000, 0x22c53600, 0x00000018, 0x8000ffac, 0x00000010, 0x001f0000,
+	0x00000000, 0x031e0000, 0x00000000, 0x83850800, 0x00000009, 0x076000ff,
+	0x0000000f, 0x0f0e0007, 0x00000000, 0x0c000000, 0x00000000, 0x0a7d0000,
+	0x00000000, 0x0afe0000, 0x00000000, 0x0b7f0000, 0x00000000, 0x0d7a0000,
+	0x00000000, 0x0bfc0000, 0x00000000, 0x0c970e00, 0x00000008, 0x0f800003,
+	0x0000000f, 0x47670010, 0x00000008, 0x070e0001, 0x0000000b, 0xc38000ff,
+	0x00000002, 0x43870000, 0x00000001, 0x33e70e00, 0x0000000f, 0x038e0010,
+	0x00000002, 0x33e70e00, 0x00000000, 0x39840000, 0x00000003, 0xb9720800,
+	0x00000000, 0x28f30000, 0x0000000f, 0x65680010, 0x00000010, 0x009f0000,
+	0x00000000, 0x02043600, 0x00000010, 0x91840a02, 0x00000002, 0x21421800,
+	0x00000008, 0x22000007, 0x00000000, 0x231b0000, 0x00000000, 0x23ff0000,
+	0x00000000, 0x241b0000, 0x00000003, 0x8384a000, 0x0000000f, 0x65870010,
+	0x00000009, 0x2607ffff, 0x00000000, 0x27110000, 0x00000000, 0x26900000,
+	0x0000000c, 0x29000000, 0x00000018, 0x80000145, 0x00000003, 0xf4683600,
+	0x00000000, 0x3a100000, 0x00000000, 0x3a910000, 0x00000003, 0xf66c2400,
+	0x00000010, 0x001f0000, 0x00000010, 0xb1923604, 0x00000008, 0x0f800004,
+	0x00000000, 0x00000000, 0x00000010, 0x009f0000, 0x00000000, 0x3e170000,
+	0x00000000, 0x3e940000, 0x00000000, 0x3f150000, 0x00000000, 0x3f960000,
+	0x00000010, 0x001f0000, 0x00000000, 0x0f060000, 0x00000010, 0x20530000,
+	0x00000000, 0x22c53600, 0x00000018, 0x8000ff73, 0x00000010, 0x0ce70005,
+	0x00000008, 0x2c80000c, 0x00000008, 0x2d000070, 0x00000008, 0x2d800010,
+	0x00000000, 0x00000000, 0x00000010, 0x205f0000, 0x00000018, 0x8000011d,
+	0x00000000, 0x2c1e0000, 0x00000008, 0x2c8000b8, 0x00000008, 0x2d000010,
+	0x00000008, 0x2d800048, 0x00000000, 0x00000000, 0x00000010, 0x91de0000,
+	0x00000018, 0x8000fe5d, 0x0000000c, 0x29800001, 0x00000000, 0x2a000000,
+	0x00000010, 0x001f0000, 0x00000000, 0x0f008000, 0x00000008, 0x0f800007,
+	0x00000018, 0x80000006, 0x0000000c, 0x29800001, 0x00000000, 0x2a000000,
+	0x00000010, 0x001f0000, 0x0000000f, 0x0f470007, 0x00000008, 0x0f800008,
+	0x00000018, 0x80000119, 0x00000010, 0x20530000, 0x00000018, 0x8000fe4f,
+	0x0000000c, 0x29800001, 0x00000010, 0x91de0000, 0x00000000, 0x2fd50000,
+	0x00000000, 0x2a000000, 0x00000009, 0x0261ffff, 0x0000000d, 0x70e10001,
+	0x00000018, 0x80000101, 0x00000000, 0x2c400000, 0x00000008, 0x2c8000c4,
+	0x00000008, 0x2d00001c, 0x00000008, 0x2d800001, 0x00000005, 0x70e10800,
+	0x00000010, 0x91de0000, 0x00000018, 0x8000fe41, 0x0000000c, 0x29800001,
+	0x00000010, 0x91de0000, 0x00000000, 0x2fd50000, 0x00000010, 0x001f0000,
+	0x00000000, 0x02700000, 0x00000000, 0x0d620000, 0x00000000, 0xbb630800,
+	0x00000000, 0x2a000000, 0x00000000, 0x0f400000, 0x00000000, 0x2c400000,
+	0x0000000c, 0x73e7001b, 0x00000010, 0x0ce7000e, 0x00000000, 0x286d0000,
+	0x0000000f, 0x65ed0010, 0x00000009, 0x266dffff, 0x00000018, 0x80000069,
+	0x00000008, 0x02000004, 0x00000010, 0x91c40803, 0x00000018, 0x800000f6,
+	0x00000010, 0x20530000, 0x00000018, 0x800000e5, 0x00000008, 0x2c8000b8,
+	0x00000008, 0x2d000010, 0x00000008, 0x2d800048, 0x00000018, 0x80000005,
+	0x00000008, 0x2c8000c4, 0x00000008, 0x2d00001c, 0x00000008, 0x2d800001,
+	0x00000000, 0x00000000, 0x00000010, 0x205f0000, 0x00000008, 0x2c800048,
+	0x00000008, 0x2d000068, 0x00000008, 0x2d800104, 0x00000000, 0x00000000,
+	0x00000010, 0x91de0000, 0x00000000, 0x27f60000, 0x00000010, 0xb87a9e04,
+	0x00000008, 0x2200000d, 0x00000018, 0x800000e2, 0x00000010, 0x20530000,
+	0x00000018, 0x8000fe18, 0x0000000c, 0x29800001, 0x00000010, 0x91de0000,
+	0x00000000, 0x2fd50000, 0x00000010, 0x001f0000, 0x00000000, 0x02700000,
+	0x00000000, 0x0d620000, 0x00000000, 0xbb630800, 0x00000000, 0x2a000000,
+	0x00000010, 0x0e670011, 0x00000000, 0x286d0000, 0x0000000f, 0x65ed0010,
+	0x00000009, 0x266dffff, 0x00000004, 0xb8f1a000, 0x00000000, 0x0f400000,
+	0x0000000c, 0x73e7001c, 0x00000018, 0x80000040, 0x00000008, 0x02000004,
+	0x00000010, 0x91c40802, 0x00000018, 0x800000cd, 0x00000000, 0x2c1e0000,
+	0x00000008, 0x2c8000b8, 0x00000008, 0x2d000010, 0x00000008, 0x2d800048,
+	0x00000010, 0x20530000, 0x00000010, 0x91de0000, 0x00000018, 0x8000fdfe,
+	0x0000000c, 0x29800001, 0x00000000, 0x03550000, 0x00000000, 0x06460000,
+	0x00000000, 0x03d60000, 0x00000000, 0x2a000000, 0x0000000f, 0x0f480007,
+	0x00000010, 0xb18c0027, 0x0000000f, 0x47420008, 0x00000009, 0x070e000f,
+	0x00000008, 0x070e0008, 0x00000010, 0x001f0000, 0x00000008, 0x09000001,
+	0x00000007, 0x09121c00, 0x00000003, 0xcbca9200, 0x00000000, 0x0b97a200,
+	0x00000007, 0x4b171c00, 0x0000000f, 0x0a960003, 0x00000000, 0x0a959c00,
+	0x00000000, 0x4a009a00, 0x00000008, 0x82120001, 0x00000001, 0x0c170800,
+	0x00000000, 0x02180000, 0x00000000, 0x0c971800, 0x00000008, 0x0d00ffff,
+	0x00000008, 0x0f800006, 0x0000000c, 0x29000000, 0x00000008, 0x22000001,
+	0x00000000, 0x22c50c00, 0x00000010, 0x009f0000, 0x00000010, 0xb197320b,
+	0x00000000, 0x231b0000, 0x00000000, 0x27110800, 0x00000000, 0x66900000,
+	0x00000018, 0x800000a4, 0x00000000, 0x02180000, 0x00000010, 0x20530000,
+	0x00000000, 0x22c53600, 0x00000010, 0x001f0000, 0x00000008, 0x0f800006,
+	0x00000018, 0x8000fff5, 0x00000010, 0x91870002, 0x00000008, 0x2200000a,
+	0x00000000, 0x231b0000, 0x00000000, 0x27110800, 0x00000000, 0x66900000,
+	0x00000018, 0x80000098, 0x00000008, 0x0200000a, 0x00000010, 0x91c40804,
+	0x00000010, 0x02c20003, 0x00000010, 0x001f0000, 0x00000008, 0x0f800008,
+	0x00000010, 0x20530000, 0x00000018, 0x8000fdc9, 0x00000000, 0x06820000,
+	0x00000010, 0x001f0000, 0x00000010, 0x0ce70028, 0x00000000, 0x03720000,
+	0x00000000, 0xa8760c00, 0x00000000, 0x0cf60000, 0x00000010, 0xb8723224,
+	0x00000000, 0x03440000, 0x00000008, 0x22000010, 0x00000000, 0x03ca0000,
+	0x0000000f, 0x65680010, 0x00000000, 0x0bcf0000, 0x00000000, 0x27f20000,
+	0x00000010, 0xb7ef3203, 0x0000000c, 0x21420004, 0x0000000c, 0x73e70019,
+	0x00000000, 0x07520000, 0x00000000, 0x29000000, 0x00000018, 0x8000007e,
+	0x00000004, 0xb9723200, 0x00000010, 0x20530000, 0x00000000, 0x22060000,
+	0x0000000c, 0x61420004, 0x00000000, 0x25070000, 0x00000000, 0x27970000,
+	0x00000000, 0x290e0000, 0x00000010, 0x0ce70010, 0x00000010, 0xb873320f,
+	0x0000000f, 0x436c0010, 0x00000000, 0x03f30c00, 0x00000000, 0x03f30000,
+	0x00000000, 0x83990e00, 0x00000001, 0x83860e00, 0x00000000, 0x83060e00,
+	0x00000003, 0xf66c0c00, 0x00000000, 0x39f30e00, 0x00000000, 0x3af50e00,
+	0x00000000, 0x7a740000, 0x0000000f, 0x43680010, 0x00000001, 0x83860e00,
+	0x00000000, 0x83060e00, 0x00000003, 0xf4680c00, 0x00000000, 0x286d0000,
+	0x00000000, 0x03690000, 0x00000010, 0xb1f60c54, 0x00000000, 0x0a6a0000,
+	0x00000000, 0x0aeb0000, 0x00000009, 0x0b6cffff, 0x00000000, 0x0c000000,
+	0x00000000, 0x0be90000, 0x00000003, 0x8cf6a000, 0x0000000c, 0x09800002,
+	0x00000010, 0x009f0000, 0x00000010, 0xb8173209, 0x00000000, 0x35140000,
+	0x00000000, 0x35950000, 0x00000005, 0x766c2c00, 0x00000000, 0x34970000,
+	0x00000004, 0xb8f12e00, 0x00000010, 0x001f0000, 0x00000008, 0x0f800004,
+	0x00000018, 0x8000fff7, 0x00000000, 0x03e90000, 0x00000010, 0xb8f6a01a,
+	0x00000010, 0x20130019, 0x00000010, 0xb1f10e18, 0x00000000, 0x83973200,
+	0x00000000, 0x38700e00, 0x00000000, 0xbb760e00, 0x00000000, 0x37d00000,
+	0x0000000c, 0x73e7001a, 0x00000003, 0xb8f1a000, 0x00000000, 0x32140000,
+	0x00000000, 0x32950000, 0x00000005, 0x73e72c00, 0x00000000, 0x33190000,
+	0x00000005, 0x74680000, 0x00000010, 0x0ce7000d, 0x00000008, 0x22000009,
+	0x00000000, 0x07520000, 0x00000000, 0x29000000, 0x0000000c, 0x73e70019,
+	0x0000000f, 0x65680010, 0x0000000c, 0x21420004, 0x00000018, 0x8000003c,
+	0x00000010, 0x20530000, 0x0000000c, 0x61420004, 0x00000000, 0x290e0000,
+	0x00000018, 0x80000002, 0x00000010, 0x91973206, 0x00000000, 0x35140000,
+	0x00000000, 0x35950000, 0x00000005, 0x766c2c00, 0x00000000, 0x34990000,
+	0x00000004, 0xb8f13200, 0x00000000, 0x83690c00, 0x00000010, 0xb1860013,
+	0x00000000, 0x28e90000, 0x00000008, 0x22000004, 0x00000000, 0x23ec0000,
+	0x00000000, 0x03690000, 0x00000010, 0xb8660c07, 0x00000009, 0x036cffff,
+	0x00000000, 0x326a0000, 0x00000000, 0x32eb0000, 0x00000005, 0x73e70c00,
+	0x00000000, 0x33690000, 0x00000005, 0x74680000, 0x0000000c, 0x73e7001c,
+	0x00000000, 0x03690000, 0x00000010, 0xb1f60c12, 0x00000010, 0xb1d00c11,
+	0x0000000c, 0x21420005, 0x0000000c, 0x33e7001c, 0x00000018, 0x8000000e,
+	0x00000010, 0x2e67000d, 0x00000000, 0x03690000, 0x00000010, 0xb1f60c0b,
+	0x00000010, 0xb1d00c0a, 0x00000000, 0x03440000, 0x00000008, 0x2200000c,
+	0x00000000, 0x07520000, 0x00000000, 0x29000000, 0x00000018, 0x80000015,
+	0x0000000c, 0x33e7001c, 0x00000010, 0x20530000, 0x00000000, 0x22060000,
+	0x00000000, 0x290e0000, 0x00000018, 0x000d0000, 0x00000000, 0x06820000,
+	0x00000010, 0x2de7000d, 0x00000010, 0x0ce7000c, 0x00000000, 0x27f20000,
+	0x00000010, 0xb96d9e0a, 0x00000000, 0xa86d9e00, 0x00000009, 0x0361ffff,
+	0x00000010, 0xb7500c07, 0x00000008, 0x2200000f, 0x0000000f, 0x65680010,
+	0x00000000, 0x29000000, 0x00000018, 0x80000004, 0x0000000c, 0x33e7001b,
+	0x00000010, 0x20530000, 0x00000018, 0x000d0000, 0x00000000, 0x2b820000,
+	0x00000010, 0x20d2002f, 0x00000010, 0x0052002e, 0x00000009, 0x054e0007,
+	0x00000010, 0xb18a002c, 0x00000000, 0x050a8c00, 0x00000008, 0x850a0008,
+	0x00000010, 0x918a0029, 0x00000003, 0xc5008800, 0x00000008, 0xa3460001,
+	0x00000010, 0xb1c60007, 0x00000008, 0x22000001, 0x0000000c, 0x29800000,
+	0x00000010, 0x20530000, 0x00000000, 0x274e8c00, 0x00000000, 0x66cd0000,
+	0x00000000, 0x22c58c00, 0x00000008, 0x22000014, 0x00000003, 0x22c58e00,
+	0x00000003, 0x23c58e00, 0x00000003, 0x22c58e00, 0x00000003, 0x26cd9e00,
+	0x00000003, 0x27cd9e00, 0x00000003, 0x26cd9e00, 0x00000003, 0x274ea000,
+	0x00000003, 0x284ea000, 0x00000003, 0x274ea000, 0x0000000c, 0x69520000,
+	0x0000000c, 0x29800000, 0x00000010, 0x20530000, 0x00000003, 0x22c58e00,
+	0x00000003, 0x23c58e00, 0x00000003, 0x22c58e00, 0x00000003, 0x26cd9e00,
+	0x00000003, 0x27cd9e00, 0x00000003, 0x26cd9e00, 0x00000003, 0x274ea000,
+	0x00000003, 0x284ea000, 0x00000003, 0x274ea000, 0x00000000, 0xa2c58c00,
+	0x00000000, 0xa74e8c00, 0x00000000, 0xe6cd0000, 0x0000000f, 0x620a0010,
+	0x00000008, 0x23460001, 0x0000000c, 0x29800000, 0x00000010, 0x20530000,
+	0x0000000c, 0x29520000, 0x00000018, 0x80000002, 0x0000000c, 0x29800000,
+	0x00000018, 0x00570000 };
+
+static const int bnx2_TPAT_b06FwReleaseMajor = 0x1;
+static const int bnx2_TPAT_b06FwReleaseMinor = 0x0;
+static const int bnx2_TPAT_b06FwReleaseFix = 0x0;
+static const u32 bnx2_TPAT_b06FwStartAddr = 0x08000860;
+static const u32 bnx2_TPAT_b06FwTextAddr = 0x08000800;
+static const int bnx2_TPAT_b06FwTextLen = 0x122c;
+static const u32 bnx2_TPAT_b06FwDataAddr = 0x08001a60;
+static const int bnx2_TPAT_b06FwDataLen = 0x0;
+static const u32 bnx2_TPAT_b06FwRodataAddr = 0x00000000;
+static const int bnx2_TPAT_b06FwRodataLen = 0x0;
+static const u32 bnx2_TPAT_b06FwBssAddr = 0x08001aa0;
+static const int bnx2_TPAT_b06FwBssLen = 0x250;
+static const u32 bnx2_TPAT_b06FwSbssAddr = 0x08001a60;
+static const int bnx2_TPAT_b06FwSbssLen = 0x34;
+static u32 bnx2_TPAT_b06FwText[(0x122c/4) + 1] = {
+	0x0a000218, 0x00000000, 0x00000000, 0x0000000d, 0x74706174, 0x20322e35,
+	0x2e313100, 0x02050b01, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x10000003, 0x00000000, 0x0000000d, 0x0000000d, 0x3c020800,
+	0x24421a60, 0x3c030800, 0x24631cf0, 0xac400000, 0x0043202b, 0x1480fffd,
+	0x24420004, 0x3c1d0800, 0x37bd2ffc, 0x03a0f021, 0x3c100800, 0x26100860,
+	0x3c1c0800, 0x279c1a60, 0x0e000546, 0x00000000, 0x0000000d, 0x8f820010,
+	0x8c450008, 0x24030800, 0xaf430178, 0x97430104, 0x3c020008, 0xaf420140,
+	0x8f820024, 0x30420001, 0x10400007, 0x3069ffff, 0x24020002, 0x2523fffe,
+	0xa7420146, 0xa7430148, 0x0a000242, 0x3c020800, 0xa7400146, 0x3c020800,
+	0x8c43083c, 0x1460000e, 0x24020f00, 0x8f820024, 0x30430020, 0x0003182b,
+	0x00031823, 0x30650009, 0x30420c00, 0x24030400, 0x14430002, 0x34a40001,
+	0x34a40005, 0xa744014a, 0x0a000264, 0x3c020800, 0x8f830014, 0x14620008,
+	0x00000000, 0x8f820024, 0x30420020, 0x0002102b, 0x00021023, 0x3042000d,
+	0x0a000262, 0x34420005, 0x8f820024, 0x30420020, 0x0002102b, 0x00021023,
+	0x30420009, 0x34420001, 0xa742014a, 0x3c020800, 0x8c430820, 0x8f840024,
+	0x3c020048, 0x00621825, 0x30840006, 0x24020002, 0x1082000d, 0x2c820003,
+	0x50400005, 0x24020004, 0x10800012, 0x3c020001, 0x0a000284, 0x00000000,
+	0x10820007, 0x24020006, 0x1482000f, 0x3c020111, 0x0a00027c, 0x00621025,
+	0x0a00027b, 0x3c020101, 0x3c020011, 0x00621025, 0x24030001, 0xaf421000,
+	0xaf830020, 0x0a000284, 0x00000000, 0x00621025, 0xaf421000, 0xaf800020,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x8f830020, 0x1060003f,
+	0x3c048000, 0x8f421000, 0x00441024, 0x1040fffd, 0x00000000, 0x10600039,
+	0x00000000, 0x8f421000, 0x3c030020, 0x00431024, 0x10400034, 0x00000000,
+	0x97421014, 0x14400031, 0x00000000, 0x97421008, 0x8f840010, 0x24420006,
+	0x00024082, 0x00081880, 0x00643821, 0x8ce50000, 0x30430003, 0x30420001,
+	0x10400004, 0x00000000, 0x0000000d, 0x0a0002c3, 0x00081080, 0x5460000f,
+	0x30a5ffff, 0x3c06ffff, 0x00a62824, 0x0005182b, 0x00a61026, 0x0002102b,
+	0x00621824, 0x10600004, 0x00000000, 0x0000000d, 0x00000000, 0x240001fb,
+	0x8ce20000, 0x0a0002c2, 0x00462825, 0x0005182b, 0x38a2ffff, 0x0002102b,
+	0x00621824, 0x10600004, 0x00000000, 0x0000000d, 0x00000000, 0x24000205,
+	0x8ce20000, 0x3445ffff, 0x00081080, 0x00441021, 0x3c030800, 0xac450000,
+	0x8c620830, 0x24420001, 0xac620830, 0x8f840018, 0x01202821, 0x24820008,
+	0x30421fff, 0x24434000, 0x0343d821, 0x30a30007, 0xaf84000c, 0xaf820018,
+	0xaf420084, 0x10600002, 0x24a20007, 0x3045fff8, 0x8f820030, 0x8f840000,
+	0x00451821, 0xaf82001c, 0x0064102b, 0xaf830030, 0x14400002, 0x00641023,
+	0xaf820030, 0x8f840030, 0x34028000, 0x00821021, 0x03421821, 0x3c021000,
+	0xaf830010, 0xaf440080, 0x03e00008, 0xaf420178, 0x8f830024, 0x27bdffe0,
+	0xafbf0018, 0xafb10014, 0x30620200, 0x14400004, 0xafb00010, 0x0000000d,
+	0x00000000, 0x24000242, 0x00031a82, 0x30630003, 0x000310c0, 0x00431021,
+	0x00021080, 0x00431021, 0x00021080, 0x3c030800, 0x24631aa0, 0x00438821,
+	0x8e240000, 0x10800004, 0x00000000, 0x0000000d, 0x00000000, 0x2400024d,
+	0x8f850010, 0x24020001, 0xae220000, 0x8ca70008, 0xa2200007, 0x8f620004,
+	0x26300014, 0x02002021, 0x00021402, 0xa2220004, 0x304600ff, 0x24c60005,
+	0x0e000673, 0x00063082, 0x8f620004, 0xa6220008, 0x8f430108, 0x3c021000,
+	0x00621824, 0x10600008, 0x00000000, 0x97420104, 0x92230007, 0x2442ffec,
+	0x3045ffff, 0x34630002, 0x0a000321, 0xa2230007, 0x97420104, 0x2442fff0,
+	0x3045ffff, 0x8f620004, 0x3042ffff, 0x2c420013, 0x54400005, 0x92230007,
+	0x92220007, 0x34420001, 0xa2220007, 0x92230007, 0x24020001, 0x10620009,
+	0x28620002, 0x14400014, 0x24020002, 0x10620012, 0x24020003, 0x1062000a,
+	0x00000000, 0x0a000342, 0x00000000, 0x8f820010, 0x8c43000c, 0x3c04ffff,
+	0x00641824, 0x00651825, 0x0a000342, 0xac43000c, 0x8f820010, 0x8c430010,
+	0x3c04ffff, 0x00641824, 0x00651825, 0xac430010, 0x8f620004, 0x3042ffff,
+	0x24420002, 0x00021083, 0xa2220005, 0x304500ff, 0x8f820010, 0x3c04ffff,
+	0x00052880, 0x00a22821, 0x8ca70000, 0x96220008, 0x97430104, 0x00e42024,
+	0x24420002, 0x00621823, 0x00833825, 0xaca70000, 0x92240005, 0x00041080,
+	0x02021021, 0x90430000, 0x3c05fff6, 0x34a5ffff, 0x3063000f, 0x00832021,
+	0xa2240006, 0x308200ff, 0x24420003, 0x00021080, 0x02021021, 0x8c460000,
+	0x308300ff, 0x8f820010, 0x3c04ff3f, 0x00031880, 0x00c53824, 0x00621821,
+	0xae26000c, 0xac67000c, 0x8e22000c, 0x92230006, 0x3484ffff, 0x00441024,
+	0x24630003, 0x00031880, 0x02031821, 0x00e42024, 0xae22000c, 0xac640000,
+	0x92220006, 0x24420004, 0x00021080, 0x02021021, 0x94470002, 0xac470000,
+	0x92230006, 0x8f820010, 0x00031880, 0x00621821, 0x24020010, 0xac670010,
+	0x24030002, 0xa7420140, 0xa7400142, 0xa7400144, 0xa7430146, 0x97420104,
+	0x24030001, 0x2442fffe, 0xa7420148, 0xa743014a, 0x8f820024, 0x24030002,
+	0x30440006, 0x1083000d, 0x2c820003, 0x10400005, 0x24020004, 0x10800011,
+	0x3c020009, 0x0a0003a5, 0x00000000, 0x10820007, 0x24020006, 0x1482000d,
+	0x3c020119, 0x0a00039f, 0x24030001, 0x0a00039e, 0x3c020109, 0x3c020019,
+	0x24030001, 0xaf421000, 0xaf830020, 0x0a0003a5, 0x00000000, 0xaf421000,
+	0xaf800020, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x92220004,
+	0x24030008, 0x8f840020, 0x24420002, 0x30420007, 0x00621823, 0x30630007,
+	0x10800006, 0xae230010, 0x3c038000, 0x8f421000, 0x00431024, 0x1040fffd,
+	0x00000000, 0x8f820018, 0xaf82000c, 0x24420010, 0x30421fff, 0xaf820018,
+	0xaf420084, 0x97430104, 0x24424000, 0x0342d821, 0x3063ffff, 0x30620007,
+	0x10400002, 0x24620007, 0x3043fff8, 0x8f820030, 0x8f840000, 0x00431821,
+	0xaf82001c, 0x0064102b, 0xaf830030, 0x14400002, 0x00641023, 0xaf820030,
+	0x8f840030, 0x34028000, 0x8fbf0018, 0x8fb10014, 0x8fb00010, 0x00821021,
+	0x03421821, 0x3c021000, 0xaf830010, 0xaf440080, 0xaf420178, 0x03e00008,
+	0x27bd0020, 0x8f830024, 0x27bdffe0, 0xafbf0018, 0xafb10014, 0x30620200,
+	0x14400004, 0xafb00010, 0x0000000d, 0x00000000, 0x240002e4, 0x00031a82,
+	0x30630003, 0x000310c0, 0x00431021, 0x00021080, 0x00431021, 0x00021080,
+	0x3c030800, 0x24631aa0, 0x00438021, 0x8e040000, 0x14800004, 0x00000000,
+	0x0000000d, 0x00000000, 0x240002e9, 0x8f620004, 0x04410008, 0x26050014,
+	0x92020006, 0x8e03000c, 0x24420003, 0x00021080, 0x00a21021, 0xac430000,
+	0xae000000, 0x92020005, 0x24420001, 0x00021080, 0x00a21021, 0x8c430000,
+	0x3c040001, 0x00641821, 0xac430000, 0x92060004, 0x27710008, 0x02202021,
+	0x24c60005, 0x0e000673, 0x00063082, 0x92040006, 0x3c057fff, 0x8f620004,
+	0x00042080, 0x00912021, 0x8c830004, 0x34a5ffff, 0x00451024, 0x00621821,
+	0xac830004, 0x92050005, 0x3c07ffff, 0x92040004, 0x00052880, 0x00b12821,
+	0x8ca30000, 0x97420104, 0x96060008, 0x00671824, 0x00441021, 0x00461023,
+	0x3042ffff, 0x00621825, 0xaca30000, 0x92030007, 0x24020001, 0x1062000a,
+	0x28620002, 0x1440001d, 0x2402000a, 0x24020002, 0x10620019, 0x24020003,
+	0x1062000e, 0x2402000a, 0x0a000447, 0x00000000, 0x92020004, 0x97430104,
+	0x8e24000c, 0x00621821, 0x2463fff2, 0x3063ffff, 0x00872024, 0x00832025,
+	0xae24000c, 0x0a000447, 0x2402000a, 0x92020004, 0x97430104, 0x8e240010,
+	0x00621821, 0x2463ffee, 0x3063ffff, 0x00872024, 0x00832025, 0xae240010,
+	0x2402000a, 0xa7420140, 0x96030012, 0x8f840024, 0xa7430142, 0x92020004,
+	0xa7420144, 0xa7400146, 0x97430104, 0x30840006, 0x24020001, 0xa7430148,
+	0xa742014a, 0x24020002, 0x1082000d, 0x2c820003, 0x10400005, 0x24020004,
+	0x10800011, 0x3c020041, 0x0a00046c, 0x00000000, 0x10820007, 0x24020006,
+	0x1482000d, 0x3c020151, 0x0a000466, 0x24030001, 0x0a000465, 0x3c020141,
+	0x3c020051, 0x24030001, 0xaf421000, 0xaf830020, 0x0a00046c, 0x00000000,
+	0xaf421000, 0xaf800020, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x8f820020, 0x8f840018, 0x10400006, 0x92030004, 0x3c058000, 0x8f421000,
+	0x00451024, 0x1040fffd, 0x00000000, 0x2463000a, 0x30620007, 0x10400002,
+	0x24620007, 0x304303f8, 0x00831021, 0x30421fff, 0xaf84000c, 0xaf820018,
+	0xaf420084, 0x97430104, 0x24424000, 0x0342d821, 0x3063ffff, 0x30620007,
+	0x10400002, 0x24620007, 0x3043fff8, 0x8f820030, 0x8f840000, 0x00431821,
+	0xaf82001c, 0x0064102b, 0xaf830030, 0x14400002, 0x00641023, 0xaf820030,
+	0x8f840030, 0x34028000, 0x8fbf0018, 0x8fb10014, 0x8fb00010, 0x00821021,
+	0x03421821, 0x3c021000, 0xaf830010, 0xaf440080, 0xaf420178, 0x03e00008,
+	0x27bd0020, 0x8f620000, 0x97430104, 0x3c048000, 0x3045ffff, 0x3066ffff,
+	0x8f420178, 0x00441024, 0x1440fffd, 0x2402000a, 0x30a30007, 0xa7420140,
+	0x24020008, 0x00431023, 0x30420007, 0x24a3fffe, 0xa7420142, 0xa7430144,
+	0xa7400146, 0xa7460148, 0x8f420108, 0x8f830024, 0x30420020, 0x0002102b,
+	0x00021023, 0x30420009, 0x34420001, 0x30630006, 0xa742014a, 0x24020002,
+	0x1062000d, 0x2c620003, 0x10400005, 0x24020004, 0x10600011, 0x3c020041,
+	0x0a0004d6, 0x00000000, 0x10620007, 0x24020006, 0x1462000d, 0x3c020151,
+	0x0a0004d0, 0x24030001, 0x0a0004cf, 0x3c020141, 0x3c020051, 0x24030001,
+	0xaf421000, 0xaf830020, 0x0a0004d6, 0x00000000, 0xaf421000, 0xaf800020,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x8f820020, 0x24a30008,
+	0x8f850018, 0x10400006, 0x30c6ffff, 0x3c048000, 0x8f421000, 0x00441024,
+	0x1040fffd, 0x00000000, 0x3063ffff, 0x30620007, 0x10400002, 0x24620007,
+	0x3043fff8, 0x00a31021, 0x30421fff, 0x24434000, 0x0343d821, 0x00c02021,
+	0x30830007, 0xaf85000c, 0xaf820018, 0xaf420084, 0x10600002, 0x24820007,
+	0x3044fff8, 0x8f820030, 0x8f850000, 0x00441821, 0xaf82001c, 0x0065102b,
+	0xaf830030, 0x14400002, 0x00651023, 0xaf820030, 0x8f840030, 0x34028000,
+	0x3c030800, 0x8c650834, 0x00821021, 0x03421821, 0xaf830010, 0xaf440080,
+	0x10a00006, 0x2402000e, 0x9383002f, 0x14620004, 0x3c021000, 0x2402043f,
+	0xa7420148, 0x3c021000, 0x03e00008, 0xaf420178, 0x8f820024, 0x30424000,
+	0x10400005, 0x24020800, 0x0000000d, 0x00000000, 0x2400040e, 0x24020800,
+	0xaf420178, 0x97440104, 0x3c030008, 0xaf430140, 0x8f820024, 0x30420001,
+	0x10400006, 0x3085ffff, 0x24020002, 0x24a3fffe, 0xa7420146, 0x0a000526,
+	0xa7430148, 0xa7400146, 0x8f840018, 0x2402000d, 0xa742014a, 0x24830008,
+	0x30631fff, 0x24624000, 0x0342d821, 0x30a20007, 0xaf84000c, 0xaf830018,
+	0xaf430084, 0x10400002, 0x24a20007, 0x3045fff8, 0x8f820030, 0x8f840000,
+	0x00451821, 0xaf82001c, 0x0064102b, 0xaf830030, 0x14400002, 0x00641023,
+	0xaf820030, 0x8f840030, 0x34028000, 0x00821021, 0x03421821, 0x3c021000,
+	0xaf830010, 0xaf440080, 0x03e00008, 0xaf420178, 0x27bdffe8, 0x3c046008,
+	0xafbf0014, 0xafb00010, 0x8c825000, 0x3c1a8000, 0x2403ff7f, 0x375b4000,
+	0x00431024, 0x3442380c, 0xac825000, 0x8f430008, 0x3c100800, 0x37428000,
+	0x34630001, 0xaf430008, 0xaf820010, 0x3c02601c, 0xaf800018, 0xaf400080,
+	0xaf400084, 0x8c450008, 0x3c036000, 0x8c620808, 0x3c040800, 0x3c030080,
+	0xac830820, 0x3042fff0, 0x38420010, 0x2c420001, 0xaf850000, 0xaf820004,
+	0x0e000658, 0x00000000, 0x8f420000, 0x30420001, 0x1040fffb, 0x00000000,
+	0x8f430108, 0x8f440100, 0x30622000, 0xaf830024, 0xaf840014, 0x10400004,
+	0x8e02082c, 0x24420001, 0x0a0005c6, 0xae02082c, 0x30620200, 0x14400003,
+	0x24020f00, 0x14820027, 0x24020d00, 0x97420104, 0x1040001c, 0x30624000,
+	0x14400005, 0x00000000, 0x0e00022f, 0x00000000, 0x0a0005bb, 0x00000000,
+	0x8f620008, 0x8f630000, 0x24020030, 0x00031e02, 0x306300f0, 0x10620007,
+	0x28620031, 0x1440002f, 0x24020040, 0x10620007, 0x00000000, 0x0a0005bb,
+	0x00000000, 0x0e0002e8, 0x00000000, 0x0a0005bb, 0x00000000, 0x0e0003db,
+	0x00000000, 0x0a0005bb, 0x00000000, 0x30620040, 0x1440002b, 0x00000000,
+	0x0000000d, 0x00000000, 0x240004b2, 0x0a0005c6, 0x00000000, 0x1482000f,
+	0x30620006, 0x97420104, 0x10400005, 0x30620040, 0x0e000510, 0x00000000,
+	0x0a0005bb, 0x00000000, 0x1440001b, 0x00000000, 0x0000000d, 0x00000000,
+	0x240004c4, 0x0a0005c6, 0x00000000, 0x1040000e, 0x30621000, 0x10400005,
+	0x00000000, 0x0e000688, 0x00000000, 0x0a0005bb, 0x00000000, 0x0e0004a1,
+	0x00000000, 0x8f82002c, 0x24420001, 0xaf82002c, 0x0a0005c6, 0x00000000,
+	0x30620040, 0x14400004, 0x00000000, 0x0000000d, 0x00000000, 0x240004db,
+	0x8f420138, 0x3c034000, 0x00431025, 0xaf420138, 0x0a000566, 0x00000000,
+	0x3c046008, 0x8c835000, 0x3c1a8000, 0x2402ff7f, 0x375b4000, 0x00621824,
+	0x3463380c, 0xac835000, 0x8f420008, 0x3c056000, 0x3c03601c, 0x34420001,
+	0xaf420008, 0x37428000, 0xaf800018, 0xaf820010, 0xaf400080, 0xaf400084,
+	0x8c660008, 0x8ca20808, 0x3c040800, 0x3c030080, 0xac830820, 0x3042fff0,
+	0x38420010, 0x2c420001, 0xaf860000, 0xaf820004, 0x03e00008, 0x00000000,
+	0x3084ffff, 0x30820007, 0x10400002, 0x24820007, 0x3044fff8, 0x8f820018,
+	0x00441821, 0x30631fff, 0x24644000, 0x0344d821, 0xaf82000c, 0xaf830018,
+	0x03e00008, 0xaf430084, 0x3084ffff, 0x30820007, 0x10400002, 0x24820007,
+	0x3044fff8, 0x8f820030, 0x8f830000, 0x00442021, 0xaf82001c, 0x0083102b,
+	0xaf840030, 0x14400002, 0x00831023, 0xaf820030, 0x8f820030, 0x34038000,
+	0x00431821, 0x03432021, 0xaf840010, 0x03e00008, 0xaf420080, 0x8f830024,
+	0x24020002, 0x30630006, 0x1062000d, 0x2c620003, 0x50400005, 0x24020004,
+	0x10600012, 0x3c020001, 0x0a00062a, 0x00000000, 0x10620007, 0x24020006,
+	0x1462000f, 0x3c020111, 0x0a000622, 0x00821025, 0x0a000621, 0x3c020101,
+	0x3c020011, 0x00821025, 0x24030001, 0xaf421000, 0xaf830020, 0x0a00062a,
+	0x00000000, 0x00821025, 0xaf421000, 0xaf800020, 0x00000000, 0x00000000,
+	0x00000000, 0x03e00008, 0x00000000, 0x8f820020, 0x10400005, 0x3c038000,
+	0x8f421000, 0x00431024, 0x1040fffd, 0x00000000, 0x03e00008, 0x00000000,
+	0x8f820024, 0x27bdffe8, 0x30424000, 0x14400005, 0xafbf0010, 0x0e00022f,
+	0x00000000, 0x0a000656, 0x8fbf0010, 0x8f620008, 0x8f630000, 0x24020030,
+	0x00031e02, 0x306300f0, 0x10620008, 0x28620031, 0x1440000d, 0x8fbf0010,
+	0x24020040, 0x10620007, 0x00000000, 0x0a000656, 0x00000000, 0x0e0002e8,
+	0x00000000, 0x0a000656, 0x8fbf0010, 0x0e0003db, 0x00000000, 0x8fbf0010,
+	0x03e00008, 0x27bd0018, 0x8f840028, 0x1080000f, 0x3c026000, 0x8c430c3c,
+	0x30630fff, 0xaf830008, 0x14600011, 0x3082000f, 0x10400005, 0x308200f0,
+	0x10400003, 0x30820f00, 0x14400006, 0x00000000, 0x0000000d, 0x00000000,
+	0x2400051a, 0x03e00008, 0x00000000, 0x0000000d, 0x00000000, 0x2400051f,
+	0x03e00008, 0x00000000, 0xaf830028, 0x03e00008, 0x00000000, 0x10c00007,
+	0x00000000, 0x8ca20000, 0x24c6ffff, 0x24a50004, 0xac820000, 0x14c0fffb,
+	0x24840004, 0x03e00008, 0x00000000, 0x0a000684, 0x00a01021, 0xac860000,
+	0x00000000, 0x00000000, 0x24840004, 0x00a01021, 0x1440fffa, 0x24a5ffff,
+	0x03e00008, 0x00000000, 0x0000000d, 0x03e00008, 0x00000000, 0x00000000};
+
+static u32 bnx2_TPAT_b06FwData[(0x0/4) + 1] = { 0x0 };
+static u32 bnx2_TPAT_b06FwRodata[(0x0/4) + 1] = { 0x0 };
+static u32 bnx2_TPAT_b06FwBss[(0x250/4) + 1] = { 0x0 };
+static u32 bnx2_TPAT_b06FwSbss[(0x34/4) + 1] = { 0x0 };
+
+static const int bnx2_TXP_b06FwReleaseMajor = 0x1;
+static const int bnx2_TXP_b06FwReleaseMinor = 0x0;
+static const int bnx2_TXP_b06FwReleaseFix = 0x0;
+static const u32 bnx2_TXP_b06FwStartAddr = 0x080034b0;
+static const u32 bnx2_TXP_b06FwTextAddr = 0x08000000;
+static const int bnx2_TXP_b06FwTextLen = 0x5748;
+static const u32 bnx2_TXP_b06FwDataAddr = 0x08005760;
+static const int bnx2_TXP_b06FwDataLen = 0x0;
+static const u32 bnx2_TXP_b06FwRodataAddr = 0x00000000;
+static const int bnx2_TXP_b06FwRodataLen = 0x0;
+static const u32 bnx2_TXP_b06FwBssAddr = 0x080057a0;
+static const int bnx2_TXP_b06FwBssLen = 0x1c4;
+static const u32 bnx2_TXP_b06FwSbssAddr = 0x08005760;
+static const int bnx2_TXP_b06FwSbssLen = 0x38;
+static u32 bnx2_TXP_b06FwText[(0x5748/4) + 1] = {
+	0x0a000d2c, 0x00000000, 0x00000000, 0x0000000d, 0x74787020, 0x322e352e,
+	0x38000000, 0x02050800, 0x0000000a, 0x000003e8, 0x0000ea60, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x10000003, 0x00000000, 0x0000000d, 0x0000000d, 0x3c020800,
+	0x24425760, 0x3c030800, 0x24635964, 0xac400000, 0x0043202b, 0x1480fffd,
+	0x24420004, 0x3c1d0800, 0x37bd7ffc, 0x03a0f021, 0x3c100800, 0x261034b0,
+	0x3c1c0800, 0x279c5760, 0x0e000f5b, 0x00000000, 0x0000000d, 0x8f840014,
+	0x27bdffe8, 0xafb10014, 0xafb00010, 0x8f460104, 0x8f830008, 0x8c8500ac,
+	0xaf430080, 0x948200a8, 0xa7420e10, 0x948300aa, 0xa7430e12, 0x8c8200ac,
+	0xaf420e18, 0x97430e10, 0xa7430e14, 0x97420e12, 0x00008021, 0xa7420e16,
+	0x8f430e18, 0x00006021, 0x00c53023, 0xaf430e1c, 0x10c001a2, 0x2d820001,
+	0x3c0e1000, 0x2419fff8, 0x24110010, 0x240f0f00, 0x3c188100, 0x93620008,
+	0x10400009, 0x00000000, 0x97620010, 0x00c2102b, 0x14400005, 0x00000000,
+	0x97620010, 0x3042ffff, 0x0a000d6d, 0xaf420e00, 0xaf460e00, 0x8f420000,
+	0x30420008, 0x1040fffd, 0x00000000, 0x97420e08, 0x8f450e04, 0x3044ffff,
+	0x30820001, 0x14400005, 0x00000000, 0x14a00005, 0x3083a040, 0x0a000f34,
+	0x00000000, 0x0000000d, 0x3083a040, 0x24020040, 0x1462004f, 0x3082a000,
+	0x308a0036, 0x8f88000c, 0x30890008, 0x24020800, 0xaf420178, 0x01001821,
+	0x9742008a, 0x00431023, 0x2442ffff, 0x30421fff, 0x2c420008, 0x1440fffa,
+	0x00a06021, 0x8f820018, 0x00cc3023, 0x24070001, 0x8f830008, 0x304b00ff,
+	0x24420001, 0xaf820018, 0x25024000, 0x106f0005, 0x03422021, 0x93820012,
+	0x30420007, 0x00021240, 0x34470001, 0x000b1400, 0x3c030100, 0x00431025,
+	0xac820000, 0x8f830018, 0x00ea3825, 0x1120000f, 0xac830004, 0x97430e0a,
+	0x8f84000c, 0x00ee3825, 0x2402000e, 0x00781825, 0xaf430160, 0x25830006,
+	0x24840008, 0x30841fff, 0xa742015a, 0xa7430158, 0xaf84000c, 0x0a000db7,
+	0x00000000, 0x8f83000c, 0x25820002, 0xa7420158, 0x24630008, 0x30631fff,
+	0xaf83000c, 0x54c0000f, 0x8f420e14, 0x8f820008, 0x504f0002, 0x24100001,
+	0x34e70040, 0x97420e10, 0x97430e12, 0x8f850014, 0x00021400, 0x00621825,
+	0xaca300a8, 0x8f840014, 0x8f420e18, 0xac8200ac, 0x8f420e14, 0x8f430e1c,
+	0xaf420144, 0xaf430148, 0xa34b0152, 0xaf470154, 0x0a000efb, 0xaf4e0178,
+	0x10400165, 0x00000000, 0x93620008, 0x50400008, 0xafa60008, 0x97620010,
+	0x00a2102b, 0x10400003, 0x30820040, 0x1040015c, 0x00000000, 0xafa60008,
+	0xa7840010, 0xaf850004, 0x93620008, 0x1440005f, 0x27ac0008, 0xaf60000c,
+	0x97820010, 0x30424000, 0x10400002, 0x2403000e, 0x24030016, 0xa363000a,
+	0x24034007, 0xaf630014, 0x93820012, 0x8f630014, 0x30420007, 0x00021240,
+	0x00621825, 0xaf630014, 0x97820010, 0x8f630014, 0x30420010, 0x00621825,
+	0xaf630014, 0x97820010, 0x30420008, 0x5040000e, 0x00002821, 0x8f620014,
+	0x004e1025, 0xaf620014, 0x97430e0a, 0x2402000e, 0x00781825, 0xaf630004,
+	0xa3620002, 0x9363000a, 0x3405fffc, 0x24630004, 0x0a000e06, 0xa363000a,
+	0xaf600004, 0xa3600002, 0x97820010, 0x9363000a, 0x30421f00, 0x00021182,
+	0x24420028, 0x00621821, 0xa3630009, 0x97420e0c, 0xa7620010, 0x93630009,
+	0x24020008, 0x24630002, 0x30630007, 0x00431023, 0x30420007, 0xa362000b,
+	0x93640009, 0x97620010, 0x8f890004, 0x97830010, 0x00441021, 0x00a21021,
+	0x30630040, 0x10600007, 0x3045ffff, 0x00a9102b, 0x14400005, 0x0125102b,
+	0x3c068000, 0x0a000e3a, 0x00005821, 0x0125102b, 0x544000c7, 0x00006021,
+	0x97420e14, 0xa7420e10, 0x97430e16, 0xa7430e12, 0x8f420e1c, 0xaf420e18,
+	0xaf450e00, 0x8f420000, 0x30420008, 0x1040fffd, 0x00000000, 0x97420e08,
+	0x00a04821, 0xa7820010, 0x8f430e04, 0x00003021, 0x240b0001, 0xaf830004,
+	0x97620010, 0x0a000e4c, 0x304dffff, 0x8f890004, 0x97820010, 0x30420040,
+	0x10400004, 0x01206821, 0x3c068000, 0x0a000e4c, 0x00005821, 0x97630010,
+	0x8f820004, 0x10430003, 0x00003021, 0x0a000eee, 0x00006021, 0x240b0001,
+	0x8d820000, 0x00491023, 0x1440000d, 0xad820000, 0x8f620014, 0x34420040,
+	0xaf620014, 0x97430e10, 0x97420e12, 0x8f840014, 0x00031c00, 0x00431025,
+	0xac8200a8, 0x8f830014, 0x8f420e18, 0xac6200ac, 0x93620008, 0x1440003e,
+	0x00000000, 0x25260002, 0x8f84000c, 0x9743008a, 0x3063ffff, 0xafa30000,
+	0x8fa20000, 0x00441023, 0x2442ffff, 0x30421fff, 0x2c420010, 0x1440fff7,
+	0x00000000, 0x8f82000c, 0x8f830018, 0x00021082, 0x00021080, 0x24424000,
+	0x03422821, 0x00605021, 0x24630001, 0x314200ff, 0x00021400, 0xaf830018,
+	0x3c033200, 0x00431025, 0xaca20000, 0x93630009, 0x9362000a, 0x00031c00,
+	0x00431025, 0xaca20004, 0x8f830018, 0xaca30008, 0x97820010, 0x30420008,
+	0x10400002, 0x00c04021, 0x25280006, 0x97430e14, 0x93640002, 0x8f450e1c,
+	0x8f660004, 0x8f670014, 0x3063ffff, 0xa7430144, 0x97420e16, 0xa7420146,
+	0xaf450148, 0xa34a0152, 0x8f82000c, 0x308400ff, 0xa744015a, 0xaf460160,
+	0xa7480158, 0xaf470154, 0xaf4e0178, 0x00511021, 0x30421fff, 0xaf82000c,
+	0x0a000ed9, 0x8d820000, 0x93620009, 0x9363000b, 0x8f85000c, 0x2463000a,
+	0x00435021, 0x25440007, 0x00992024, 0x9743008a, 0x3063ffff, 0xafa30000,
+	0x8fa20000, 0x00451023, 0x2442ffff, 0x30421fff, 0x0044102b, 0x1440fff7,
+	0x00000000, 0x8f82000c, 0x8f840018, 0x00021082, 0x00021080, 0x24424000,
+	0x03422821, 0x00804021, 0x24840001, 0xaf840018, 0x93630009, 0x310200ff,
+	0x00022400, 0x3c024100, 0x24630002, 0x00621825, 0x00832025, 0xaca40000,
+	0x8f62000c, 0x00461025, 0xaca20004, 0x97430e14, 0x93640002, 0x8f450e1c,
+	0x8f660004, 0x8f670014, 0x3063ffff, 0xa7430144, 0x97420e16, 0x308400ff,
+	0xa7420146, 0xaf450148, 0xa3480152, 0x8f83000c, 0x25420007, 0x00591024,
+	0xa744015a, 0xaf460160, 0xa7490158, 0xaf470154, 0xaf4e0178, 0x00621821,
+	0x30631fff, 0xaf83000c, 0x8d820000, 0x14400005, 0x00000000, 0x8f620014,
+	0x2403ffbf, 0x00431024, 0xaf620014, 0x8f62000c, 0x004d1021, 0xaf62000c,
+	0x93630008, 0x14600008, 0x00000000, 0x11600006, 0x00000000, 0x8f630014,
+	0x3c02efff, 0x3442fffe, 0x00621824, 0xaf630014, 0xa36b0008, 0x01206021,
+	0x1580000c, 0x8fa60008, 0x97420e14, 0x97430e16, 0x8f850014, 0x00021400,
+	0x00621825, 0xaca300a8, 0x8f840014, 0x8f420e1c, 0xac8200ac, 0x0a000efd,
+	0x2d820001, 0x14c0fe65, 0x2d820001, 0x00501025, 0x10400058, 0x24020f00,
+	0x8f830008, 0x14620023, 0x3c048000, 0x11800009, 0x3c038000, 0x97420e08,
+	0x30420040, 0x14400005, 0x00000000, 0x0000000d, 0x00000000, 0x2400032c,
+	0x3c038000, 0x8f420178, 0x00431024, 0x1440fffd, 0x00000000, 0x97420e10,
+	0x3c030500, 0x00431025, 0xaf42014c, 0x97430e14, 0xa7430144, 0x97420e16,
+	0xa7420146, 0x8f430e1c, 0x24022000, 0xaf430148, 0x3c031000, 0xa3400152,
+	0xa740015a, 0xaf400160, 0xa7400158, 0xaf420154, 0xaf430178, 0x8f830008,
+	0x3c048000, 0x8f420178, 0x00441024, 0x1440fffd, 0x24020f00, 0x10620016,
+	0x00000000, 0x97420e14, 0xa7420144, 0x97430e16, 0xa7430146, 0x8f420e1c,
+	0x3c031000, 0xaf420148, 0x0a000f51, 0x24020240, 0x97420e14, 0x97430e16,
+	0x8f840014, 0x00021400, 0x00621825, 0xac8300a8, 0x8f850014, 0x8f420e1c,
+	0x00006021, 0xaca200ac, 0x0a000efd, 0x2d820001, 0xaf40014c, 0x11800007,
+	0x00000000, 0x97420e10, 0xa7420144, 0x97430e12, 0xa7430146, 0x0a000f4e,
+	0x8f420e18, 0x97420e14, 0xa7420144, 0x97430e16, 0xa7430146, 0x8f420e1c,
+	0xaf420148, 0x24020040, 0x3c031000, 0xa3400152, 0xa740015a, 0xaf400160,
+	0xa7400158, 0xaf420154, 0xaf430178, 0x8fb10014, 0x8fb00010, 0x03e00008,
+	0x27bd0018, 0x27bdffd0, 0x3c1a8000, 0x3c0420ff, 0x3484fffd, 0x3c020008,
+	0x03421821, 0xafbf002c, 0xafb60028, 0xafb50024, 0xafb40020, 0xafb3001c,
+	0xafb20018, 0xafb10014, 0xafb00010, 0xaf830014, 0xaf440e00, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x3c0200ff, 0x3442fffd,
+	0x3c046004, 0xaf420e00, 0x8c835000, 0x24160800, 0x24150d00, 0x3c140800,
+	0x24130f00, 0x3c120800, 0x3c114000, 0x2402ff7f, 0x00621824, 0x3463380c,
+	0x24020009, 0xac835000, 0xaf420008, 0xaf800018, 0xaf80000c, 0x0e001559,
+	0x00000000, 0x0e000ff0, 0x00000000, 0x3c020800, 0x245057c0, 0x8f420000,
+	0x30420001, 0x1040fffd, 0x00000000, 0x8f440100, 0xaf840008, 0xaf440020,
+	0xaf560178, 0x93430108, 0xa3830012, 0x93820012, 0x30420001, 0x10400008,
+	0x00000000, 0x93820012, 0x30420006, 0x00021100, 0x0e000d43, 0x0050d821,
+	0x0a000fac, 0x00000000, 0x14950005, 0x00000000, 0x0e000d43, 0x269b5840,
+	0x0a000fac, 0x00000000, 0x14930005, 0x00000000, 0x0e000d43, 0x265b5860,
+	0x0a000fac, 0x00000000, 0x0e0010ea, 0x00000000, 0xaf510138, 0x0a000f89,
+	0x00000000, 0x27bdfff8, 0x3084ffff, 0x24820007, 0x3044fff8, 0x8f85000c,
+	0x9743008a, 0x3063ffff, 0xafa30000, 0x8fa20000, 0x00451023, 0x2442ffff,
+	0x30421fff, 0x0044102b, 0x1440fff7, 0x00000000, 0x8f82000c, 0x00021082,
+	0x00021080, 0x24424000, 0x03421021, 0x03e00008, 0x27bd0008, 0x3084ffff,
+	0x8f82000c, 0x24840007, 0x3084fff8, 0x00441021, 0x30421fff, 0xaf82000c,
+	0x03e00008, 0x00000000, 0x27bdffe8, 0x3c1a8000, 0x3c0420ff, 0x3484fffd,
+	0x3c020008, 0x03421821, 0xafbf0010, 0xaf830014, 0xaf440e00, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x3c0200ff, 0x3442fffd,
+	0x3c046004, 0xaf420e00, 0x8c825000, 0x2403ff7f, 0x00431024, 0x3442380c,
+	0x24030009, 0xac825000, 0xaf430008, 0xaf800018, 0xaf80000c, 0x0e001559,
+	0x00000000, 0x0e000ff0, 0x00000000, 0x8fbf0010, 0x03e00008, 0x27bd0018,
+	0x27bdffe8, 0x3c02000a, 0x03421821, 0x3c040800, 0x24845880, 0x24050019,
+	0xafbf0010, 0xaf830024, 0x0e001565, 0x00003021, 0x3c050800, 0x3c020800,
+	0x24425330, 0xaca258e8, 0x24a558e8, 0x3c020800, 0x244254f8, 0x3c030800,
+	0x2463550c, 0x3c040800, 0xaca20004, 0x3c020800, 0x24425338, 0xaca30008,
+	0xac825900, 0x24845900, 0x3c020800, 0x244253c4, 0x3c070800, 0x24e75404,
+	0x3c060800, 0x24c65520, 0x3c050800, 0x24a55438, 0x3c030800, 0xac820004,
+	0x3c020800, 0x24425528, 0xac870008, 0xac86000c, 0xac850010, 0xac625920,
+	0x24635920, 0x8fbf0010, 0x3c020800, 0x24425540, 0xac620004, 0x3c020800,
+	0xac670008, 0xac66000c, 0xac650010, 0xac400048, 0x03e00008, 0x27bd0018,
+	0x974309da, 0x00804021, 0xad030000, 0x8f4209dc, 0xad020004, 0x8f4309e0,
+	0xad030008, 0x934409d9, 0x24020001, 0x30840003, 0x1082001f, 0x30a900ff,
+	0x28820002, 0x10400005, 0x24020002, 0x10800009, 0x3c0a0800, 0x0a001078,
+	0x93420934, 0x1082000b, 0x24020003, 0x10820026, 0x3c0a0800, 0x0a001078,
+	0x93420934, 0x974209e4, 0x00021400, 0x34420800, 0xad02000c, 0x0a001077,
+	0x25080010, 0x974209e4, 0x00021400, 0x34428100, 0xad02000c, 0x974309e8,
+	0x3c0a0800, 0x00031c00, 0x34630800, 0xad030010, 0x0a001077, 0x25080014,
+	0x974409e4, 0x3c050800, 0x24a25880, 0x9443001c, 0x94460014, 0x94470010,
+	0x00a05021, 0x24020800, 0xad000010, 0xad020014, 0x00042400, 0x00661821,
+	0x00671823, 0x2463fff2, 0x00832025, 0xad04000c, 0x0a001077, 0x25080018,
+	0x974209e4, 0x3c050800, 0x00021400, 0x34428100, 0xad02000c, 0x974409e8,
+	0x24a25880, 0x9443001c, 0x94460014, 0x94470010, 0x00a05021, 0x24020800,
+	0xad000014, 0xad020018, 0x00042400, 0x00661821, 0x00671823, 0x2463ffee,
+	0x00832025, 0xad040010, 0x2508001c, 0x93420934, 0x93450921, 0x3c074000,
+	0x25445880, 0x94830018, 0x94860014, 0x00021082, 0x00021600, 0x00052c00,
+	0x00a72825, 0x00451025, 0x00661821, 0x00431025, 0xad020000, 0x9783002c,
+	0x974209ea, 0x00621821, 0x00031c00, 0xad030004, 0x9782002c, 0x24420001,
+	0x30427fff, 0xa782002c, 0x93430920, 0x3c020006, 0x00031e00, 0x00621825,
+	0xad030008, 0x8f42092c, 0xad02000c, 0x8f430930, 0xad030010, 0x8f440938,
+	0x25080014, 0xad040000, 0x8f820020, 0x11200004, 0xad020004, 0x8f420940,
+	0x0a0010a1, 0x2442ffff, 0x8f420940, 0xad020008, 0x8f440948, 0x8f420940,
+	0x93430936, 0x00823023, 0x00663006, 0x3402ffff, 0x0046102b, 0x54400001,
+	0x3406ffff, 0x93420937, 0x25445880, 0x90830024, 0xad000010, 0x00021700,
+	0x34630010, 0x00031c00, 0x00431025, 0x00461025, 0xad02000c, 0x8c830008,
+	0x14600031, 0x25080014, 0x3c020800, 0x8c430048, 0x1060002d, 0x00000000,
+	0x9342010b, 0xad020000, 0x8f830000, 0x8c6200b0, 0xad020004, 0x8f830000,
+	0x8c6200b4, 0xad020008, 0x8f830000, 0x8c6200c0, 0xad02000c, 0x8f830000,
+	0x8c6200c4, 0xad020010, 0x8f830000, 0x8c6200c8, 0xad020014, 0x8f830000,
+	0x8c6200cc, 0xad020018, 0x8f830000, 0x8c6200e0, 0xad02001c, 0x8f830000,
+	0x8c6200e8, 0xad020020, 0x8f830000, 0x8c6200f0, 0x3c04600e, 0xad020024,
+	0x8c8200d0, 0xad020028, 0x8c8300d4, 0xad03002c, 0x8f820028, 0x3c046012,
+	0xad020030, 0x8c8200a8, 0xad020034, 0x8c8300ac, 0x3c026000, 0xad030038,
+	0x8c434448, 0xad03003c, 0x03e00008, 0x01001021, 0x27bdffa8, 0x3c020008,
+	0x03423021, 0xafbf0054, 0xafbe0050, 0xafb7004c, 0xafb60048, 0xafb50044,
+	0xafb40040, 0xafb3003c, 0xafb20038, 0xafb10034, 0xafb00030, 0xaf860000,
+	0x24020040, 0xaf420814, 0xaf400810, 0x8f420944, 0x8f430950, 0x8f440954,
+	0x8f45095c, 0xaf820034, 0xaf830020, 0xaf84001c, 0xaf850030, 0x90c20000,
+	0x24030020, 0x304400ff, 0x10830005, 0x24020030, 0x10820022, 0x3c030800,
+	0x0a001139, 0x8c62002c, 0x24020088, 0xaf420818, 0x3c020800, 0x244258e8,
+	0xafa20020, 0x93430109, 0x3c020800, 0x10600009, 0x24575900, 0x3c026000,
+	0x24030100, 0xac43081c, 0x3c030001, 0xac43081c, 0x0000000d, 0x00000000,
+	0x24000376, 0x9342010a, 0x30420080, 0x14400021, 0x24020800, 0x3c026000,
+	0x24030100, 0xac43081c, 0x3c030001, 0xac43081c, 0x0000000d, 0x00000000,
+	0x2400037d, 0x0a001141, 0x24020800, 0x93430109, 0x3063007f, 0x00031140,
+	0x000318c0, 0x00431021, 0x24430088, 0xaf430818, 0x0000000d, 0x3c020800,
+	0x24425940, 0x3c030800, 0x24775950, 0x0a001140, 0xafa20020, 0x24420001,
+	0xac62002c, 0x0000000d, 0x00000000, 0x24000395, 0x0a0014c1, 0x8fbf0054,
+	0x24020800, 0xaf420178, 0x8f450104, 0x8f420988, 0x00a21023, 0x58400005,
+	0x8f4309a0, 0x0000000d, 0x00000000, 0x240003b1, 0x8f4309a0, 0x3c100800,
+	0xae0358b0, 0x8f4209a4, 0x8f830020, 0x260458b0, 0x2491ffd0, 0xae220034,
+	0x00a21023, 0xae230028, 0xac82ffd0, 0x8fa30020, 0x8c620000, 0x0040f809,
+	0x0200b021, 0x00409021, 0x32440010, 0x32420002, 0x10400007, 0xafa40024,
+	0x8e220020, 0x32530040, 0x2403ffbf, 0x00431024, 0x0a001493, 0xae220020,
+	0x32420020, 0x10400002, 0x3c020800, 0x24575920, 0x32420001, 0x14400007,
+	0x00000000, 0x8f820008, 0xaf420080, 0x8ec358b0, 0xaf430e10, 0x8e220034,
+	0xaf420e18, 0x9343010b, 0x93420905, 0x30420008, 0x1040003c, 0x307400ff,
+	0x8f820000, 0x8c430074, 0x0460000a, 0x00000000, 0x3c026000, 0x24030100,
+	0xac43081c, 0x3c030001, 0xac43081c, 0x0000000d, 0x00000000, 0x240003ed,
+	0x8f820000, 0x9044007b, 0x9343010a, 0x14830027, 0x32530040, 0x00003821,
+	0x24052000, 0x3c090800, 0x3c038000, 0x8f420178, 0x00431024, 0x1440fffd,
+	0x8ec258b0, 0x26c458b0, 0x2484ffd0, 0xaf420144, 0x8c820034, 0x3c030100,
+	0xaf420148, 0x24020047, 0xaf43014c, 0xa3420152, 0x8d230030, 0x3c021000,
+	0xa7470158, 0xaf450154, 0xaf420178, 0x8c860034, 0x24630001, 0xad230030,
+	0x9342010a, 0x3c030047, 0xafa50014, 0x00021600, 0x00431025, 0x00471025,
+	0xafa20010, 0x9343010b, 0xafa30018, 0x8f440100, 0x8f450104, 0x0e00159b,
+	0x3c070100, 0x3c050800, 0x24a25880, 0x0a001250, 0x8c430020, 0x32820002,
+	0x10400050, 0x00000000, 0x0e0015b9, 0x32530040, 0x3c039000, 0x34630001,
+	0x8f820008, 0x3c048000, 0x00431025, 0xaf420020, 0x8f420020, 0x00441024,
+	0x1440fffd, 0x00000000, 0x8f830000, 0x90620005, 0x34420008, 0xa0620005,
+	0x8f840000, 0x8c820074, 0x3c038000, 0x00431025, 0xac820074, 0x90830000,
+	0x24020020, 0x10620004, 0x00000000, 0x0000000d, 0x00000000, 0x2400040b,
+	0x8f830008, 0x3c028000, 0x34420001, 0x00621825, 0xaf430020, 0x9084007b,
+	0x9342010a, 0x14820028, 0x3c030800, 0x00003821, 0x24052000, 0x3c090800,
+	0x3c038000, 0x8f420178, 0x00431024, 0x1440fffd, 0x8ec258b0, 0x26c458b0,
+	0x2484ffd0, 0xaf420144, 0x8c820034, 0x3c030100, 0xaf420148, 0x24020046,
+	0xaf43014c, 0xa3420152, 0x8d230030, 0x3c021000, 0xa7470158, 0xaf450154,
+	0xaf420178, 0x8c860034, 0x24630001, 0xad230030, 0x9342010a, 0x3c030046,
+	0xafa50014, 0x00021600, 0x00431025, 0x00471025, 0xafa20010, 0x9343010b,
+	0xafa30018, 0x8f440100, 0x8f450104, 0x0e00159b, 0x3c070100, 0x3c030800,
+	0x24625880, 0x0a001250, 0x8c430020, 0x93420108, 0x30420010, 0x50400056,
+	0x9343093f, 0x8f860000, 0x90c2007f, 0x8cc30178, 0x304800ff, 0x15030004,
+	0x00000000, 0x0000000d, 0x00000000, 0x24000425, 0x90c2007e, 0x90c40080,
+	0x00081c00, 0x00021600, 0x00431025, 0x00042200, 0x90c3007a, 0x90c5000a,
+	0x00441025, 0x11050028, 0x00623825, 0xa0c8000a, 0x00004021, 0x24056000,
+	0x3c090800, 0x3c038000, 0x8f420178, 0x00431024, 0x1440fffd, 0x8ec258b0,
+	0x26c458b0, 0x2484ffd0, 0xaf420144, 0x8c820034, 0xaf420148, 0x24020052,
+	0xaf47014c, 0xa3420152, 0x8d230030, 0x3c021000, 0xa7480158, 0xaf450154,
+	0xaf420178, 0x8c860034, 0x24630001, 0xad230030, 0x9342010a, 0x3c030052,
+	0xafa50014, 0x00021600, 0x00431025, 0x00481025, 0xafa20010, 0x9343010b,
+	0xafa30018, 0x8f440100, 0x0e00159b, 0x8f450104, 0x0a00124a, 0x00000000,
+	0x3c026000, 0x24030100, 0xac43081c, 0x3c030001, 0xac43081c, 0x0000000d,
+	0x00000000, 0x2400043e, 0x16800009, 0x3c050800, 0x3c040800, 0x24825880,
+	0x8c430020, 0x32530040, 0x2404ffbf, 0x00641824, 0x0a001493, 0xac430020,
+	0x8ca25880, 0x10400005, 0x3c030800, 0x8c620034, 0xaca05880, 0x24420001,
+	0xac620034, 0x9343093f, 0x24020012, 0x5462000e, 0x97420908, 0x32820038,
+	0x14400009, 0x3c030800, 0x8f830000, 0x8c62004c, 0xac62005c, 0x3c020800,
+	0x24445880, 0x8c820020, 0x0a001285, 0x32530040, 0xac605880, 0x97420908,
+	0x5440001c, 0x97420908, 0x3c039000, 0x34630001, 0x8f820008, 0x32530040,
+	0x3c048000, 0x00431025, 0xaf420020, 0x8f420020, 0x00441024, 0x1440fffd,
+	0x3c028000, 0x8f840000, 0x8f850008, 0x8c830050, 0x34420001, 0x00a22825,
+	0xaf830020, 0xac830070, 0xac83005c, 0xaf450020, 0x3c050800, 0x24a45880,
+	0x8c820020, 0x2403ffbf, 0x00431024, 0x0a001493, 0xac820020, 0x000211c0,
+	0xaf420024, 0x97420908, 0x3c030080, 0x34630003, 0x000211c0, 0xaf42080c,
+	0xaf43081c, 0x974209ec, 0x8f4309a4, 0xa782002c, 0x3c020800, 0x24445880,
+	0xac83002c, 0x93420937, 0x93430934, 0x00021080, 0x00621821, 0xa4830018,
+	0x934209d8, 0x32850038, 0xafa50028, 0x00621821, 0xa483001a, 0x934209d8,
+	0x93430934, 0x3c1e0800, 0x00809821, 0x00431021, 0x24420010, 0xa4820016,
+	0x24020006, 0xae620020, 0x8fa20028, 0x10400003, 0x0000a821, 0x0a0012f0,
+	0x24120008, 0x8f420958, 0x8f830020, 0x8f840030, 0x00431023, 0x00832023,
+	0x04800003, 0xae620004, 0x04410003, 0x0082102b, 0x0a0012bc, 0xae600004,
+	0x54400001, 0xae640004, 0x8ee20000, 0x0040f809, 0x00000000, 0x00409021,
+	0x32420001, 0x5440001e, 0x8ee20004, 0x8e630008, 0x1060002b, 0x3c02c000,
+	0x00621025, 0xaf420e00, 0x8f420000, 0x30420008, 0x1040fffd, 0x00000000,
+	0x97420e08, 0xa7820010, 0x8f430e04, 0x8e620008, 0xaf830004, 0x8f840004,
+	0x0044102b, 0x1040000b, 0x24150001, 0x24020100, 0x3c016000, 0xac22081c,
+	0x3c020001, 0x3c016000, 0xac22081c, 0x0000000d, 0x00000000, 0x240004cd,
+	0x24150001, 0x8ee20004, 0x0040f809, 0x00000000, 0x02429025, 0x32420002,
+	0x5040001d, 0x8f470940, 0x12a00006, 0x8ec258b0, 0x8f830000, 0xac6200a8,
+	0x8f840000, 0x8e620034, 0xac8200ac, 0x32420004, 0x50400013, 0x8f470940,
+	0x3c020800, 0x3283007d, 0x10600110, 0x24575920, 0x32820001, 0x50400006,
+	0x36520002, 0x8f830034, 0x8f420940, 0x10620109, 0x00000000, 0x36520002,
+	0x24020008, 0xa6600010, 0xa6620012, 0xae600008, 0xa2600024, 0x8f470940,
+	0x3c030800, 0x24685880, 0x8d02002c, 0x8d050008, 0x95040010, 0x9506000a,
+	0x95030026, 0x00451021, 0x00862021, 0x00641821, 0xaf870034, 0xad02002c,
+	0x32820030, 0x10400008, 0xa5030014, 0x91020024, 0x32910040, 0x34420004,
+	0xa1020024, 0xaf400048, 0x0a001345, 0x3c040800, 0x93420923, 0x30420002,
+	0x10400029, 0x32910040, 0x8f830000, 0x8f840020, 0x8c620084, 0x00441023,
+	0x0442000a, 0x3c039000, 0x95020014, 0x8c630084, 0x00821021, 0x00621823,
+	0x1c600004, 0x3c039000, 0x91020024, 0x34420001, 0xa1020024, 0x34630001,
+	0x8f820008, 0x32910040, 0x3c048000, 0x00431025, 0xaf420020, 0x8f420020,
+	0x00441024, 0x1440fffd, 0x00000000, 0x8f840000, 0x9083003f, 0x2402000a,
+	0x10620005, 0x2402000c, 0x9083003f, 0x24020008, 0x14620002, 0x24020014,
+	0xa082003f, 0x8f830008, 0x3c028000, 0x34420001, 0x00621825, 0xaf430020,
+	0x3c040800, 0x24865880, 0x94c20010, 0x94c3001a, 0x8cc40008, 0x00432821,
+	0x14800006, 0xa4c5001c, 0x3c020800, 0x8c430048, 0x10600002, 0x24a20040,
+	0xa4c2001c, 0x27d05880, 0x9604001c, 0x96020012, 0x00822021, 0x24840002,
+	0x0e000faf, 0x3084ffff, 0x8f850018, 0x00a01821, 0xa2030025, 0x8ee60008,
+	0x00402021, 0x24a50001, 0xaf850018, 0x00c0f809, 0x00000000, 0x00402021,
+	0x0e001026, 0x02202821, 0x8ee3000c, 0x0060f809, 0x00402021, 0x9604001c,
+	0x96020012, 0x00822021, 0x24840002, 0x0e000fc5, 0x3084ffff, 0x8fc25880,
+	0x8e030008, 0x00431023, 0x14400012, 0xafc25880, 0x54600006, 0x8e020020,
+	0x3243004a, 0x24020002, 0x14620005, 0x00000000, 0x8e020020, 0x34420040,
+	0x0a001382, 0xae020020, 0x52a00006, 0x36520002, 0x8e020030, 0xaf420e10,
+	0x8e030034, 0xaf430e18, 0x36520002, 0x52a00008, 0x96670014, 0x8f830000,
+	0x8f420e10, 0xac6200a8, 0x8f840000, 0x8f420e18, 0xac8200ac, 0x96670014,
+	0x92680024, 0x24020040, 0xaf420814, 0x8f830020, 0x8f82001c, 0x00671821,
+	0x00621023, 0xaf830020, 0x18400008, 0x00000000, 0x8f820000, 0xaf83001c,
+	0xac430054, 0x54e00005, 0xaf400040, 0x0a0013a0, 0x8f42095c, 0x54e00001,
+	0xaf400044, 0x8f42095c, 0x31030008, 0xaf820030, 0x1060001a, 0x00000000,
+	0x8f840000, 0x90820120, 0x90830121, 0x304600ff, 0x00c31823, 0x30630007,
+	0x24020007, 0x1062000e, 0x00000000, 0x90820122, 0x304200fe, 0xa0820122,
+	0x8f850000, 0x00061880, 0x8f840020, 0x24a20100, 0x00431021, 0x24c30001,
+	0x30630007, 0xac440000, 0x0a0013bd, 0xa0a30120, 0x90820122, 0x34420001,
+	0xa0820122, 0x14e00003, 0x31020001, 0x10400031, 0x32510002, 0x8f820000,
+	0x8c43000c, 0x30630001, 0x1060002c, 0x32510002, 0x3c029000, 0x8f830008,
+	0x34420001, 0x3c048000, 0x00621825, 0xaf430020, 0x8f420020, 0x00441024,
+	0x1440fffd, 0x00000000, 0x8f870000, 0x8ce2000c, 0x30420001, 0x10400018,
+	0x00000000, 0x94e2006a, 0x00022880, 0x50a00001, 0x24050001, 0x94e30068,
+	0x90e40081, 0x3c020800, 0x8c460024, 0x00652821, 0x00852804, 0x00c5102b,
+	0x54400001, 0x00a03021, 0x3c020800, 0x8c440028, 0x00c4182b, 0x54600001,
+	0x00c02021, 0x8f430074, 0x2402fffe, 0x00822824, 0x00a31821, 0xace3000c,
+	0x8f830008, 0x3c028000, 0x34420001, 0x00621825, 0xaf430020, 0x8f820020,
+	0x3c050800, 0x24b05880, 0xae020028, 0x8ee30010, 0x0060f809, 0x00000000,
+	0x8f820028, 0x24420001, 0xaf820028, 0x12a00005, 0xaf40004c, 0x8f420e10,
+	0xae020030, 0x8f430e18, 0xae030034, 0x1220fea7, 0x24020006, 0x8f870024,
+	0x9786002c, 0x8f830000, 0x8f820034, 0x8f840020, 0x8f85001c, 0x32530040,
+	0xa4e6002c, 0xac620044, 0x32420008, 0xac640050, 0xac650054, 0x1040007a,
+	0x32820020, 0x10400027, 0x32910010, 0x00003821, 0x24052000, 0x3c090800,
+	0x3c038000, 0x8f420178, 0x00431024, 0x1440fffd, 0x8ec258b0, 0x26c458b0,
+	0x2484ffd0, 0xaf420144, 0x8c820034, 0x3c030400, 0xaf420148, 0x24020041,
+	0xaf43014c, 0xa3420152, 0x8d230030, 0x3c021000, 0xa7470158, 0xaf450154,
+	0xaf420178, 0x8c860034, 0x24630001, 0xad230030, 0x9342010a, 0x3c030041,
+	0xafa50014, 0x00021600, 0x00431025, 0x00471025, 0xafa20010, 0x9343010b,
+	0xafa30018, 0x8f440100, 0x8f450104, 0x0e00159b, 0x3c070400, 0x12200028,
+	0x00003821, 0x24052000, 0x3c090800, 0x3c038000, 0x8f420178, 0x00431024,
+	0x1440fffd, 0x8ec258b0, 0x26c458b0, 0x2484ffd0, 0xaf420144, 0x8c820034,
+	0x3c030300, 0xaf420148, 0x2402004e, 0xaf43014c, 0xa3420152, 0x8d230030,
+	0x3c021000, 0xa7470158, 0xaf450154, 0xaf420178, 0x8c860034, 0x24630001,
+	0xad230030, 0x9342010a, 0x3c03004e, 0xafa50014, 0x00021600, 0x00431025,
+	0x00471025, 0xafa20010, 0x9343010b, 0xafa30018, 0x8f440100, 0x8f450104,
+	0x0e00159b, 0x3c070300, 0x0a00148b, 0x8fa20024, 0x32820008, 0x10400026,
+	0x24052000, 0x00003821, 0x3c090800, 0x3c038000, 0x8f420178, 0x00431024,
+	0x1440fffd, 0x8ec258b0, 0x26c458b0, 0x2484ffd0, 0xaf420144, 0x8c820034,
+	0x3c030200, 0xaf420148, 0x2402004b, 0xaf43014c, 0xa3420152, 0x8d230030,
+	0x3c021000, 0xa7470158, 0xaf450154, 0xaf420178, 0x8c860034, 0x24630001,
+	0xad230030, 0x9342010a, 0x3c03004b, 0xafa50014, 0x00021600, 0x00431025,
+	0x00471025, 0xafa20010, 0x9343010b, 0xafa30018, 0x8f440100, 0x8f450104,
+	0x0e00159b, 0x3c070200, 0x8fa20024, 0x14400004, 0x8fa30020, 0x32420010,
+	0x10400004, 0x00000000, 0x8c620004, 0x0040f809, 0x00000000, 0x12600006,
+	0x8fa40020, 0x8c820008, 0x0040f809, 0x00000000, 0x0a0014c1, 0x8fbf0054,
+	0x3c030800, 0x8c6258a0, 0x30420040, 0x14400023, 0x8fbf0054, 0x00002821,
+	0x24040040, 0x8f870020, 0x3c038000, 0x8f420178, 0x00431024, 0x1440fffd,
+	0x8ec258b0, 0x26c358b0, 0x2463ffd0, 0xaf420144, 0x8c620034, 0xaf420148,
+	0x24020049, 0xaf47014c, 0xa3420152, 0x3c021000, 0xa7450158, 0xaf440154,
+	0xaf420178, 0x8c660034, 0x9342010a, 0x3c030049, 0xafa40014, 0x00021600,
+	0x00431025, 0x00451025, 0xafa20010, 0x9343010b, 0xafa30018, 0x8f440100,
+	0x0e00159b, 0x8f450104, 0x8fbf0054, 0x8fbe0050, 0x8fb7004c, 0x8fb60048,
+	0x8fb50044, 0x8fb40040, 0x8fb3003c, 0x8fb20038, 0x8fb10034, 0x8fb00030,
+	0x03e00008, 0x27bd0058, 0x03e00008, 0x00001021, 0x3c020800, 0x24435880,
+	0x8c650004, 0x8c445880, 0x0085182b, 0x10600002, 0x00403021, 0x00802821,
+	0x9744093c, 0x00a4102b, 0x54400001, 0x00a02021, 0x93420923, 0x0004182b,
+	0x00021042, 0x30420001, 0x00431024, 0x1040000d, 0x24c25880, 0x8f850000,
+	0x8f830020, 0x8ca20084, 0x00431023, 0x04420007, 0x24c25880, 0x8ca20084,
+	0x00641821, 0x00431023, 0x28420001, 0x00822023, 0x24c25880, 0xac440008,
+	0xa4400026, 0x03e00008, 0x00001021, 0x8f850004, 0x97840010, 0x3c030800,
+	0x24635880, 0x24020008, 0xa4620012, 0x8f820004, 0xa4600010, 0x000420c2,
+	0x30840008, 0x2c420001, 0x00021023, 0x30420006, 0xac650008, 0x03e00008,
+	0xa0640024, 0x3c020800, 0x24425880, 0x90450025, 0x9443001c, 0x3c021100,
+	0xac800004, 0x00052c00, 0x24630002, 0x00621825, 0x00a32825, 0x24820008,
+	0x03e00008, 0xac850000, 0x27bdffd8, 0x3c020800, 0x24425880, 0xafbf0020,
+	0x90480025, 0x8c440008, 0x8c460020, 0x8f870020, 0x3c030800, 0x3c058000,
+	0x8f420178, 0x00451024, 0x1440fffd, 0x8c6258b0, 0x246358b0, 0x2469ffd0,
+	0xaf420144, 0x8d220034, 0x30c32000, 0xaf420148, 0x3c021000, 0xaf47014c,
+	0xa3480152, 0xa7440158, 0xaf460154, 0xaf420178, 0x10600004, 0x3c030800,
+	0x8c620030, 0x24420001, 0xac620030, 0x9342010a, 0x00081c00, 0x3084ffff,
+	0xafa60014, 0x00021600, 0x00431025, 0x00441025, 0xafa20010, 0x9343010b,
+	0xafa30018, 0x8f440100, 0x8f450104, 0x0e00159b, 0x8d260034, 0x8fbf0020,
+	0x03e00008, 0x27bd0028, 0x0000000d, 0x00000000, 0x2400019d, 0x03e00008,
+	0x00000000, 0x0000000d, 0x00000000, 0x240001a9, 0x03e00008, 0x00000000,
+	0x03e00008, 0x00000000, 0x3c020800, 0x24425880, 0xac400008, 0xa4400026,
+	0x03e00008, 0x24020001, 0x3c020800, 0x24425880, 0x24030008, 0xac400008,
+	0xa4400010, 0xa4430012, 0xa0400024, 0x03e00008, 0x24020004, 0x03e00008,
+	0x00001021, 0x10c00007, 0x00000000, 0x8ca20000, 0x24c6ffff, 0x24a50004,
+	0xac820000, 0x14c0fffb, 0x24840004, 0x03e00008, 0x00000000, 0x0a00156c,
+	0x00a01021, 0xac860000, 0x00000000, 0x00000000, 0x24840004, 0x00a01021,
+	0x1440fffa, 0x24a5ffff, 0x03e00008, 0x00000000, 0x3c0a0800, 0x8d490068,
+	0x3c050800, 0x24a52098, 0x00093140, 0x00c51021, 0xac440000, 0x8f440e04,
+	0x00a61021, 0xac440004, 0x97430e08, 0x97420e0c, 0x00a62021, 0x00031c00,
+	0x00431025, 0xac820008, 0x8f430e10, 0x00801021, 0xac43000c, 0x8f440e14,
+	0xac440010, 0x8f430e18, 0x3c0800ff, 0xac430014, 0x8f470e1c, 0x3508ffff,
+	0x25290001, 0xac470018, 0x3c070800, 0x8ce3006c, 0x9344010a, 0x3c026000,
+	0x24630001, 0xace3006c, 0x8c434448, 0x3129007f, 0x00a62821, 0xad490068,
+	0x00042600, 0x00681824, 0x00832025, 0x03e00008, 0xaca4001c, 0x8fac0010,
+	0x8fad0014, 0x8fae0018, 0x3c0b0800, 0x8d6a0060, 0x3c080800, 0x25080080,
+	0x000a4940, 0x01281021, 0x01091821, 0xac440000, 0x00601021, 0xac650004,
+	0xac460008, 0xac67000c, 0xac4c0010, 0xac6d0014, 0x3c036000, 0xac4e0018,
+	0x8c654448, 0x3c040800, 0x8c820064, 0x254a0001, 0x314a00ff, 0x01094021,
+	0xad6a0060, 0x24420001, 0xac820064, 0x03e00008, 0xad05001c, 0x3c030800,
+	0x3c090800, 0x8d250070, 0x246330b0, 0x8f460100, 0x00053900, 0x00e31021,
+	0xac460000, 0x8f440104, 0x00671021, 0xac440004, 0x8f460108, 0x8f840014,
+	0x24a50001, 0xac460008, 0x8c880074, 0x3c060800, 0x8cc20074, 0x30a5003f,
+	0x00671821, 0xad250070, 0x24420001, 0xacc20074, 0x03e00008, 0xac68000c,
+	0x00000000 };
+
+static u32 bnx2_TXP_b06FwData[(0x0/4) + 1] = { 0x0 };
+static u32 bnx2_TXP_b06FwRodata[(0x0/4) + 1] = { 0x0 };
+static u32 bnx2_TXP_b06FwBss[(0x1c4/4) + 1] = { 0x0 };
+static u32 bnx2_TXP_b06FwSbss[(0x38/4) + 1] = { 0x0 };
diff -pruN 1.0.0+git-20190125.36a4c85-5.1/src/drivers/net/bnx2.h 1.21.1+git-20220113.fbbdc3926-0ubuntu1/src/drivers/net/bnx2.h
--- 1.0.0+git-20190125.36a4c85-5.1/src/drivers/net/bnx2.h	1970-01-01 00:00:00.000000000 +0000
+++ 1.21.1+git-20220113.fbbdc3926-0ubuntu1/src/drivers/net/bnx2.h	2022-01-13 13:43:08.000000000 +0000
@@ -0,0 +1,4598 @@
+/* bnx2.h: Broadcom NX2 network driver.
+ *
+ * Copyright (c) 2004, 2005, 2006 Broadcom Corporation
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation.
+ *
+ * Written by: Michael Chan  (mchan@broadcom.com)
+ */
+
+FILE_LICENCE ( GPL_ANY );
+
+#ifndef BNX2_H
+#define BNX2_H
+
+#define L1_CACHE_BYTES 128 /* Rough approximaition of the cache line size */
+#define L1_CACHE_ALIGN(X) (((X) + L1_CACHE_BYTES-1)&~(L1_CACHE_BYTES -1))
+
+typedef unsigned long dma_addr_t;
+
+/* From pci.h */
+typedef int pci_power_t;
+
+#define PCI_D0          ((pci_power_t) 0)
+#define PCI_D1          ((pci_power_t) 1)
+#define PCI_D2          ((pci_power_t) 2)
+#define PCI_D3hot       ((pci_power_t) 3)
+#define PCI_D3cold      ((pci_power_t) 4)
+#define PCI_UNKNOWN     ((pci_power_t) 5)
+#define PCI_POWER_ERROR ((pci_power_t) -1)
+
+/* From pci_regs.h */
+
+#define  PCI_CAP_ID_PCIX	0x07	/* PCI-X */
+#define  PCI_X_CMD		2	/* Modes & Features */
+#define  PCI_X_CMD_ERO		0x0002	/* Enable Relaxed Ordering */
+
+/* From mii.h */
+
+/* Indicates what features are advertised by the interface. */
+#define ADVERTISED_10baseT_Half		(1 << 0)
+#define ADVERTISED_10baseT_Full		(1 << 1)
+#define ADVERTISED_100baseT_Half	(1 << 2)
+#define ADVERTISED_100baseT_Full	(1 << 3)
+#define ADVERTISED_1000baseT_Half	(1 << 4)
+#define ADVERTISED_1000baseT_Full	(1 << 5)
+#define ADVERTISED_Autoneg		(1 << 6)
+#define ADVERTISED_TP			(1 << 7)
+#define ADVERTISED_AUI			(1 << 8)
+#define ADVERTISED_MII			(1 << 9)
+#define ADVERTISED_FIBRE		(1 << 10)
+#define ADVERTISED_BNC			(1 << 11)
+
+/* The following are all involved in forcing a particular link
+ * mode for the device for setting things.  When getting the
+ * devices settings, these indicate the current mode and whether
+ * it was foced up into this mode or autonegotiated.
+ */
+
+/* Duplex, half or full. */
+#define DUPLEX_HALF		0x00
+#define DUPLEX_FULL		0x01
+#define DUPLEX_INVALID          0x02
+
+/* Which connector port. */
+#define PORT_TP			0x00
+#define PORT_AUI		0x01
+#define PORT_MII		0x02
+#define PORT_FIBRE		0x03
+#define PORT_BNC		0x04
+
+/* Which tranceiver to use. */
+#define XCVR_INTERNAL		0x00
+#define XCVR_EXTERNAL		0x01
+#define XCVR_DUMMY1		0x02
+#define XCVR_DUMMY2		0x03
+#define XCVR_DUMMY3		0x04
+
+/* Enable or disable autonegotiation.  If this is set to enable,
+ * the forced link modes above are completely ignored.
+ */
+#define AUTONEG_DISABLE		0x00
+#define AUTONEG_ENABLE		0x01
+
+/* Wake-On-Lan options. */
+#define WAKE_PHY		(1 << 0)
+#define WAKE_UCAST		(1 << 1)
+#define WAKE_MCAST		(1 << 2)
+#define WAKE_BCAST		(1 << 3)
+#define WAKE_ARP		(1 << 4)
+#define WAKE_MAGIC		(1 << 5)
+#define WAKE_MAGICSECURE	(1 << 6) /* only meaningful if WAKE_MAGIC */
+
+/* The following are all involved in forcing a particular link
+ *  * mode for the device for setting things.  When getting the
+ *   * devices settings, these indicate the current mode and whether
+ *    * it was foced up into this mode or autonegotiated.
+ *     */
+
+/* The forced speed, 10Mb, 100Mb, gigabit. */
+#define SPEED_10                10
+#define SPEED_100               100
+#define SPEED_1000              1000
+#define SPEED_2500		2500
+#define SPEED_INVALID           0 /* XXX was 3 */
+
+
+/* Duplex, half or full. */
+#define DUPLEX_HALF             0x00
+#define DUPLEX_FULL             0x01
+#define DUPLEX_INVALID          0x02
+
+/* Which connector port. */
+#define PORT_TP                 0x00
+#define PORT_AUI                0x01
+#define PORT_MII                0x02
+#define PORT_FIBRE              0x03
+#define PORT_BNC                0x04
+
+/* Which tranceiver to use. */
+#define XCVR_INTERNAL           0x00
+#define XCVR_EXTERNAL           0x01
+#define XCVR_DUMMY1             0x02
+#define XCVR_DUMMY2             0x03
+#define XCVR_DUMMY3             0x04
+
+/* Enable or disable autonegotiation.  If this is set to enable,
+ *  * the forced link modes above are completely ignored.
+ *   */
+#define AUTONEG_DISABLE         0x00
+#define AUTONEG_ENABLE          0x01
+
+/* Wake-On-Lan options. */
+#define WAKE_PHY                (1 << 0)
+#define WAKE_UCAST              (1 << 1)
+#define WAKE_MCAST              (1 << 2)
+#define WAKE_BCAST              (1 << 3)
+#define WAKE_ARP                (1 << 4)
+#define WAKE_MAGIC              (1 << 5)
+#define WAKE_MAGICSECURE        (1 << 6) /* only meaningful if WAKE_MAGIC */
+
+/* Hardware data structures and register definitions automatically
+ * generated from RTL code. Do not modify.
+ */
+
+/*
+ *  tx_bd definition
+ */
+struct tx_bd {
+	u32 tx_bd_haddr_hi;
+	u32 tx_bd_haddr_lo;                                   
+	u32 tx_bd_mss_nbytes;                                     
+	u32 tx_bd_vlan_tag_flags;                                      
+		#define TX_BD_FLAGS_CONN_FAULT		(1<<0)
+		#define TX_BD_FLAGS_TCP_UDP_CKSUM	(1<<1)
+		#define TX_BD_FLAGS_IP_CKSUM		(1<<2)
+		#define TX_BD_FLAGS_VLAN_TAG		(1<<3)
+		#define TX_BD_FLAGS_COAL_NOW		(1<<4)
+		#define TX_BD_FLAGS_DONT_GEN_CRC	(1<<5)
+		#define TX_BD_FLAGS_END			(1<<6)
+		#define TX_BD_FLAGS_START		(1<<7)
+		#define TX_BD_FLAGS_SW_OPTION_WORD	(0x1f<<8)
+		#define TX_BD_FLAGS_SW_FLAGS		(1<<13)
+		#define TX_BD_FLAGS_SW_SNAP		(1<<14)
+		#define TX_BD_FLAGS_SW_LSO		(1<<15)
+
+};
+
+
+/*
+ *  rx_bd definition
+ */
+struct rx_bd {
+	u32 rx_bd_haddr_hi;
+	u32 rx_bd_haddr_lo;
+	u32 rx_bd_len;
+	u32 rx_bd_flags;
+		#define RX_BD_FLAGS_NOPUSH		(1<<0)
+		#define RX_BD_FLAGS_DUMMY		(1<<1)
+		#define RX_BD_FLAGS_END			(1<<2)
+		#define RX_BD_FLAGS_START		(1<<3)
+
+};
+
+
+/*
+ *  status_block definition
+ */
+struct status_block {
+	u32 status_attn_bits;
+		#define STATUS_ATTN_BITS_LINK_STATE		(1L<<0)
+		#define STATUS_ATTN_BITS_TX_SCHEDULER_ABORT	(1L<<1)
+		#define STATUS_ATTN_BITS_TX_BD_READ_ABORT	(1L<<2)
+		#define STATUS_ATTN_BITS_TX_BD_CACHE_ABORT	(1L<<3)
+		#define STATUS_ATTN_BITS_TX_PROCESSOR_ABORT	(1L<<4)
+		#define STATUS_ATTN_BITS_TX_DMA_ABORT		(1L<<5)
+		#define STATUS_ATTN_BITS_TX_PATCHUP_ABORT	(1L<<6)
+		#define STATUS_ATTN_BITS_TX_ASSEMBLER_ABORT	(1L<<7)
+		#define STATUS_ATTN_BITS_RX_PARSER_MAC_ABORT	(1L<<8)
+		#define STATUS_ATTN_BITS_RX_PARSER_CATCHUP_ABORT	(1L<<9)
+		#define STATUS_ATTN_BITS_RX_MBUF_ABORT		(1L<<10)
+		#define STATUS_ATTN_BITS_RX_LOOKUP_ABORT	(1L<<11)
+		#define STATUS_ATTN_BITS_RX_PROCESSOR_ABORT	(1L<<12)
+		#define STATUS_ATTN_BITS_RX_V2P_ABORT		(1L<<13)
+		#define STATUS_ATTN_BITS_RX_BD_CACHE_ABORT	(1L<<14)
+		#define STATUS_ATTN_BITS_RX_DMA_ABORT		(1L<<15)
+		#define STATUS_ATTN_BITS_COMPLETION_ABORT	(1L<<16)
+		#define STATUS_ATTN_BITS_HOST_COALESCE_ABORT	(1L<<17)
+		#define STATUS_ATTN_BITS_MAILBOX_QUEUE_ABORT	(1L<<18)
+		#define STATUS_ATTN_BITS_CONTEXT_ABORT		(1L<<19)
+		#define STATUS_ATTN_BITS_CMD_SCHEDULER_ABORT	(1L<<20)
+		#define STATUS_ATTN_BITS_CMD_PROCESSOR_ABORT	(1L<<21)
+		#define STATUS_ATTN_BITS_MGMT_PROCESSOR_ABORT	(1L<<22)
+		#define STATUS_ATTN_BITS_MAC_ABORT		(1L<<23)
+		#define STATUS_ATTN_BITS_TIMER_ABORT		(1L<<24)
+		#define STATUS_ATTN_BITS_DMAE_ABORT		(1L<<25)
+		#define STATUS_ATTN_BITS_FLSH_ABORT		(1L<<26)
+		#define STATUS_ATTN_BITS_GRC_ABORT		(1L<<27)
+		#define STATUS_ATTN_BITS_PARITY_ERROR		(1L<<31)
+
+	u32 status_attn_bits_ack;
+#if __BYTE_ORDER == __BIG_ENDIAN
+	u16 status_tx_quick_consumer_index0;
+	u16 status_tx_quick_consumer_index1;
+	u16 status_tx_quick_consumer_index2;
+	u16 status_tx_quick_consumer_index3;
+	u16 status_rx_quick_consumer_index0;
+	u16 status_rx_quick_consumer_index1;
+	u16 status_rx_quick_consumer_index2;
+	u16 status_rx_quick_consumer_index3;
+	u16 status_rx_quick_consumer_index4;
+	u16 status_rx_quick_consumer_index5;
+	u16 status_rx_quick_consumer_index6;
+	u16 status_rx_quick_consumer_index7;
+	u16 status_rx_quick_consumer_index8;
+	u16 status_rx_quick_consumer_index9;
+	u16 status_rx_quick_consumer_index10;
+	u16 status_rx_quick_consumer_index11;
+	u16 status_rx_quick_consumer_index12;
+	u16 status_rx_quick_consumer_index13;
+	u16 status_rx_quick_consumer_index14;
+	u16 status_rx_quick_consumer_index15;
+	u16 status_completion_producer_index;
+	u16 status_cmd_consumer_index;
+	u16 status_idx;
+	u16 status_unused;
+#elif __BYTE_ORDER == __LITTLE_ENDIAN
+	u16 status_tx_quick_consumer_index1;
+	u16 status_tx_quick_consumer_index0;
+	u16 status_tx_quick_consumer_index3;
+	u16 status_tx_quick_consumer_index2;
+	u16 status_rx_quick_consumer_index1;
+	u16 status_rx_quick_consumer_index0;
+	u16 status_rx_quick_consumer_index3;
+	u16 status_rx_quick_consumer_index2;
+	u16 status_rx_quick_consumer_index5;
+	u16 status_rx_quick_consumer_index4;
+	u16 status_rx_quick_consumer_index7;
+	u16 status_rx_quick_consumer_index6;
+	u16 status_rx_quick_consumer_index9;
+	u16 status_rx_quick_consumer_index8;
+	u16 status_rx_quick_consumer_index11;
+	u16 status_rx_quick_consumer_index10;
+	u16 status_rx_quick_consumer_index13;
+	u16 status_rx_quick_consumer_index12;
+	u16 status_rx_quick_consumer_index15;
+	u16 status_rx_quick_consumer_index14;
+	u16 status_cmd_consumer_index;
+	u16 status_completion_producer_index;
+	u16 status_unused;
+	u16 status_idx;
+#endif
+};
+
+
+/*
+ *  statistics_block definition
+ */
+struct statistics_block {
+	u32 stat_IfHCInOctets_hi;
+	u32 stat_IfHCInOctets_lo;
+	u32 stat_IfHCInBadOctets_hi;
+	u32 stat_IfHCInBadOctets_lo;
+	u32 stat_IfHCOutOctets_hi;
+	u32 stat_IfHCOutOctets_lo;
+	u32 stat_IfHCOutBadOctets_hi;
+	u32 stat_IfHCOutBadOctets_lo;
+	u32 stat_IfHCInUcastPkts_hi;
+	u32 stat_IfHCInUcastPkts_lo;
+	u32 stat_IfHCInMulticastPkts_hi;
+	u32 stat_IfHCInMulticastPkts_lo;
+	u32 stat_IfHCInBroadcastPkts_hi;
+	u32 stat_IfHCInBroadcastPkts_lo;
+	u32 stat_IfHCOutUcastPkts_hi;
+	u32 stat_IfHCOutUcastPkts_lo;
+	u32 stat_IfHCOutMulticastPkts_hi;
+	u32 stat_IfHCOutMulticastPkts_lo;
+	u32 stat_IfHCOutBroadcastPkts_hi;
+	u32 stat_IfHCOutBroadcastPkts_lo;
+	u32 stat_emac_tx_stat_dot3statsinternalmactransmiterrors;
+	u32 stat_Dot3StatsCarrierSenseErrors;
+	u32 stat_Dot3StatsFCSErrors;
+	u32 stat_Dot3StatsAlignmentErrors;
+	u32 stat_Dot3StatsSingleCollisionFrames;
+	u32 stat_Dot3StatsMultipleCollisionFrames;
+	u32 stat_Dot3StatsDeferredTransmissions;
+	u32 stat_Dot3StatsExcessiveCollisions;
+	u32 stat_Dot3StatsLateCollisions;
+	u32 stat_EtherStatsCollisions;
+	u32 stat_EtherStatsFragments;
+	u32 stat_EtherStatsJabbers;
+	u32 stat_EtherStatsUndersizePkts;
+	u32 stat_EtherStatsOverrsizePkts;
+	u32 stat_EtherStatsPktsRx64Octets;
+	u32 stat_EtherStatsPktsRx65Octetsto127Octets;
+	u32 stat_EtherStatsPktsRx128Octetsto255Octets;
+	u32 stat_EtherStatsPktsRx256Octetsto511Octets;
+	u32 stat_EtherStatsPktsRx512Octetsto1023Octets;
+	u32 stat_EtherStatsPktsRx1024Octetsto1522Octets;
+	u32 stat_EtherStatsPktsRx1523Octetsto9022Octets;
+	u32 stat_EtherStatsPktsTx64Octets;
+	u32 stat_EtherStatsPktsTx65Octetsto127Octets;
+	u32 stat_EtherStatsPktsTx128Octetsto255Octets;
+	u32 stat_EtherStatsPktsTx256Octetsto511Octets;
+	u32 stat_EtherStatsPktsTx512Octetsto1023Octets;
+	u32 stat_EtherStatsPktsTx1024Octetsto1522Octets;
+	u32 stat_EtherStatsPktsTx1523Octetsto9022Octets;
+	u32 stat_XonPauseFramesReceived;
+	u32 stat_XoffPauseFramesReceived;
+	u32 stat_OutXonSent;
+	u32 stat_OutXoffSent;
+	u32 stat_FlowControlDone;
+	u32 stat_MacCo